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/.travis.yml b/.travis.yml index 7138b23354..bef3a69ad7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: generic sudo: false +dist: xenial branches: except: - ___TGS3TempBranch @@ -14,6 +15,7 @@ matrix: packages: - python3 - python3-pip + - python3-setuptools cache: directories: - tgui/node_modules @@ -43,7 +45,8 @@ matrix: - gcc-multilib - g++-7 - g++-7-multilib - - libmariadbclient-dev:i386 + - libmariadb-client-lgpl-dev:i386 + - libmariadbd-dev cache: directories: - $HOME/.cargo diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index b3a0289761..738148c948 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -209,6 +209,8 @@ dir = 8 }, /obj/item/malf_upgrade, +/obj/item/disk/tech_disk/illegal, +/obj/structure/safe, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) "aB" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index ba291fc258..945ea515c7 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -272,7 +272,13 @@ /obj/machinery/light, /turf/open/floor/plasteel/freezer, /area/ruin/powered/seedvault) - +"Z" = ( +/obj/item/disk/design_disk/plant_disk, +/obj/machinery/autolathe/hacked{ + 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 +381,7 @@ h h u R -u +Z Q a a diff --git a/_maps/RandomRuins/SpaceRuins/arcade.dmm b/_maps/RandomRuins/SpaceRuins/arcade.dmm new file mode 100644 index 0000000000..771c33c55b --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/arcade.dmm @@ -0,0 +1,711 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"c" = ( +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"d" = ( +/turf/closed/wall/mineral/titanium/survival/pod, +/area/ruin/powered) +"e" = ( +/obj/machinery/computer/arcade, +/turf/open/floor/engine, +/area/ruin/powered) +"f" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/vending/coffee, +/turf/open/floor/engine, +/area/ruin/powered) +"g" = ( +/obj/item/coin, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"h" = ( +/obj/effect/mob_spawn/human/corpse/assistant, +/obj/effect/decal/cleanable/blood, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"i" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"j" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/engine, +/area/ruin/powered) +"k" = ( +/obj/item/coin/gold, +/turf/open/floor/engine, +/area/ruin/powered) +"l" = ( +/turf/open/floor/engine, +/area/ruin/powered) +"m" = ( +/obj/item/coin/iron, +/turf/open/floor/engine, +/area/ruin/powered) +"n" = ( +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"o" = ( +/obj/item/kitchen/knife{ + pixel_x = 5; + pixel_y = 11 + }, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"p" = ( +/turf/closed/wall/mineral/titanium/survival/nodiagonal, +/area/ruin/powered) +"q" = ( +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"r" = ( +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/ruin/powered) +"s" = ( +/obj/machinery/door/airlock/external/glass, +/obj/structure/fans/tiny, +/turf/open/floor/engine, +/area/ruin/powered) +"t" = ( +/obj/item/trash/chips, +/turf/open/floor/engine, +/area/ruin/powered) +"u" = ( +/obj/item/trash/cheesie, +/turf/open/floor/engine, +/area/ruin/powered) +"v" = ( +/obj/item/coin, +/turf/open/floor/engine, +/area/ruin/powered) +"w" = ( +/obj/item/coin/diamond, +/turf/open/floor/engine, +/area/ruin/powered) +"x" = ( +/obj/machinery/jukebox/disco/indestructible, +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"y" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/ruin/powered) +"z" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/engine, +/area/ruin/powered) +"A" = ( +/obj/machinery/door/airlock/external/glass, +/turf/open/floor/engine, +/area/ruin/powered) +"B" = ( +/obj/machinery/vending/cola/random, +/turf/open/floor/engine, +/area/ruin/powered) +"C" = ( +/obj/machinery/vending/snack/random, +/turf/open/floor/engine, +/area/ruin/powered) +"D" = ( +/obj/item/trash/can, +/turf/open/floor/engine, +/area/ruin/powered) +"E" = ( +/obj/item/trash/sosjerky, +/turf/open/floor/engine, +/area/ruin/powered) +"F" = ( +/obj/structure/closet/crate/trashcart, +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"G" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/engine, +/area/ruin/powered) +"H" = ( +/obj/structure/chair/sofa/left, +/obj/item/bedsheet/ian, +/turf/open/floor/engine, +/area/ruin/powered) +"I" = ( +/obj/item/aiModule/toyAI, +/turf/open/floor/engine, +/area/ruin/powered) +"J" = ( +/obj/item/twohanded/dualsaber/toy, +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"K" = ( +/obj/item/gun/energy/pumpaction/toy, +/turf/open/floor/engine, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +a +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +a +a +b +b +b +b +b +b +b +b +a +a +a +b +b +b +b +a +a +"} +(4,1,1) = {" +a +a +a +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +a +"} +(5,1,1) = {" +a +a +a +b +b +c +c +c +c +b +b +b +b +b +b +c +c +c +b +b +"} +(6,1,1) = {" +a +a +a +b +c +c +c +c +c +b +b +b +b +c +c +c +c +c +c +b +"} +(7,1,1) = {" +a +a +a +b +c +c +d +d +d +d +d +d +d +d +d +d +c +c +c +b +"} +(8,1,1) = {" +a +a +a +b +c +c +d +e +j +l +l +K +j +G +B +d +c +c +b +b +"} +(9,1,1) = {" +a +a +a +b +c +c +d +e +k +l +v +l +l +H +C +d +c +c +b +a +"} +(10,1,1) = {" +a +a +b +b +c +c +d +e +l +I +l +l +l +k +B +d +c +c +b +a +"} +(11,1,1) = {" +a +a +b +c +c +c +d +e +l +l +w +l +y +d +d +p +c +b +b +a +"} +(12,1,1) = {" +a +a +b +c +c +c +d +e +m +J +r +q +l +A +l +s +b +b +b +a +"} +(13,1,1) = {" +a +b +b +c +c +c +d +f +l +r +x +r +l +d +d +d +b +b +b +a +"} +(14,1,1) = {" +a +b +b +c +c +c +d +e +l +q +r +q +D +A +l +s +b +b +b +a +"} +(15,1,1) = {" +a +b +b +b +c +c +d +e +t +u +l +E +y +d +d +p +b +b +b +a +"} +(16,1,1) = {" +a +b +b +b +c +c +d +e +g +n +t +k +l +l +B +d +c +b +b +a +"} +(17,1,1) = {" +a +b +b +c +c +c +d +e +h +o +D +l +D +l +C +d +c +c +b +b +"} +(18,1,1) = {" +a +a +b +c +c +c +d +e +i +n +E +l +z +m +B +d +c +c +c +b +"} +(19,1,1) = {" +a +a +b +c +c +c +d +d +d +d +d +d +d +d +d +d +c +c +c +b +"} +(20,1,1) = {" +a +a +b +b +c +c +c +c +c +c +b +F +b +c +c +c +c +c +c +b +"} +(21,1,1) = {" +a +a +a +b +c +c +c +c +c +c +b +b +b +c +c +c +c +c +b +b +"} +(22,1,1) = {" +a +a +a +b +b +c +c +c +c +b +b +b +b +b +b +c +c +b +b +a +"} +(23,1,1) = {" +a +a +a +a +b +b +b +b +b +b +a +b +b +b +b +b +b +b +a +a +"} +(24,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +a +a +a +"} +(25,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm new file mode 100644 index 0000000000..c64050ce3a --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm @@ -0,0 +1,731 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"c" = ( +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"d" = ( +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"e" = ( +/obj/machinery/mecha_part_fabricator, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"f" = ( +/turf/closed/wall/rust, +/area/ruin/powered) +"g" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/plasteel, +/area/ruin/powered) +"h" = ( +/obj/machinery/mecha_part_fabricator, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"i" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/plasteel, +/area/ruin/powered) +"j" = ( +/obj/structure/chair/sofa/right, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"k" = ( +/turf/open/floor/plasteel, +/area/ruin/powered) +"l" = ( +/obj/structure/chair/sofa/left, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"m" = ( +/obj/machinery/computer/rdconsole/production{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"n" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"o" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"p" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"q" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/aug_manipulator, +/turf/open/floor/plasteel, +/area/ruin/powered) +"r" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/organ/cyberimp/chest/reviver, +/turf/open/floor/plasteel, +/area/ruin/powered) +"s" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/organ/cyberimp/arm/surgery, +/turf/open/floor/plasteel, +/area/ruin/powered) +"t" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/backpack/duffelbag/med/surgery, +/turf/open/floor/plasteel, +/area/ruin/powered) +"u" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"v" = ( +/obj/machinery/porta_turret/syndicate/energy{ + mode = 1 + }, +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"w" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/computer/mech_bay_power_console{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"x" = ( +/obj/effect/decal/cleanable/oil, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"y" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1, +/turf/open/floor/plasteel, +/area/ruin/powered) +"z" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/belt/utility/full, +/obj/item/clothing/glasses/welding, +/turf/open/floor/plasteel, +/area/ruin/powered) +"A" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/mmi/posibrain{ + pixel_y = 9 + }, +/obj/item/mmi, +/turf/open/floor/plasteel, +/area/ruin/powered) +"B" = ( +/obj/structure/table/optable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"C" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"D" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mech_bay_recharge_floor, +/area/ruin/powered) +"E" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"F" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/autosurgeon{ + name = "rusted autosurgeon"; + desc = "A device that automatically inserts an implant or organ into the user without the hassle of extensive surgery. It has a slot to insert an organ of implant. But this rusted version looks like it could only manage one implant...."; + uses = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"G" = ( +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"H" = ( +/obj/effect/decal/cleanable/oil, +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"I" = ( +/obj/machinery/door/airlock/external/glass, +/turf/open/floor/plasteel, +/area/ruin/powered) +"J" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1{ + dir = 4 + }, +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"K" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"L" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"M" = ( +/obj/structure/mecha_wreckage/ripley, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"N" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"O" = ( +/obj/machinery/turretid{ + lethal = 1; + pixel_y = -25; + req_access = null + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"P" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel, +/area/ruin/powered) +"Q" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"R" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel, +/area/ruin/powered) +"S" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"T" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/tank/air{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"U" = ( +/obj/machinery/door/airlock/external/glass, +/obj/structure/fans/tiny, +/turf/open/floor/plasteel, +/area/ruin/powered) +"V" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plasteel, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +a +a +a +b +b +b +b +a +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +a +a +a +b +b +c +c +c +c +J +b +b +a +a +a +a +a +a +a +"} +(4,1,1) = {" +a +a +a +b +c +c +c +c +c +c +K +c +b +b +b +a +a +a +a +a +"} +(5,1,1) = {" +a +a +b +c +c +d +d +d +d +d +L +d +c +c +b +a +a +a +a +a +"} +(6,1,1) = {" +a +a +b +c +d +d +m +q +w +C +M +d +d +c +b +a +a +a +a +a +"} +(7,1,1) = {" +a +b +b +c +d +e +n +o +x +D +N +f +d +v +b +a +a +a +a +a +"} +(8,1,1) = {" +a +b +c +c +d +g +o +o +y +Q +S +I +k +U +b +a +a +a +a +a +"} +(9,1,1) = {" +a +b +c +c +d +h +p +r +z +o +G +f +f +d +b +a +a +a +a +a +"} +(10,1,1) = {" +a +b +c +c +d +i +p +s +A +o +H +f +f +d +b +a +a +a +a +a +"} +(11,1,1) = {" +a +b +c +c +d +j +p +t +F +o +p +I +k +U +b +a +a +a +a +a +"} +(12,1,1) = {" +a +b +c +c +d +l +p +p +P +R +O +f +d +v +b +b +a +a +a +a +"} +(13,1,1) = {" +a +b +b +c +d +d +V +u +B +E +T +d +d +c +c +b +a +a +a +a +"} +(14,1,1) = {" +a +a +b +c +c +d +d +d +d +d +d +d +c +c +c +b +a +a +a +a +"} +(15,1,1) = {" +a +a +a +b +c +c +c +c +c +c +c +c +c +c +b +b +a +a +a +a +"} +(16,1,1) = {" +a +a +a +b +b +b +b +c +c +c +c +b +b +b +b +a +a +a +a +a +"} +(17,1,1) = {" +a +a +a +a +a +a +b +b +b +b +b +b +a +a +a +a +a +a +a +a +"} +(18,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(19,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(20,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/bigape.dmm b/_maps/RandomRuins/SpaceRuins/bigape.dmm new file mode 100644 index 0000000000..09e85e129d --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/bigape.dmm @@ -0,0 +1,196 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/template_noop) +"c" = ( +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"d" = ( +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"e" = ( +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/structure/fans/tiny/invisible, +/obj/structure/closet/secure_closet/freezer, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"f" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"g" = ( +/obj/item/flashlight/lamp/bananalamp{ + brightness_on = 10 + }, +/obj/structure/table/wood, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"h" = ( +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"i" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"j" = ( +/obj/structure/sink/puddle, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"k" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/mob/living/simple_animal/hostile/gorilla{ + AIStatus = null; + desc = "There is no need to be upset."; + dir = 4; + name = "Familiar Gorilla" + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"l" = ( +/obj/effect/overlay/palmtree_r, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"m" = ( +/obj/item/grown/bananapeel, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +b +a +"} +(2,1,1) = {" +a +a +b +b +b +b +b +b +a +a +"} +(3,1,1) = {" +a +a +b +b +g +d +d +b +b +a +"} +(4,1,1) = {" +a +a +b +d +f +k +i +d +d +b +"} +(5,1,1) = {" +a +a +b +e +c +c +m +j +d +b +"} +(6,1,1) = {" +a +a +b +d +c +h +c +l +d +b +"} +(7,1,1) = {" +a +b +b +b +d +d +d +b +b +a +"} +(8,1,1) = {" +a +b +a +a +b +b +b +b +b +b +"} +(9,1,1) = {" +a +b +a +a +a +b +a +a +a +b +"} +(10,1,1) = {" +a +a +a +a +a +b +a +a +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/originalcontent.dmm b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm index 624aa03d7c..2945a06b25 100644 --- a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm +++ b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm @@ -742,6 +742,7 @@ /turf/open/indestructible/paper, /area/ruin/powered) "cc" = ( +/obj/item/book/granter/action/origami, /mob/living/simple_animal/hostile/boss/paper_wizard, /turf/open/indestructible/paper, /area/ruin/powered) @@ -912,6 +913,10 @@ }, /turf/open/indestructible/paper, /area/ruin/powered) +"Ns" = ( +/obj/item/paper/secretrecipe, +/turf/open/indestructible/paper, +/area/ruin/powered) (1,1,1) = {" aa @@ -2246,7 +2251,7 @@ ap az af al -aA +Ns bW ca af diff --git a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm new file mode 100644 index 0000000000..341dcf7b99 --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm @@ -0,0 +1,2941 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/turf/closed/mineral/random/low_chance, +/area/ruin/unpowered) +"ac" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ad" = ( +/obj/machinery/hydroponics/soil, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ae" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"af" = ( +/obj/effect/spawner/structure/window/shuttle, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ag" = ( +/obj/structure/shuttle/engine/propulsion/right{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"ah" = ( +/obj/structure/table/wood, +/obj/item/shovel, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ai" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/template_noop) +"aj" = ( +/obj/machinery/computer/cryopod, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"ak" = ( +/obj/structure/fluff/empty_cryostasis_sleeper, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"al" = ( +/obj/machinery/status_display/shuttle, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"am" = ( +/obj/item/circuitboard/computer/rdconsole, +/obj/item/circuitboard/machine/protolathe/department/science, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"an" = ( +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ao" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 8 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ap" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"aq" = ( +/obj/machinery/computer{ + desc = "A computer long since rendered non-functional due to lack of maintenance. Spitting out error messages."; + dir = 4; + name = "Broken Computer" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ar" = ( +/obj/machinery/door/airlock/titanium{ + name = "Escape Pod Airlock" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"as" = ( +/obj/machinery/light, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"at" = ( +/obj/structure/shuttle/engine/propulsion/left{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"au" = ( +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"av" = ( +/obj/structure/table/wood, +/obj/item/paper/crumpled{ + info = "

So this is it, I guess.. Always thought I'd go out doing something stupid, but.. not like this.
Should anyone find this note, tell Jeremy Clarke he can kiss my ass. Launching the pod unprepared like that..
Well. Now that I'm keeling over here, I guess I should write how I came to be the last one standing here.
Four of us took this pod.. only three of us woke up though.. fourth pod is locked from the inside, we couldn't figure out how to get it open.
Me and the clown set up a farm s'we can survive at least a while.. though, he didn't seem to understand that man cannot live on banana alone.
Had a bunch of circuits on him for some reason when he eventually passed, whispered to me something about a chem dispenser.. I.. don't know what he meant by that. I was never good with machinary. Maybe he wanted space lube?
The assistant that we gave the space suit to go out and find help never came back.. I'm betting he found salvation and left us behind.. never can trust those grubby greytiders." + }, +/obj/item/pen, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aw" = ( +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ax" = ( +/obj/item/twohanded/spear, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ay" = ( +/obj/item/grown/log, +/obj/item/grown/log, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"az" = ( +/obj/structure/table/wood, +/obj/item/storage/bag/plants/portaseeder, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aA" = ( +/turf/open/floor/plating/asteroid/airless, +/area/ruin/unpowered) +"aB" = ( +/obj/item/seeds/banana, +/obj/item/seeds/banana, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aC" = ( +/obj/effect/mob_spawn/human/clown/corpse, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aD" = ( +/obj/item/mining_scanner, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aE" = ( +/obj/machinery/status_display/shuttle, +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"aF" = ( +/obj/item/pickaxe/emergency, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aG" = ( +/obj/structure/sink/puddle, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aH" = ( +/obj/structure/table/wood, +/obj/item/storage/firstaid/regular, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aI" = ( +/obj/effect/mob_spawn/human/corpse/assistant, +/turf/template_noop, +/area/template_noop) +"aJ" = ( +/obj/structure/table/wood, +/obj/item/storage/bag/ore, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aK" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aL" = ( +/obj/structure/table/wood, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/head/welding, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aM" = ( +/mob/living/simple_animal/hostile/carp, +/turf/template_noop, +/area/template_noop) +"aN" = ( +/obj/structure/mineral_door/sandstone, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aO" = ( +/mob/living/simple_animal/hostile/carp, +/turf/open/floor/plating/asteroid/airless, +/area/ruin/unpowered) +"aP" = ( +/obj/item/stack/ore/gold, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aQ" = ( +/obj/item/stack/ore/gold, +/obj/item/stack/ore/gold, +/obj/item/stack/ore/gold, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aR" = ( +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aS" = ( +/turf/closed/wall/mineral/iron, +/area/ruin/unpowered) +"aT" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aU" = ( +/obj/item/flashlight/lamp, +/obj/structure/table/wood, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aV" = ( +/obj/item/clothing/suit/space/orange, +/turf/template_noop, +/area/template_noop) +"aW" = ( +/obj/item/clothing/head/helmet/space/orange, +/turf/template_noop, +/area/template_noop) +"aX" = ( +/mob/living/simple_animal/hostile/carp/megacarp, +/turf/template_noop, +/area/template_noop) +"aY" = ( +/obj/effect/mob_spawn/human/hermit{ + flavour_text = "You've been late to awaken from your cryo slumber. Blasted machine, you set it to 10 days not 10 weeks! Where have the others gone while we were out? Did they manage to survive? These thoughts are dispelled by yet another recollection of how you got here... "; + job_description = "Space Hermit" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"aZ" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"ba" = ( +/obj/effect/spawner/structure/window/shuttle, +/turf/open/floor/mineral/titanium, +/area/ruin/unpowered) +"bb" = ( +/obj/structure/shuttle/engine/propulsion/left{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"bc" = ( +/obj/item/circuitboard/machine/circuit_imprinter, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bd" = ( +/obj/item/grown/bananapeel, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"be" = ( +/obj/effect/mob_spawn/human/corpse/cargo_tech, +/obj/structure/fans/tiny/invisible, +/obj/effect/decal/cleanable/vomit, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bf" = ( +/obj/item/clothing/glasses/meson, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bg" = ( +/obj/item/stock_parts/matter_bin, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bh" = ( +/obj/item/circuitboard/machine/autolathe, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"bi" = ( +/obj/item/stock_parts/manipulator, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bj" = ( +/obj/item/holosign_creator/atmos, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bk" = ( +/obj/structure/holosign/barrier/atmos, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bl" = ( +/obj/machinery/power/floodlight, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bm" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bn" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bo" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bp" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bq" = ( +/obj/structure/cable, +/obj/machinery/power/port_gen/pacman{ + active = 1; + anchored = 1; + sheets = 10 + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"br" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bs" = ( +/obj/item/flashlight/lamp/bananalamp, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +ac +aO +aA +aA +aA +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +aA +aA +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +aa +aa +aa +aa +aW +aa +aM +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aV +aI +aX +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +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 +"} +(6,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aA +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 +aM +aa +aa +aa +"} +(7,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aA +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 +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +aa +"} +(8,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +af +ae +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +"} +(9,1,1) = {" +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +aq +af +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(10,1,1) = {" +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ao +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(11,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +an +an +an +af +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(12,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +bh +an +an +ae +aZ +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(13,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +aY +ao +ao +ao +ak +ba +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(14,1,1) = {" +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +al +aj +ap +an +as +aj +aE +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(15,1,1) = {" +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +ak +ao +ao +ao +ak +ba +ac +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(16,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +az +ab +ab +ab +ab +ab +ab +ab +ab +aR +ae +ae +an +an +an +ae +aZ +ac +ab +ab +ab +ab +ab +ab +ab +aA +aM +"} +(17,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aR +ag +ag +af +ar +af +at +bb +ac +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(18,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ad +ac +ac +ac +ac +ab +aH +aJ +aL +ab +ab +aT +ac +ac +ac +ac +ac +ac +ac +aR +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(19,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +au +ac +aB +am +ac +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +bg +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(20,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +aw +bs +aC +ac +ac +ac +ac +ac +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(21,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +ax +ac +aD +aF +ac +ac +ac +ab +ab +ab +aU +bd +ac +ac +bl +bm +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(22,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +ay +ac +ac +ac +aG +ac +ac +ab +ab +ab +av +be +ac +ac +ac +bn +bo +bo +bq +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(23,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +bc +bf +ac +ac +ac +ac +ac +ac +br +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(24,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ab +ac +ac +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +aN +ac +ac +ac +ac +aR +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +"} +(26,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +aa +aa +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aK +ab +ab +ac +ac +ac +ac +ac +ac +ac +bp +ac +ac +aR +ab +ab +ab +aA +aa +aa +aa +aM +"} +(28,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aP +ac +ac +ac +ac +ac +ac +ac +ac +ac +aR +ab +ab +ab +aA +aa +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aQ +aP +ac +ac +aR +ac +ac +ac +ac +ab +ac +ab +ab +ab +aA +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +aP +ac +bg +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aa +aa +ab +aA +"} +(32,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +bg +ac +ac +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aa +aO +ab +ab +"} +(33,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +bj +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aA +ab +ab +ab +"} +(34,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aS +bi +ac +ac +ac +aS +aS +ab +ab +ab +ab +aA +aa +aA +ab +ab +aA +"} +(35,1,1) = {" +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aM +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aS +ac +ac +ac +ac +aS +aS +ab +ab +ab +aA +aa +aa +aA +ab +ab +ab +"} +(36,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aS +aS +aS +bk +bk +aS +aS +aS +aS +ab +ab +aA +aa +aa +aa +ab +ab +ab +"} +(37,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +ab +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +aA +aS +aS +aS +bk +aS +aS +aS +aA +aA +ab +aA +aa +aa +aa +aa +aA +aA +"} +(38,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +ai +ai +ai +ai +ai +ai +ai +ai +aA +aA +ab +aA +aa +aa +aa +aa +aa +aa +"} +(39,1,1) = {" +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +ai +ai +ai +aa +ai +aa +aa +aA +ab +aA +aa +aa +aa +aa +aa +aa +"} +(40,1,1) = {" +aa +aa +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +ai +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aa +"} +(41,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aa +"} +(42,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +aA +aA +aA +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aM +aa +aa +aa +"} +(43,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(44,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ac +aa +aa +aa +"} +(45,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +ac +ab +ac +aa +aa +"} +(46,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +aa +aa +"} +(47,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +aa +aa +"} +(48,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ac +ab +ac +aa +aa +"} +(49,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +ac +aa +aa +aa +aa +"} +(50,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +"} 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 de28ff59fa..4420059f62 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -41,6 +41,24 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/bar) +"aad" = ( +/obj/structure/bed, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/button/door{ + id = "Dorm4"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) "aae" = ( /obj/effect/landmark/carpspawn, /turf/open/space, @@ -515,10 +533,13 @@ /turf/closed/wall, /area/security/main) "abq" = ( -/turf/closed/wall, +/turf/closed/wall/r_wall, /area/crew_quarters/heads/hos) "abr" = ( /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "hos" + }, /turf/open/floor/plating, /area/crew_quarters/heads/hos) "abs" = ( @@ -574,6 +595,19 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/security/execution/transfer) +"abz" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Dorm5"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) "abA" = ( /obj/machinery/light, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -846,8 +880,13 @@ }, /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{ + pixel_x = -5 + }, /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "abX" = ( @@ -1449,6 +1488,9 @@ "adm" = ( /obj/structure/disposalpipe/segment, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "hos" + }, /turf/open/floor/plating, /area/crew_quarters/heads/hos) "adn" = ( @@ -1674,6 +1716,11 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/button/door{ + id = "hos"; + name = "HoS Office Shutters"; + pixel_y = -25 + }, /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "adN" = ( @@ -2053,6 +2100,9 @@ "aex" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "hos" + }, /turf/open/floor/plating, /area/crew_quarters/heads/hos) "aey" = ( @@ -2099,6 +2149,55 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"aeD" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Dorm6"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) +"aeE" = ( +/obj/structure/bed, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/button/door{ + id = "Dorm3"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) +"aeF" = ( +/obj/structure/bed, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/button/door{ + id = "Dorm2"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) "aeG" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -2475,6 +2574,11 @@ }, /turf/open/floor/plasteel, /area/security/main) +"afn" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/turf/open/floor/plasteel/white, +/area/medical/virology) "afo" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod Three" @@ -2495,6 +2599,14 @@ }, /turf/open/space/basic, /area/space) +"afq" = ( +/obj/structure/bed, +/obj/item/tank/internals/anesthetic, +/obj/item/clothing/mask/breath, +/obj/effect/decal/cleanable/semen, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/plating, +/area/maintenance/bar) "aft" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 5 @@ -7391,24 +7503,6 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) -"aqn" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/machinery/button/door{ - id = "Dorm4"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "aqo" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -8189,19 +8283,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness) -"asu" = ( -/obj/structure/bed, -/obj/item/bedsheet/red, -/obj/machinery/button/door{ - id = "Dorm5"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "asv" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance{ @@ -8293,19 +8374,6 @@ }, /turf/open/floor/plating, /area/maintenance/port/fore) -"asL" = ( -/obj/structure/bed, -/obj/item/bedsheet/red, -/obj/machinery/button/door{ - id = "Dorm6"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "asM" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -8912,24 +8980,6 @@ }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness) -"auw" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/machinery/button/door{ - id = "Dorm3"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "aux" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -10796,24 +10846,6 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) -"ayV" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/machinery/button/door{ - id = "Dorm2"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "ayW" = ( /turf/closed/wall, /area/ai_monitored/storage/eva) @@ -11691,7 +11723,7 @@ /area/maintenance/port/fore) "aAW" = ( /obj/structure/rack, -/obj/item/tank/jetpack/carbondioxide, +/obj/item/tank/jetpack/carbondioxide/eva, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -11815,7 +11847,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/item/tank/jetpack/carbondioxide, +/obj/item/tank/jetpack/carbondioxide/eva, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -26208,9 +26240,7 @@ /turf/open/floor/plasteel, /area/quartermaster/office) "bkx" = ( -/obj/machinery/status_display/supply{ - pixel_y = 2 - }, +/obj/machinery/status_display/supply, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -27901,8 +27931,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) @@ -31325,7 +31355,9 @@ id = "QMLoad" }, /obj/machinery/light, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_y = -32 + }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -31596,7 +31628,7 @@ /area/medical/sleeper) "bwC" = ( /obj/machinery/computer/med_data{ - dir = 4 + dir = 3 }, /turf/open/floor/plasteel/white, /area/medical/sleeper) @@ -33592,7 +33624,9 @@ name = "Station Intercom (General)"; pixel_y = -35 }, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_x = -32 + }, /obj/machinery/computer/security/qm{ dir = 4 }, @@ -36664,14 +36698,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" = ( @@ -37987,22 +38018,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" = ( @@ -38456,24 +38488,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" = ( @@ -39352,11 +39377,6 @@ /obj/machinery/announcement_system, /turf/open/floor/plasteel, /area/tcommsat/computer) -"bOm" = ( -/obj/item/bedsheet, -/obj/structure/bed, -/turf/open/floor/plasteel/white, -/area/medical/virology) "bOn" = ( /obj/machinery/light{ dir = 1 @@ -42618,11 +42638,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/medical/virology) -"bWk" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/turf/open/floor/plasteel/white, -/area/medical/virology) "bWl" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -46031,6 +46046,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" = ( @@ -46039,6 +46057,9 @@ name = "engineering security door" }, /obj/effect/turf_decal/delivery, +/obj/machinery/shower{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cel" = ( @@ -56650,6 +56671,12 @@ /obj/item/stock_parts/cell/high, /turf/open/floor/plasteel/white, /area/science/circuit) +"eef" = ( +/obj/machinery/autolathe{ + name = "public autolathe" + }, +/turf/open/floor/plasteel, +/area/quartermaster/office) "evR" = ( /turf/open/floor/plating, /area/maintenance/bar) @@ -56742,6 +56769,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" @@ -57109,6 +57146,12 @@ }, /turf/open/floor/plating, /area/construction/mining/aux_base) +"lKX" = ( +/mob/living/simple_animal/bot/cleanbot{ + name = "C.L.E.A.N." + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "lMg" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -57340,14 +57383,6 @@ }, /turf/open/floor/plating, /area/construction) -"rMN" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/item/tank/internals/anesthetic, -/obj/item/clothing/mask/breath, -/obj/effect/decal/cleanable/semen, -/turf/open/floor/plating, -/area/maintenance/bar) "rNc" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -57499,6 +57534,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 @@ -79814,7 +79853,7 @@ sAM imH evR evR -rMN +afq bCq bUs bLv @@ -81576,7 +81615,7 @@ cNG cNJ bLF aZK -bbR +eef bbR bqt cBq @@ -88451,7 +88490,7 @@ aaa aaf aaf aaa -abp +adR abP aco acO @@ -88478,13 +88517,13 @@ aoD aod aqe arf -aqn +aad ath arf -auw +aeE ath arf -ayV +aeF ath dgz aCd @@ -88965,7 +89004,7 @@ aaa aaa aaf aaa -abp +adR abO acq acq @@ -89479,15 +89518,15 @@ aaa aaa aaa aaf -abp +adR abR abP abP abP abP -abp -abp -abp +adR +adR +adR agA afU ahF @@ -90278,7 +90317,7 @@ cSA aqe arf ari -asu +abz aun auW avR @@ -91306,7 +91345,7 @@ apr aqj arf ark -asL +aeD aun avu awt @@ -94171,7 +94210,7 @@ blm bmL boi bpw -bhh +lKX bsx btX bvj @@ -95728,8 +95767,8 @@ bof bof bof bJE -bof -bof +bJE +bJE bNd bIJ bPo @@ -95985,7 +96024,7 @@ bof bGT bIo bof -bIo +tRe bLU bNd bII @@ -96499,10 +96538,10 @@ bof bGU bqQ bof -bCR +fTg bLV bNd -bOm +afn bPp bQF bRN @@ -98308,7 +98347,7 @@ bRQ bOr bSQ bWj -bWk +afn bXc bYe bNd @@ -98822,7 +98861,7 @@ bRQ bOr bSQ bWj -bWk +afn bXc bYe bNd diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index bd159e4e9c..bfc4a60f08 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -124,6 +124,22 @@ }, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"aaq" = ( +/obj/structure/bed, +/obj/machinery/status_display{ + pixel_y = 32 + }, +/obj/item/bedsheet/clown, +/turf/open/floor/plasteel/grimy, +/area/hallway/secondary/service) +"aar" = ( +/obj/structure/bed, +/obj/machinery/status_display{ + pixel_y = 32 + }, +/obj/item/bedsheet/mime, +/turf/open/floor/wood, +/area/hallway/secondary/service) "aas" = ( /obj/docking_port/stationary/random{ id = "pod_lavaland1"; @@ -143,6 +159,52 @@ /obj/effect/landmark/xeno_spawn, /turf/open/space, /area/solar/starboard/fore) +"aav" = ( +/obj/structure/bed, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/status_display{ + pixel_y = 32 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) +"aaw" = ( +/obj/structure/bed, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) +"aax" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) +"aay" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/plasteel/grimy, +/area/crew_quarters/dorms) +"aaz" = ( +/obj/structure/bed, +/obj/machinery/light, +/obj/machinery/status_display{ + pixel_y = -32 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) +"aaA" = ( +/obj/structure/bed, +/obj/item/tank/internals/anesthetic, +/obj/item/clothing/mask/breath, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/plating, +/area/crew_quarters/abandoned_gambling_den) "aaE" = ( /obj/structure/lattice/catwalk, /turf/open/space, @@ -13706,14 +13768,6 @@ }, /turf/open/floor/plasteel/grimy, /area/hallway/secondary/service) -"aDF" = ( -/obj/structure/bed, -/obj/machinery/status_display{ - pixel_y = 32 - }, -/obj/item/bedsheet/rainbow, -/turf/open/floor/plasteel/grimy, -/area/hallway/secondary/service) "aDG" = ( /turf/open/floor/plasteel/grimy, /area/hallway/secondary/service) @@ -16868,14 +16922,6 @@ }, /turf/open/floor/wood, /area/hallway/secondary/service) -"aIP" = ( -/obj/structure/bed, -/obj/machinery/status_display{ - pixel_y = 32 - }, -/obj/item/bedsheet/orange, -/turf/open/floor/wood, -/area/hallway/secondary/service) "aIQ" = ( /obj/structure/dresser, /turf/open/floor/wood{ @@ -35021,12 +35067,13 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "blM" = ( -/obj/structure/table, -/obj/item/storage/box/lights/mixed, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/autolathe{ + name = "public autolathe" + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "blN" = ( @@ -35043,6 +35090,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/item/storage/box/lights/mixed, /turf/open/floor/plasteel, /area/hallway/primary/fore) "blO" = ( @@ -78958,17 +79006,6 @@ /obj/structure/dresser, /turf/open/floor/carpet, /area/crew_quarters/dorms) -"cCi" = ( -/obj/structure/bed, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/bedsheet/red, -/obj/machinery/status_display{ - pixel_y = 32 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "cCj" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/item/clothing/suit/jacket{ @@ -79373,12 +79410,12 @@ }, /obj/structure/window/reinforced, /obj/structure/rack, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = 4; pixel_y = -1 }, -/obj/item/tank/jetpack/carbondioxide, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva, +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = -4; pixel_y = 1 }, @@ -80186,11 +80223,11 @@ /area/engine/storage) "cEi" = ( /obj/structure/table/reinforced, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = 3; pixel_y = 3 }, -/obj/item/tank/jetpack/carbondioxide, +/obj/item/tank/jetpack/carbondioxide/eva, /obj/machinery/power/apc{ dir = 4; name = "Engineering Storage APC"; @@ -80986,24 +81023,10 @@ icon_state = "wood-broken2" }, /area/crew_quarters/dorms) -"cFx" = ( -/obj/structure/bed, -/obj/item/bedsheet/black, -/obj/effect/decal/cleanable/dirt{ - desc = "A thin layer of dust coating the floor."; - name = "dust" - }, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "cFy" = ( /obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/wood, /area/crew_quarters/dorms) -"cFz" = ( -/obj/structure/bed, -/obj/item/bedsheet/blue, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "cFA" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp/green, @@ -87800,11 +87823,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cRs" = ( -/obj/structure/bed, -/obj/item/bedsheet/clown, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "cRt" = ( /obj/structure/table/wood, /obj/item/storage/briefcase{ @@ -88878,11 +88896,6 @@ /obj/structure/chair/office/dark, /turf/open/floor/wood, /area/crew_quarters/dorms) -"cTc" = ( -/obj/structure/bed, -/obj/item/bedsheet/mime, -/turf/open/floor/plasteel/grimy, -/area/crew_quarters/dorms) "cTd" = ( /obj/structure/table, /obj/item/storage/fancy/donut_box, @@ -90079,15 +90092,6 @@ }, /turf/open/floor/wood, /area/crew_quarters/dorms) -"cUX" = ( -/obj/structure/bed, -/obj/machinery/light, -/obj/item/bedsheet/brown, -/obj/machinery/status_display{ - pixel_y = -32 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "cUY" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/item/clothing/suit/jacket{ @@ -101814,6 +101818,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" = ( @@ -126296,6 +126301,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{ @@ -126355,6 +126374,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 @@ -126584,6 +126619,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, @@ -126593,6 +126635,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 @@ -126743,6 +126797,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 @@ -126853,6 +126924,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 @@ -126909,6 +126996,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 @@ -127110,13 +127214,6 @@ dir = 1 }, /area/science/circuit) -"poI" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/item/tank/internals/anesthetic, -/obj/item/clothing/mask/breath, -/turf/open/floor/plating, -/area/crew_quarters/abandoned_gambling_den) "psi" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/bodycontainer/morgue{ @@ -127259,6 +127356,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" @@ -151573,7 +151680,7 @@ djm fow dod dod -poI +aaA dfY ajr aad @@ -160727,11 +160834,11 @@ ary aAf aBu aCB -aDF +aaq aEJ aFV aDI -aIP +aar aKo aLE aMX @@ -174190,9 +174297,9 @@ dfL dCM dEb cPy -dfL -dCM -dEb +cNz +fhE +hSf cPy dhs dMS @@ -174447,7 +174554,7 @@ dBo cSF dEc cPy -dBo +lzF cSF dEc cPy @@ -174961,8 +175068,8 @@ dBq dCN dEe cPy -dBq -dCN +lTx +cSK dEe cPy cMg @@ -175218,9 +175325,9 @@ dBr dCO dEf cPy -dBr +eLw dCO -dEf +tRT cPy dLo dMW @@ -175475,9 +175582,9 @@ dBs dCP dEg cPy -dBs +jOE dCP -dEg +iwL cPy dLp dMV @@ -178267,7 +178374,7 @@ cyY cAx cCd cDD -cFx +aaw cGU cAw cJl @@ -178275,7 +178382,7 @@ cLa cMx cIi cPR -cRs +aax cDG cUW cAw @@ -179048,7 +179155,7 @@ cNU cDI cFB cDI -cUX +aaz cAw cYj cZV @@ -179295,7 +179402,7 @@ czc cAw cCg cDG -cFz +aax cGW cIi cJo @@ -180064,7 +180171,7 @@ bHq cxt coI cAw -cCi +aav cDI cFB cDI @@ -180332,7 +180439,7 @@ cMB cIi cPW cRv -cTc +aay cVb cAw cYp diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 228700580a..4de1657e48 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -2,10 +2,58 @@ "aaa" = ( /turf/open/space/basic, /area/space) +"aab" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Cabin3"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) "aac" = ( /obj/effect/landmark/carpspawn, /turf/open/space, /area/space) +"aad" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/machinery/button/door{ + id = "Cabin4"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_x = -25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) +"aae" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Cabin2"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) "aaf" = ( /obj/structure/lattice, /turf/open/space, @@ -252,6 +300,19 @@ }, /turf/open/floor/plating, /area/security/prison) +"aaM" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Cabin5"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = -25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) "aaN" = ( /obj/structure/cable{ icon_state = "0-2" @@ -294,6 +355,37 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"aaU" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Cabin6"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = -25; + specialfunctions = 4 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) +"aaV" = ( +/obj/machinery/button/door{ + id = "Cabin7"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = -25; + specialfunctions = 4 + }, +/obj/structure/bed, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) "aaY" = ( /obj/structure/cable{ icon_state = "1-2" @@ -10141,22 +10233,6 @@ /obj/item/clothing/under/assistantformal, /turf/open/floor/wood, /area/crew_quarters/dorms) -"asV" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/button/door{ - id = "Cabin3"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "asW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -10195,23 +10271,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) -"ata" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/button/door{ - id = "Cabin4"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_x = -25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/structure/bed, -/obj/item/bedsheet, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "atb" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/machinery/airalarm{ @@ -11892,21 +11951,6 @@ /obj/item/clothing/under/suit_jacket/tan, /turf/open/floor/carpet, /area/crew_quarters/dorms) -"awE" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/button/door{ - id = "Cabin2"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "awF" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -11920,19 +11964,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) -"awG" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/button/door{ - id = "Cabin5"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = -25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "awH" = ( /obj/machinery/newscaster{ pixel_y = 32 @@ -14983,22 +15014,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) -"aCJ" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/button/door{ - id = "Cabin6"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = -25; - specialfunctions = 4 - }, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "aCK" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/machinery/airalarm{ @@ -17575,21 +17590,6 @@ }, /turf/open/floor/plasteel/dark, /area/crew_quarters/dorms) -"aHS" = ( -/obj/machinery/button/door{ - id = "Cabin7"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_x = -25; - specialfunctions = 4 - }, -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "aHT" = ( /obj/structure/chair/wood/normal{ dir = 4 @@ -17692,7 +17692,9 @@ pixel_x = -28; pixel_y = 23 }, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_y = 32 + }, /obj/machinery/conveyor{ dir = 5; id = "QMLoad2" @@ -21617,7 +21619,9 @@ /obj/structure/table, /obj/item/clipboard, /obj/item/stamp/qm, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_x = 32 + }, /turf/open/floor/plasteel, /area/quartermaster/qm) "aQu" = ( @@ -27037,7 +27041,9 @@ /area/hallway/primary/port) "baA" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_y = 32 + }, /obj/structure/table, /obj/item/folder/yellow, /obj/effect/turf_decal/tile/brown{ @@ -27920,7 +27926,9 @@ /area/quartermaster/office) "bbS" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_y = 32 + }, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -31526,6 +31534,10 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plasteel, /area/hallway/primary/port) "biO" = ( @@ -32402,10 +32414,6 @@ /turf/open/floor/plasteel, /area/quartermaster/office) "bks" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/effect/spawner/lootdrop/maintenance, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -32413,6 +32421,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/autolathe{ + name = "public autolathe" + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "bkt" = ( @@ -47699,12 +47710,12 @@ }, /obj/structure/window/reinforced, /obj/structure/rack, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = 4; pixel_y = -1 }, -/obj/item/tank/jetpack/carbondioxide, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva, +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = -4; pixel_y = 1 }, @@ -64367,6 +64378,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" = ( @@ -65463,24 +65475,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 }, @@ -65493,31 +65490,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 }, @@ -65525,19 +65515,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{ @@ -65962,65 +65952,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 }, @@ -66033,9 +66011,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" = ( @@ -105762,8 +105737,8 @@ css dux dux dux -dux -dux +cxU +cxU cxU cyO czP @@ -120078,10 +120053,10 @@ agz aoV dhs arB -asV +aab auf arB -awE +aae axE arB dhA @@ -121620,19 +121595,19 @@ anK aoZ aqk arB -ata +aad aul avp -awG +aaM axJ avp aAj arB -aCJ +aaU aEe arB boS -aHS +aaV aJh aKt aLW diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index dbb26f8808..cef0aefc50 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -2833,7 +2833,9 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hop) "aeP" = ( -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_x = -32 + }, /obj/effect/turf_decal/loading_area, /turf/open/floor/plasteel, /area/quartermaster/storage) diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 4a8eee364c..e03ba4fcd2 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -2,12 +2,44 @@ "aaa" = ( /turf/open/space/basic, /area/space) +"aab" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Dorm3Shutters"; + name = "Privacy Shutters Control"; + pixel_y = 26 + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/wood, +/area/crew_quarters/dorms) +"aac" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Dorm2Shutters"; + name = "Privacy Shutters Control"; + pixel_y = 26; + req_access_txt = "0" + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet, +/area/crew_quarters/dorms) "aad" = ( /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating{ icon_state = "platingdmg3" }, /area/maintenance/department/science) +"aae" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "Dorm1Shutters"; + name = "Privacy Shutters Control"; + pixel_y = 26; + req_access_txt = "0" + }, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/plasteel/grimy, +/area/crew_quarters/dorms) "abf" = ( /obj/structure/bed, /turf/open/floor/plating, @@ -8605,16 +8637,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/dorms) -"ave" = ( -/obj/structure/bed, -/obj/item/bedsheet/nanotrasen, -/obj/machinery/button/door{ - id = "Dorm3Shutters"; - name = "Privacy Shutters Control"; - pixel_y = 26 - }, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "avf" = ( /obj/machinery/light/small{ dir = 1 @@ -10058,17 +10080,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/dorms) -"ayj" = ( -/obj/structure/bed, -/obj/item/bedsheet/nanotrasen, -/obj/machinery/button/door{ - id = "Dorm2Shutters"; - name = "Privacy Shutters Control"; - pixel_y = 26; - req_access_txt = "0" - }, -/turf/open/floor/carpet, -/area/crew_quarters/dorms) "ayk" = ( /obj/machinery/light/small{ dir = 1 @@ -11516,17 +11527,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/dorms) -"aBM" = ( -/obj/structure/bed, -/obj/item/bedsheet/nanotrasen, -/obj/machinery/button/door{ - id = "Dorm1Shutters"; - name = "Privacy Shutters Control"; - pixel_y = 26; - req_access_txt = "0" - }, -/turf/open/floor/plasteel/grimy, -/area/crew_quarters/dorms) "aBN" = ( /obj/machinery/light/small{ dir = 1 @@ -16464,8 +16464,8 @@ /area/storage/eva) "aNt" = ( /obj/structure/rack, -/obj/item/tank/jetpack/carbondioxide, -/obj/item/tank/jetpack/carbondioxide{ +/obj/item/tank/jetpack/carbondioxide/eva, +/obj/item/tank/jetpack/carbondioxide/eva{ pixel_x = -4; pixel_y = 1 }, @@ -17294,7 +17294,7 @@ lootcount = 2; name = "2maintenance loot spawner" }, -/obj/item/clothing/gloves/color/random, +/obj/effect/spawner/lootdrop/gloves, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/bar) "aPD" = ( @@ -21743,7 +21743,9 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aZj" = ( -/obj/machinery/status_display/supply, +/obj/machinery/status_display/supply{ + pixel_x = -32 + }, /obj/machinery/computer/bounty{ dir = 4 }, @@ -35713,13 +35715,13 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/obj/machinery/rnd/production/protolathe/department/medical, /obj/effect/turf_decal/tile/blue{ dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/rnd/production/techfab/department/medical, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bEw" = ( @@ -36058,7 +36060,9 @@ /obj/item/folder/white, /obj/item/pen, /obj/item/stamp/rd, -/obj/machinery/status_display/ai, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /obj/machinery/camera{ c_tag = "Research Director's Office"; dir = 1; @@ -44325,7 +44329,9 @@ dir = 1; pixel_y = -22 }, -/obj/structure/closet/radiation, +/obj/machinery/shower{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/break_room) "bWF" = ( @@ -44352,7 +44358,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" = ( @@ -44932,6 +44941,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/closet/radiation, /turf/open/floor/plasteel, /area/engine/engineering) "bYn" = ( @@ -44956,6 +44966,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/closet/radiation, /turf/open/floor/plasteel, /area/engine/engineering) "bYp" = ( @@ -53780,7 +53791,7 @@ "eSB" = ( /obj/machinery/computer/cryopod{ dir = 1; - pixel_y = -26; + pixel_y = -26 }, /turf/open/floor/plasteel/dark, /area/security/prison) @@ -99261,13 +99272,13 @@ ale asb coe apX -ave +aab awn apX -ayj +aac azr apX -aBM +aae aDb apX oFo diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index d005f1eb40..d796330cc8 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -2248,6 +2248,11 @@ }, /turf/open/floor/plasteel, /area/tdome/arena_source) +"fR" = ( +/obj/item/paicard, +/obj/structure/table/wood, +/turf/open/floor/engine/cult, +/area/wizard_station) "fS" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -2935,6 +2940,22 @@ /obj/machinery/capture_the_flag/red, /turf/open/floor/circuit/green/anim, /area/ctf) +"hH" = ( +/obj/structure/table/reinforced, +/obj/item/flashlight/seclite, +/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/item/paicard, +/turf/open/floor/plasteel/dark, +/area/centcom/ferry) "hI" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -11370,21 +11391,6 @@ /obj/structure/table/reinforced, /turf/open/floor/plasteel/grimy, /area/centcom/ferry) -"AL" = ( -/obj/structure/table/reinforced, -/obj/item/flashlight/seclite, -/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/centcom/ferry) "AM" = ( /obj/machinery/shuttle_manipulator, /turf/open/floor/circuit/green, @@ -25222,7 +25228,7 @@ lI lI lI Ax -qZ +EW qZ qZ Ax @@ -25480,7 +25486,7 @@ lI lI Ax ra -qZ +Bf qZ tX qZ @@ -25736,7 +25742,7 @@ lI lI lI Ax -qZ +fR qZ qZ Ax @@ -56332,7 +56338,7 @@ yr sw sw Ad -AL +hH Bx sw Cv diff --git a/_maps/shuttles/pirate_default.dmm b/_maps/shuttles/pirate_default.dmm index 445c29241c..1c8670d5b6 100644 --- a/_maps/shuttles/pirate_default.dmm +++ b/_maps/shuttles/pirate_default.dmm @@ -239,6 +239,23 @@ }, /turf/open/floor/plasteel, /area/shuttle/pirate) +"as" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel, +/area/shuttle/pirate) +"at" = ( +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel, +/area/shuttle/pirate) "au" = ( /obj/machinery/door/airlock/hatch{ id_tag = "piratebridgebolt"; @@ -314,6 +331,13 @@ }, /turf/open/floor/plasteel, /area/shuttle/pirate) +"aA" = ( +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, +/obj/item/bedsheet/pirate, +/turf/open/floor/wood, +/area/shuttle/pirate) "aB" = ( /obj/machinery/light/small{ dir = 4 @@ -408,12 +432,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/shuttle/pirate) -"aM" = ( -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/wood, -/area/shuttle/pirate) "aN" = ( /obj/machinery/light/small, /obj/machinery/button/door{ @@ -1022,12 +1040,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/shuttle/pirate) -"mD" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, -/area/shuttle/pirate) "mU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/engineering{ @@ -1172,15 +1184,6 @@ }, /turf/open/floor/wood, /area/shuttle/pirate) -"Ur" = ( -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/shuttle/pirate) (1,1,1) = {" af @@ -1231,7 +1234,7 @@ aq ar aj RY -aM +aA ep aH af @@ -1406,9 +1409,9 @@ af af af aj -mD +as bB -Ur +at aj aj aj diff --git a/_maps/shuttles/ruin_pirate_cutter.dmm b/_maps/shuttles/ruin_pirate_cutter.dmm index 4e36ea9edf..424436f1b3 100644 --- a/_maps/shuttles/ruin_pirate_cutter.dmm +++ b/_maps/shuttles/ruin_pirate_cutter.dmm @@ -1,7 +1,81 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/obj/structure/bed, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -26 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark/side{ + dir = 6 + }, +/area/shuttle/caravan/pirate) +"ab" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/machinery/turretid{ + icon_state = "control_kill"; + lethal = 1; + locked = 0; + pixel_y = -30; + req_access = null + }, +/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 + }, +/mob/living/simple_animal/hostile/pirate/ranged{ + environment_smash = 0 + }, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) +"ac" = ( +/obj/structure/bed, +/obj/machinery/airalarm/all_access{ + dir = 4; + pixel_x = -24 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) +"ad" = ( +/obj/effect/decal/cleanable/dirt, +/mob/living/simple_animal/hostile/pirate/ranged{ + environment_smash = 0 + }, +/turf/open/floor/plasteel, +/area/shuttle/caravan/pirate) +"ae" = ( +/obj/structure/rack, +/obj/item/storage/bag/money/vault, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/mob/living/simple_animal/parrot{ + faction = list("pirate"); + name = "Pegwing" + }, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) "af" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/caravan/pirate) +"ag" = ( +/obj/machinery/light/small, +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) "aE" = ( /obj/structure/closet{ name = "pirate outfits" @@ -89,18 +163,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"fS" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/obj/machinery/airalarm/all_access{ - dir = 4; - pixel_x = -24 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "fU" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/red, @@ -223,18 +285,6 @@ dir = 1 }, /area/shuttle/caravan/pirate) -"ku" = ( -/obj/structure/rack, -/obj/item/storage/bag/money/vault, -/mob/living/simple_animal/parrot{ - faction = list("pirate"); - name = "Pegwing" - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "kY" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -502,13 +552,6 @@ /obj/item/reagent_containers/food/drinks/bottle/rum, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"tM" = ( -/mob/living/simple_animal/hostile/pirate/ranged{ - environment_smash = 0 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, -/area/shuttle/caravan/pirate) "ul" = ( /obj/structure/table, /obj/item/retractor, @@ -535,17 +578,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, /area/shuttle/caravan/pirate) -"vq" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -26 - }, -/turf/open/floor/plasteel/dark/side{ - dir = 6 - }, -/area/shuttle/caravan/pirate) "vW" = ( /obj/machinery/light/small{ dir = 4 @@ -734,32 +766,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"EB" = ( -/obj/structure/chair/office/dark{ - dir = 4 - }, -/obj/machinery/turretid{ - icon_state = "control_kill"; - lethal = 1; - locked = 0; - pixel_y = -30; - req_access = null - }, -/mob/living/simple_animal/hostile/pirate/ranged{ - environment_smash = 0 - }, -/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/shuttle/caravan/pirate) "EK" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -1018,12 +1024,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"Wb" = ( -/obj/machinery/light/small, -/obj/structure/bed, -/obj/item/bedsheet/brown, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "Xq" = ( /obj/structure/table/reinforced, /obj/machinery/recharger, @@ -1181,7 +1181,7 @@ su Ag af jo -tM +ad sr af af @@ -1253,9 +1253,9 @@ Jv af aE SF -vq +aa NM -fS +ac RC oF af @@ -1272,7 +1272,7 @@ hZ wZ de iF -Wb +ag af Jv Jv @@ -1286,7 +1286,7 @@ xg qC pK Sk -ku +ae af qo Jv @@ -1374,7 +1374,7 @@ Jv Jv Bi oO -EB +ab bd Bi Jv 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 9f5f52180c..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 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..8d86826ac2 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -130,6 +130,17 @@ #define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) #define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) #define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) +#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () +#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) + #define COMPONENT_UPPERCASE_SPEECH 1 + // used to access COMSIG_MOB_SAY argslist + #define SPEECH_MESSAGE 1 + // #define SPEECH_BUBBLE_TYPE 2 + #define SPEECH_SPANS 3 + /* #define SPEECH_SANITIZE 4 + #define SPEECH_LANGUAGE 5 + #define SPEECH_IGNORE_SPAM 6 + #define SPEECH_FORCED 7 */ // /mob/living signals #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) @@ -142,8 +153,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 9f3d38efa1..ee51fb6909 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -102,7 +102,8 @@ #define CAT_SANDWICH "Sandwiches" #define CAT_SOUP "Soups" #define CAT_SPAGHETTI "Spaghettis" -#define CAT_SUSHI "Fish" +#define CAT_FISH "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..2fe70961f8 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -8,6 +8,7 @@ #define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) #define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) #define CHECK_BITFIELD(variable, flag) (variable & flag) +#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) @@ -56,9 +57,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/food.dm b/code/__DEFINES/food.dm index 2c7a66ce40..15c7af5749 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -16,3 +16,4 @@ #define DRINK_GOOD 2 #define DRINK_VERYGOOD 3 #define DRINK_FANTASTIC 4 +#define FOOD_AMAZING 5 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/logging.dm b/code/__DEFINES/logging.dm index 55131a26ed..8234059a36 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -16,6 +16,7 @@ #define INVESTIGATE_EXONET "exonet" #define INVESTIGATE_NANITES "nanites" #define INVESTIGATE_CIRCUIT "circuit" +#define INVESTIGATE_RCD "rcd" // Logging types for log_message() #define LOG_ATTACK (1 << 0) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index be58b64f41..30a7694e5f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -114,8 +114,9 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define TRANSITIONEDGE 7 //Distance from edge to move to another z-level -#define BE_CLOSE 1 //in the case of a silicon, to select if they need to be next to the atom -#define NO_DEXTERY 1 //if other mobs (monkeys, aliens, etc) can use this +#define BE_CLOSE TRUE //in the case of a silicon, to select if they need to be next to the atom +#define NO_DEXTERY TRUE //if other mobs (monkeys, aliens, etc) can use this +#define NO_TK TRUE //used by canUseTopic() //singularity defines @@ -218,6 +219,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" @@ -262,6 +266,15 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE)) +//pda icon reskins +#define PDA_SKIN_CLASSIC "Classic" +#define PDA_SKIN_ALT "Holographic" +#define PDA_SKIN_RUGGED "Rugged" +#define PDA_SKIN_MODERN "Modern" + +GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_SKIN_ALT = 'icons/obj/pda_alt.dmi', + PDA_SKIN_RUGGED = 'icons/obj/pda_rugged.dmi', PDA_SKIN_MODERN = 'icons/obj/pda_modern.dmi')) + //Color Defines #define OOC_COLOR "#002eb8" #define AOOC_COLOR "#b8002e" @@ -369,6 +382,7 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE)) #define CLOCK_SILICONS 22 #define CLOCK_PROSELYTIZATION 23 #define SHUTTLE_HIJACK 24 +#define GANG_VICTORY 25 #define FIELD_TURF 1 #define FIELD_EDGE 2 @@ -476,4 +490,7 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE)) #define AREASELECT_CORNERA "corner A" #define AREASELECT_CORNERB "corner B" -#define PREF_SAVELOAD_COOLDOWN 5 \ No newline at end of file +#define PREF_SAVELOAD_COOLDOWN 5 + +#define VOMIT_TOXIC 1 +#define VOMIT_PURPLE 2 \ No newline at end of file diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 4b42595b48..1d1dda6d99 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -54,6 +54,10 @@ #define BODYPART_ORGANIC 1 #define BODYPART_ROBOTIC 2 +#define BODYPART_NOT_DISABLED 0 +#define BODYPART_DISABLED_DAMAGE 1 +#define BODYPART_DISABLED_PARALYSIS 2 + #define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi' #define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi' diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index e6d4fd126b..1c3832001f 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -20,12 +20,12 @@ #define FORCE_STRING_OVERRIDE (1<<2) // used for tooltips #define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use. #define SLOWS_WHILE_IN_HAND (1<<4) -#define NO_MAT_REDEMPTION (1<<5) // Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. -#define DROPDEL (1<<6) // When dropped, it calls qdel on itself +#define NO_MAT_REDEMPTION (1<<5) // Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. +#define DROPDEL (1<<6) // When dropped, it calls qdel on itself #define NOBLUDGEON (1<<7) // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby() -#define NODROP (1<<8) // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted. -#define ABSTRACT (1<<9) // for all things that are technically items but used for various different stuff -#define IMMUTABLE_SLOW (1<<10) //When players should not be able to change the slowdown of the item (Speed potions, ect) +#define ABSTRACT (1<<8) // for all things that are technically items but used for various different stuff +#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect) +#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes) // Flags for the clothing_flags var on /obj/item/clothing @@ -35,3 +35,5 @@ #define MASKINTERNALS (1<<3) // mask allows internals #define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc #define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. +#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled. +#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off. \ No newline at end of file diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index b72a14468f..1c36120a0c 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -23,6 +23,11 @@ #define STIMULUM_ABSOLUTE_DROP 0.00000335 #define REACTION_OPPRESSION_THRESHOLD 5 #define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense. +//Research point amounts +#define NOBLIUM_RESEARCH_AMOUNT 1000 +#define BZ_RESEARCH_AMOUNT 150 +#define MIASMA_RESEARCH_AMOUNT 160 +#define STIMULUM_RESEARCH_AMOUNT 50 //Plasma fusion properties #define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction #define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction 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/subsystems.dm b/code/__DEFINES/subsystems.dm index f54a0542f4..19d0540e0e 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -81,7 +81,7 @@ #define INIT_ORDER_STICKY_BAN -10 #define INIT_ORDER_LIGHTING -20 #define INIT_ORDER_SHUTTLE -21 -#define INIT_ORDER_SQUEAK -40 +#define INIT_ORDER_MINOR_MAPPING -40 #define INIT_ORDER_PATH -50 #define INIT_ORDER_PERSISTENCE -100 @@ -102,7 +102,6 @@ #define FIRE_PRIORITY_SPACEDRIFT 30 #define FIRE_PRIORITY_FIELDS 30 #define FIRE_PRIOTITY_SMOOTHING 35 -#define FIRE_PRIORITY_ORBIT 35 #define FIRE_PRIORITY_NETWORKS 40 #define FIRE_PRIORITY_OBJ 40 #define FIRE_PRIORITY_ACID 40 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 805e72cfcb..7bcb4881f0 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" @@ -50,7 +108,20 @@ #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" #define TRAIT_MINDSHIELD "mindshield" +#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it +#define TRAIT_PARALYSIS_R_ARM "para-r-arm" +#define TRAIT_PARALYSIS_L_LEG "para-l-leg" +#define TRAIT_PARALYSIS_R_LEG "para-r-leg" +#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech" +#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism" +#define TRAIT_STRONG_GRABBER "strong_grabber" +#define TRAIT_CALCIUM_HEALER "calcium_healer" + //non-mob traits +#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it + +// item traits +#define TRAIT_NODROP "nodrop" #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" #define TRAIT_AGEUSIA "ageusia" @@ -71,6 +142,12 @@ #define TRAIT_MUSICIAN "musician" #define TRAIT_CROCRIN_IMMUNE "crocin_immune" #define TRAIT_NYMPHO "nymphomania" +#define TRAIT_MASO "masochism" +#define TRAIT_PARA "paraplegic" +#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" @@ -81,6 +158,13 @@ #define TRAUMA_TRAIT "trauma" #define SPECIES_TRAIT "species" #define ORGAN_TRAIT "organ" +#define JOB_TRAIT "job" +#define CYBORG_ITEM_TRAIT "cyborg-item" +#define ADMIN_TRAIT "admin" // (B)admins only. +#define CHANGELING_TRAIT "changeling" +#define CULT_TRAIT "cult" +#define CURSED_ITEM_TRAIT "cursed-item" // The item is magically cursed +#define ABSTRACT_ITEM_TRAIT "abstract-item" #define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention // unique trait sources, still defines @@ -93,4 +177,24 @@ #define STASIS_MUTE "stasis" #define GENETICS_SPELL "genetics_spell" #define EYES_COVERED "eyes_covered" -#define CULT_EYES "cult_eyes" +#define CULT_TRAIT "cult" +#define CLOWN_NUKE_TRAIT "clown-nuke" +#define STICKY_MOUSTACHE_TRAIT "sticky-moustache" +#define CHAINSAW_FRENZY_TRAIT "chainsaw-frenzy" +#define CHRONO_GUN_TRAIT "chrono-gun" +#define REVERSE_BEAR_TRAP_TRAIT "reverse-bear-trap" +#define GLUED_ITEM_TRAIT "glued-item" +#define CURSED_MASK_TRAIT "cursed-mask" +#define HIS_GRACE_TRAIT "his-grace" +#define HAND_REPLACEMENT_TRAIT "magic-hand" +#define HOT_POTATO_TRAIT "hot-potato" +#define SABRE_SUICIDE_TRAIT "sabre-suicide" +#define ABDUCTOR_VEST_TRAIT "abductor-vest" +#define CAPTURE_THE_FLAG_TRAIT "capture-the-flag" +#define EYE_OF_GOD_TRAIT "eye-of-god" +#define SHAMEBRERO_TRAIT "shamebrero" +#define CHRONOSUIT_TRAIT "chronosuit" +#define FLIGHTSUIT_TRAIT "flightsuit" +#define LOCKED_HELMET_TRAIT "locked-helmet" +#define NINJA_SUIT_TRAIT "ninja-suit" +#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" \ No newline at end of file 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/areas.dm b/code/__HELPERS/areas.dm index f05bf6f3e1..1f5b82f7bf 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -86,6 +86,8 @@ newA.contents += thing thing.change_area(old_area, newA) + newA.reg_in_areas_in_z() + var/list/firedoors = oldA.firedoors for(var/door in firedoors) var/obj/machinery/door/firedoor/FD = door diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 899ef16306..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) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index f6ef08fe0d..c8a33959ed 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -8,11 +8,11 @@ //facial hair init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) //underwear - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) //undershirt - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) //socks - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) //bodypart accessories (blizzard intensifies) init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) @@ -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/matrices.dm b/code/__HELPERS/matrices.dm index 8b77b170e0..d96ec76a7c 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -2,7 +2,7 @@ . = new_angle - old_angle Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT -/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3) +/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) if(!segments) return var/segment = 360/segments @@ -18,7 +18,11 @@ speed /= segments - animate(src, transform = matrices[1], time = speed, loops) + if(parallel) + animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) + else + animate(src, transform = matrices[1], time = speed, loops) + for(var/i in 2 to segments) //2 because 1 is covered above animate(transform = matrices[i], time = speed) //doesn't have an object argument because this is "Stacking" with the animate call above diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 74a1fbd785..5ec839130a 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -20,35 +20,34 @@ else return "000" -/proc/random_underwear(gender)//Cit change - makes random underwear always return nude +#define UNDIE_COLORABLE(U) (U?.has_color) + +/proc/random_underwear(gender) if(!GLOB.underwear_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - return "Nude" - /*switch(gender) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + switch(gender) if(MALE) return pick(GLOB.underwear_m) if(FEMALE) return pick(GLOB.underwear_f) else - return pick(GLOB.underwear_list)*/ + return pick(GLOB.underwear_list) -/proc/random_undershirt(gender)//Cit change - makes random undershirts always return nude +/proc/random_undershirt(gender) if(!GLOB.undershirt_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - return "Nude" - /*switch(gender) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + switch(gender) if(MALE) return pick(GLOB.undershirt_m) if(FEMALE) return pick(GLOB.undershirt_f) else - return pick(GLOB.undershirt_list)*/ + return pick(GLOB.undershirt_list) -/proc/random_socks()//Cit change - makes random socks always return nude +/proc/random_socks() if(!GLOB.socks_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) - return "Nude" - //return pick(GLOB.socks_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) + return pick(GLOB.socks_list) /proc/random_features() if(!GLOB.tails_list_human.len) @@ -77,6 +76,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 +169,7 @@ "balls_amount" = 2, "balls_sack_size" = BALLS_SACK_SIZE_DEF, "balls_size" = BALLS_SIZE_DEF, + "balls_shape" = "Single", "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, @@ -185,7 +187,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 +296,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 +329,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/names.dm b/code/__HELPERS/names.dm index 09e0aa95b9..db2eba2422 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -151,6 +151,10 @@ GLOBAL_VAR(command_name) GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. GLOBAL_VAR(syndicate_code_response) //Code response for traitors. +//Cached regex search - for checking if codewords are used. +GLOBAL_DATUM(syndicate_code_phrase_regex, /regex) +GLOBAL_DATUM(syndicate_code_response_regex, /regex) + /* Should be expanded. How this works: diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm new file mode 100644 index 0000000000..f1208abdd3 --- /dev/null +++ b/code/__HELPERS/reagents.dm @@ -0,0 +1,74 @@ +/proc/chem_recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2) + //do the non-list tests first, because they are cheaper + if(r1.required_container != r2.required_container) + return FALSE + if(r1.is_cold_recipe == r2.is_cold_recipe) + if(r1.required_temp != r2.required_temp) + //one reaction requires a more extreme temperature than the other, so there is no conflict + return FALSE + else + var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2 + var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1 + if(cold_one.required_temp < warm_one.required_temp) + //the range of temperatures does not overlap, so there is no conflict + return FALSE + + //find the reactions with the shorter and longer required_reagents list + var/datum/chemical_reaction/long_req + var/datum/chemical_reaction/short_req + if(r1.required_reagents.len > r2.required_reagents.len) + long_req = r1 + short_req = r2 + else if(r1.required_reagents.len < r2.required_reagents.len) + long_req = r2 + short_req = r1 + else + //if they are the same length, sort instead by the length of the catalyst list + //this is important if the required_reagents lists are the same + if(r1.required_catalysts.len > r2.required_catalysts.len) + long_req = r1 + short_req = r2 + else + long_req = r2 + short_req = r1 + + + //check if the shorter reaction list is a subset of the longer one + var/list/overlap = r1.required_reagents & r2.required_reagents + if(overlap.len != short_req.required_reagents.len) + //there is at least one reagent in the short list that is not in the long list, so there is no conflict + return FALSE + + //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list + //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine + //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict + var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts + if(short_minus_long_catalysts.len) + //there is at least one unique catalyst for the short reaction, so there is no conflict + return FALSE + + //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise + return TRUE + +/proc/get_chemical_reaction(id) + if(!GLOB.chemical_reactions_list) + return + for(var/reagent in GLOB.chemical_reactions_list) + for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[reagent]) + if(R.id == id) + return R + +/proc/remove_chemical_reaction(datum/chemical_reaction/R) + if(!GLOB.chemical_reactions_list || !R) + return + for(var/rid in R.required_reagents) + GLOB.chemical_reactions_list[rid] -= R + +//see build_chemical_reactions_list in holder.dm for explanations +/proc/add_chemical_reaction(datum/chemical_reaction/R) + if(!GLOB.chemical_reactions_list || !R.id || !R.required_reagents || !R.required_reagents.len) + return + var/primary_reagent = R.required_reagents[1] + if(!GLOB.chemical_reactions_list[primary_reagent]) + GLOB.chemical_reactions_list[primary_reagent] = list() + GLOB.chemical_reactions_list[primary_reagent] += R diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7d6c017b77..1ee5ce986f 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 @@ -765,3 +767,27 @@ GLOBAL_LIST_INIT(binary, list("0","1")) return "twelfth" else return "[number]\th" + +/proc/unintelligize(message) + var/prefix=copytext(message,1,2) + if(prefix == ";") + message = copytext(message,2) + else if(prefix in list(":","#")) + prefix += copytext(message,2,3) + message = copytext(message,3) + else + prefix="" + + var/list/words = splittext(message," ") + var/list/rearranged = list() + for(var/i=1;i<=words.len;i++) + var/cword = pick(words) + words.Remove(cword) + var/suffix = copytext(cword,length(cword)-1,length(cword)) + while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) + cword = copytext(cword,1 ,length(cword)-1) + suffix = copytext(cword,length(cword)-1,length(cword) ) + if(length(cword)) + rearranged += cword + message = "[prefix][jointext(rearranged," ")]" + . = message diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 200e1f907f..b28e7b5807 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -70,3 +70,6 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(hour) hourT = " and [hour] hour[(hour != 1)? "s":""]" return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]" + +/proc/daysSince(realtimev) + return round((world.realtime - realtimev) / (24 HOURS)) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 2f69b63ae9..7e078184b7 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1239,19 +1239,21 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) pixel_x = initialpixelx pixel_y = initialpixely -/atom/proc/do_jiggle(targetangle = 45) +/atom/proc/do_jiggle(targetangle = 45, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) + var/halftime = timer * 0.5 M.Turn(pick(-targetangle, targetangle)) - animate(src, transform = M, time = 10, easing = ELASTIC_EASING) - animate(src, transform = OM, time = 10, easing = ELASTIC_EASING) + animate(src, transform = M, time = halftime, easing = ELASTIC_EASING) + animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING) -/atom/proc/do_squish(squishx = 1.2, squishy = 0.6) +/atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) + var/halftime = timer * 0.5 M.Scale(squishx, squishy) - animate(src, transform = M, time = 10, easing = BOUNCE_EASING) - animate(src, transform = OM, time = 10, easing = BOUNCE_EASING) + animate(src, transform = M, time = halftime, easing = BOUNCE_EASING) + animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING) /proc/weightclass2text(var/w_class) switch(w_class) @@ -1483,7 +1485,9 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/grown/mushroom, /obj/item/reagent_containers/food/snacks/grown/nettle, // base type - /obj/item/reagent_containers/food/snacks/deepfryholder + /obj/item/reagent_containers/food/snacks/deepfryholder, + /obj/item/reagent_containers/food/snacks/grown/shell, + /obj/item/reagent_containers/food/snacks/store/bread ) blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 835a733752..bb9fc98b8e 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -47,7 +47,6 @@ GLOBAL_LIST_INIT(bitfields, list( "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, "DROPDEL" = DROPDEL, "NOBLUDGEON" = NOBLUDGEON, - "NODROP" = NODROP, "ABSTRACT" = ABSTRACT, ), "admin_flags" = list( @@ -115,9 +114,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, @@ -143,6 +139,8 @@ GLOBAL_LIST_INIT(bitfields, list( "MASKINTERNALS" = MASKINTERNALS, "NOSLIP" = NOSLIP, "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, ), "tesla_flags" = list( "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE, @@ -158,13 +156,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, @@ -173,4 +172,9 @@ GLOBAL_LIST_INIT(bitfields, list( "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, ), - )) + "disease_flags" = list( + "CURABLE" = CURABLE, + "CAN_CARRY" = CAN_CARRY, + "CAN_RESIST" = CAN_RESIST + ), + )) \ No newline at end of file diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 8b0ac278cd..82ccd439ee 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -7,15 +7,15 @@ GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/faci GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) //stores only hair names GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) //stores only hair names //Underwear -GLOBAL_LIST_EMPTY(underwear_list) //stores /datum/sprite_accessory/underwear indexed by name +GLOBAL_LIST_EMPTY(underwear_list) //stores /datum/sprite_accessory/underwear/bottom indexed by name GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name GLOBAL_LIST_EMPTY(underwear_f) //stores only underwear name //Undershirts -GLOBAL_LIST_EMPTY(undershirt_list) //stores /datum/sprite_accessory/undershirt indexed by name +GLOBAL_LIST_EMPTY(undershirt_list) //stores /datum/sprite_accessory/underwear/top indexed by name GLOBAL_LIST_EMPTY(undershirt_m) //stores only undershirt name GLOBAL_LIST_EMPTY(undershirt_f) //stores only undershirt name //Socks -GLOBAL_LIST_EMPTY(socks_list) //stores /datum/sprite_accessory/socks indexed by name +GLOBAL_LIST_EMPTY(socks_list) //stores /datum/sprite_accessory/underwear/socks indexed by name //Lizard Bits (all datum lists indexed by name) GLOBAL_LIST_EMPTY(body_markings_list) GLOBAL_LIST_EMPTY(tails_list_lizard) @@ -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 36049de77b..ef460cd54c 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -43,7 +43,8 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/assembly/timer = 3, /obj/item/flashlight = 4, /obj/item/flashlight/pen = 1, - /obj/item/flashlight/glowstick/random = 4, + /obj/effect/spawner/lootdrop/glowstick = 4, + /obj/effect/spawner/lootdrop/mre = 3, /obj/item/multitool = 2, /obj/item/radio/off = 2, /obj/item/t_scanner = 5, @@ -68,7 +69,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/crowbar = 1, /obj/item/crowbar/red = 1, /obj/item/extinguisher = 11, - //obj/item/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc. /obj/item/hand_labeler = 1, /obj/item/paper/crumpled = 1, /obj/item/pen = 1, @@ -101,13 +101,18 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/assembly/signaler = 2, /obj/item/assembly/mousetrap = 2, /obj/item/reagent_containers/syringe = 2, - /obj/item/clothing/gloves/color/random = 8, + /obj/effect/spawner/lootdrop/gloves = 8, /obj/item/clothing/shoes/laceup = 1, /obj/item/storage/secure/briefcase = 3, /obj/item/storage/toolbox/artistic = 2, /obj/item/toy/eightball = 1, /obj/item/reagent_containers/pill/floorpill = 1, + /obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 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, + /obj/item/autosurgeon/penis = 1, + /obj/item/autosurgeon/testicles = 1, "" = 3 )) diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index fa0ecf117d..e7b2ae6cbe 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -18,3 +18,12 @@ GLOBAL_LIST_EMPTY(powernets) GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details + +// All religion stuff +GLOBAL_VAR(religion) +GLOBAL_VAR(deity) +GLOBAL_VAR(bible_name) +GLOBAL_VAR(bible_icon_state) +GLOBAL_VAR(bible_item_state) +GLOBAL_VAR(holy_weapon_type) +GLOBAL_VAR(holy_armor_type) \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 0c01468712..7a495b95e7 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -23,6 +23,9 @@ return next_click = world.time + 1 + if(!can_interact_with(A)) + return + if(multicam_on) var/turf/T = get_turf(A) if(T) @@ -60,7 +63,6 @@ controlled_mech.click_action(A, src, params) //Override AI normal click behavior. return - return if(modifiers["shift"]) ShiftClickOn(A) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 3d6de49a6a..22210bfd08 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -366,11 +366,15 @@ SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) var/turf/T = get_turf(src) if(T && user.TurfAdjacent(T)) - if(user.listed_turf == T) - user.listed_turf = null - else - user.listed_turf = T - user.client.statpanel = T.name + user.listed_turf = T + user.client.statpanel = T.name + +// Use this instead of /mob/proc/AltClickOn(atom/A) where you only want turf content listing without additional atom alt-click interaction +/atom/proc/AltClickNoInteract(mob/user, atom/A) + var/turf/T = get_turf(A) + if(T && user.TurfAdjacent(T)) + user.listed_turf = T + user.client.statpanel = T.name /mob/proc/TurfAdjacent(turf/T) return T.Adjacent(src) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 73a207a457..2b5af9ddb8 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -20,10 +20,23 @@ else return TRUE -/obj/screen/movable/action_button/MouseDrop() - if (!can_use(usr)) +/obj/screen/movable/action_button/MouseDrop(over_object) + if(!can_use(usr)) return - return ..() + if((istype(over_object, /obj/screen/movable/action_button) && !istype(over_object, /obj/screen/movable/action_button/hide_toggle))) + if(locked) + to_chat(usr, "Action button \"[name]\" is locked, unlock it first.") + return + var/obj/screen/movable/action_button/B = over_object + var/list/actions = usr.actions + actions.Swap(actions.Find(src.linked_action), actions.Find(B.linked_action)) + moved = FALSE + ordered = TRUE + B.moved = FALSE + B.ordered = TRUE + usr.update_action_buttons() + else + return ..() /obj/screen/movable/action_button/Click(location,control,params) if (!can_use(usr)) 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..3896c3eac3 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 && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") return diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 6cacc90fcb..299d7f64f8 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -31,7 +31,7 @@ ShiftClickOn(A) return if(modifiers["alt"]) - AltClickOn(A) + AltClickNoInteract(src, A) return if(modifiers["ctrl"]) CtrlClickOn(A) diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm index 875f1ee7d3..1b1c7bc3b7 100644 --- a/code/controllers/subsystem/augury.dm +++ b/code/controllers/subsystem/augury.dm @@ -50,7 +50,7 @@ SUBSYSTEM_DEF(augury) watchers -= w continue var/mob/dead/observer/O = w - if(biggest_doom && (!O.orbiting || O.orbiting.orbiting != biggest_doom)) + if(biggest_doom && (!O.orbiting || O.orbiting.parent != biggest_doom)) O.ManualFollow(biggest_doom) /datum/action/innate/augury diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index a2c60618ac..a365405ce6 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -256,10 +256,13 @@ GLOBAL_LIST_EMPTY(the_station_areas) /datum/controller/subsystem/mapping/proc/generate_station_area_list() var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin, /area/asteroid/nearstation)) for(var/area/A in world) - var/turf/picked = safepick(get_area_turfs(A.type)) - if(picked && is_station_level(picked.z)) - if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist)) - GLOB.the_station_areas.Add(A.type) + if (is_type_in_typecache(A, station_areas_blacklist)) + continue + if (!A.contents.len || !A.unique) + continue + var/turf/picked = A.contents[1] + if (is_station_level(picked.z)) + GLOB.the_station_areas += A.type if(!GLOB.the_station_areas.len) log_world("ERROR: Station areas list failed to generate!") @@ -495,4 +498,9 @@ GLOBAL_LIST_EMPTY(the_station_areas) clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already. unused_turfs.Cut() used_turfs.Cut() - reserve_turfs(clearing) \ No newline at end of file + reserve_turfs(clearing) + +/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas) + for(var/B in areas) + var/area/A = B + A.reg_in_areas_in_z() diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/minor_mapping.dm similarity index 62% rename from code/controllers/subsystem/squeak.dm rename to code/controllers/subsystem/minor_mapping.dm index 861bb0d8d5..2160cae6e3 100644 --- a/code/controllers/subsystem/squeak.dm +++ b/code/controllers/subsystem/minor_mapping.dm @@ -1,22 +1,14 @@ -// The Squeak -// because this is about placement of mice mobs, and nothing to do with -// mice - the computer peripheral - -SUBSYSTEM_DEF(squeak) - name = "Squeak" - init_order = INIT_ORDER_SQUEAK +SUBSYSTEM_DEF(minor_mapping) + name = "Minor Mapping" + init_order = INIT_ORDER_MINOR_MAPPING flags = SS_NO_FIRE - var/list/exposed_wires = list() - -/datum/controller/subsystem/squeak/Initialize(timeofday) +/datum/controller/subsystem/minor_mapping/Initialize(timeofday) trigger_migration(CONFIG_GET(number/mice_roundstart)) return ..() -/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10) - if(!num_mice) - return - find_exposed_wires() +/datum/controller/subsystem/minor_mapping/proc/trigger_migration(num_mice=10) + var/list/exposed_wires = find_exposed_wires() var/mob/living/simple_animal/mouse/M var/turf/proposed_turf @@ -31,7 +23,8 @@ SUBSYSTEM_DEF(squeak) num_mice -= 1 M = null -/datum/controller/subsystem/squeak/proc/find_exposed_wires() +/proc/find_exposed_wires() + var/list/exposed_wires = list() exposed_wires.Cut() var/list/all_turfs for (var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) @@ -41,3 +34,5 @@ SUBSYSTEM_DEF(squeak) continue if(locate(/obj/structure/cable) in T) exposed_wires += T + + return shuffle(exposed_wires) \ No newline at end of file diff --git a/code/controllers/subsystem/orbit.dm b/code/controllers/subsystem/orbit.dm deleted file mode 100644 index 45d280b601..0000000000 --- a/code/controllers/subsystem/orbit.dm +++ /dev/null @@ -1,44 +0,0 @@ -SUBSYSTEM_DEF(orbit) - name = "Orbits" - priority = FIRE_PRIORITY_ORBIT - wait = 2 - flags = SS_NO_INIT|SS_TICKER - - var/list/currentrun = list() - var/list/processing = list() - -/datum/controller/subsystem/orbit/stat_entry() - ..("P:[processing.len]") - - -/datum/controller/subsystem/orbit/fire(resumed = 0) - if (!resumed) - src.currentrun = processing.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while (currentrun.len) - var/datum/orbit/O = currentrun[currentrun.len] - currentrun.len-- - if (!O) - processing -= O - if (MC_TICK_CHECK) - return - continue - if (!O.orbiter) - qdel(O) - if (MC_TICK_CHECK) - return - continue - if (O.lastprocess >= world.time) //we already checked recently - if (MC_TICK_CHECK) - return - continue - var/targetloc = get_turf(O.orbiting) - if (targetloc != O.lastloc || O.orbiter.loc != targetloc) - O.Check(targetloc) - if (MC_TICK_CHECK) - return - - diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 978eedb62f..455b53b1df 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -28,6 +28,7 @@ SUBSYSTEM_DEF(persistence) LoadPhotoPersistence() if(CONFIG_GET(flag/use_antag_rep)) LoadAntagReputation() + LoadRandomizedRecipes() return ..() /datum/controller/subsystem/persistence/proc/LoadSatchels() @@ -206,6 +207,7 @@ SUBSYSTEM_DEF(persistence) SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION. if(CONFIG_GET(flag/use_antag_rep)) CollectAntagReputation() + SaveRandomizedRecipes() /datum/controller/subsystem/persistence/proc/GetPhotoAlbums() var/album_path = file("data/photo_albums.json") @@ -371,3 +373,43 @@ SUBSYSTEM_DEF(persistence) fdel(FILE_ANTAG_REP) text2file(json_encode(antag_rep), FILE_ANTAG_REP) +/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes() + var/json_file = file("data/RandomizedChemRecipes.json") + var/json + if(fexists(json_file)) + json = json_decode(file2text(json_file)) + + for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) + var/datum/chemical_reaction/randomized/R = new randomized_type + var/loaded = FALSE + if(R.persistent && json) + var/list/recipe_data = json[R.id] + if(recipe_data && R.LoadOldRecipe(recipe_data) && (daysSince(R.created) <= R.persistence_period)) + loaded = TRUE + if(!loaded) //We do not have information for whatever reason, just generate new one + R.GenerateRecipe() + + if(!R.HasConflicts()) //Might want to try again if conflicts happened in the future. + add_chemical_reaction(R) + +/datum/controller/subsystem/persistence/proc/SaveRandomizedRecipes() + var/json_file = file("data/RandomizedChemRecipes.json") + var/list/file_data = list() + + //asert globchems done + for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) + var/datum/chemical_reaction/randomized/R = randomized_type + R = get_chemical_reaction(initial(R.id)) //ew, would be nice to add some simple tracking + if(R && R.persistent && R.id) + var/recipe_data = list() + recipe_data["timestamp"] = R.created + recipe_data["required_reagents"] = R.required_reagents + recipe_data["required_catalysts"] = R.required_catalysts + recipe_data["required_temp"] = R.required_temp + recipe_data["is_cold_recipe"] = R.is_cold_recipe + recipe_data["results"] = R.results + recipe_data["required_container"] = "[R.required_container]" + file_data["[R.id]"] = recipe_data + + fdel(json_file) + WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/controllers/subsystem/religion.dm b/code/controllers/subsystem/religion.dm deleted file mode 100644 index 1c3cd76da4..0000000000 --- a/code/controllers/subsystem/religion.dm +++ /dev/null @@ -1,11 +0,0 @@ -SUBSYSTEM_DEF(religion) - name = "Religion" - flags = SS_NO_FIRE|SS_NO_INIT - - var/religion - var/deity - var/bible_name - var/bible_icon_state - var/bible_item_state - var/holy_weapon_type - var/holy_armor_type 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 4a3143da79..df96c44df7 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -126,9 +126,20 @@ SUBSYSTEM_DEF(ticker) if(!GLOB.syndicate_code_phrase) - GLOB.syndicate_code_phrase = generate_code_phrase() + GLOB.syndicate_code_phrase = generate_code_phrase(return_list=TRUE) + + var/codewords = jointext(GLOB.syndicate_code_phrase, "|") + var/regex/codeword_match = new("([codewords])", "ig") + + GLOB.syndicate_code_phrase_regex = codeword_match + if(!GLOB.syndicate_code_response) - GLOB.syndicate_code_response = generate_code_phrase() + GLOB.syndicate_code_response = generate_code_phrase(return_list=TRUE) + + var/codewords = jointext(GLOB.syndicate_code_response, "|") + var/regex/codeword_match = new("([codewords])", "ig") + + GLOB.syndicate_code_response_regex = codeword_match start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) if(CONFIG_GET(flag/randomize_shift_time)) @@ -561,6 +572,15 @@ SUBSYSTEM_DEF(ticker) news_message = "The burst of energy released near [station_name()] has been confirmed as merely a test of a new weapon. However, due to an unexpected mechanical error, their communications system has been knocked offline." if(SHUTTLE_HIJACK) news_message = "During routine evacuation procedures, the emergency shuttle of [station_name()] had its navigation protocols corrupted and went off course, but was recovered shortly after." + if(GANG_VICTORY) + news_message = "Company officials reaffirmed that sudden deployments of special forces are not in any way connected to rumors of [station_name()] being covered in graffiti." + + if(SSblackbox.first_death) + var/list/ded = SSblackbox.first_death + if(ded.len) + news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]" + else + news_message += " NT Sanctioned Psykers proudly confirm reports that nobody died this shift!" if(news_message) send2otherserver(news_source, news_message,"News_Report") diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index c92db7cd01..d0eb0b9ce2 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -71,7 +71,6 @@ SUBSYSTEM_DEF(timer) for(var/I in second_queue) log_world(get_timer_debug_string(I)) - var/cut_start_index = 1 var/next_clienttime_timer_index = 0 var/len = length(clienttime_timers) @@ -94,14 +93,14 @@ SUBSYSTEM_DEF(timer) if(ctime_timer.flags & TIMER_LOOP) ctime_timer.spent = 0 - clienttime_timers.Insert(ctime_timer, 1) - cut_start_index++ + ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait + BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun) else qdel(ctime_timer) if (next_clienttime_timer_index) - clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1) + clienttime_timers.Cut(1, next_clienttime_timer_index+1) if (MC_TICK_CHECK) return diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index d70493dedf..ee1f5b8c3d 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -72,7 +72,7 @@ SUBSYSTEM_DEF(traumas) "security" = typecacheof(list(/obj/item/clothing/under/rank/security, /obj/item/clothing/under/rank/warden, /obj/item/clothing/under/rank/head_of_security, /obj/item/clothing/under/rank/det, /obj/item/melee/baton, /obj/item/gun/energy/taser, /obj/item/restraints/handcuffs, - /obj/machinery/door/airlock/security)), + /obj/machinery/door/airlock/security, /obj/effect/hallucination/simple/securitron)), "clowns" = typecacheof(list(/obj/item/clothing/under/rank/clown, /obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/mask/gas/clown_hat, /obj/item/instrument/bikehorn, @@ -160,22 +160,22 @@ SUBSYSTEM_DEF(traumas) /obj/item/grown/bananapeel/mimanapeel, /obj/item/cartridge/virus/mime, /obj/item/clothing/shoes/sneakers/mime, /obj/item/bedsheet/mime, /obj/item/reagent_containers/food/snacks/burger/mime, /obj/item/clothing/head/beret, /obj/item/clothing/mask/gas/sexymime, /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)), - + "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/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/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)) @@ -199,7 +199,7 @@ SUBSYSTEM_DEF(traumas) "anime" = 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/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/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm index 941e7103c6..56a3f3969b 100644 --- a/code/datums/brain_damage/brain_trauma.dm +++ b/code/datums/brain_damage/brain_trauma.dm @@ -9,7 +9,8 @@ var/obj/item/organ/brain/brain //the poor bastard's brain var/gain_text = "You feel traumatized." var/lose_text = "You no longer feel traumatized." - var/can_gain = TRUE //can this be gained through random traumas? + var/can_gain = TRUE + var/random_gain = TRUE //can this be gained through random traumas? var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure? /datum/brain_trauma/Destroy() @@ -23,7 +24,7 @@ //Called on life ticks /datum/brain_trauma/proc/on_life() return - + //Called on death /datum/brain_trauma/proc/on_death() return @@ -31,16 +32,18 @@ //Called when given to a mob /datum/brain_trauma/proc/on_gain() to_chat(owner, gain_text) + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) //Called when removed from a mob /datum/brain_trauma/proc/on_lose(silent) if(!silent) to_chat(owner, lose_text) + UnregisterSignal(owner, COMSIG_MOB_SAY) //Called when hearing a spoken message /datum/brain_trauma/proc/on_hear(message, speaker, message_language, raw_message, radio_freq) return message //Called when speaking -/datum/brain_trauma/proc/on_say(message) - return message +/datum/brain_trauma/proc/handle_speech(datum/source, list/speech_args) + UnregisterSignal(owner, COMSIG_MOB_SAY) diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index afd53726db..c049a7db33 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") ..() @@ -68,18 +68,12 @@ lose_text = "" /datum/brain_trauma/mild/speech_impediment/on_gain() - owner.dna.add_mutation(UNINTELLIGIBLE) - ..() - -//no fiddling with genetics to get out of this one -/datum/brain_trauma/mild/speech_impediment/on_life() - if(!(GLOB.mutations_list[UNINTELLIGIBLE] in owner.dna.mutations)) - on_gain() - ..() + ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT) + . = ..() /datum/brain_trauma/mild/speech_impediment/on_lose() - owner.dna.remove_mutation(UNINTELLIGIBLE) - ..() + REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT) + . = ..() /datum/brain_trauma/mild/concussion name = "Concussion" diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index c6ccbee38c..6723c89ba5 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -78,14 +78,13 @@ break return message -/datum/brain_trauma/mild/phobia/on_say(message) +/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args) for(var/word in trigger_words) var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i") - - if(findtext(message, reg)) + + if(findtext(speech_args[SPEECH_MESSAGE], reg)) to_chat(owner, "You can't bring yourself to say the word \"[word]\"!") - return "" - return message + speech_args[SPEECH_MESSAGE] = "" /datum/brain_trauma/mild/phobia/proc/freak_out(atom/reason, trigger_word) next_scare = world.time + 120 @@ -119,3 +118,7 @@ owner.confused += 10 owner.Jitter(10) owner.stuttering += 10 + +/datum/brain_trauma/mild/phobia/security + phobia_type = "security" + random_gain = FALSE diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index a8adbfbce8..d094c162d7 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 @@ -60,18 +60,68 @@ /datum/brain_trauma/severe/paralysis name = "Paralysis" - desc = "Patient's brain can no longer control its motor functions." + desc = "Patient's brain can no longer control part of its motor functions." scan_desc = "cerebral paralysis" - gain_text = "You can't feel your body anymore!" - lose_text = "You can feel your limbs again!" + gain_text = "" + lose_text = "" + var/paralysis_type + var/list/paralysis_traits = list() + //for descriptions -/datum/brain_trauma/severe/paralysis/on_life() - owner.Knockdown(200, ignore_canknockdown = TRUE) +/datum/brain_trauma/severe/paralysis/New(specific_type) + if(specific_type) + paralysis_type = specific_type + if(!paralysis_type) + paralysis_type = pick("full","left","right","arms","legs","r_arm","l_arm","r_leg","l_leg") + var/subject + switch(paralysis_type) + if("full") + subject = "your body" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG) + if("left") + subject = "the left side of your body" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_L_LEG) + if("right") + subject = "the right side of your body" + paralysis_traits = list(TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG) + if("arms") + subject = "your arms" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM) + if("legs") + subject = "your legs" + paralysis_traits = list(TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG) + if("r_arm") + subject = "your right arm" + paralysis_traits = list(TRAIT_PARALYSIS_R_ARM) + if("l_arm") + subject = "your left arm" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM) + if("r_leg") + subject = "your right leg" + paralysis_traits = list(TRAIT_PARALYSIS_R_LEG) + if("l_leg") + subject = "your left leg" + paralysis_traits = list(TRAIT_PARALYSIS_L_LEG) + + gain_text = "You can't feel [subject] anymore!" + lose_text = "You can feel [subject] again!" + +/datum/brain_trauma/severe/paralysis/on_gain() ..() + for(var/X in paralysis_traits) + ADD_TRAIT(owner, X, "trauma_paralysis") + owner.update_disabled_bodyparts() /datum/brain_trauma/severe/paralysis/on_lose() - owner.SetKnockdown(0) ..() + for(var/X in paralysis_traits) + REMOVE_TRAIT(owner, X, "trauma_paralysis") + owner.update_disabled_bodyparts() + +/datum/brain_trauma/severe/paralysis/paraplegic + //can_gain = FALSE maybe breaks. + paralysis_type = "legs" + resilience = TRAUMA_RESILIENCE_ABSOLUTE /datum/brain_trauma/severe/narcolepsy name = "Narcolepsy" @@ -121,7 +171,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 +233,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 +248,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) - ..() \ No newline at end of file + REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT) + ..() diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index 0bbbf8de08..d9e6f00643 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -134,3 +134,71 @@ /datum/brain_trauma/special/psychotic_brawling/bath_salts name = "Chemical Violent Psychosis" + random_gain = FALSE + +/datum/brain_trauma/special/beepsky + name = "Criminal" + desc = "Patient seems to be a criminal." + scan_desc = "criminal mind" + gain_text = "Justice is coming for you." + lose_text = "You were absolved for your crimes." + random_gain = FALSE + var/obj/effect/hallucination/simple/securitron/beepsky + +/datum/brain_trauma/special/beepsky/on_gain() + create_securitron() + ..() + +/datum/brain_trauma/special/beepsky/proc/create_securitron() + var/turf/where = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z) + beepsky = new(where, owner) + beepsky.victim = owner + +/datum/brain_trauma/special/beepsky/on_lose() + QDEL_NULL(beepsky) + ..() + +/datum/brain_trauma/special/beepsky/on_life() + if(QDELETED(beepsky) || !beepsky.loc || beepsky.z != owner.z) + QDEL_NULL(beepsky) + if(prob(30)) + create_securitron() + else + return + if(get_dist(owner, beepsky) >= 10 && prob(20)) + QDEL_NULL(beepsky) + create_securitron() + if(owner.stat != CONSCIOUS) + if(prob(20)) + owner.playsound_local(beepsky, 'sound/voice/beepsky/iamthelaw.ogg', 50) + return + if(get_dist(owner, beepsky) <= 1) + owner.playsound_local(owner, 'sound/weapons/egloves.ogg', 50) + owner.visible_message("[owner]'s body jerks as if it was shocked.", "You feel the fist of the LAW.") + owner.take_bodypart_damage(0,0,rand(40, 70)) + QDEL_NULL(beepsky) + if(prob(20) && get_dist(owner, beepsky) <= 8) + owner.playsound_local(beepsky, 'sound/voice/beepsky/criminal.ogg', 40) + ..() + +/obj/effect/hallucination/simple/securitron + name = "Securitron" + desc = "The LAW is coming." + image_icon = 'icons/mob/aibots.dmi' + image_state = "secbot-c" + var/victim + +/obj/effect/hallucination/simple/securitron/New() + name = pick ( "officer Beepsky", "officer Johnson", "officer Pingsky") + START_PROCESSING(SSfastprocess,src) + ..() + +/obj/effect/hallucination/simple/securitron/process() + if(prob(60)) + forceMove(get_step_towards(src, victim)) + if(prob(5)) + to_chat(victim, "[name] exclaims, \"Level 10 infraction alert!\"") + +/obj/effect/hallucination/simple/securitron/Destroy() + STOP_PROCESSING(SSfastprocess,src) + return ..() \ 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..653b8a98c0 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -192,17 +192,16 @@ 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]") addtimer(CALLBACK(src, /datum/brain_trauma/severe/split_personality.proc/switch_personalities), 10) return message -/datum/brain_trauma/severe/split_personality/brainwashing/on_say(message) - if(findtext(message, codeword)) - return "" //oh hey did you want to tell people about the secret word to bring you back? - return message +/datum/brain_trauma/severe/split_personality/brainwashing/handle_speech(datum/source, list/speech_args) + if(findtext(speech_args[SPEECH_MESSAGE], codeword)) + speech_args[SPEECH_MESSAGE] = "" //oh hey did you want to tell people about the secret word to bring you back? /mob/living/split_personality/traitor name = "split personality" diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm new file mode 100644 index 0000000000..f6a2a89195 --- /dev/null +++ b/code/datums/components/bouncy.dm @@ -0,0 +1,40 @@ +/datum/component/bouncy + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/bouncy_mod = 1 + var/list/bounce_signals = list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_HIT_REACT, COMSIG_ITEM_ATTACK) + +/datum/component/bouncy/Initialize(_bouncy_mod, list/_bounce_signals) + if(!ismovableatom(parent)) + return COMPONENT_INCOMPATIBLE + if(_bouncy_mod) + bouncy_mod = _bouncy_mod + if(_bounce_signals) + bounce_signals = _bounce_signals + +/datum/component/bouncy/InheritComponent(datum/component/bouncy/B, original, _bouncy_mod, list/_bounce_signals) + if(_bouncy_mod) + bouncy_mod = max(bouncy_mod, _bouncy_mod) + if(_bounce_signals) + var/list/diff_bounces = difflist(bounce_signals, _bounce_signals, TRUE) + for(var/bounce in diff_bounces) + bounce_signals += bounce + RegisterSignal(parent, bounce, .proc/bounce_up) + +/datum/component/bouncy/RegisterWithParent() + RegisterSignal(parent, bounce_signals, .proc/bounce_up) + +/datum/component/bouncy/UnregisterFromParent() + UnregisterSignal(parent, bounce_signals) + +/datum/component/bouncy/proc/bounce_up(datum/source) + var/atom/movable/A = parent + switch(rand(1, 3)) + if(1) + A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14) + if(2) + var/min_b = 0.6/bouncy_mod + var/max_b = 1.2 * bouncy_mod + A.do_squish(rand(min_b, max_b), rand(min_b, max_b), 14) + if(3) + var/pixelshift = 8 * bouncy_mod + A.Shake(pixelshift, pixelshift, duration = 15) 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/nanites.dm b/code/datums/components/nanites.dm index 426855f887..c7dd7123d2 100644 --- a/code/datums/components/nanites.dm +++ b/code/datums/components/nanites.dm @@ -2,10 +2,10 @@ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/mob/living/host_mob - var/nanite_volume = 100 //amount of nanites in the system, used as fuel for nanite programs - var/max_nanites = 500 //maximum amount of nanites in the system + var/nanite_volume = 50 //amount of nanites in the system, used as fuel for nanite programs + var/max_nanites = 250 //maximum amount of nanites in the system var/regen_rate = 0.5 //nanites generated per second - var/safety_threshold = 50 //how low nanites will get before they stop processing/triggering + var/safety_threshold = 25 //how low nanites will get before they stop processing/triggering var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from var/next_sync = 0 var/list/datum/nanite_program/programs = list() @@ -311,4 +311,4 @@ mob_program["trigger_code"] = P.trigger_code id++ mob_programs += list(mob_program) - data["mob_programs"] = mob_programs \ No newline at end of file + data["mob_programs"] = mob_programs diff --git a/code/datums/components/orbiter.dm b/code/datums/components/orbiter.dm new file mode 100644 index 0000000000..301e50dc42 --- /dev/null +++ b/code/datums/components/orbiter.dm @@ -0,0 +1,156 @@ +/datum/component/orbiter + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/list/orbiters + var/datum/callback/orbiter_spy + var/datum/callback/orbited_spy + +//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) +//clockwise: whether you orbit clockwise or anti clockwise +//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) +//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. +//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts +/datum/component/orbiter/Initialize(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + if(!istype(orbiter) || !isatom(parent) || isarea(parent)) + return COMPONENT_INCOMPATIBLE + + orbiters = list() + orbiter_spy = CALLBACK(src, .proc/orbiter_move_react) + orbited_spy = CALLBACK(src, .proc/move_react) + + var/atom/master = parent + master.orbiters = src + + begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + +/datum/component/orbiter/RegisterWithParent() + var/atom/target = parent + while(ismovableatom(target)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy) + target = target.loc + +/datum/component/orbiter/UnregisterFromParent() + var/atom/target = parent + while(ismovableatom(target)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + target = target.loc + +/datum/component/orbiter/Destroy() + var/atom/master = parent + master.orbiters = null + for(var/i in orbiters) + end_orbit(i) + orbiters = null + QDEL_NULL(orbiter_spy) + QDEL_NULL(orbited_spy) + return ..() + +/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, list/arguments) + if(arguments) + begin_orbit(arglist(arguments)) + return + // The following only happens on component transfers + orbiters += newcomp.orbiters + +/datum/component/orbiter/PostTransfer() + if(!isatom(parent) || isarea(parent) || !get_turf(parent)) + return COMPONENT_INCOMPATIBLE + move_react() + +/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + if(orbiter.orbiting) + if(orbiter.orbiting == src) + orbiter.orbiting.end_orbit(orbiter, TRUE) + else + orbiter.orbiting.end_orbit(orbiter) + orbiters[orbiter] = TRUE + orbiter.orbiting = src + RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, orbiter_spy) + var/matrix/initial_transform = matrix(orbiter.transform) + + // Head first! + if(pre_rotation) + var/matrix/M = matrix(orbiter.transform) + var/pre_rot = 90 + if(!clockwise) + pre_rot = -90 + M.Turn(pre_rot) + orbiter.transform = M + + var/matrix/shift = matrix(orbiter.transform) + shift.Translate(0, radius) + orbiter.transform = shift + + orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE) + + //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit + orbiter.transform = initial_transform + orbiter.forceMove(get_turf(parent)) + to_chat(orbiter, "Now orbiting [parent].") + +/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE) + if(!orbiters[orbiter]) + return + UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED) + orbiter.SpinAnimation(0, 0) + orbiters -= orbiter + orbiter.stop_orbit(src) + orbiter.orbiting = null + if(!refreshing && !length(orbiters) && !QDELING(src)) + qdel(src) + +// This proc can receive signals by either the thing being directly orbited or anything holding it +/datum/component/orbiter/proc/move_react(atom/orbited, atom/oldloc, direction) + set waitfor = FALSE // Transfer calls this directly and it doesnt care if the ghosts arent done moving + + var/atom/movable/master = parent + if(master.loc == oldloc) + return + + var/turf/newturf = get_turf(master) + if(!newturf) + qdel(src) + + // Handling the signals of stuff holding us (or not anymore) + // These are prety rarely activated, how often are you following something in a bag? + if(oldloc && !isturf(oldloc)) // We used to be registered to it, probably + var/atom/target = oldloc + while(ismovableatom(target)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + target = target.loc + if(orbited?.loc && orbited.loc != newturf) // We want to know when anything holding us moves too + var/atom/target = orbited.loc + while(ismovableatom(target)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy, TRUE) + target = target.loc + + var/atom/curloc = master.loc + for(var/i in orbiters) + var/atom/movable/thing = i + if(QDELETED(thing) || thing.loc == newturf) + continue + thing.forceMove(newturf) + if(CHECK_TICK && master.loc != curloc) + // We moved again during the checktick, cancel current operation + break + + +/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction) + if(orbiter.loc == get_turf(parent)) + return + end_orbit(orbiter) + +///////////////////// + +/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE) + if(!istype(A) || !get_turf(A) || A == src) + return + + return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + +/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits) + return // We're just a simple hook + +/atom/proc/transfer_observers_to(atom/target) + if(!orbiters || !istype(target) || !get_turf(target) || target == src) + return + target.TakeComponent(orbiters) 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..48880ff605 --- /dev/null +++ b/code/datums/components/storage/concrete/emergency.dm @@ -0,0 +1,38 @@ +/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/on_attack_hand(datum/source, mob/user) + var/atom/A = parent + if(!attack_hand_interact) + return + if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item + user.active_storage.close(user) + close(user) + . = COMPONENT_NO_ATTACK_HAND + return + . = COMPONENT_NO_ATTACK_HAND + if(!check_locked(source, user, TRUE)) + show_to(user) + A.do_jiggle() + if(rustle_sound) + playsound(A, "rustle", 50, 1, -5) + +/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/emergency/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/storage.dm b/code/datums/components/storage/storage.dm index dc25729e37..0c701cb943 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) @@ -535,11 +531,9 @@ if(!istype(M)) return FALSE A.add_fingerprint(M) - if(locked && !force) - to_chat(M, "[parent] seems to be locked!") + if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE))) return FALSE - if(force || M.CanReach(parent, view_only = TRUE)) - show_to(M) + show_to(M) /datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M) if(isitem(O)) @@ -563,10 +557,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) @@ -599,7 +592,7 @@ if(!stop_messages) to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!") return FALSE //To prevent the stacking of same sized storage items. - if(I.item_flags & NODROP) //SHOULD be handled in unEquip, but better safe than sorry. + if(HAS_TRAIT(I, TRAIT_NODROP)) //SHOULD be handled in unEquip, but better safe than sorry. to_chat(M, "\the [I] is stuck to your hand, you can't put it in \the [host]!") return FALSE var/datum/component/storage/concrete/master = master() @@ -659,8 +652,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 +715,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,15 +740,15 @@ /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 if(!quickdraw) A.add_fingerprint(user) user_show_to_mob(user) - playsound(A, "rustle", 50, 1, -5) + if(rustle_sound) + playsound(A, "rustle", 50, 1, -5) return if(!user.incapacitated()) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index c5966452bb..8982530ab6 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -21,6 +21,9 @@ GLOBAL_LIST_EMPTY(uplinks) var/datum/uplink_purchase_log/purchase_log var/list/uplink_items var/hidden_crystals = 0 + var/unlock_note + var/unlock_code + var/failsafe_code /datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) if(!isitem(parent)) @@ -219,7 +222,10 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text) var/obj/item/pda/master = parent - if(trim(lowertext(new_ring_text)) != trim(lowertext(master.lock_code))) //why is the lock code stored on the pda? + if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code))) + if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code))) + failsafe() + return COMPONENT_STOP_RINGTONE_CHANGE return locked = FALSE interact(null, user) @@ -233,7 +239,9 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/new_frequency(datum/source, list/arguments) var/obj/item/radio/master = parent var/frequency = arguments[1] - if(frequency != master.traitor_frequency) + if(frequency != unlock_code) + if(frequency == failsafe_code) + failsafe() return locked = FALSE if(ismob(master.loc)) @@ -243,9 +251,38 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user) var/obj/item/pen/master = parent - if(degrees != master.traitor_unlock_degrees) + if(degrees != unlock_code) + if(degrees == failsafe_code) //Getting failsafes on pens is risky business + failsafe() return locked = FALSE master.degrees = 0 interact(null, user) - to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") \ No newline at end of file + to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") + +/datum/component/uplink/proc/setup_unlock_code() + unlock_code = generate_code() + var/obj/item/P = parent + if(istype(parent,/obj/item/pda)) + unlock_note = "Uplink Passcode: [unlock_code] ([P.name])." + else if(istype(parent,/obj/item/radio)) + unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." + else if(istype(parent,/obj/item/pen)) + unlock_note = "Uplink Degrees: [unlock_code] ([P.name])." + +/datum/component/uplink/proc/generate_code() + if(istype(parent,/obj/item/pda)) + return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" + else if(istype(parent,/obj/item/radio)) + return sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) + else if(istype(parent,/obj/item/pen)) + return rand(1, 360) + +/datum/component/uplink/proc/failsafe() + if(!parent) + return + var/turf/T = get_turf(parent) + if(!T) + return + explosion(T,1,2,3) + qdel(parent) //Alternatively could brick the uplink. 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/pierrot_throat.dm b/code/datums/diseases/pierrot_throat.dm index 64f453cd48..b2241d59ba 100644 --- a/code/datums/diseases/pierrot_throat.dm +++ b/code/datums/diseases/pierrot_throat.dm @@ -26,3 +26,30 @@ if(4) if(prob(5)) affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat") + +/datum/disease/pierrot_throat/after_add() + RegisterSignal(affected_mob, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/disease/pierrot_throat/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/list/split_message = splittext(message, " ") //List each word in the message + var/applied = 0 + for (var/i in 1 to length(split_message)) + if(prob(3 * stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% + if(findtext(split_message[i], "*") || findtext(split_message[i], ";") || findtext(split_message[i], ":")) + continue + split_message[i] = "HONK" + if (applied++ > stage) + break + if (applied) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN // a little bonus + message = jointext(split_message, " ") + speech_args[SPEECH_MESSAGE] = message + +/datum/disease/pierrot_throat/Destroy() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) + return ..() + +/datum/disease/pierrot_throat/remove_disease() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) + return ..() \ No newline at end of file diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 938515625d..33e92e4de5 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -185,25 +185,6 @@ if(DNA_TAUR_BLOCK) construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) -/datum/dna/proc/mutations_say_mods(message) - if(message) - for(var/datum/mutation/human/M in mutations) - message = M.say_mod(message) - return message - -/datum/dna/proc/mutations_get_spans() - var/list/spans = list() - for(var/datum/mutation/human/M in mutations) - spans |= M.get_spans() - return spans - -/datum/dna/proc/species_get_spans() - var/list/spans = list() - if(species) - spans |= species.get_spans() - return spans - - /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 && custom_species == D.custom_species) if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) 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/explosion.dm b/code/datums/explosion.dm index fe16b9459f..b3c57e4838 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -198,7 +198,8 @@ GLOBAL_LIST_EMPTY(explosions) var/list/items = list() for(var/I in T) var/atom/A = I - items += A.GetAllContents() + if (!A.prevent_content_explosion()) //The atom/contents_explosion() proc returns null if the contents ex_acting has been handled by the atom, and TRUE if it hasn't. + items += A.GetAllContents() for(var/O in items) var/atom/A = O if(!QDELETED(A)) 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/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm similarity index 91% rename from code/datums/looping_sounds/looping_sound.dm rename to code/datums/looping_sounds/_looping_sound.dm index 2eba36dc90..1b7a304494 100644 --- a/code/datums/looping_sounds/looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -11,7 +11,6 @@ chance (num) Chance per loop to play a mid_sound volume (num) Sound output volume - muted (bool) Private. Used to stop the sound loop. max_loops (num) The max amount of loops to run for. direct (bool) If true plays directly to provided atoms instead of from them */ @@ -68,7 +67,7 @@ if(!chance || prob(chance)) play(get_sound(starttime)) if(!timerid) - timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP) + timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP) /datum/looping_sound/proc/play(soundfile) var/list/atoms_cache = output_atoms @@ -84,10 +83,7 @@ playsound(thing, S, volume) /datum/looping_sound/proc/get_sound(starttime, _mid_sounds) - if(!_mid_sounds) - . = mid_sounds - else - . = _mid_sounds + . = _mid_sounds || mid_sounds while(!isfile(.) && !isnull(.)) . = pickweight(.) @@ -96,7 +92,7 @@ if(start_sound) play(start_sound) start_wait = start_length - addtimer(CALLBACK(src, .proc/sound_loop), start_wait) + addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME) /datum/looping_sound/proc/on_stop() if(end_sound) diff --git a/code/datums/martial.dm b/code/datums/martial.dm index 2bc01e0bf6..ae8f92a342 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -5,6 +5,7 @@ var/current_target var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary var/deflection_chance = 0 //Chance to deflect projectiles + var/reroute_deflection = FALSE //Delete the bullet, or actually deflect it in some direction? var/block_chance = 0 //Chance to block melee attacks using items while on throw mode. var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not var/help_verb diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 8a5f0f9439..4283d7f78f 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -86,13 +86,13 @@ return 0 /datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.stat || D.IsKnockdown()) + if(D.lying || D.IsKnockdown()) return 0 D.visible_message("[A] leg sweeps [D]!", \ "[A] leg sweeps you!") playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1) D.apply_damage(5, BRUTE) - D.Knockdown(40) + D.Knockdown(40, override_hardstun = 0.01, 25) log_combat(A, D, "leg sweeped") return 1 @@ -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 = "combat" + 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..5f19c37b99 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -7,6 +7,7 @@ /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" deflection_chance = 100 + reroute_deflection = TRUE no_guns = TRUE allow_temp_override = FALSE help_verb = /mob/living/carbon/human/proc/sleeping_carp_help @@ -179,7 +180,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/mind.dm b/code/datums/mind.dm index 90affe0228..7d150d890d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -233,13 +233,10 @@ /datum/mind/proc/remove_antag_equip() var/list/Mob_Contents = current.get_contents() for(var/obj/item/I in Mob_Contents) - if(istype(I, /obj/item/pda)) - var/obj/item/pda/P = I - P.lock_code = "" - - else if(istype(I, /obj/item/radio)) - var/obj/item/radio/R = I - R.traitor_frequency = 0 + var/datum/component/uplink/O = I.GetComponent(/datum/component/uplink) +//Todo make this reset signal + if(O) + O.unlock_code = null /datum/mind/proc/remove_all_antag() //For the Lazy amongst us. remove_changeling() @@ -304,33 +301,22 @@ . = 0 else . = uplink_loc - uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) - var/unlock_note - - if(uplink_loc == R) - R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.") - unlock_note = "Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name])." - else if(uplink_loc == PDA) - PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.") - unlock_note = "Uplink Passcode: [PDA.lock_code] ([PDA.name])." - - else if(uplink_loc == P) - P.traitor_unlock_degrees = rand(1, 360) - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.") - unlock_note = "Uplink Degrees: [P.traitor_unlock_degrees] ([P.name])." + var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) + if(!U) + CRASH("Uplink creation failed.") + U.setup_unlock_code() + if(!silent) + if(uplink_loc == R) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") + else if(uplink_loc == PDA) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") + else if(uplink_loc == P) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") if(uplink_owner) - uplink_owner.antag_memory += unlock_note + "
" + uplink_owner.antag_memory += U.unlock_note + "
" else - traitor_mob.mind.store_memory(unlock_note) + traitor_mob.mind.store_memory(U.unlock_note) //Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. diff --git a/code/datums/mood_events/drink_events.dm b/code/datums/mood_events/drink_events.dm index db5a91009e..5d0eb0e0cb 100644 --- a/code/datums/mood_events/drink_events.dm +++ b/code/datums/mood_events/drink_events.dm @@ -22,3 +22,8 @@ description = "That drink was amazing!\n" mood_change = 4 timeout = 1200 + +/datum/mood_event/amazingtaste + description = "Amazing taste!\n" + mood_change = 50 + timeout = 10 MINUTES diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 4021d11128..b2b03fb56b 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -117,6 +117,16 @@ description = "I'm missing my family heirloom...\n" mood_change = -4 +/datum/mood_event/loud_gong + description = "That loud gong noise really hurt my ears!\n" + mood_change = -3 + timeout = 1200 + +/datum/mood_event/spooked + description = "The rattling of those bones...It still haunts me.\n" + mood_change = -4 + timeout = 2400 + //These are unused so far but I want to remember them to use them later /datum/mood_event/cloned_corpse description = "I recently saw my own corpse...\n" @@ -125,3 +135,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 6989744fe3..051a548d1d 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -75,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.dm b/code/datums/mutations.dm index 7de9ca8b4a..efa248b4f0 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -105,13 +105,6 @@ GLOBAL_LIST_EMPTY(mutations_list) return 0 return 1 -/datum/mutation/human/proc/say_mod(message) - if(message) - return message - -/datum/mutation/human/proc/get_spans() - return list() - /mob/living/carbon/proc/update_mutations_overlay() return 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..85cecca489 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -11,10 +11,11 @@ /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) + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) /datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) if(proximity) //no telekinetic hulk attack @@ -28,12 +29,15 @@ /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") + UnregisterSignal(owner, COMSIG_MOB_SAY) -/datum/mutation/human/hulk/say_mod(message) +/datum/mutation/human/hulk/proc/handle_speech(original_message, wrapped_message) + var/message = wrapped_message[1] if(message) - message = "[uppertext(replacetext(message, ".", "!"))]!!" - return message + message = "[replacetext(message, ".", "!")]!!" + wrapped_message[1] = message + return COMPONENT_UPPERCASE_SPEECH diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 3f303535ce..21adc944f6 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -17,9 +17,20 @@ text_gain_indication = "You feel an off sensation in your voicebox." text_lose_indication = "The off sensation passes." -/datum/mutation/human/wacky/get_spans() - return list(SPAN_SANS) +/datum/mutation/human/wacky/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) +/datum/mutation/human/wacky/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/wacky/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_SANS /datum/mutation/human/mute name = "Mute" @@ -28,14 +39,16 @@ text_lose_indication = "You feel able to speak freely again." /datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) - if(..()) + . = ..() + 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(..()) + . = ..() + if(.) return - owner.remove_trait(TRAIT_MUTE, GENETIC_MUTATION) + REMOVE_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) /datum/mutation/human/smile @@ -45,7 +58,20 @@ text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)" text_lose_indication = "Everything is terrible again. :(" -/datum/mutation/human/smile/say_mod(message) +/datum/mutation/human/smile/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/smile/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/smile/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " //Time for a friendly game of SS13 @@ -92,7 +118,7 @@ message = replacetext(message," cunt "," privates ") message = replacetext(message," dick "," jerk ") message = replacetext(message," vagina "," privates ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/unintelligible @@ -102,30 +128,17 @@ text_gain_indication = "You can't seem to form any coherent thoughts!" text_lose_indication = "Your mind feels more clear." -/datum/mutation/human/unintelligible/say_mod(message) - if(message) - var/prefix=copytext(message,1,2) - if(prefix == ";") - message = copytext(message,2) - else if(prefix in list(":","#")) - prefix += copytext(message,2,3) - message = copytext(message,3) - else - prefix="" +/datum/mutation/human/unintelligible/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) - var/list/words = splittext(message," ") - var/list/rearranged = list() - for(var/i=1;i<=words.len;i++) - var/cword = pick(words) - words.Remove(cword) - var/suffix = copytext(cword,length(cword)-1,length(cword)) - while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) - cword = copytext(cword,1 ,length(cword)-1) - suffix = copytext(cword,length(cword)-1,length(cword) ) - if(length(cword)) - rearranged += cword - message ="[prefix][jointext(rearranged," ")]" - return message +/datum/mutation/human/unintelligible/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) /datum/mutation/human/swedish @@ -135,7 +148,20 @@ text_gain_indication = "You feel Swedish, however that works." text_lose_indication = "The feeling of Swedishness passes." -/datum/mutation/human/swedish/say_mod(message) +/datum/mutation/human/swedish/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/swedish/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/swedish/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = replacetext(message,"w","v") message = replacetext(message,"j","y") @@ -144,7 +170,7 @@ message = replacetext(message,"o",pick("�","�","o")) if(prob(30)) message += " Bork[pick("",", bork",", bork, bork")]!" - return message + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/chav @@ -154,7 +180,20 @@ text_gain_indication = "Ye feel like a reet prat like, innit?" text_lose_indication = "You no longer feel like being rude and sassy." -/datum/mutation/human/chav/say_mod(message) +/datum/mutation/human/chav/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/chav/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/chav/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " message = replacetext(message," looking at "," gawpin' at ") @@ -178,7 +217,7 @@ message = replacetext(message," break "," do ") message = replacetext(message," your "," yer ") message = replacetext(message," security "," coppers ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/elvis @@ -199,7 +238,20 @@ if(prob(15)) owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!") -/datum/mutation/human/elvis/say_mod(message) +/datum/mutation/human/elvis/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/elvis/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/elvis/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " message = replacetext(message," i'm not "," I aint ") @@ -211,7 +263,7 @@ message = replacetext(message," yes ",pick(" sure", "yea ")) message = replacetext(message," faggot "," square ") message = replacetext(message," muh valids "," getting my kicks ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/stoner @@ -229,4 +281,4 @@ /datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) ..() owner.grant_language(/datum/language/common) - owner.remove_language(/datum/language/beachbum) + owner.remove_language(/datum/language/beachbum) \ No newline at end of file diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 058c820f7a..22fca23902 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -281,3 +281,27 @@ suffix = "cloning_facility.dmm" name = "Ancient Cloning Lab" description = "An experimental cloning lab snapped off from an ancient ship. The cloner model inside lacks many modern functionalities and security measures." + +/datum/map_template/ruin/space/augmentation + id = "augmentationfacility" + suffix = "augmentationfacility.dmm" + name = "Roboticst Augmentation Facility" + description = "A mysterious lab in the depths of space containing robotics supplies and a one use autosurgeon." + +/datum/map_template/ruin/space/harambe + id = "bigape" + suffix = "bigape.dmm" + name = "Big Ape" + description = "A gorilla? Out here? But why." + +/datum/map_template/ruin/space/space_arcade + id = "arcade" + suffix = "arcade.dmm" + name = "Space Arcade" + description = "A lonely arcade in the depths of space." + +/datum/map_template/ruin/space/hermit + id = "spacehermit" + suffix = "spacehermit.dmm" + name = "Space Hermit" + description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck." 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/negative.dm b/code/datums/traits/negative.dm index 614cc65cbb..36c6733cf7 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -38,13 +38,13 @@ var/obj/item/heirloom_type switch(quirk_holder.mind.assigned_role) if("Clown") - heirloom_type = /obj/item/paint/anycolor - heirloom_type = /obj/item/bikehorn/golden + heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/bikehorn/golden) if("Mime") - heirloom_type = /obj/item/paint/anycolor - heirloom_type = /obj/item/toy/dummy + heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/toy/dummy) if("Cook") heirloom_type = /obj/item/kitchen/knife/scimitar + if("Botanist") + heirloom_type = pick(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie) if("Medical Doctor") heirloom_type = /obj/item/healthanalyzer/advanced if("Station Engineer") @@ -60,7 +60,7 @@ if("Scientist") heirloom_type = /obj/item/toy/plush/slimeplushie if("Assistant") - heirloom_type = /obj/item/storage/toolbox/mechanical/old/heirloom + heirloom_type = /obj/item/clothing/gloves/cut/family if("Chaplain") heirloom_type = /obj/item/camera/spooky/family if("Captain") @@ -187,6 +187,41 @@ to_chat(quirk_holder, "Your antagonistic nature has caused you to renounce your pacifism.") qdel(src) +/datum/quirk/paraplegic + name = "Paraplegic" + desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!" + value = -3 + mob_trait = TRAIT_PARA + human_only = TRUE + gain_text = null // Handled by trauma. + lose_text = null + medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities." + +/datum/quirk/paraplegic/add() + var/datum/brain_trauma/severe/paralysis/paraplegic/T = new() + var/mob/living/carbon/human/H = quirk_holder + H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/quirk/paraplegic/on_spawn() + if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs. + quirk_holder.buckled.unbuckle_mob(quirk_holder) + + var/turf/T = get_turf(quirk_holder) + var/obj/structure/chair/spawn_chair = locate() in T + + var/obj/vehicle/ridden/wheelchair/wheels = new(T) + if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking + wheels.setDir(spawn_chair.dir) + + wheels.buckle_mob(quirk_holder) + + // During the spawning process, they may have dropped what they were holding, due to the paralysis + // So put the things back in their hands. + + for(var/obj/item/I in T) + if(I.fingerprintslast == quirk_holder.ckey) + quirk_holder.put_in_hands(I) + /datum/quirk/poor_aim name = "Poor Aim" desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out." @@ -208,8 +243,12 @@ var/slot_string = "limb" /datum/quirk/prosthetic_limb/on_spawn() - var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/mob/living/carbon/human/H = quirk_holder + var/limb_slot + if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced + limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) + else + limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot) var/obj/item/bodypart/prosthetic switch(limb_slot) diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index f299e9904a..f70e3a3c68 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -93,3 +93,12 @@ 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/datums/wires/microwave.dm b/code/datums/wires/microwave.dm new file mode 100644 index 0000000000..8c74abfa46 --- /dev/null +++ b/code/datums/wires/microwave.dm @@ -0,0 +1,27 @@ +/datum/wires/microwave + holder_type = /obj/machinery/microwave + proper_name = "Microwave" + +/datum/wires/microwave/New(atom/holder) + wires = list( + WIRE_ACTIVATE + ) + ..() + +/datum/wires/microwave/interactable(mob/user) + . = FALSE + var/obj/machinery/microwave/M = holder + if(M.panel_open) + . = TRUE + +/datum/wires/microwave/on_pulse(wire) + var/obj/machinery/microwave/M = holder + switch(wire) + if(WIRE_ACTIVATE) + M.cook() + +/datum/wires/microwave/on_cut(wire, mend) + var/obj/machinery/microwave/M = holder + switch(wire) + if(WIRE_ACTIVATE) + M.wire_disabled = !mend diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 10650153d6..dfbb59811b 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -76,7 +76,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) continue if(GLOB.teleportlocs[AR.name]) continue - var/turf/picked = safepick(get_area_turfs(AR.type)) + if (!AR.contents.len) + continue + var/turf/picked = AR.contents[1] if (picked && is_station_level(picked.z)) GLOB.teleportlocs[AR.name] = AR @@ -120,6 +122,14 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(!IS_DYNAMIC_LIGHTING(src)) add_overlay(/obj/effect/fullbright) + reg_in_areas_in_z() + + return INITIALIZE_HINT_LATELOAD + +/area/LateInitialize() + power_change() // all machines set to current power level, also updates icon + +/area/proc/reg_in_areas_in_z() if(contents.len) var/list/areas_in_z = SSmapping.areas_in_z var/z @@ -137,11 +147,6 @@ GLOBAL_LIST_EMPTY(teleportlocs) areas_in_z["[z]"] = list() areas_in_z["[z]"] += src - return INITIALIZE_HINT_LATELOAD - -/area/LateInitialize() - power_change() // all machines set to current power level, also updates icon - /area/Destroy() if(GLOB.areas_by_type[type] == src) GLOB.areas_by_type[type] = null diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 48596a0b6d..88fe2c8d13 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. @@ -32,6 +31,8 @@ var/list/filter_data //For handling persistent filters + var/datum/component/orbiter/orbiters + var/rad_flags = NONE // Will move to flags_1 when i can be arsed to var/rad_insulation = RAD_NO_INSULATION @@ -203,16 +204,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 +262,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 +275,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 @@ -288,8 +289,11 @@ to_chat(user, "You can't move while buckled to [src]!") return +/atom/proc/prevent_content_explosion() + return FALSE + /atom/proc/contents_explosion(severity, target) - return + return //For handling the effects of explosions on contents that would not normally be effected /atom/proc/ex_act(severity, target) set waitfor = FALSE diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e56f6d366c..83762240bc 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -14,6 +14,7 @@ var/verb_exclaim = "exclaims" var/verb_whisper = "whispers" var/verb_yell = "yells" + var/speech_span var/inertia_dir = 0 var/atom/inertia_last_loc var/inertia_moving = 0 @@ -31,6 +32,8 @@ var/atom/movable/pulling var/grab_state = 0 var/throwforce = 0 + var/datum/component/orbiter/orbiting + 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") @@ -295,14 +298,7 @@ if (length(client_mobs_in_contents)) update_parallax_contents() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - O.Check() - if (orbiting) - orbiting.Check() - - return 1 + return TRUE /atom/movable/Destroy(force) QDEL_NULL(proximity_monitor) @@ -324,6 +320,10 @@ if(pulledby) pulledby.stop_pulling() + if(orbiting) + orbiting.end_orbit(src) + orbiting = null + // Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. // You probably want CanPass() /atom/movable/Cross(atom/movable/AM) 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/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index feb81d44e0..d6131ce58e 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -86,8 +86,11 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name user.underwear = chosen_prof.underwear + user.undie_color = chosen_prof.undie_color user.undershirt = chosen_prof.undershirt + user.shirt_color =chosen_prof.shirt_color user.socks = chosen_prof.socks + user.socks_color =chosen_prof.socks_color chosen_dna.transfer_identity(user, 1) user.updateappearance(mutcolor_update=1) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index d6513b5d40..94ca86e0dd 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 @@ -275,7 +275,7 @@ Credit where due: gloves = /obj/item/clothing/gloves/color/yellow belt = /obj/item/storage/belt/utility/servant backpack_contents = list(/obj/item/storage/box/engineer = 1, \ - /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1) + /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/holyoil = 1) id = /obj/item/pda var/plasmaman //We use this to determine if we should activate internals in post_equip() @@ -338,6 +338,10 @@ Credit where due: CLOCKCULTCHANGELOG\ \
\ +
  • Zelus oil: A new reagent. It can be used to heal the faithful to Ratvar, or kill heretics and moreso stun blood cultists,\ + or splashed onto metal sheets to make brass. This chemical can be found in minimal quantities by grinding brass sheets.\ +
  • Brass Flasks:Intended to store Zelus Oil in, but can also be used as fragile single use throwing weapons in a pinch! \ + These are crafted with a single sheet of brass and fit in the Clockwork Cuirass' suit storage.\ Good luck!" /obj/item/paper/servant_primer/Initialize() diff --git a/code/game/gamemodes/clown_ops/bananium_bomb.dm b/code/game/gamemodes/clown_ops/bananium_bomb.dm index 0d5f0691c4..b63d5b2e79 100644 --- a/code/game/gamemodes/clown_ops/bananium_bomb.dm +++ b/code/game/gamemodes/clown_ops/bananium_bomb.dm @@ -42,18 +42,19 @@ var/obj/item/clothing/C if(!H.w_uniform || H.dropItemToGround(H.w_uniform)) C = new /obj/item/clothing/under/rank/clown(H) - C.item_flags |= NODROP //mwahaha + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_W_UNIFORM) if(!H.shoes || H.dropItemToGround(H.shoes)) C = new /obj/item/clothing/shoes/clown_shoes(H) - C.item_flags |= NODROP + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_SHOES) if(!H.wear_mask || H.dropItemToGround(H.wear_mask)) C = new /obj/item/clothing/mask/gas/clown_hat(H) - C.item_flags |= NODROP + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_WEAR_MASK) H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) H.gain_trauma(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_LOBOTOMY, "clowns") //MWA HA HA diff --git a/code/game/gamemodes/clown_ops/clown_ops.dm b/code/game/gamemodes/clown_ops/clown_ops.dm index 12d3106c8d..66de72bad2 100644 --- a/code/game/gamemodes/clown_ops/clown_ops.dm +++ b/code/game/gamemodes/clown_ops/clown_ops.dm @@ -58,9 +58,11 @@ if(visualsOnly) return H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) /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/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index a3440fad39..9d1a3b650c 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -216,11 +216,11 @@ /obj/item/clothing/mask/fakemoustache/sticky/Initialize() . = ..() - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT) addtimer(CALLBACK(src, .proc/unstick), unstick_time) /obj/item/clothing/mask/fakemoustache/sticky/proc/unstick() - item_flags &= ~NODROP + ADD_TRAIT(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT) //DARK H.O.N.K. AND CLOWN MECH WEAPONS 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.dm b/code/game/gamemodes/objective.dm index 7532d18d06..f6b1def645 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -542,6 +542,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) return checking.researched_nodes.len >= target_amount /datum/objective/capture + var/captured_amount = 0 /datum/objective/capture/proc/gen_amount_goal() target_amount = rand(5,10) @@ -549,8 +550,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) return target_amount /datum/objective/capture/check_completion()//Basically runs through all the mobs in the area to determine how much they are worth. - var/captured_amount = 0 - var/area/centcom/holding/A = GLOB.areas_by_type[/area/centcom/holding] + /*var/area/centcom/holding/A = GLOB.areas_by_type[/area/centcom/holding] for(var/mob/living/carbon/human/M in A)//Humans. if(M.stat == DEAD)//Dead folks are worth less. captured_amount+=0.5 @@ -573,7 +573,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) if(M.stat == DEAD) captured_amount+=1 continue - captured_amount+=2 + captured_amount+=2*/ //Removed in favour of adding points on capture, in energy_net_nets.dm return captured_amount >= target_amount 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/PDApainter.dm b/code/game/machinery/PDApainter.dm index 53aebc53dc..45a3b59661 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -35,15 +35,14 @@ /obj/item/pda/clear, /obj/item/pda/syndicate, /obj/item/pda/chameleon, - /obj/item/pda/chameleon/broken) + /obj/item/pda/chameleon/broken, + /obj/item/pda/lieutenant) - for(var/P in typesof(/obj/item/pda) - blocked) - var/obj/item/pda/D = new P - - //D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA" - D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works. - - src.colorlist += D + for(var/A in typesof(/obj/item/pda) - blocked) + var/obj/item/pda/P = A + var/PDA_name = initial(P.name) + colorlist += PDA_name + colorlist[PDA_name] = list(initial(P.icon_state), initial(P.desc), initial(P.overlays_offsets), initial(P.overlays_icons)) /obj/machinery/pdapainter/Destroy() QDEL_NULL(storedpda) @@ -108,22 +107,20 @@ if(.) return - if(storedpda) - var/obj/item/pda/P - P = input(user, "Select your color!", "PDA Painting") as null|anything in colorlist - if(!P) - return - if(!in_range(src, user)) - return - if(!storedpda)//is the pda still there? - return - storedpda.icon_state = P.icon_state - storedpda.desc = P.desc - ejectpda() - - else + if(!storedpda) to_chat(user, "[src] is empty.") - + return + var/choice = input(user, "Select the new skin!", "PDA Painting") as null|anything in colorlist + if(!choice || !storedpda || !in_range(src, user)) + return + var/list/P = colorlist[choice] + storedpda.icon_state = P[1] + storedpda.desc = P[2] + storedpda.overlays_offsets = P[3] + storedpda.overlays_icons = P[4] + storedpda.set_new_overlays() + storedpda.update_icon() + ejectpda() /obj/machinery/pdapainter/verb/ejectpda() set name = "Eject PDA" diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 9b5aa96b0b..b0e4c699d7 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -168,9 +168,11 @@ Class Procs: update_icon() updateUsrDialog() -/obj/machinery/proc/dropContents() +/obj/machinery/proc/dropContents(list/subset = null) var/turf/T = get_turf(src) for(var/atom/movable/A in contents) + if(subset && !(A in subset)) + continue A.forceMove(T) if(isliving(A)) var/mob/living/L = A diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 959bcfab4d..884b818f32 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -96,10 +96,10 @@ GLOBAL_LIST_EMPTY(announcement_systems) message = "The arrivals shuttle has been damaged. Docking for repairs..." if(channels.len == 0) - radio.talk_into(src, message, null, list(SPAN_ROBOT), get_default_language()) + radio.talk_into(src, message, null) else for(var/channel in channels) - radio.talk_into(src, message, channel, list(SPAN_ROBOT), get_default_language()) + radio.talk_into(src, message, channel) //config stuff diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index c751ba007a..71dcb89ce7 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -49,12 +49,9 @@ if(next_warning < world.time && prob(15)) var/area/A = get_area(loc) var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!" - radio.talk_into(src, message, radio_channel, get_spans()) + radio.talk_into(src, message, radio_channel) next_warning = world.time + minimum_time_between_warnings -/obj/machinery/computer/bank_machine/get_spans() - . = ..() | SPAN_ROBOT - /obj/machinery/computer/bank_machine/ui_interact(mob/user) . = ..() var/dat = "[station_name()] secure vault. Authorized personnel only.
    " diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index d3b5e53a1b..ba9b6fc225 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -6,7 +6,7 @@ #define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical #define MINIMUM_HEAL_LEVEL 40 -#define SPEAK(message) radio.talk_into(src, message, radio_channel, get_spans(), get_default_language()) +#define SPEAK(message) radio.talk_into(src, message, radio_channel) /obj/machinery/clonepod name = "cloning pod" @@ -182,11 +182,11 @@ //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) @@ -361,11 +361,11 @@ 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() @@ -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) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 1f262c0979..8d0cfb95e8 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,3 +1,9 @@ +#define ARCADE_WEIGHT_TRICK 4 +#define ARCADE_WEIGHT_USELESS 2 +#define ARCADE_WEIGHT_RARE 1 +#define ARCADE_WEIGHT_PLUSH 65 + + /obj/machinery/computer/arcade name = "random arcade" desc = "random arcade machine" @@ -6,55 +12,64 @@ 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_PLUSH, + /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/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, + + /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 @@ -66,20 +81,32 @@ // If it's a generic arcade machine, pick a random arcade // circuit board for it and make the new machine if(!circuit) - var/choice = pick(subtypesof(/obj/item/circuitboard/computer/arcade)) - var/obj/item/circuitboard/CB = new choice() + var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 33, + /obj/item/circuitboard/computer/arcade/orion_trail = 33, + /obj/item/circuitboard/computer/arcade/minesweeper = 33, + /obj/item/circuitboard/computer/arcade/amputation = 2) + var/thegame = pickweight(gameodds) + var/obj/item/circuitboard/CB = new thegame() new CB.build_path(loc, CB) return INITIALIZE_HINT_QDEL Reset() -/obj/machinery/computer/arcade/proc/prizevend(mob/user) +/obj/machinery/computer/arcade/proc/prizevend(mob/user, list/rarity_classes) 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) if(!contents.len) - var/prizeselect = pickweight(prizes) + var/list/toy_raffle + if(rarity_classes) + for(var/A in prizes) + if(prizes[A] in rarity_classes) + LAZYSET(toy_raffle, A, prizes[A]) + if(!toy_raffle) + toy_raffle = prizes + var/prizeselect = pickweight(toy_raffle) new prizeselect(src) var/atom/movable/prize = pick(contents) @@ -104,1020 +131,3 @@ empprize = pickweight(prizes) new empprize(loc) explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) - - -// ** BATTLE ** // - - -/obj/machinery/computer/arcade/battle - name = "arcade machine" - desc = "Does not support Pinball." - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/battle - var/enemy_name = "Space Villain" - var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc - var/player_hp = 30 //Player health/attack points - var/player_mp = 10 - var/enemy_hp = 45 //Enemy health/attack points - var/enemy_mp = 20 - var/gameover = FALSE - var/blocked = FALSE //Player cannot attack/heal while set - var/turtle = 0 - -/obj/machinery/computer/arcade/battle/Reset() - var/name_action - var/name_part1 - var/name_part2 - - name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") - - name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") - name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - - enemy_name = replacetext((name_part1 + name_part2), "the ", "") - name = (name_action + name_part1 + name_part2) - -/obj/machinery/computer/arcade/battle/ui_interact(mob/user) - . = ..() - var/dat = "Close" - dat += "

    [enemy_name]

    " - - dat += "

    [temp]

    " - dat += "
    Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
    " - - if (gameover) - dat += "
    New Game" - else - dat += "
    Attack | " - dat += "Heal | " - dat += "Recharge Power" - - dat += "
    " - var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open() - -/obj/machinery/computer/arcade/battle/Topic(href, href_list) - if(..()) - return - - if (!blocked && !gameover) - if (href_list["attack"]) - blocked = TRUE - var/attackamt = rand(2,6) - temp = "You attack for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) - updateUsrDialog() - if(turtle > 0) - turtle-- - - sleep(10) - enemy_hp -= attackamt - arcade_action(usr) - - else if (href_list["heal"]) - blocked = TRUE - var/pointamt = rand(1,3) - var/healamt = rand(6,8) - temp = "You use [pointamt] magic to heal for [healamt] damage!" - playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) - updateUsrDialog() - turtle++ - - sleep(10) - player_mp -= pointamt - player_hp += healamt - blocked = TRUE - updateUsrDialog() - arcade_action(usr) - - else if (href_list["charge"]) - blocked = TRUE - var/chargeamt = rand(4,7) - temp = "You regain [chargeamt] points" - playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10) - player_mp += chargeamt - if(turtle > 0) - turtle-- - - updateUsrDialog() - sleep(10) - arcade_action(usr) - - if (href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - else if (href_list["newgame"]) //Reset everything - temp = "New Round" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = FALSE - turtle = 0 - - if(obj_flags & EMAGGED) - Reset() - obj_flags &= ~EMAGGED - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user) - if ((enemy_mp <= 0) || (enemy_hp <= 0)) - if(!gameover) - gameover = TRUE - temp = "[enemy_name] has fallen! Rejoice!" - playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10) - - if(obj_flags & EMAGGED) - new /obj/effect/spawner/newbomb/timer/syndicate(loc) - new /obj/item/clothing/head/collectable/petehat(loc) - message_admins("[ADMIN_LOOKUPFLW(usr)] has outbombed Cuban Pete and been awarded a bomb.") - log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") - Reset() - obj_flags &= ~EMAGGED - else - prizevend(user) - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) - - - else if ((obj_flags & EMAGGED) && (turtle >= 4)) - var/boomamt = rand(5,10) - temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" - playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10) - player_hp -= boomamt - - else if ((enemy_mp <= 5) && (prob(70))) - var/stealamt = rand(2,3) - temp = "[enemy_name] steals [stealamt] of your power!" - playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10) - player_mp -= stealamt - updateUsrDialog() - - if (player_mp <= 0) - gameover = TRUE - sleep(10) - temp = "You have been drained! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) - if(obj_flags & EMAGGED) - usr.gib() - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal"))) - - else if ((enemy_hp <= 10) && (enemy_mp > 4)) - temp = "[enemy_name] heals for 4 health!" - playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) - enemy_hp += 4 - enemy_mp -= 4 - - else - var/attackamt = rand(3,6) - temp = "[enemy_name] attacks for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) - player_hp -= attackamt - - if ((player_mp <= 0) || (player_hp <= 0)) - gameover = TRUE - temp = "You have been crushed! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) - if(obj_flags & EMAGGED) - usr.gib() - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) - - blocked = FALSE - return - - -/obj/machinery/computer/arcade/battle/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - to_chat(user, "A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!") - temp = "If you die in the game, you die for real!" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = FALSE - blocked = FALSE - - obj_flags |= EMAGGED - - enemy_name = "Cuban Pete" - name = "Outbomb Cuban Pete" - - - updateUsrDialog() - - - -// *** THE ORION TRAIL ** // - -#define ORION_TRAIL_WINTURN 9 - -//Orion Trail Events -#define ORION_TRAIL_RAIDERS "Raiders" -#define ORION_TRAIL_FLUX "Interstellar Flux" -#define ORION_TRAIL_ILLNESS "Illness" -#define ORION_TRAIL_BREAKDOWN "Breakdown" -#define ORION_TRAIL_LING "Changelings?" -#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" -#define ORION_TRAIL_MALFUNCTION "Malfunction" -#define ORION_TRAIL_COLLISION "Collision" -#define ORION_TRAIL_SPACEPORT "Spaceport" -#define ORION_TRAIL_BLACKHOLE "BlackHole" - -#define ORION_STATUS_START 1 -#define ORION_STATUS_NORMAL 2 -#define ORION_STATUS_GAMEOVER 3 -#define ORION_STATUS_MARKET 4 - -/obj/machinery/computer/arcade/orion_trail - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/orion_trail - var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game. - var/engine = 0 - var/hull = 0 - var/electronics = 0 - var/food = 80 - var/fuel = 60 - var/turns = 4 - var/alive = 4 - var/eventdat = null - var/event = null - var/list/settlers = list("Harry","Larry","Bob") - var/list/events = list(ORION_TRAIL_RAIDERS = 3, - ORION_TRAIL_FLUX = 1, - ORION_TRAIL_ILLNESS = 3, - ORION_TRAIL_BREAKDOWN = 2, - ORION_TRAIL_LING = 3, - ORION_TRAIL_MALFUNCTION = 2, - ORION_TRAIL_COLLISION = 1, - ORION_TRAIL_SPACEPORT = 2 - ) - var/list/stops = list() - var/list/stopblurbs = list() - var/lings_aboard = 0 - var/spaceport_raided = 0 - var/spaceport_freebie = 0 - var/last_spaceport_action = "" - var/gameStatus = ORION_STATUS_START - var/canContinueEvent = 0 - -/obj/machinery/computer/arcade/orion_trail/kobayashi - name = "Kobayashi Maru control computer" - desc = "A test for cadets" - icon = 'icons/obj/machines/particle_accelerator.dmi' - icon_state = "control_boxp" - events = list("Raiders" = 3, "Interstellar Flux" = 1, "Illness" = 3, "Breakdown" = 2, "Malfunction" = 2, "Collision" = 1, "Spaceport" = 2) - prizes = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1) - settlers = list("Kirk","Worf","Gene") - -/obj/machinery/computer/arcade/orion_trail/Reset() - // Sets up the main trail - stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") - stopblurbs = list( - "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", - "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", - "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", - "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", - "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", - "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", - "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", - "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", - "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" - ) - -/obj/machinery/computer/arcade/orion_trail/proc/newgame() - // Set names of settlers in crew - settlers = list() - for(var/i = 1; i <= 3; i++) - add_crewmember() - add_crewmember("[usr]") - // Re-set items to defaults - engine = 1 - hull = 1 - electronics = 1 - food = 80 - fuel = 60 - alive = 4 - turns = 1 - event = null - gameStatus = ORION_STATUS_NORMAL - lings_aboard = 0 - - //spaceport junk - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - -/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user) - . = ..() - if(fuel <= 0 || food <=0 || settlers.len == 0) - gameStatus = ORION_STATUS_GAMEOVER - event = null - var/dat = "" - if(gameStatus == ORION_STATUS_GAMEOVER) - dat = "

    Game Over

    " - dat += "Like many before you, your crew never made it to Orion, lost to space...
    Forever." - if(!settlers.len) - dat += "
    Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy." - else - if(food <= 0) - dat += "
    You ran out of food and starved." - if(obj_flags & EMAGGED) - user.nutrition = 0 //yeah you pretty hongry - to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") - if(fuel <= 0) - dat += "
    You ran out of fuel, and drift, slowly, into a star." - if(obj_flags & EMAGGED) - var/mob/living/M = user - M.adjust_fire_stacks(5) - M.IgniteMob() //flew into a star, so you're on fire - to_chat(user, "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.") - - if(obj_flags & EMAGGED) - to_chat(user, "You're never going to make it to Orion...") - user.death() - obj_flags &= ~EMAGGED //removes the emagged status after you lose - gameStatus = ORION_STATUS_START - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - - dat += "

    May They Rest In Peace

    " - else if(event) - dat = eventdat - else if(gameStatus == ORION_STATUS_NORMAL) - var/title = stops[turns] - var/subtext = stopblurbs[turns] - dat = "

    [title]

    " - dat += "[subtext]" - dat += "

    Crew:

    " - dat += english_list(settlers) - dat += "
    Food: [food] | Fuel: [fuel]" - dat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - if(turns == 7) - dat += "

    Go Around Continue

    " - else - dat += "

    Continue

    " - dat += "

    Kill a Crewmember

    " - dat += "

    Close

    " - else - dat = "

    The Orion Trail

    " - dat += "

    Experience the journey of your ancestors!



    " - dat += "
    New Game
    " - dat += "

    Close

    " - var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open() - return - -/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) - if(..()) - return - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - if(busy) - return - busy = TRUE - - if (href_list["continue"]) //Continue your travels - if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) - if(turns >= ORION_TRAIL_WINTURN) - win(usr) - else - food -= (alive+lings_aboard)*2 - fuel -= 5 - if(turns == 2 && prob(30)) - event = ORION_TRAIL_COLLISION - event() - else if(prob(75)) - event = pickweight(events) - if(lings_aboard) - if(event == ORION_TRAIL_LING || prob(55)) - event = ORION_TRAIL_LING_ATTACK - event() - turns += 1 - if(obj_flags & EMAGGED) - var/mob/living/carbon/M = usr //for some vars - switch(event) - if(ORION_TRAIL_RAIDERS) - if(prob(50)) - to_chat(usr, "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?") - M.hallucination += 30 - else - to_chat(usr, "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...") - M.take_bodypart_damage(30) - playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1) - if(ORION_TRAIL_ILLNESS) - var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS - if(severity == 1) - to_chat(M, "You suddenly feel slightly nauseated." ) - if(severity == 2) - to_chat(usr, "You suddenly feel extremely nauseated and hunch over until it passes.") - M.Stun(60) - if(severity >= 3) //you didn't pray hard enough - to_chat(M, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.") - M.Stun(100) - sleep(30) - M.vomit(10, distance = 5) - if(ORION_TRAIL_FLUX) - if(prob(75)) - M.Knockdown(60) - say("A sudden gust of powerful wind slams [M] into the floor!") - M.take_bodypart_damage(25) - playsound(loc, 'sound/weapons/genhit.ogg', 100, 1) - else - to_chat(M, "A violent gale blows past you, and you barely manage to stay standing!") - if(ORION_TRAIL_COLLISION) //by far the most damaging event - if(prob(90)) - playsound(loc, 'sound/effects/bang.ogg', 100, 1) - var/turf/open/floor/F - for(F in orange(1, src)) - F.ScrapeAway() - say("Something slams into the floor around [src], exposing it to space!") - if(hull) - sleep(10) - say("A new floor suddenly appears around [src]. What the hell?") - playsound(loc, 'sound/weapons/genhit.ogg', 100, 1) - var/turf/open/space/T - for(T in orange(1, src)) - T.PlaceOnTop(/turf/open/floor/plating) - else - say("Something slams into the floor around [src] - luckily, it didn't get through!") - playsound(loc, 'sound/effects/bang.ogg', 50, 1) - if(ORION_TRAIL_MALFUNCTION) - playsound(loc, 'sound/effects/empulse.ogg', 50, 1) - visible_message("[src] malfunctions, randomizing in-game stats!") - var/oldfood = food - var/oldfuel = fuel - food = rand(10,80) / rand(1,2) - fuel = rand(10,60) / rand(1,2) - if(electronics) - sleep(10) - if(oldfuel > fuel && oldfood > food) - audible_message("[src] lets out a somehow reassuring chime.") - else if(oldfuel < fuel || oldfood < food) - audible_message("[src] lets out a somehow ominous chime.") - food = oldfood - fuel = oldfuel - playsound(loc, 'sound/machines/chime.ogg', 50, 1) - - else if(href_list["newgame"]) //Reset everything - if(gameStatus == ORION_STATUS_START) - newgame() - else if(href_list["menu"]) //back to the main menu - if(gameStatus == ORION_STATUS_GAMEOVER) - gameStatus = ORION_STATUS_START - event = null - food = 80 - fuel = 60 - settlers = list("Harry","Larry","Bob") - else if(href_list["slow"]) //slow down - if(event == ORION_TRAIL_FLUX) - food -= (alive+lings_aboard)*2 - fuel -= 5 - event = null - else if(href_list["pastblack"]) //slow down - if(turns == 7) - food -= ((alive+lings_aboard)*2)*3 - fuel -= 15 - turns += 1 - event = null - else if(href_list["useengine"]) //use parts - if(event == ORION_TRAIL_BREAKDOWN) - engine = max(0, --engine) - event = null - else if(href_list["useelec"]) //use parts - if(event == ORION_TRAIL_MALFUNCTION) - electronics = max(0, --electronics) - event = null - else if(href_list["usehull"]) //use parts - if(event == ORION_TRAIL_COLLISION) - hull = max(0, --hull) - event = null - else if(href_list["wait"]) //wait 3 days - if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION) - food -= ((alive+lings_aboard)*2)*3 - event = null - else if(href_list["keepspeed"]) //keep speed - if(event == ORION_TRAIL_FLUX) - if(prob(75)) - event = "Breakdown" - event() - else - event = null - else if(href_list["blackhole"]) //keep speed past a black hole - if(turns == 7) - if(prob(75)) - event = ORION_TRAIL_BLACKHOLE - event() - if(obj_flags & EMAGGED) - playsound(loc, 'sound/effects/supermatter.ogg', 100, 1) - say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") - if(isliving(usr)) - var/mob/living/L = usr - L.Stun(200, ignore_canstun = TRUE) //you can't run :^) - var/S = new /obj/singularity/academy(usr.loc) - addtimer(CALLBACK(src, /atom/movable/proc/say, "[S] winks out, just as suddenly as it appeared."), 50) - QDEL_IN(S, 50) - else - event = null - turns += 1 - else if(href_list["holedeath"]) - if(event == ORION_TRAIL_BLACKHOLE) - gameStatus = ORION_STATUS_GAMEOVER - event = null - else if(href_list["eventclose"]) //end an event - if(canContinueEvent) - event = null - - else if(href_list["killcrew"]) //shoot a crewmember - if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING) - var/sheriff = remove_crewmember() //I shot the sheriff - playsound(loc,'sound/weapons/gunshot.ogg', 100, 1) - - if(settlers.len == 0 || alive == 0) - say("The last crewmember [sheriff], shot themselves, GAME OVER!") - if(obj_flags & EMAGGED) - usr.death(0) - obj_flags &= EMAGGED - gameStatus = ORION_STATUS_GAMEOVER - event = null - else if(obj_flags & EMAGGED) - if(usr.name == sheriff) - say("The crew of the ship chose to kill [usr.name]!") - usr.death(0) - - if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places - event = null - - //Spaceport specific interactions - //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) - //they also call event() again, to regen the eventdata, which is kind of odd but necessary - else if(href_list["buycrew"]) //buy a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && food >= 10 && fuel >= 10) - var/bought = add_crewmember() - last_spaceport_action = "You hired [bought] as a new crewmember." - fuel -= 10 - food -= 10 - event() - - else if(href_list["sellcrew"]) //sell a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && settlers.len > 1) - var/sold = remove_crewmember() - last_spaceport_action = "You sold your crewmember, [sold]!" - fuel += 7 - food += 7 - event() - - else if(href_list["leave_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - event = null - gameStatus = ORION_STATUS_NORMAL - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - - else if(href_list["raid_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - var/success = min(15 * alive,100) //default crew (4) have a 60% chance - spaceport_raided = 1 - - var/FU = 0 - var/FO = 0 - if(prob(success)) - FU = rand(5,15) - FO = rand(5,15) - last_spaceport_action = "You successfully raided the spaceport! You gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" - else - FU = rand(-5,-15) - FO = rand(-5,-15) - last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" - - //your chance of lose a crewmember is 1/2 your chance of success - //this makes higher % failures hurt more, don't get cocky space cowboy! - if(prob(success*5)) - var/lost_crew = remove_crewmember() - last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" - if(obj_flags & EMAGGED) - say("WEEWOO! WEEWOO! Spaceport security en route!") - playsound(src, 'sound/items/weeoo1.ogg', 100, FALSE) - for(var/i, i<=3, i++) - var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion(get_turf(src)) - O.target = usr - - - fuel += FU - food += FO - event() - - else if(href_list["buyparts"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && fuel > 5) - switch(text2num(href_list["buyparts"])) - if(1) //Engine Parts - engine++ - last_spaceport_action = "Bought Engine Parts" - if(2) //Hull Plates - hull++ - last_spaceport_action = "Bought Hull Plates" - if(3) //Spare Electronics - electronics++ - last_spaceport_action = "Bought Spare Electronics" - fuel -= 5 //they all cost 5 - event() - - else if(href_list["trade"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - switch(text2num(href_list["trade"])) - if(1) //Fuel - if(fuel > 5) - fuel -= 5 - food += 5 - last_spaceport_action = "Traded Fuel for Food" - event() - if(2) //Food - if(food > 5) - fuel += 5 - food -= 5 - last_spaceport_action = "Traded Food for Fuel" - event() - - add_fingerprint(usr) - updateUsrDialog() - busy = FALSE - return - - -/obj/machinery/computer/arcade/orion_trail/proc/event() - eventdat = "

    [event]

    " - canContinueEvent = 0 - switch(event) - if(ORION_TRAIL_RAIDERS) - eventdat += "Raiders have come aboard your ship!" - if(prob(50)) - var/sfood = rand(1,10) - var/sfuel = rand(1,10) - food -= sfood - fuel -= sfuel - eventdat += "
    They have stolen [sfood] Food and [sfuel] Fuel." - else if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
    [deadname] tried to fight back, but was killed." - else - eventdat += "
    Fortunately, you fended them off without any trouble." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - canContinueEvent = 1 - - if(ORION_TRAIL_FLUX) - eventdat += "This region of space is highly turbulent.
    If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." - eventdat += "
    What will you do?" - eventdat += "

    Slow Down Continue

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_ILLNESS) - eventdat += "A deadly illness has been contracted!" - var/deadname = remove_crewmember() - eventdat += "
    [deadname] was killed by the disease." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - canContinueEvent = 1 - - if(ORION_TRAIL_BREAKDOWN) - eventdat += "Oh no! The engine has broken down!" - eventdat += "
    You can repair it with an engine part, or you can make repairs for 3 days." - if(engine >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_MALFUNCTION) - eventdat += "The ship's systems are malfunctioning!" - eventdat += "
    You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." - if(electronics >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_COLLISION) - eventdat += "Something hit us! Looks like there's some hull damage." - if(prob(25)) - var/sfood = rand(5,15) - var/sfuel = rand(5,15) - food -= sfood - fuel -= sfuel - eventdat += "
    [sfood] Food and [sfuel] Fuel was vented out into space." - if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
    [deadname] was killed by rapid depressurization." - eventdat += "
    You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." - if(hull >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_BLACKHOLE) - eventdat += "You were swept away into the black hole." - eventdat += "

    Oh...

    " - eventdat += "

    Close

    " - settlers = list() - - if(ORION_TRAIL_LING) - eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." - if(settlers.len <= 2) - eventdat += "
    Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - if(prob(10)) // "likely", I didn't say it was guaranteed! - lings_aboard = min(++lings_aboard,2) - else - if(lings_aboard) //less likely to stack lings - if(prob(20)) - lings_aboard = min(++lings_aboard,2) - else if(prob(70)) - lings_aboard = min(++lings_aboard,2) - - eventdat += "

    Kill a Crewmember

    " - eventdat += "

    Risk it

    " - eventdat += "

    Close

    " - canContinueEvent = 1 - - if(ORION_TRAIL_LING_ATTACK) - if(lings_aboard <= 0) //shouldn't trigger, but hey. - eventdat += "Haha, fooled you, there are no changelings on board!" - eventdat += "
    (You should report this to a coder :S)" - else - var/ling1 = remove_crewmember() - var/ling2 = "" - if(lings_aboard >= 2) - ling2 = remove_crewmember() - - eventdat += "Changelings among your crew suddenly burst from hiding and attack!" - if(ling2) - eventdat += "
    [ling1] and [ling2]'s arms twist and contort into grotesque blades!" - else - eventdat += "
    [ling1]'s arm twists and contorts into a grotesque blade!" - - var/chance2attack = alive*20 - if(prob(chance2attack)) - var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance - if(prob(chancetokill)) - var/deadguy = remove_crewmember() - var/murder_text = pick("The changeling[ling2 ? "s" : ""] bring[ling2 ? "" : "s"] down [deadguy] and disembowel[ling2 ? "" : "s"] them in a spray of gore!", \ - "[ling2 ? pick(ling1, ling2) : ling1] corners [deadguy] and impales them through the stomach!", \ - "[ling2 ? pick(ling1, ling2) : ling1] decapitates [deadguy] in a single cleaving arc!") - eventdat += "
    [murder_text]" - else - eventdat += "

    You valiantly fight off the changeling[ling2 ? "s":""]!" - if(ling2) - food += 30 - lings_aboard = max(0,lings_aboard-2) - else - food += 15 - lings_aboard = max(0,--lings_aboard) - eventdat += "
    Well, it's perfectly good food...\ -
    You cut the changeling[ling2 ? "s" : ""] into meat, gaining [ling2 ? "30" : "15"] Food!" - else - eventdat += "

    [pick("Sensing unfavorable odds", "After a failed attack", "Suddenly breaking nerve")], \ - the changeling[ling2 ? "s":""] vanish[ling2 ? "" : "es"] into space through the airlocks! You're safe... for now." - if(ling2) - lings_aboard = max(0,lings_aboard-2) - else - lings_aboard = max(0,--lings_aboard) - - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - canContinueEvent = 1 - - - if(ORION_TRAIL_SPACEPORT) - gameStatus = ORION_STATUS_MARKET - if(spaceport_raided) - eventdat += "The spaceport is on high alert! You've been barred from docking by the local authorities after your failed raid." - if(last_spaceport_action) - eventdat += "
    Last Spaceport Action: [last_spaceport_action]" - eventdat += "

    Depart Spaceport

    " - eventdat += "

    Close

    " - else - eventdat += "Your jump into the sector yields a spaceport - a lucky find!" - eventdat += "
    This spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." - eventdat += "
    Trading terms: FU = Fuel, FO = Food" - if(last_spaceport_action) - eventdat += "
    Last action: [last_spaceport_action]" - eventdat += "

    Crew:

    " - eventdat += english_list(settlers) - eventdat += "
    Food: [food] | Fuel: [fuel]" - eventdat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - - - //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) - if(!spaceport_freebie && (fuel < 20 || food < 20)) - spaceport_freebie++ - var/FU = 10 - var/FO = 10 - var/freecrew = 0 - if(prob(30)) - FU = 25 - FO = 25 - - if(prob(10)) - add_crewmember() - freecrew++ - - eventdat += "
    The traders of the spaceport take pity on you, and generously give you some free supplies! (+[FU]FU, +[FO]FO)" - if(freecrew) - eventdat += "
    You also gain a new crewmember!" - - fuel += FU - food += FO - - //CREW INTERACTIONS - eventdat += "

    Crew Management:

    " - - //Buy crew - if(food >= 10 && fuel >= 10) - eventdat += "

    Hire a New Crewmember (-10FU, -10FO)

    " - else - eventdat += "

    You cannot afford a new crewmember.

    " - - //Sell crew - if(settlers.len > 1) - eventdat += "

    Sell Crew for Fuel and Food (+7FU, +7FO)

    " - else - eventdat += "

    You have no other crew to sell.

    " - - //BUY/SELL STUFF - eventdat += "

    Spare Parts:

    " - - //Engine parts - if(fuel > 5) - eventdat += "

    Buy Engine Parts (-5FU)

    " - else - eventdat += "

    You cannot afford engine parts." - - //Hull plates - if(fuel > 5) - eventdat += "

    Buy Hull Plates (-5FU)

    " - else - eventdat += "

    You cannot afford hull plates." - - //Electronics - if(fuel > 5) - eventdat += "

    Buy Spare Electronics (-5FU)

    " - else - eventdat += "

    You cannot afford spare electronics." - - //Trade - if(fuel > 5) - eventdat += "

    Trade Fuel for Food (-5FU,+5FO)

    " - else - eventdat += "

    You don't have 5FU to trade. 5) - eventdat += "

    Trade Food for Fuel (+5FU,-5FO)

    " - else - eventdat += "

    You don't have 5FO to trade.You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") - name = "The Orion Trail: Realism Edition" - desc = "Learn how our ancestors got to Orion, and try not to die in the process!" - newgame() - obj_flags |= EMAGGED - -/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion - name = "spaceport security" - desc = "Premier corporate security forces for all spaceports found along the Orion Trail." - faction = list("orion") - loot = list() - del_on_death = TRUE - -/obj/item/orion_ship - name = "model settler ship" - desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - w_class = WEIGHT_CLASS_SMALL - var/active = 0 //if the ship is on - -/obj/item/orion_ship/examine(mob/user) - ..() - if(!(in_range(user, src))) - return - if(!active) - to_chat(user, "There's a little switch on the bottom. It's flipped down.") - else - to_chat(user, "There's a little switch on the bottom. It's flipped up.") - -/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse - if(active) - return - - message_admins("[ADMIN_LOOKUPFLW(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") - log_game("[key_name(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") - - to_chat(user, "You flip the switch on the underside of [src].") - active = 1 - visible_message("[src] softly beeps and whirs to life!") - playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) - say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") - sleep(20) - visible_message("[src] begins to vibrate...") - say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") - sleep(30) - say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1) - sleep(3.6) - visible_message("[src] explodes!") - explosion(loc, 2,4,8, flame_range = 16) - qdel(src) - - -#undef ORION_TRAIL_WINTURN -#undef ORION_TRAIL_RAIDERS -#undef ORION_TRAIL_FLUX -#undef ORION_TRAIL_ILLNESS -#undef ORION_TRAIL_BREAKDOWN -#undef ORION_TRAIL_LING -#undef ORION_TRAIL_LING_ATTACK -#undef ORION_TRAIL_MALFUNCTION -#undef ORION_TRAIL_COLLISION -#undef ORION_TRAIL_SPACEPORT -#undef ORION_TRAIL_BLACKHOLE - -#undef ORION_STATUS_START -#undef ORION_STATUS_NORMAL -#undef ORION_STATUS_GAMEOVER -#undef ORION_STATUS_MARKET diff --git a/code/game/machinery/computer/arcade/battle.dm b/code/game/machinery/computer/arcade/battle.dm new file mode 100644 index 0000000000..ded9cf95f6 --- /dev/null +++ b/code/game/machinery/computer/arcade/battle.dm @@ -0,0 +1,206 @@ +// ** BATTLE ** // + + +/obj/machinery/computer/arcade/battle + name = "arcade machine" + desc = "Does not support Pinball." + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/battle + var/enemy_name = "Space Villain" + var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc + var/player_hp = 30 //Player health/attack points + var/player_mp = 10 + var/enemy_hp = 45 //Enemy health/attack points + var/enemy_mp = 20 + var/gameover = FALSE + 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 + var/name_part2 + + name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") + + name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") + name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") + + enemy_name = replacetext((name_part1 + name_part2), "the ", "") + name = (name_action + name_part1 + name_part2) + +/obj/machinery/computer/arcade/battle/ui_interact(mob/user) + . = ..() + var/dat = "Close" + dat += "

    [enemy_name]

    " + + dat += "

    [temp]

    " + dat += "
    Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
    " + + if (gameover) + dat += "
    New Game" + else + dat += "
    Attack | " + dat += "Heal | " + dat += "Recharge Power" + + dat += "
    " + var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + +/obj/machinery/computer/arcade/battle/Topic(href, href_list) + if(..()) + return + + if (!blocked && !gameover) + if (href_list["attack"]) + blocked = TRUE + var/attackamt = rand(2,6) + temp = "You attack for [attackamt] damage!" + playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) + updateUsrDialog() + if(turtle > 0) + turtle-- + + sleep(turn_speed) + enemy_hp -= attackamt + arcade_action(usr) + + else if (href_list["heal"]) + blocked = TRUE + var/pointamt = rand(1,3) + var/healamt = rand(6,8) + temp = "You use [pointamt] magic to heal for [healamt] damage!" + playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) + updateUsrDialog() + turtle++ + + sleep(turn_speed) + player_mp -= pointamt + player_hp += healamt + blocked = TRUE + updateUsrDialog() + arcade_action(usr) + + else if (href_list["charge"]) + blocked = TRUE + var/chargeamt = rand(4,7) + temp = "You regain [chargeamt] points" + playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10) + player_mp += chargeamt + if(turtle > 0) + turtle-- + + updateUsrDialog() + sleep(turn_speed) + arcade_action(usr) + + if (href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=arcade") + + else if (href_list["newgame"]) //Reset everything + temp = "New Round" + player_hp = initial(player_hp) + player_mp = initial(player_mp) + enemy_hp = initial(enemy_hp) + enemy_mp = initial(enemy_mp) + gameover = FALSE + turtle = 0 + + if(obj_flags & EMAGGED) + Reset() + obj_flags &= ~EMAGGED + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user) + if ((enemy_mp <= 0) || (enemy_hp <= 0)) + if(!gameover) + gameover = TRUE + temp = "[enemy_name] has fallen! Rejoice!" + playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10) + + if(obj_flags & EMAGGED) + new /obj/effect/spawner/newbomb/timer/syndicate(loc) + new /obj/item/clothing/head/collectable/petehat(loc) + message_admins("[ADMIN_LOOKUPFLW(usr)] has outbombed Cuban Pete and been awarded a bomb.") + log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") + Reset() + obj_flags &= ~EMAGGED + else + prizevend(user) + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) + + + else if ((obj_flags & EMAGGED) && (turtle >= 4)) + var/boomamt = rand(5,10) + temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" + playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10) + player_hp -= boomamt + + else if ((enemy_mp <= 5) && (prob(70))) + var/stealamt = rand(2,3) + temp = "[enemy_name] steals [stealamt] of your power!" + playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10) + player_mp -= stealamt + updateUsrDialog() + + if (player_mp <= 0) + gameover = TRUE + 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) + usr.gib() + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal"))) + + else if ((enemy_hp <= 10) && (enemy_mp > 4)) + temp = "[enemy_name] heals for 4 health!" + playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) + enemy_hp += 4 + enemy_mp -= 4 + + else + var/attackamt = rand(3,6) + temp = "[enemy_name] attacks for [attackamt] damage!" + playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) + player_hp -= attackamt + + if ((player_mp <= 0) || (player_hp <= 0)) + gameover = TRUE + temp = "You have been crushed! GAME OVER" + playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) + if(obj_flags & EMAGGED) + usr.gib() + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) + + blocked = FALSE + return + + +/obj/machinery/computer/arcade/battle/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + to_chat(user, "A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!") + temp = "If you die in the game, you die for real!" + player_hp = 30 + player_mp = 10 + enemy_hp = 45 + enemy_mp = 20 + gameover = FALSE + blocked = FALSE + + obj_flags |= EMAGGED + + enemy_name = "Cuban Pete" + name = "Outbomb Cuban Pete" + + + updateUsrDialog() diff --git a/code/game/machinery/computer/arcade/minesweeper.dm b/code/game/machinery/computer/arcade/minesweeper.dm new file mode 100644 index 0000000000..fe69860f76 --- /dev/null +++ b/code/game/machinery/computer/arcade/minesweeper.dm @@ -0,0 +1,390 @@ +#define MINESWEEPER_GAME_MAIN_MENU 0 +#define MINESWEEPER_GAME_PLAYING 1 +#define MINESWEEPER_GAME_LOST 2 +#define MINESWEEPER_GAME_WON 3 +#define MINESWEEPERIMG(what) {""} //Basically bypassing asset.icon_tag() + +/obj/machinery/computer/arcade/minesweeper + name = "Minesweeper" + desc = "An arcade machine that generates grids. It seems that the machine sparks and screeches when a grid is generated, as if it cannot cope with the intensity of generating the grid." + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/minesweeper + var/area + var/difficulty = "" //To show what difficulty you are playing + var/flag_text = "" + var/flagging = FALSE + var/game_status = MINESWEEPER_GAME_MAIN_MENU + var/mine_limit = 0 + var/mine_placed = 0 + var/mine_sound = TRUE //So it doesn't get repeated when multiple mines are exposed + var/randomcolour = 1 + var/randomnumber = 1 //Random emagged game iteration number to be displayed, put here so it is persistent across one individual arcade machine + var/safe_squares_revealed + var/saved_web = "" //To display the web if you click on the arcade + var/win_condition + var/rows = 1 + var/columns = 1 + var/table[31][51] //Make the board boys, 30x50 board + var/spark_spam = FALSE + +/obj/machinery/computer/arcade/minesweeper/interact(mob/user) + var/emagged = CHECK_BITFIELD(obj_flags, EMAGGED) + var/dat + if(game_status == MINESWEEPER_GAME_MAIN_MENU) + dat += "Minesweeper
    Minesweeper[emagged ? " EXTREME EDITION: Iteration #[randomnumber]" : ""]
    " //Different colour mix for every random number made + dat += " [emagged ? "Explode in the game, explode in real life" : "Reveal all the squares without hitting a mine"]!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" + else + dat = saved_web + user = usr + + var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) + assets.send(user) + + user << browse(dat,"window=minesweeper,size=400x500") + add_fingerprint(user) + + . = ..() + +/obj/machinery/computer/arcade/minesweeper/proc/reset_spark_spam() + spark_spam = FALSE + +/obj/machinery/computer/arcade/minesweeper/Topic(href, href_list) + . = ..() + if(.) + return + + var/exploding_hell = FALSE //For emagged failures + var/reset_board = FALSE + var/mob/living/user = usr //To identify who the hell is using this window, this should also make things like aliens and monkeys able to use the machine!! + var/web_difficulty_menu = " Reveal all the squares without hitting a mine!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" + var/web = "Minesweeper
    Minesweeper
    " + var/static_web = "Minesweeper
    Minesweeper
    " //When we need to revert to the main menu we set web as this + web = static_web + + if(CHECK_BITFIELD(obj_flags, EMAGGED)) + web = "Minesweeper
    Minesweeper EXTREME EDITION: Iteration #[randomnumber]
    " //Different colour mix for every random number made + if(!spark_spam) + do_sparks(5, 1, src) + spark_spam = TRUE + addtimer(CALLBACK(src, .proc/reset_spark_spam), 30) + + + var/startup_sound = CHECK_BITFIELD(obj_flags, EMAGGED) ? 'sound/arcade/minesweeper_emag2.ogg' : 'sound/arcade/minesweeper_startup.ogg' + + if(href_list["Main_Menu"]) + game_status = MINESWEEPER_GAME_MAIN_MENU + mine_limit = 0 + rows = 0 + columns = 0 + mine_placed = 0 + if(href_list["Easy"]) + playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) + flag_text = "OFF" + game_status = MINESWEEPER_GAME_PLAYING + reset_board = TRUE + difficulty = "Easy" + rows = 10 //9x9 board + columns = 10 + mine_limit = 10 + if(href_list["Intermediate"]) + playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) + flag_text = "OFF" + game_status = MINESWEEPER_GAME_PLAYING + reset_board = TRUE + difficulty = "Intermediate" + rows = 17 //16x16 board + columns = 17 + mine_limit = 40 + if(href_list["Hard"]) + playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) + flag_text = "OFF" + game_status = MINESWEEPER_GAME_PLAYING + reset_board = TRUE + difficulty = "Hard" + rows = 17 //16x30 board + columns = 31 + mine_limit = 99 + if(href_list["Custom"]) + if(custom_generation(usr)) + flag_text = "OFF" + game_status = MINESWEEPER_GAME_PLAYING + reset_board = TRUE + difficulty = "Custom" + playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) + if(href_list["Flag"]) + playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) + if(!flagging) + flagging = TRUE + flag_text = "ON" + else + flagging = FALSE + flag_text = "OFF" + + if(game_status == MINESWEEPER_GAME_MAIN_MENU) + if(CHECK_BITFIELD(obj_flags, EMAGGED)) + playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10) + web += "Explode in the game, explode in real life!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" + else + playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10) + web += web_difficulty_menu + + if(game_status == MINESWEEPER_GAME_PLAYING) + mine_sound = TRUE + + area = (rows-1)*(columns-1) + + if(reset_board) + mine_placed = 0 + var/reset_everything = TRUE + make_mines(reset_everything) + + safe_squares_revealed = 0 + win_condition = area-mine_placed + + if(game_status != MINESWEEPER_GAME_MAIN_MENU) + for(var/y1=1;y1= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode + table[y1][x1] += 10 + if(table[y1][x1] != 10) + playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) + else + if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON) + game_status = MINESWEEPER_GAME_LOST + if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell) + exploding_hell = TRUE + explode_EVERYTHING() + if(mine_sound) + switch(rand(1,3)) //Play every time a mine is hit + if(1) + playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, 0, extrarange = -3, falloff = 10) + if(2) + playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, 0, extrarange = -3, falloff = 10) + if(3) + playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, 0, extrarange = -3, falloff = 10) + mine_sound = FALSE + else + playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) + if(table[y1][x1] >= 0) //Check that it's not already flagged + table[y1][x1] -= 10 + else if(table[y1][x1] < 0) //If flagged, remove the flag + table[y1][x1] += 10 + if(href_list["same_board"]) //Reset the board... kinda + if(game_status != MINESWEEPER_GAME_PLAYING) + game_status = MINESWEEPER_GAME_PLAYING + if(table[y1][x1] >= 10) //If revealed, become unrevealed! + playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) + table[y1][x1] -= 10 + if(table[y1][x1] > 10 && !reset_board) + safe_squares_revealed += 1 + var/y2 = y1 + var/x2 = x1 + work_squares(y2, x2) //Work squares while in this loop so there's less load + reset_board = FALSE + + web += "" //Start setting up the html table + web += "" + for(var/y1=1;y1= win_condition && game_status == MINESWEEPER_GAME_PLAYING) + game_status = MINESWEEPER_GAME_WON + if(rows < 10 || columns < 10) //If less than easy difficulty + playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, 0, extrarange = -3, falloff = 10) + say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!") + else + playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, 0, extrarange = -3, falloff = 10) + say("You cleared the board of all mines! Congratulations!") + if(CHECK_BITFIELD(obj_flags, EMAGGED)) + var/itemname + switch(rand(1,3)) + if(1) + itemname = "a syndicate bomb beacon" + new /obj/item/sbeacondrop/bomb(loc) + if(2) + itemname = "a grenade launcher" + new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(loc) + new /obj/item/ammo_casing/a40mm(loc) + new /obj/item/ammo_casing/a40mm(loc) + new /obj/item/ammo_casing/a40mm(loc) + if(3) + itemname = "two bags of c4" + new /obj/item/storage/backpack/duffelbag/syndie/c4(loc) + new /obj/item/storage/backpack/duffelbag/syndie/x4(loc) + message_admins("[key_name_admin(user)] won emagged Minesweeper and got [itemname]!") + visible_message("[src] dispenses [itemname]!", "You hear a chime and a clunk.") + DISABLE_BITFIELD(obj_flags, EMAGGED) + else + var/dope_prizes = (area >= 480) ? list(ARCADE_WEIGHT_RARE) : (area >= 256) ? list(ARCADE_WEIGHT_RARE, ARCADE_WEIGHT_TRICK) : null + prizevend(user, dope_prizes) + + if(game_status == MINESWEEPER_GAME_WON) + web += "[(rows < 10 || columns < 10) ? "You won, but your board was too small! Pick a bigger board next time!" : "Congratulations, you have won!"]
    Want to play again?
    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom

    Play on the same board
    Return to Main Menu
    " + + if(game_status == MINESWEEPER_GAME_LOST) + web += "You have lost!
    Try again?
    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom

    Play on the same board
    Return to Main Menu
    " + + if(game_status == MINESWEEPER_GAME_PLAYING) + web += "Return to Main Menu
    " + web += "
    Difficulty: [difficulty]
    Mines: [mine_placed]
    Rows: [rows-1]
    Columns: [columns-1]
    Flagging mode: [flag_text]
    " + + web += "" + var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) + saved_web = sheet.css_tag() + saved_web += web + updateDialog() + return + +/obj/machinery/computer/arcade/minesweeper/emag_act(mob/user) + if(CHECK_BITFIELD(obj_flags, EMAGGED)) + return + desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!" + do_sparks(5, 1, src) + randomnumber = rand(1,255) + randomcolour = rgb(randomnumber,randomnumber/2,randomnumber/3) + ENABLE_BITFIELD(obj_flags, EMAGGED) + if(game_status == MINESWEEPER_GAME_MAIN_MENU) + to_chat(user, "An ominous tune plays from the arcade's speakers!") + playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10) + else //Can't let you do that, star fox! + to_chat(user, "The machine buzzes and sparks... the game has been reset!") + playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz + game_status = MINESWEEPER_GAME_MAIN_MENU + +/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user) + playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound + var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num + if(!new_rows || !user.canUseTopic(src, !issilicon(user))) + return FALSE + new_rows = CLAMP(new_rows + 1, 4, 30) + playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) + var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num + if(!new_columns || !user.canUseTopic(src, !issilicon(user))) + return FALSE + new_columns = CLAMP(new_columns + 1, 4, 50) + playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) + var/grid_area = (new_rows - 1) * (new_columns - 1) + var/lower_limit = round(grid_area*0.156) + var/upper_limit = round(grid_area*0.85) + var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num + if(!new_mine_limit || !user.canUseTopic(src, !issilicon(user))) + return FALSE + playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) + rows = new_rows + columns = new_columns + mine_limit = CLAMP(new_mine_limit, lower_limit, upper_limit) + return TRUE + +/obj/machinery/computer/arcade/minesweeper/proc/make_mines(var/reset_everything) + if(mine_placed < mine_limit) + for(var/y1=1;y1 0 && x3 > 0) + y2 = y3 + x2 = x3 + if(table[y2][x2] == 1) + for(y3=y2-1;y3= rows || y3 < 1) + continue + for(x3=x2-1;x3= columns || x3 < 1) + continue + if(table[y3][x3] == 0) + table[y2][x2] += 1 + if(table[y2][x2] == 11) + for(y3=y2-1;y3= rows || y3 < 1) + continue + for(x3=x2-1;x3= columns || x3 < 1) + continue + if(table[y3][x3] > 0 && table[y3][x3] < 10) + table[y3][x3] += 10 + work_squares(y3, x3) //Refresh so we check everything we might be missing + +/obj/machinery/computer/arcade/minesweeper/proc/explode_EVERYTHING() + var/mob/living/user = usr + to_chat(user, "You feel a great sense of dread wash over you, as if you just unleashed armageddon upon yourself!") + var/row_limit = rows-1 + var/column_limit = columns-1 + var/mine_limit_v2 = mine_limit + if(rows > 11) + row_limit = 10 + if(columns > 11) + column_limit = 10 + if(mine_limit > (rows*columns) * 0.25) + mine_limit_v2 = 24 + message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!") + if(mine_limit_v2 < 10) + explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh?? + else + explosion(loc, 1, 3, rand(1,5), rand(1,10)) + for(var/y69=y-row_limit;y69coward!\"" + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/amputation + +/obj/machinery/computer/arcade/amputation/attack_hand(mob/user) + if(!iscarbon(user)) + return + var/mob/living/carbon/c_user = user + if(!c_user.get_bodypart(BODY_ZONE_L_ARM) && !c_user.get_bodypart(BODY_ZONE_R_ARM)) + return + to_chat(c_user, "You move your hand towards the machine, and begin to hesitate as a bloodied guillotine emerges from inside of it...") + if(do_after(c_user, 50, target = src)) + to_chat(c_user, "The guillotine drops on your arm, and the machine sucks it in!") + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) + var/which_hand = BODY_ZONE_L_ARM + if(!(c_user.active_hand_index % 2)) + which_hand = BODY_ZONE_R_ARM + var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand) + chopchop.dismember() + qdel(chopchop) + playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10) + for(var/i=1; i<=rand(3,5); i++) + prizevend(user) + else + to_chat(c_user, "You (wisely) decide against putting your hand in the machine.") \ No newline at end of file diff --git a/code/game/machinery/computer/arcade/orion_trail.dm b/code/game/machinery/computer/arcade/orion_trail.dm new file mode 100644 index 0000000000..12941dea35 --- /dev/null +++ b/code/game/machinery/computer/arcade/orion_trail.dm @@ -0,0 +1,809 @@ + + +// *** THE ORION TRAIL ** // + +#define ORION_TRAIL_WINTURN 9 + +//Orion Trail Events +#define ORION_TRAIL_RAIDERS "Raiders" +#define ORION_TRAIL_FLUX "Interstellar Flux" +#define ORION_TRAIL_ILLNESS "Illness" +#define ORION_TRAIL_BREAKDOWN "Breakdown" +#define ORION_TRAIL_LING "Changelings?" +#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" +#define ORION_TRAIL_MALFUNCTION "Malfunction" +#define ORION_TRAIL_COLLISION "Collision" +#define ORION_TRAIL_SPACEPORT "Spaceport" +#define ORION_TRAIL_BLACKHOLE "BlackHole" + +#define ORION_STATUS_START 1 +#define ORION_STATUS_NORMAL 2 +#define ORION_STATUS_GAMEOVER 3 +#define ORION_STATUS_MARKET 4 + +/obj/machinery/computer/arcade/orion_trail + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/orion_trail + var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game. + var/engine = 0 + var/hull = 0 + var/electronics = 0 + var/food = 80 + var/fuel = 60 + var/turns = 4 + var/alive = 4 + var/eventdat = null + var/event = null + var/list/settlers = list("Harry","Larry","Bob") + var/list/events = list(ORION_TRAIL_RAIDERS = 3, + ORION_TRAIL_FLUX = 1, + ORION_TRAIL_ILLNESS = 3, + ORION_TRAIL_BREAKDOWN = 2, + ORION_TRAIL_LING = 3, + ORION_TRAIL_MALFUNCTION = 2, + ORION_TRAIL_COLLISION = 1, + ORION_TRAIL_SPACEPORT = 2 + ) + var/list/stops = list() + var/list/stopblurbs = list() + var/lings_aboard = 0 + var/spaceport_raided = 0 + var/spaceport_freebie = 0 + var/last_spaceport_action = "" + var/gameStatus = ORION_STATUS_START + var/canContinueEvent = 0 + +/obj/machinery/computer/arcade/orion_trail/kobayashi + name = "Kobayashi Maru control computer" + desc = "A test for cadets" + icon = 'icons/obj/machines/particle_accelerator.dmi' + icon_state = "control_boxp" + events = list("Raiders" = 3, "Interstellar Flux" = 1, "Illness" = 3, "Breakdown" = 2, "Malfunction" = 2, "Collision" = 1, "Spaceport" = 2) + prizes = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1) + settlers = list("Kirk","Worf","Gene") + +/obj/machinery/computer/arcade/orion_trail/Reset() + // Sets up the main trail + stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") + stopblurbs = list( + "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", + "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", + "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", + "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", + "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", + "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", + "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", + "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", + "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" + ) + +/obj/machinery/computer/arcade/orion_trail/proc/newgame() + // Set names of settlers in crew + settlers = list() + for(var/i = 1; i <= 3; i++) + add_crewmember() + add_crewmember("[usr]") + // Re-set items to defaults + engine = 1 + hull = 1 + electronics = 1 + food = 80 + fuel = 60 + alive = 4 + turns = 1 + event = null + gameStatus = ORION_STATUS_NORMAL + lings_aboard = 0 + + //spaceport junk + spaceport_raided = 0 + spaceport_freebie = 0 + last_spaceport_action = "" + +/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user) + . = ..() + if(fuel <= 0 || food <=0 || settlers.len == 0) + gameStatus = ORION_STATUS_GAMEOVER + event = null + var/dat = "" + if(gameStatus == ORION_STATUS_GAMEOVER) + dat = "

    Game Over

    " + dat += "Like many before you, your crew never made it to Orion, lost to space...
    Forever." + if(!settlers.len) + dat += "
    Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy." + else + if(food <= 0) + dat += "
    You ran out of food and starved." + if(obj_flags & EMAGGED) + user.nutrition = 0 //yeah you pretty hongry + to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") + if(fuel <= 0) + dat += "
    You ran out of fuel, and drift, slowly, into a star." + if(obj_flags & EMAGGED) + var/mob/living/M = user + M.adjust_fire_stacks(5) + M.IgniteMob() //flew into a star, so you're on fire + to_chat(user, "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.") + + if(obj_flags & EMAGGED) + to_chat(user, "You're never going to make it to Orion...") + user.death() + obj_flags &= ~EMAGGED //removes the emagged status after you lose + gameStatus = ORION_STATUS_START + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + + dat += "

    May They Rest In Peace

    " + else if(event) + dat = eventdat + else if(gameStatus == ORION_STATUS_NORMAL) + var/title = stops[turns] + var/subtext = stopblurbs[turns] + dat = "

    [title]

    " + dat += "[subtext]" + dat += "

    Crew:

    " + dat += english_list(settlers) + dat += "
    Food: [food] | Fuel: [fuel]" + dat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" + if(turns == 7) + dat += "

    Go Around Continue

    " + else + dat += "

    Continue

    " + dat += "

    Kill a Crewmember

    " + dat += "

    Close

    " + else + dat = "

    The Orion Trail

    " + dat += "

    Experience the journey of your ancestors!



    " + dat += "
    New Game
    " + dat += "

    Close

    " + var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + return + +/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) + if(..()) + return + if(href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=arcade") + + if(busy) + return + busy = TRUE + + if (href_list["continue"]) //Continue your travels + if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) + if(turns >= ORION_TRAIL_WINTURN) + win(usr) + else + food -= (alive+lings_aboard)*2 + fuel -= 5 + if(turns == 2 && prob(30)) + event = ORION_TRAIL_COLLISION + event() + else if(prob(75)) + event = pickweight(events) + if(lings_aboard) + if(event == ORION_TRAIL_LING || prob(55)) + event = ORION_TRAIL_LING_ATTACK + event() + turns += 1 + if(obj_flags & EMAGGED) + var/mob/living/carbon/M = usr //for some vars + switch(event) + if(ORION_TRAIL_RAIDERS) + if(prob(50)) + to_chat(usr, "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?") + M.hallucination += 30 + else + to_chat(usr, "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...") + M.take_bodypart_damage(30) + playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1) + if(ORION_TRAIL_ILLNESS) + var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS + if(severity == 1) + to_chat(M, "You suddenly feel slightly nauseated." ) + if(severity == 2) + to_chat(usr, "You suddenly feel extremely nauseated and hunch over until it passes.") + M.Stun(60) + if(severity >= 3) //you didn't pray hard enough + to_chat(M, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.") + M.Stun(100) + sleep(30) + M.vomit(10, distance = 5) + if(ORION_TRAIL_FLUX) + if(prob(75)) + M.Knockdown(60) + say("A sudden gust of powerful wind slams [M] into the floor!") + M.take_bodypart_damage(25) + playsound(loc, 'sound/weapons/genhit.ogg', 100, 1) + else + to_chat(M, "A violent gale blows past you, and you barely manage to stay standing!") + if(ORION_TRAIL_COLLISION) //by far the most damaging event + if(prob(90)) + playsound(loc, 'sound/effects/bang.ogg', 100, 1) + var/turf/open/floor/F + for(F in orange(1, src)) + F.ScrapeAway() + say("Something slams into the floor around [src], exposing it to space!") + if(hull) + sleep(10) + say("A new floor suddenly appears around [src]. What the hell?") + playsound(loc, 'sound/weapons/genhit.ogg', 100, 1) + var/turf/open/space/T + for(T in orange(1, src)) + T.PlaceOnTop(/turf/open/floor/plating) + else + say("Something slams into the floor around [src] - luckily, it didn't get through!") + playsound(loc, 'sound/effects/bang.ogg', 50, 1) + if(ORION_TRAIL_MALFUNCTION) + playsound(loc, 'sound/effects/empulse.ogg', 50, 1) + visible_message("[src] malfunctions, randomizing in-game stats!") + var/oldfood = food + var/oldfuel = fuel + food = rand(10,80) / rand(1,2) + fuel = rand(10,60) / rand(1,2) + if(electronics) + sleep(10) + if(oldfuel > fuel && oldfood > food) + audible_message("[src] lets out a somehow reassuring chime.") + else if(oldfuel < fuel || oldfood < food) + audible_message("[src] lets out a somehow ominous chime.") + food = oldfood + fuel = oldfuel + playsound(loc, 'sound/machines/chime.ogg', 50, 1) + + else if(href_list["newgame"]) //Reset everything + if(gameStatus == ORION_STATUS_START) + newgame() + else if(href_list["menu"]) //back to the main menu + if(gameStatus == ORION_STATUS_GAMEOVER) + gameStatus = ORION_STATUS_START + event = null + food = 80 + fuel = 60 + settlers = list("Harry","Larry","Bob") + else if(href_list["slow"]) //slow down + if(event == ORION_TRAIL_FLUX) + food -= (alive+lings_aboard)*2 + fuel -= 5 + event = null + else if(href_list["pastblack"]) //slow down + if(turns == 7) + food -= ((alive+lings_aboard)*2)*3 + fuel -= 15 + turns += 1 + event = null + else if(href_list["useengine"]) //use parts + if(event == ORION_TRAIL_BREAKDOWN) + engine = max(0, --engine) + event = null + else if(href_list["useelec"]) //use parts + if(event == ORION_TRAIL_MALFUNCTION) + electronics = max(0, --electronics) + event = null + else if(href_list["usehull"]) //use parts + if(event == ORION_TRAIL_COLLISION) + hull = max(0, --hull) + event = null + else if(href_list["wait"]) //wait 3 days + if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION) + food -= ((alive+lings_aboard)*2)*3 + event = null + else if(href_list["keepspeed"]) //keep speed + if(event == ORION_TRAIL_FLUX) + if(prob(75)) + event = "Breakdown" + event() + else + event = null + else if(href_list["blackhole"]) //keep speed past a black hole + if(turns == 7) + if(prob(75)) + event = ORION_TRAIL_BLACKHOLE + event() + if(obj_flags & EMAGGED) + playsound(loc, 'sound/effects/supermatter.ogg', 100, 1) + say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") + if(isliving(usr)) + var/mob/living/L = usr + L.Stun(200, ignore_canstun = TRUE) //you can't run :^) + var/S = new /obj/singularity/academy(usr.loc) + addtimer(CALLBACK(src, /atom/movable/proc/say, "[S] winks out, just as suddenly as it appeared."), 50) + QDEL_IN(S, 50) + else + event = null + turns += 1 + else if(href_list["holedeath"]) + if(event == ORION_TRAIL_BLACKHOLE) + gameStatus = ORION_STATUS_GAMEOVER + event = null + else if(href_list["eventclose"]) //end an event + if(canContinueEvent) + event = null + + else if(href_list["killcrew"]) //shoot a crewmember + if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING) + var/sheriff = remove_crewmember() //I shot the sheriff + playsound(loc,'sound/weapons/gunshot.ogg', 100, 1) + + if(settlers.len == 0 || alive == 0) + say("The last crewmember [sheriff], shot themselves, GAME OVER!") + if(obj_flags & EMAGGED) + usr.death(0) + obj_flags &= EMAGGED + gameStatus = ORION_STATUS_GAMEOVER + event = null + else if(obj_flags & EMAGGED) + if(usr.name == sheriff) + say("The crew of the ship chose to kill [usr.name]!") + usr.death(0) + + if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places + event = null + + //Spaceport specific interactions + //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) + //they also call event() again, to regen the eventdata, which is kind of odd but necessary + else if(href_list["buycrew"]) //buy a crewmember + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && food >= 10 && fuel >= 10) + var/bought = add_crewmember() + last_spaceport_action = "You hired [bought] as a new crewmember." + fuel -= 10 + food -= 10 + event() + + else if(href_list["sellcrew"]) //sell a crewmember + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && settlers.len > 1) + var/sold = remove_crewmember() + last_spaceport_action = "You sold your crewmember, [sold]!" + fuel += 7 + food += 7 + event() + + else if(href_list["leave_spaceport"]) + if(gameStatus == ORION_STATUS_MARKET) + event = null + gameStatus = ORION_STATUS_NORMAL + spaceport_raided = 0 + spaceport_freebie = 0 + last_spaceport_action = "" + + else if(href_list["raid_spaceport"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided) + var/success = min(15 * alive,100) //default crew (4) have a 60% chance + spaceport_raided = 1 + + var/FU = 0 + var/FO = 0 + if(prob(success)) + FU = rand(5,15) + FO = rand(5,15) + last_spaceport_action = "You successfully raided the spaceport! You gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" + else + FU = rand(-5,-15) + FO = rand(-5,-15) + last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" + + //your chance of lose a crewmember is 1/2 your chance of success + //this makes higher % failures hurt more, don't get cocky space cowboy! + if(prob(success*5)) + var/lost_crew = remove_crewmember() + last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" + if(obj_flags & EMAGGED) + say("WEEWOO! WEEWOO! Spaceport security en route!") + playsound(src, 'sound/items/weeoo1.ogg', 100, FALSE) + for(var/i, i<=3, i++) + var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion(get_turf(src)) + O.target = usr + + + fuel += FU + food += FO + event() + + else if(href_list["buyparts"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && fuel > 5) + switch(text2num(href_list["buyparts"])) + if(1) //Engine Parts + engine++ + last_spaceport_action = "Bought Engine Parts" + if(2) //Hull Plates + hull++ + last_spaceport_action = "Bought Hull Plates" + if(3) //Spare Electronics + electronics++ + last_spaceport_action = "Bought Spare Electronics" + fuel -= 5 //they all cost 5 + event() + + else if(href_list["trade"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided) + switch(text2num(href_list["trade"])) + if(1) //Fuel + if(fuel > 5) + fuel -= 5 + food += 5 + last_spaceport_action = "Traded Fuel for Food" + event() + if(2) //Food + if(food > 5) + fuel += 5 + food -= 5 + last_spaceport_action = "Traded Food for Fuel" + event() + + add_fingerprint(usr) + updateUsrDialog() + busy = FALSE + return + + +/obj/machinery/computer/arcade/orion_trail/proc/event() + eventdat = "

    [event]

    " + canContinueEvent = 0 + switch(event) + if(ORION_TRAIL_RAIDERS) + eventdat += "Raiders have come aboard your ship!" + if(prob(50)) + var/sfood = rand(1,10) + var/sfuel = rand(1,10) + food -= sfood + fuel -= sfuel + eventdat += "
    They have stolen [sfood] Food and [sfuel] Fuel." + else if(prob(10)) + var/deadname = remove_crewmember() + eventdat += "
    [deadname] tried to fight back, but was killed." + else + eventdat += "
    Fortunately, you fended them off without any trouble." + eventdat += "

    Continue

    " + eventdat += "

    Close

    " + canContinueEvent = 1 + + if(ORION_TRAIL_FLUX) + eventdat += "This region of space is highly turbulent.
    If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." + eventdat += "
    What will you do?" + eventdat += "

    Slow Down Continue

    " + eventdat += "

    Close

    " + + if(ORION_TRAIL_ILLNESS) + eventdat += "A deadly illness has been contracted!" + var/deadname = remove_crewmember() + eventdat += "
    [deadname] was killed by the disease." + eventdat += "

    Continue

    " + eventdat += "

    Close

    " + canContinueEvent = 1 + + if(ORION_TRAIL_BREAKDOWN) + eventdat += "Oh no! The engine has broken down!" + eventdat += "
    You can repair it with an engine part, or you can make repairs for 3 days." + if(engine >= 1) + eventdat += "

    Use PartWait

    " + else + eventdat += "

    Wait

    " + eventdat += "

    Close

    " + + if(ORION_TRAIL_MALFUNCTION) + eventdat += "The ship's systems are malfunctioning!" + eventdat += "
    You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." + if(electronics >= 1) + eventdat += "

    Use PartWait

    " + else + eventdat += "

    Wait

    " + eventdat += "

    Close

    " + + if(ORION_TRAIL_COLLISION) + eventdat += "Something hit us! Looks like there's some hull damage." + if(prob(25)) + var/sfood = rand(5,15) + var/sfuel = rand(5,15) + food -= sfood + fuel -= sfuel + eventdat += "
    [sfood] Food and [sfuel] Fuel was vented out into space." + if(prob(10)) + var/deadname = remove_crewmember() + eventdat += "
    [deadname] was killed by rapid depressurization." + eventdat += "
    You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." + if(hull >= 1) + eventdat += "

    Use PartWait

    " + else + eventdat += "

    Wait

    " + eventdat += "

    Close

    " + + if(ORION_TRAIL_BLACKHOLE) + eventdat += "You were swept away into the black hole." + eventdat += "

    Oh...

    " + eventdat += "

    Close

    " + settlers = list() + + if(ORION_TRAIL_LING) + eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." + if(settlers.len <= 2) + eventdat += "
    Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." + eventdat += "

    Continue

    " + eventdat += "

    Close

    " + if(prob(10)) // "likely", I didn't say it was guaranteed! + lings_aboard = min(++lings_aboard,2) + else + if(lings_aboard) //less likely to stack lings + if(prob(20)) + lings_aboard = min(++lings_aboard,2) + else if(prob(70)) + lings_aboard = min(++lings_aboard,2) + + eventdat += "

    Kill a Crewmember

    " + eventdat += "

    Risk it

    " + eventdat += "

    Close

    " + canContinueEvent = 1 + + if(ORION_TRAIL_LING_ATTACK) + if(lings_aboard <= 0) //shouldn't trigger, but hey. + eventdat += "Haha, fooled you, there are no changelings on board!" + eventdat += "
    (You should report this to a coder :S)" + else + var/ling1 = remove_crewmember() + var/ling2 = "" + if(lings_aboard >= 2) + ling2 = remove_crewmember() + + eventdat += "Changelings among your crew suddenly burst from hiding and attack!" + if(ling2) + eventdat += "
    [ling1] and [ling2]'s arms twist and contort into grotesque blades!" + else + eventdat += "
    [ling1]'s arm twists and contorts into a grotesque blade!" + + var/chance2attack = alive*20 + if(prob(chance2attack)) + var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance + if(prob(chancetokill)) + var/deadguy = remove_crewmember() + var/murder_text = pick("The changeling[ling2 ? "s" : ""] bring[ling2 ? "" : "s"] down [deadguy] and disembowel[ling2 ? "" : "s"] them in a spray of gore!", \ + "[ling2 ? pick(ling1, ling2) : ling1] corners [deadguy] and impales them through the stomach!", \ + "[ling2 ? pick(ling1, ling2) : ling1] decapitates [deadguy] in a single cleaving arc!") + eventdat += "
    [murder_text]" + else + eventdat += "

    You valiantly fight off the changeling[ling2 ? "s":""]!" + if(ling2) + food += 30 + lings_aboard = max(0,lings_aboard-2) + else + food += 15 + lings_aboard = max(0,--lings_aboard) + eventdat += "
    Well, it's perfectly good food...\ +
    You cut the changeling[ling2 ? "s" : ""] into meat, gaining [ling2 ? "30" : "15"] Food!" + else + eventdat += "

    [pick("Sensing unfavorable odds", "After a failed attack", "Suddenly breaking nerve")], \ + the changeling[ling2 ? "s":""] vanish[ling2 ? "" : "es"] into space through the airlocks! You're safe... for now." + if(ling2) + lings_aboard = max(0,lings_aboard-2) + else + lings_aboard = max(0,--lings_aboard) + + eventdat += "

    Continue

    " + eventdat += "

    Close

    " + canContinueEvent = 1 + + + if(ORION_TRAIL_SPACEPORT) + gameStatus = ORION_STATUS_MARKET + if(spaceport_raided) + eventdat += "The spaceport is on high alert! You've been barred from docking by the local authorities after your failed raid." + if(last_spaceport_action) + eventdat += "
    Last Spaceport Action: [last_spaceport_action]" + eventdat += "

    Depart Spaceport

    " + eventdat += "

    Close

    " + else + eventdat += "Your jump into the sector yields a spaceport - a lucky find!" + eventdat += "
    This spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." + eventdat += "
    Trading terms: FU = Fuel, FO = Food" + if(last_spaceport_action) + eventdat += "
    Last action: [last_spaceport_action]" + eventdat += "

    Crew:

    " + eventdat += english_list(settlers) + eventdat += "
    Food: [food] | Fuel: [fuel]" + eventdat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" + + + //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) + if(!spaceport_freebie && (fuel < 20 || food < 20)) + spaceport_freebie++ + var/FU = 10 + var/FO = 10 + var/freecrew = 0 + if(prob(30)) + FU = 25 + FO = 25 + + if(prob(10)) + add_crewmember() + freecrew++ + + eventdat += "
    The traders of the spaceport take pity on you, and generously give you some free supplies! (+[FU]FU, +[FO]FO)" + if(freecrew) + eventdat += "
    You also gain a new crewmember!" + + fuel += FU + food += FO + + //CREW INTERACTIONS + eventdat += "

    Crew Management:

    " + + //Buy crew + if(food >= 10 && fuel >= 10) + eventdat += "

    Hire a New Crewmember (-10FU, -10FO)

    " + else + eventdat += "

    You cannot afford a new crewmember.

    " + + //Sell crew + if(settlers.len > 1) + eventdat += "

    Sell Crew for Fuel and Food (+7FU, +7FO)

    " + else + eventdat += "

    You have no other crew to sell.

    " + + //BUY/SELL STUFF + eventdat += "

    Spare Parts:

    " + + //Engine parts + if(fuel > 5) + eventdat += "

    Buy Engine Parts (-5FU)

    " + else + eventdat += "

    You cannot afford engine parts." + + //Hull plates + if(fuel > 5) + eventdat += "

    Buy Hull Plates (-5FU)

    " + else + eventdat += "

    You cannot afford hull plates." + + //Electronics + if(fuel > 5) + eventdat += "

    Buy Spare Electronics (-5FU)

    " + else + eventdat += "

    You cannot afford spare electronics." + + //Trade + if(fuel > 5) + eventdat += "

    Trade Fuel for Food (-5FU,+5FO)

    " + else + eventdat += "

    You don't have 5FU to trade. 5) + eventdat += "

    Trade Food for Fuel (+5FU,-5FO)

    " + else + eventdat += "

    You don't have 5FO to trade.You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") + name = "The Orion Trail: Realism Edition" + desc = "Learn how our ancestors got to Orion, and try not to die in the process!" + newgame() + obj_flags |= EMAGGED + +/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion + name = "spaceport security" + desc = "Premier corporate security forces for all spaceports found along the Orion Trail." + faction = list("orion") + loot = list() + del_on_death = TRUE + +/obj/item/orion_ship + name = "model settler ship" + desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + w_class = WEIGHT_CLASS_SMALL + var/active = 0 //if the ship is on + +/obj/item/orion_ship/examine(mob/user) + ..() + if(!(in_range(user, src))) + return + if(!active) + to_chat(user, "There's a little switch on the bottom. It's flipped down.") + else + to_chat(user, "There's a little switch on the bottom. It's flipped up.") + +/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse + if(active) + return + + message_admins("[ADMIN_LOOKUPFLW(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") + log_game("[key_name(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") + + to_chat(user, "You flip the switch on the underside of [src].") + active = 1 + visible_message("[src] softly beeps and whirs to life!") + playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) + say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") + sleep(20) + visible_message("[src] begins to vibrate...") + say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") + sleep(30) + say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1) + sleep(3.6) + visible_message("[src] explodes!") + explosion(loc, 2,4,8, flame_range = 16) + qdel(src) + +#undef ORION_TRAIL_WINTURN +#undef ORION_TRAIL_RAIDERS +#undef ORION_TRAIL_FLUX +#undef ORION_TRAIL_ILLNESS +#undef ORION_TRAIL_BREAKDOWN +#undef ORION_TRAIL_LING +#undef ORION_TRAIL_LING_ATTACK +#undef ORION_TRAIL_MALFUNCTION +#undef ORION_TRAIL_COLLISION +#undef ORION_TRAIL_SPACEPORT +#undef ORION_TRAIL_BLACKHOLE + +#undef ORION_STATUS_START +#undef ORION_STATUS_NORMAL +#undef ORION_STATUS_GAMEOVER +#undef ORION_STATUS_MARKET 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/communications.dm b/code/game/machinery/computer/communications.dm index 43f5b96fbd..752765baa1 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -173,14 +173,15 @@ var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines if(M) SSshuttle.shuttle_purchased = TRUE - M.unload_preview() - M.load_template(S) - M.existing_shuttle = SSshuttle.emergency - M.action_load(S) SSshuttle.points -= S.credit_cost minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase") message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].") SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]") + M.unload_preview() + M.load_template(S) + M.existing_shuttle = SSshuttle.emergency + M.action_load(S) + message_admins("[S.name] loaded, purchased by [usr]") else to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.") else diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 09cbb68083..c11f7d9edc 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -31,7 +31,6 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) var/list/jobs = new/list() jobs["Captain"] = 00 - jobs["Head of Personnel"] = 50 jobs["Head of Security"] = 10 jobs["Warden"] = 11 jobs["Security Officer"] = 12 @@ -47,9 +46,10 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) jobs["Chief Engineer"] = 40 jobs["Station Engineer"] = 41 jobs["Atmospheric Technician"] = 42 - jobs["Quartermaster"] = 51 - jobs["Shaft Miner"] = 52 - jobs["Cargo Technician"] = 53 + jobs["Quartermaster"] = 50 + jobs["Shaft Miner"] = 51 + jobs["Cargo Technician"] = 52 + jobs["Head of Personnel"] = 60 jobs["Bartender"] = 61 jobs["Cook"] = 62 jobs["Botanist"] = 63 @@ -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/dance_machine.dm b/code/game/machinery/dance_machine.dm index 7beb32eebb..1c6d713437 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -214,11 +214,11 @@ sparkles += S switch(i) if(1 to 8) - S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 30, TRUE, 60, 36, TRUE) if(9 to 16) - S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 62, TRUE, 60, 36, TRUE) if(17 to 24) - S.orbit(src, 95, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 95, TRUE, 60, 36, TRUE) if(25) S.pixel_y = 7 S.forceMove(get_turf(src)) diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index 7b7c8a3411..4210435f33 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -69,7 +69,7 @@ if(defib) to_chat(user, "There's already a defibrillator in [src]!") return - if(I.item_flags & NODROP || !user.transferItemToLoc(I, src)) + if(HAS_TRAIT(I, TRAIT_NODROP) || !user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return user.visible_message("[user] hooks up [I] to [src]!", \ diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 90a6b07733..7895fb8c9f 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -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..8be7becfdd 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -65,7 +65,7 @@ if(!isitem(A)) continue var/obj/item/I = A - if(!(I.item_flags & NODROP)) + if(!HAS_TRAIT(I, TRAIT_NODROP)) say("Subject may not have abiotic items on.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1) return @@ -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 7284b3c738..03c60be91c 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -81,12 +81,6 @@ 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/requests_console.dm b/code/game/machinery/requests_console.dm index f2c216ca98..ad9a846bdc 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -323,7 +323,7 @@ GLOBAL_LIST_EMPTY(allConsoles) emergency = "Medical" if(radio_freq) Radio.set_frequency(radio_freq) - Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq,get_spans(),get_default_language()) + Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq) update_icon() addtimer(CALLBACK(src, .proc/clear_emergency), 3000) @@ -382,7 +382,7 @@ GLOBAL_LIST_EMPTY(allConsoles) screen = 6 if(radio_freq) - Radio.talk_into(src,"[alert]: [message]",radio_freq,get_spans(),get_default_language()) + Radio.talk_into(src, "[alert]: [message]", radio_freq) switch(priority) if(2) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index b84db2ca8d..90166dacf0 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -51,6 +51,7 @@ /obj/machinery/suit_storage_unit/security suit_type = /obj/item/clothing/suit/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/jetpack/oxygen/security /obj/machinery/suit_storage_unit/hos suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos 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/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index d8c0fbeeb3..2e5a13beb2 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -305,7 +305,7 @@ name = "\improper SRM-8 missile rack" desc = "A weapon for combat exosuits. Shoots light explosive missiles." icon_state = "mecha_missilerack" - projectile = /obj/item/projectile/bullet/srmrocket + projectile = /obj/item/projectile/bullet/a84mm_he fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 8 projectile_energy_cost = 1000 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d5de4a4898..fc0665f51e 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)) @@ -538,7 +537,7 @@ var/oldloc = loc if(internal_damage & MECHA_INT_CONTROL_LOST) move_result = mechsteprand() - else if(dir != direction && !strafe) + else if(dir != direction && (!strafe || occupant.client.keys_held["Alt"])) move_result = mechturn(direction) else move_result = mechstep(direction) diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm index 6d42c302e1..7b00e208cc 100644 --- a/code/game/mecha/mecha_actions.dm +++ b/code/game/mecha/mecha_actions.dm @@ -128,7 +128,7 @@ /datum/action/innate/mecha/strafe - name = "Toggle Strafing" + name = "Toggle Strafing. Disabled when Alt is held." button_icon_state = "strafe" /datum/action/innate/mecha/strafe/Activate() 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/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 55a162ad38..cc69b88cc4 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -219,7 +219,7 @@ name = "stabilized plasma" desc = "A puddle of stabilized plasma." icon_state = "flour" - color = "#C8A5DC" + color = "#9e0089" /obj/effect/decal/cleanable/insectguts name = "insect guts" 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..32d91ee76a 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -131,7 +131,7 @@ var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc) victim.log_message("entered a blood frenzy", LOG_ATTACK) - chainsaw.item_flags |= NODROP + ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT) victim.drop_all_held_items() victim.put_in_hands(chainsaw, forced = TRUE) chainsaw.attack_self(victim) @@ -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/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 4a77274d23..bdb949a570 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -30,6 +30,18 @@ loot_spawned++ return INITIALIZE_HINT_QDEL +/obj/effect/spawner/lootdrop/bedsheet + icon = 'icons/obj/bedsheets.dmi' + icon_state = "random_bedsheet" + name = "random dorms bedsheet" + loot = list(/obj/item/bedsheet = 8, /obj/item/bedsheet/blue = 8, /obj/item/bedsheet/green = 8, + /obj/item/bedsheet/grey = 8, /obj/item/bedsheet/orange = 8, /obj/item/bedsheet/purple = 8, + /obj/item/bedsheet/red = 8, /obj/item/bedsheet/yellow = 8, /obj/item/bedsheet/brown = 8, + /obj/item/bedsheet/black = 8, /obj/item/bedsheet/patriot = 3, /obj/item/bedsheet/rainbow = 3, + /obj/item/bedsheet/ian = 3, /obj/item/bedsheet/runtime = 3, /obj/item/bedsheet/nanotrasen = 3, + /obj/item/bedsheet/pirate = 1, /obj/item/bedsheet/cosmos = 1, /obj/item/bedsheet/gondola = 1 + ) + /obj/effect/spawner/lootdrop/armory_contraband name = "armory contraband gun spawner" lootdoubles = FALSE @@ -108,6 +120,33 @@ loot = GLOB.maintenance_loot . = ..() +/obj/effect/spawner/lootdrop/glowstick + name = "random colored glowstick" + icon = 'icons/obj/lighting.dmi' + icon_state = "random_glowstick" + +/obj/effect/spawner/lootdrop/glowstick/Initialize() + loot = typesof(/obj/item/flashlight/glowstick) + . = ..() + + +/obj/effect/spawner/lootdrop/gloves + name = "random gloves" + desc = "These gloves are supposed to be a random color..." + icon = 'icons/obj/clothing/gloves.dmi' + icon_state = "random_gloves" + loot = list( + /obj/item/clothing/gloves/color/orange = 1, + /obj/item/clothing/gloves/color/red = 1, + /obj/item/clothing/gloves/color/blue = 1, + /obj/item/clothing/gloves/color/purple = 1, + /obj/item/clothing/gloves/color/green = 1, + /obj/item/clothing/gloves/color/grey = 1, + /obj/item/clothing/gloves/color/light_brown = 1, + /obj/item/clothing/gloves/color/brown = 1, + /obj/item/clothing/gloves/color/white = 1, + /obj/item/clothing/gloves/color/rainbow = 1) + /obj/effect/spawner/lootdrop/crate_spawner name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF! lootdoubles = FALSE @@ -214,6 +253,20 @@ /obj/item/aiModule/core/full/damaged ) +/obj/effect/spawner/lootdrop/mre + name = "random MRE" + icon = 'icons/obj/storage.dmi' + icon_state = "mre" + +/obj/effect/spawner/lootdrop/mre/Initialize() + for(var/A in subtypesof(/obj/item/storage/box/mre)) + var/obj/item/storage/box/mre/M = A + var/our_chance = initial(M.spawner_chance) + if(our_chance) + LAZYSET(loot, M, our_chance) + return ..() + + // Tech storage circuit board spawners // For these, make sure that lootcount equals the number of list items diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 9ff1b5cf01..384a1e4ee4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -109,6 +109,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! + /obj/item/Initialize() materials = typelist("materials", materials) @@ -229,9 +230,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) research_msg += "." to_chat(user, research_msg.Join()) -/obj/item/proc/speechModification(message) //for message modding by mask slot. - return message - /obj/item/interact(mob/user) add_fingerprint(user) ui_interact(user) @@ -256,7 +254,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 +447,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 +521,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)) @@ -642,11 +644,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) else . = "" - -//when an item modify our speech spans when in our active hand. Override this to modify speech spans. -/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) - return - /obj/item/hitby(atom/movable/AM) return @@ -681,7 +678,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) ..() /obj/item/proc/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) + if(istype(M) && M.dirty < 100) M.dirty++ /obj/item/proc/on_mob_death(mob/living/L, gibbed) @@ -820,6 +817,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return ..() /obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback) - if (item_flags & NODROP) + if (HAS_TRAIT(src, TRAIT_NODROP)) return return ..() diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 7881c277ff..8895bffd70 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 @@ -350,14 +414,16 @@ RLD return FALSE if(do_after(user, rcd_results["delay"] * delay_mod, target = A)) if(checkResource(rcd_results["cost"], user)) + var/atom/cached = A if(A.rcd_act(user, src, rcd_results["mode"])) useResource(rcd_results["cost"], user) activate() - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + investigate_log("[user] used [src] on [cached] (now [A]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD) + playsound(src, '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 +432,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)) @@ -531,6 +624,7 @@ RLD sheetmultiplier = 16 var/mode = LIGHT_MODE actions_types = list(/datum/action/item_action/pick_color) + ammo_sections = 5 var/wallcost = 10 var/floorcost = 15 @@ -551,7 +645,7 @@ RLD ..() /obj/item/construction/rld/update_icon() - icon_state = "rld-[round(matter/35)]" + icon_state = "rld-[round((matter/max_matter) * 5, 1)]" ..() 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..6dbf0c2ad3 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -233,6 +233,10 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1) return(BRUTELOSS) +/obj/item/pipe_dispenser/ui_base_html(html) + var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/pipes) + . = replacetext(html, "", assets.css_tag()) + /obj/item/pipe_dispenser/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) @@ -331,7 +335,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/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index f7c37715aa..5db5aa416e 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -48,7 +48,7 @@ icon_state = "chronogun" item_state = "chronogun" w_class = WEIGHT_CLASS_NORMAL - item_flags = NODROP | DROPDEL + item_flags = DROPDEL ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam) can_charge = 0 fire_delay = 50 @@ -58,6 +58,7 @@ /obj/item/gun/energy/chrono_gun/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHRONO_GUN_TRAIT) if(istype(loc, /obj/item/chrono_eraser)) TED = loc else //admin must have spawned it @@ -150,8 +151,8 @@ gun = loc . = ..() - - + + /obj/effect/chrono_field @@ -248,9 +249,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..000c52ae43 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" @@ -709,9 +707,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = null w_class = WEIGHT_CLASS_TINY var/chem_volume = 100 - var/vapetime = 0 //this so it won't puff out clouds every tick - var/screw = 0 // kinky - var/super = 0 //for the fattest vapes dude. + var/vapetime = FALSE //this so it won't puff out clouds every tick + var/screw = FALSE // kinky + var/super = FALSE //for the fattest vapes dude. /obj/item/clothing/mask/vape/suicide_act(mob/user) user.visible_message("[user] is puffin hard on dat vape, [user.p_they()] trying to join the vape life on a whole notha plane!")//it doesn't give you cancer, it is cancer @@ -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 + create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it reagents.add_reagent("nicotine", 50) if(!icon_state) if(!param_color) @@ -730,52 +727,48 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "[param_color]_vape" /obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params) - if(O.is_drainable()) - if(reagents.total_volume < chem_volume) - if(O.reagents.total_volume > 0) - O.reagents.trans_to(src,25) - to_chat(user, "You add the contents of [O] to [src].") - else - to_chat(user, "[O] is empty!") - else - to_chat(user, "[src] can't hold anymore reagents!") - - if(istype(O, /obj/item/screwdriver)) + if(O.tool_behaviour == TOOL_SCREWDRIVER) if(!screw) - screw = 1 + screw = TRUE to_chat(user, "You open the cap on [src].") - if(super) + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + if(obj_flags & EMAGGED) + add_overlay("vapeopen_high") + else if(super) add_overlay("vapeopen_med") else add_overlay("vapeopen_low") else - screw = 0 + screw = FALSE to_chat(user, "You close the cap on [src].") + DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) cut_overlays() - if(istype(O, /obj/item/multitool)) + if(O.tool_behaviour == TOOL_MULTITOOL) if(screw && !(obj_flags & EMAGGED))//also kinky if(!super) cut_overlays() - super = 1 + super = TRUE to_chat(user, "You increase the voltage of [src].") add_overlay("vapeopen_med") else cut_overlays() - super = 0 + super = FALSE to_chat(user, "You decrease the voltage of [src].") add_overlay("vapeopen_low") if(screw && (obj_flags & EMAGGED)) to_chat(user, "[src] can't be modified!") + else + ..() /obj/item/clothing/mask/vape/emag_act(mob/user)// I WON'T REGRET WRITTING THIS, SURLY. if(screw) if(!(obj_flags & EMAGGED)) cut_overlays() obj_flags |= EMAGGED - super = 0 + super = FALSE to_chat(user, "You maximize the voltage of [src].") add_overlay("vapeopen_high") var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect @@ -790,13 +783,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 +796,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/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 26f00c730e..a1ee62e2eb 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -123,6 +123,14 @@ name = "Orion Trail (Computer Board)" build_path = /obj/machinery/computer/arcade/orion_trail +/obj/item/circuitboard/computer/arcade/minesweeper + name = "Minesweeper (Computer Board)" + build_path = /obj/machinery/computer/arcade/minesweeper + +/obj/item/circuitboard/computer/arcade/amputation + name = "Mediborg's Amputation Adventure (Computer Board)" + build_path = /obj/machinery/computer/arcade/amputation + /obj/item/circuitboard/computer/turbine_control name = "Turbine control (Computer Board)" build_path = /obj/machinery/computer/turbine_computer 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 5868ef4b1d..55e75b3992 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -444,7 +444,7 @@ /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(req_defib) @@ -585,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." @@ -713,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" @@ -726,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/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm index 29f0cf27f9..55d1a2c78a 100644 --- a/code/game/objects/items/dehy_carp.dm +++ b/code/game/objects/items/dehy_carp.dm @@ -19,6 +19,9 @@ else return ..() +/obj/item/toy/plush/carpplushie/dehy_carp/plop(obj/item/toy/plush/Daddy) + return FALSE + /obj/item/toy/plush/carpplushie/dehy_carp/proc/Swell() desc = "It's growing!" visible_message("[src] swells up!") diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 7d3d36c5b2..45baa542d4 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -10,11 +10,20 @@ GLOBAL_LIST_EMPTY(PDAs) #define PDA_SCANNER_HALOGEN 4 #define PDA_SCANNER_GAS 5 #define PDA_SPAM_DELAY 2 MINUTES +#define PDA_STANDARD_OVERLAYS list("pda-r", "blank", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay") + +//pda icon overlays list defines +#define PDA_OVERLAY_ALERT 1 +#define PDA_OVERLAY_SCREEN 2 +#define PDA_OVERLAY_ID 3 +#define PDA_OVERLAY_ITEM 4 +#define PDA_OVERLAY_LIGHT 5 +#define PDA_OVERLAY_PAI 6 /obj/item/pda name = "\improper PDA" desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." - icon = 'icons/obj/pda.dmi' + icon = 'icons/obj/pda_alt.dmi' icon_state = "pda" item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' @@ -31,7 +40,8 @@ GLOBAL_LIST_EMPTY(PDAs) var/default_cartridge = 0 // Access level defined by cartridge var/obj/item/cartridge/cartridge = null //current cartridge var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge. - var/icon_alert = "pda-r" //Icon to be overlayed for message alerts. Taken from the pda icon file. + var/list/overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_default", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")) + var/current_overlays = PDA_STANDARD_OVERLAYS var/font_index = 0 //This int tells DM which font is currently selected and lets DM know when the last font has been selected so that it can cycle back to the first font when "toggle font" is pressed again. var/font_mode = "font-family:monospace;" //The currently selected font. var/background_color = "#808000" //The currently selected background color. @@ -58,7 +68,6 @@ GLOBAL_LIST_EMPTY(PDAs) var/last_everyone //No text for everyone spamming var/last_noise //Also no honk spamming that's bad too var/ttone = "beep" //The ringtone! - var/lock_code = "" // Lockcode to unlock uplink var/honkamt = 0 //How many honks left when infected with honk.exe var/mimeamt = 0 //How many silence left when infected with mime.exe var/note = "Congratulations, your station has chosen the Thinktronic 5230 Personal Data Assistant! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." //Current note in the notepad function @@ -78,7 +87,9 @@ GLOBAL_LIST_EMPTY(PDAs) var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette) var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above. - var/overlays_x_offset = 0 //x offset to use for certain overlays + var/list/overlays_offsets // offsets to use for certain overlays + var/overlays_x_offset = 0 + var/overlays_y_offset = 0 var/underline_flag = TRUE //flag for underline @@ -91,15 +102,13 @@ GLOBAL_LIST_EMPTY(PDAs) return BRUTELOSS /obj/item/pda/examine(mob/user) - ..() - if(!id && !inserted_item) - return - - if(id) - to_chat(user, "Alt-click to remove the id.") - + . = ..() + var/dat = id ? "Alt-click to remove the id." : "" if(inserted_item && (!isturf(loc))) - to_chat(user, "Ctrl-click to remove [inserted_item].") + dat += "\nCtrl-click to remove [inserted_item]." + if(LAZYLEN(GLOB.pda_reskins)) + dat += "\nCtrl-shift-click it to reskin it." + to_chat(user, dat) /obj/item/pda/Initialize() . = ..() @@ -113,30 +122,71 @@ GLOBAL_LIST_EMPTY(PDAs) inserted_item = new inserted_item(src) else inserted_item = new /obj/item/pen(src) - update_icon() + update_icon(FALSE, TRUE) + +/obj/item/pda/CtrlShiftClick(mob/living/user) + . = ..() + if(GLOB.pda_reskins && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + reskin_obj(user) + +/obj/item/pda/reskin_obj(mob/M) + if(!LAZYLEN(GLOB.pda_reskins)) + return + var/dat = "Reskin options for [name]:" + for(var/V in GLOB.pda_reskins) + var/output = icon2html(GLOB.pda_reskins[V], M, icon_state) + dat += "\n[V]: [output]" + to_chat(M, dat) + + var/choice = input(M, "Choose the a reskin for [src]","Reskin Object") as null|anything in GLOB.pda_reskins + var/new_icon = GLOB.pda_reskins[choice] + if(QDELETED(src) || isnull(new_icon) || new_icon == icon || M.incapacitated() || !in_range(M,src)) + return + icon = new_icon + update_icon(FALSE, TRUE) + to_chat(M, "[src] is now skinned as '[choice]'.") + +/obj/item/pda/proc/set_new_overlays() + if(!overlays_offsets || !(icon in overlays_offsets)) + overlays_x_offset = 0 + overlays_y_offset = 0 + else + var/list/new_offsets = overlays_offsets[icon] + if(new_offsets) + overlays_x_offset = new_offsets[1] + overlays_y_offset = new_offsets[2] + if(!(icon in overlays_icons)) + current_overlays = PDA_STANDARD_OVERLAYS + return + current_overlays = overlays_icons[icon] /obj/item/pda/equipped(mob/user, slot) . = ..() - if(!equipped) - if(user.client) - background_color = user.client.prefs.pda_color - switch(user.client.prefs.pda_style) - if(MONO) - font_index = MODE_MONO - font_mode = FONT_MONO - if(SHARE) - font_index = MODE_SHARE - font_mode = FONT_SHARE - if(ORBITRON) - font_index = MODE_ORBITRON - font_mode = FONT_ORBITRON - if(VT) - font_index = MODE_VT - font_mode = FONT_VT - else - font_index = MODE_MONO - font_mode = FONT_MONO - equipped = TRUE + if(equipped) + return + if(user.client) + background_color = user.client.prefs.pda_color + switch(user.client.prefs.pda_style) + if(MONO) + font_index = MODE_MONO + font_mode = FONT_MONO + if(SHARE) + font_index = MODE_SHARE + font_mode = FONT_SHARE + if(ORBITRON) + font_index = MODE_ORBITRON + font_mode = FONT_ORBITRON + if(VT) + font_index = MODE_VT + font_mode = FONT_VT + else + font_index = MODE_MONO + font_mode = FONT_MONO + var/pref_skin = GLOB.pda_reskins[user.client.prefs.pda_skin] + if(icon != pref_skin) + icon = pref_skin + update_icon(FALSE, TRUE) + equipped = TRUE /obj/item/pda/proc/update_label() name = "PDA-[owner] ([ownjob])" //Name generalisation @@ -150,33 +200,36 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/GetID() return id -/obj/item/pda/update_icon() +/obj/item/pda/update_icon(alert = FALSE, new_overlays = FALSE) + if(new_overlays) + set_new_overlays() cut_overlays() + add_overlay(alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]) var/mutable_appearance/overlay = new() overlay.pixel_x = overlays_x_offset if(id) - overlay.icon_state = "id_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_ID] add_overlay(new /mutable_appearance(overlay)) if(inserted_item) - overlay.icon_state = "insert_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_ITEM] add_overlay(new /mutable_appearance(overlay)) if(fon) - overlay.icon_state = "light_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_LIGHT] add_overlay(new /mutable_appearance(overlay)) if(pai) - if(pai.pai) - overlay.icon_state = "pai_overlay" - add_overlay(new /mutable_appearance(overlay)) - else - overlay.icon_state = "pai_off_overlay" - add_overlay(new /mutable_appearance(overlay)) + overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]" + add_overlay(new /mutable_appearance(overlay)) -/obj/item/pda/MouseDrop(obj/over_object, src_location, over_location) +/obj/item/pda/MouseDrop(mob/over, src_location, over_location) var/mob/M = usr - if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src)) + if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return attack_self(M) return ..() +/obj/item/pda/attack_self_tk(mob/user) + to_chat(user, "The PDA's capacitive touch screen doesn't seem to respond!") + return + /obj/item/pda/interact(mob/user) if(!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") @@ -358,9 +411,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 += "
    " @@ -382,7 +435,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/mob/living/U = usr //Looking for master was kind of pointless since PDAs don't appear to have one. - if(usr.canUseTopic(src) && !href_list["close"]) + if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"]) add_fingerprint(U) U.set_machine(src) @@ -636,7 +689,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_id() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if (id) @@ -736,8 +789,7 @@ GLOBAL_LIST_EMPTY(PDAs) to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [signal.format_message()] (Reply)") - update_icon() - add_overlay(icon_alert) + update_icon(TRUE) /obj/item/pda/proc/send_to_all(mob/living/U) if (last_everyone && world.time < last_everyone + PDA_SPAM_DELAY) @@ -802,7 +854,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_pen() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(inserted_item) @@ -1076,4 +1128,11 @@ GLOBAL_LIST_EMPTY(PDAs) #undef PDA_SCANNER_HALOGEN #undef PDA_SCANNER_GAS #undef PDA_SPAM_DELAY +#undef PDA_STANDARD_OVERLAYS +#undef PDA_OVERLAY_ALERT +#undef PDA_OVERLAY_SCREEN +#undef PDA_OVERLAY_ID +#undef PDA_OVERLAY_ITEM +#undef PDA_OVERLAY_LIGHT +#undef PDA_OVERLAY_PAI \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 80d8cb5963..54b82d8e07 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -124,6 +124,16 @@ icon_state = "pda-captain" detonatable = FALSE +/obj/item/pda/lieutenant + name = "lieutenant PDA" + default_cartridge = /obj/item/cartridge/captain + inserted_item = /obj/item/pen/fountain/captain + icon_state = "pda-lieutenant" + ttone = "bwoink" + detonatable = FALSE + hidden = TRUE + note = "Congratulations, you have chosen the Thinktronic 5230-2 Personal Data Assistant Prestige Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." + /obj/item/pda/cargo name = "cargo technician PDA" default_cartridge = /obj/item/cartridge/quartermaster @@ -171,25 +181,29 @@ /obj/item/pda/curator name = "curator PDA" icon_state = "pda-library" - icon_alert = "pda-r-library" + overlays_icons = list('icons/obj/pda.dmi' = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay"), + 'icons/obj/pda_alt.dmi' = list("pda-r","screen_default","id_overlay","insert_overlay", "light_overlay", "pai_overlay")) + current_overlays = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay") default_cartridge = /obj/item/cartridge/curator inserted_item = /obj/item/pen/fountain desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader." - note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" + note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." silent = TRUE //Quiet in the library! + overlays_offsets = list('icons/obj/pda.dmi' = list(-3,0)) overlays_x_offset = -3 /obj/item/pda/clear name = "clear PDA" icon_state = "pda-clear" desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" + note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." /obj/item/pda/neko name = "neko PDA" icon_state = "pda-neko" - desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition a feline fine case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~!" + overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_neko", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")) + desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special feline edition." + note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." /obj/item/pda/cook name = "cook PDA" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index fc268e2b3e..bf352e8eb7 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" @@ -87,7 +87,7 @@ /obj/item/cartridge/detective name = "\improper D.E.T.E.C.T. cartridge" - icon_state = "cart-s" + icon_state = "cart-eye" access = CART_SECURITY | CART_MEDICAL | CART_MANIFEST bot_access_flags = SEC_BOT @@ -100,23 +100,25 @@ /obj/item/cartridge/lawyer name = "\improper P.R.O.V.E. cartridge" - icon_state = "cart-s" + icon_state = "cart-law" access = CART_SECURITY spam_enabled = 1 /obj/item/cartridge/curator name = "\improper Lib-Tweet cartridge" - icon_state = "cart-s" + icon_state = "cart-lib" access = CART_NEWSCASTER /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 + icon_state = "cart-robo" + bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT access = CART_DRONEPHONE /obj/item/cartridge/signal name = "generic signaler cartridge" + icon_state = "cart-sig" desc = "A data cartridge with an integrated radio signaler module." /obj/item/cartridge/signal/toxins @@ -160,7 +162,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 +174,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 +185,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/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm index 13d653a4fe..d85c5d72d8 100644 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ b/code/game/objects/items/devices/PDA/virus_cart.dm @@ -53,7 +53,6 @@ /obj/item/cartridge/virus/syndicate name = "\improper Detomatix cartridge" - icon_state = "cart" access = CART_REMOTE_DOOR remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. charges = 4 @@ -85,7 +84,7 @@ /obj/item/cartridge/virus/frame name = "\improper F.R.A.M.E. cartridge" - icon_state = "cart" + icon_state = "cart-f" var/telecrystals = 0 /obj/item/cartridge/virus/frame/send_virus(obj/item/pda/target, mob/living/U) @@ -99,7 +98,7 @@ GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target) if(!hidden_uplink) hidden_uplink = target.AddComponent(/datum/component/uplink) - target.lock_code = lock_code + hidden_uplink.unlock_code = lock_code else hidden_uplink.hidden_crystals += hidden_uplink.telecrystals //Temporarially hide the PDA's crystals, so you can't steal telecrystals. hidden_uplink.telecrystals = telecrystals diff --git a/code/game/objects/items/devices/compressionkit.dm b/code/game/objects/items/devices/compressionkit.dm new file mode 100644 index 0000000000..5ac958328d --- /dev/null +++ b/code/game/objects/items/devices/compressionkit.dm @@ -0,0 +1,127 @@ +/obj/item/compressionkit + name = "bluespace compression kit" + desc = "An illegally modified BSRPED, capable of reducing the size of most items." + icon = 'icons/obj/tools.dmi' + icon_state = "compression_c" + item_state = "RPED" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + w_class = WEIGHT_CLASS_NORMAL + var/charges = 5 + // var/damage_multiplier = 0.2 Not in use yet. + var/mode = 0 + +/obj/item/compressionkit/examine(mob/user) + ..() + to_chat(user, "It has [charges] charges left. Recharge with bluespace crystals.") + to_chat(user, "Use in-hand to swap toggle compress/expand mode (expand mode not yet implemented).") + +/obj/item/compressionkit/attack_self(mob/user) + if(mode == 0) + mode = 1 + icon_state = "compression_e" + to_chat(user, "You switch the compressor to expand mode. This isn't implemented yet, so right now it wont do anything different!") + return + if(mode == 1) + mode = 0 + icon_state = "compression_c" + to_chat(user, "You switch the compressor to compress mode. Usage will now reduce the size of objects.") + return + else + mode = 0 + icon_state = "compression_c" + to_chat(user, "Some coder cocked up or an admin broke your compressor. It's been set back to compress mode..") + +/obj/item/compressionkit/proc/sparks() + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(5, 1, get_turf(src)) + s.start() + +/obj/item/compressionkit/suicide_act(mob/living/carbon/M) + M.visible_message("[M] is sticking their head in [src] and turning it on! [M.p_theyre(TRUE)] going to compress their own skull!") + 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/weapons/flash.ogg', 50, 1) + playsound(M, 'sound/effects/splat.ogg', 50, 1) + + return OXYLOSS + +/obj/item/compressionkit/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity || !target) + return + else + if(charges == 0) + playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1) + to_chat(user, "The bluespace compression kit is out of charges! Recharge it with bluespace crystals.") + return + if(istype(target, /obj/item)) + var/obj/item/O = target + if(O.w_class == 1) + playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1) + to_chat(user, "[target] cannot be compressed smaller!.") + return + if(O.GetComponent(/datum/component/storage)) + to_chat(user, "You feel like compressing an item that stores other items would be counterproductive.") + return + if(O.w_class > 1) + playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1) + user.visible_message("[user] is compressing [O] with their bluespace compression kit!") + if(do_mob(user, O, 40) && charges > 0 && O.w_class > 1) + playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1) + sparks() + flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN) + O.w_class -= 1 + // O.force_mult -= damage_multiplier + charges -= 1 + to_chat(user, "You successfully compress [target]! The compressor now has [charges] charges.") + else + to_chat(user, "Anomalous error. Summon a coder.") + + if(istype(target, /mob/living)) + var/mob/living/victim = target + if(istype(victim, /mob/living/carbon/human)) + if(user.zone_selected == "groin") // pp smol. There's probably a smarter way to do this but im retarded. If you have a simpler method let me know. + var/list/organs = victim.getorganszone("groin") + for(var/internal_organ in organs) + if(istype(internal_organ, /obj/item/organ/genital/penis)) + var/obj/item/organ/genital/penis/O = internal_organ + playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1) + victim.visible_message("[user] is preparing to shrink [victim]\'s [O.name] with their bluespace compression kit!") + if(do_mob(user, victim, 40) && charges > 0 && O.length > 0) + victim.visible_message("[user] has shrunk [victim]\'s [O.name]!") + playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1) + sparks() + flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN) + charges -= 1 + O.length -= 5 + if(O.length < 1) + victim.visible_message("[user]\'s [O.name] vanishes!") + qdel(O) // no pp for you + else + O.update_size() + O.update_appearance() + + + +/obj/item/compressionkit/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/stack/ore/bluespace_crystal)) + var/obj/item/stack/ore/bluespace_crystal/B = I + charges += 2 + to_chat(user, "You insert [I] into [src]. It now has [charges] charges.") + if(B.amount > 1) + B.amount -= 1 + else + qdel(I) \ No newline at end of file diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index 9163fb0849..7f3c7f3bfc 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -17,7 +17,7 @@ var/eject_port = "ingestion" var/escape_in_progress = FALSE var/message_cooldown - var/breakout_time = 300 + var/breakout_time = 150 var/tmp/last_hearcheck = 0 var/tmp/list/hearing_mobs var/list/items_preserved = list() @@ -77,7 +77,7 @@ to_chat(user, "Your [src] is already occupied.") return user.visible_message("[hound.name] is carefully inserting [target.name] into their [src].", "You start placing [target] into your [src]...") - if(!patient && iscarbon(target) && !target.buckled && do_after (user, 50, target = target)) + if(!patient && iscarbon(target) && !target.buckled && do_after (user, 100, 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. @@ -420,6 +420,7 @@ desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves." icon = 'icons/mob/dogborg.dmi' icon_state = "sleeper" + breakout_time = 30 //Medical sleepers should be designed to be as easy as possible to get out of. /obj/item/dogborg/sleeper/K9 //The K9 portabrig name = "Mobile Brig" @@ -429,6 +430,7 @@ inject_amount = 0 min_health = -100 injection_chems = null //So they don't have all the same chems as the medihound! + breakout_time = 300 /obj/item/storage/attackby(obj/item/dogborg/sleeper/K9, mob/user, proximity) if(istype(K9)) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index cbbd7a387a..722510dccb 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -13,7 +13,8 @@ actions_types = list(/datum/action/item_action/toggle_light) var/on = FALSE var/brightness_on = 4 //range of light when on - var/flashlight_power = 1 //strength of the light when on + var/flashlight_power = 0.8 //strength of the light when on + light_color = "#FFCC66" /obj/item/flashlight/Initialize() . = ..() @@ -52,7 +53,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()) @@ -63,7 +64,7 @@ to_chat(user, "[M] doesn't have a head!") return - if(flashlight_power < 1) + if(flashlight_power < 0.3) to_chat(user, "\The [src] isn't bright enough to see anything! ") return @@ -86,7 +87,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!") @@ -168,6 +169,8 @@ item_state = "" flags_1 = CONDUCT_1 brightness_on = 2 + light_color = "#FFDDCC" + flashlight_power = 0.3 var/holo_cooldown = 0 /obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag) @@ -204,6 +207,8 @@ righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' force = 9 // Not as good as a stun baton. brightness_on = 5 // A little better than the standard flashlight. + light_color = "#CDDDFF" + flashlight_power = 0.9 hitsound = 'sound/weapons/genhit1.ogg' // the desk lamps are a bit special @@ -216,6 +221,7 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' force = 10 brightness_on = 5 + light_color = "#FFDDBB" w_class = WEIGHT_CLASS_BULKY flags_1 = CONDUCT_1 materials = list() @@ -252,6 +258,7 @@ desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'." w_class = WEIGHT_CLASS_SMALL brightness_on = 7 // Pretty bright. + light_color = "#FA421A" icon_state = "flare" item_state = "flare" actions_types = list() @@ -325,6 +332,7 @@ desc = "A torch fashioned from some leaves and a log." w_class = WEIGHT_CLASS_BULKY brightness_on = 4 + light_color = "#FAA44B" icon_state = "torch" item_state = "torch" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' @@ -341,6 +349,8 @@ righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' desc = "A mining lantern." brightness_on = 6 // luminosity when on + light_color = "#FFAA44" + flashlight_power = 0.75 /obj/item/flashlight/slime @@ -354,6 +364,8 @@ slot_flags = ITEM_SLOT_BELT materials = list() brightness_on = 6 //luminosity when on + light_color = "#FFEEAA" + flashlight_power = 0.6 /obj/item/flashlight/emp var/emp_max_charges = 4 @@ -500,23 +512,13 @@ name = "pink glowstick" color = LIGHT_COLOR_PINK -/obj/item/flashlight/glowstick/random - name = "random colored glowstick" - icon_state = "random_glowstick" - color = null - -/obj/item/flashlight/glowstick/random/Initialize() - ..() - var/T = pick(typesof(/obj/item/flashlight/glowstick) - /obj/item/flashlight/glowstick/random) - new T(loc) - return INITIALIZE_HINT_QDEL - /obj/item/flashlight/spotlight //invisible lighting source name = "disco light" desc = "Groovy..." icon_state = null light_color = null brightness_on = 0 + flashlight_power = 1 light_range = 0 light_power = 10 alpha = 0 @@ -538,7 +540,6 @@ name = "eyelight" desc = "This shouldn't exist outside of someone's head, how are you seeing this?" brightness_on = 15 - flashlight_power = 1 flags_1 = CONDUCT_1 item_flags = DROPDEL actions_types = list() diff --git a/code/game/objects/items/devices/glue.dm b/code/game/objects/items/devices/glue.dm new file mode 100644 index 0000000000..2c57ede706 --- /dev/null +++ b/code/game/objects/items/devices/glue.dm @@ -0,0 +1,32 @@ +/obj/item/syndie_glue + name = "bottle of super glue" + desc = "A black market brand of high strength adhesive, rarely sold to the public. Do not ingest." + icon = 'icons/obj/tools.dmi' + icon_state = "glue" + w_class = WEIGHT_CLASS_SMALL + var/uses = 1 + +/obj/item/syndie_glue/suicide_act(mob/living/carbon/M) + return //todo + +/obj/item/syndie_glue/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity || !target) + return + else + if(uses == 0) + to_chat(user, "The bottle of glue is empty!") + return + if(istype(target, /obj/item)) + var/obj/item/I = target + if(HAS_TRAIT_FROM(I, TRAIT_NODROP, GLUED_ITEM_TRAIT)) + to_chat(user, "[I] is already sticky!") + return + uses -= 1 + ADD_TRAIT(I, TRAIT_NODROP, GLUED_ITEM_TRAIT) + I.desc += " It looks sticky." + to_chat(user, "You smear the [I] with glue, making it incredibly sticky!") + if(uses == 0) + icon_state = "glue_used" + name = "empty bottle of super glue" + return \ No newline at end of file diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index c362d9f7f2..637bb794d3 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -156,7 +156,10 @@ GLOBAL_LIST_EMPTY(GPS_list) icon_state = "gps-b" gpstag = "BORG0" desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams." - item_flags = NODROP + +/obj/item/gps/cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) /obj/item/gps/internal icon_state = null diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index c5ed5fb601..5894b559ae 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 @@ -234,11 +234,18 @@ w_class = WEIGHT_CLASS_SMALL actions_types = list(/datum/action/item_action/instrument) -/obj/item/instrument/harmonica/speechModification(message) +/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args) if(song.playing && ismob(loc)) to_chat(loc, "You stop playing the harmonica to talk...") song.playing = FALSE - return message + +/obj/item/instrument/harmonica/equipped(mob/M, slot) + . = ..() + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + +/obj/item/instrument/harmonica/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) /obj/item/instrument/bikehorn name = "gilded bike horn" 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/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 4b244e3002..347bb6894d 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -17,13 +17,25 @@ user.say("AAAAAAAAAAAARGHHHHH", forced="megaphone suicide")//he must have died while coding this return OXYLOSS -/obj/item/megaphone/get_held_item_speechspans(mob/living/carbon/user) - if(spamcheck > world.time) - to_chat(user, "\The [src] needs to recharge!") +/obj/item/megaphone/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HANDS) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else - playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1) - spamcheck = world.time + 50 - return voicespan + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/megaphone/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/megaphone/proc/handle_speech(mob/living/carbon/user, list/speech_args) + if (user.get_active_held_item() == src) + if(spamcheck > world.time) + to_chat(user, "\The [src] needs to recharge!") + else + playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1) + spamcheck = world.time + 50 + speech_args[SPEECH_SPANS] |= voicespan /obj/item/megaphone/emag_act(mob/user) if(obj_flags & EMAGGED) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 2f8b111b4b..b74b0fa3d4 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -38,7 +38,7 @@ /obj/item/electropack/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/clothing/head/helmet)) - var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user ) + var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' if(!user.transferItemToLoc(W, A)) @@ -53,8 +53,6 @@ user.put_in_hands(A) A.add_fingerprint(user) - if(item_flags & NODROP) - A.item_flags |= NODROP else return ..() @@ -106,8 +104,7 @@ if(shock_cooldown != 0) return shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 + addtimer(VARSET_CALLBACK(src, shock_cooldown, 0), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 719fe6ddd8..1d51aabf86 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -16,7 +16,6 @@ var/on = TRUE var/frequency = FREQ_COMMON - var/traitor_frequency = 0 // If tuned to this frequency, uplink will be unlocked. var/canhear_range = 3 // The range around the radio in which mobs can hear what it receives. var/emped = 0 // Tracks the number of EMPs currently stacked. @@ -190,7 +189,7 @@ /obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language) if(!spans) - spans = M.get_spans() + spans = list(M.speech_span) if(!language) language = M.get_default_language() INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language) diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index 2f137861aa..20107373d3 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -49,7 +49,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user if(C.get_item_by_slot(SLOT_HEAD) == src) - if((item_flags & NODROP) && !struggling) + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) && !struggling) struggling = TRUE var/fear_string switch(time_left) @@ -74,7 +74,7 @@ else user.visible_message("The lock on [user]'s [name] pops open!", \ "You force open the padlock!", "You hear a single, pronounced click!") - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) struggling = FALSE else ..() @@ -116,7 +116,7 @@ /obj/item/reverse_bear_trap/proc/reset() ticking = FALSE - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) soundloop.stop() soundloop2.stop() STOP_PROCESSING(SSprocessing, src) @@ -125,7 +125,7 @@ ticking = TRUE escape_chance = initial(escape_chance) //we keep these vars until re-arm, for tracking purposes time_left = initial(time_left) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) soundloop.start() soundloop2.mid_length = initial(soundloop2.mid_length) soundloop2.start() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 79b04c771b..9f52b4c1ac 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -95,7 +95,7 @@ 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!") var/msg = "*---------*\nAnalyzing results for The floor:\n\tOverall status: Healthy\n" @@ -127,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 @@ -199,10 +199,10 @@ SLIME SCANNER 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 msg += "\tSubject is genetically deaf.\n" - else if(C.has_trait(TRAIT_DEAF)) + else if(HAS_TRAIT(C, TRAIT_DEAF)) healthy = FALSE msg += "\tSubject is deaf.\n" else @@ -220,10 +220,10 @@ SLIME SCANNER msg += "\t==EYE STATUS==\n" if(istype(eyes)) var/healthy = TRUE - if(C.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(C, TRAIT_BLIND)) msg += "\tSubject is blind.\n" healthy = FALSE - if(C.has_trait(TRAIT_NEARSIGHT)) + if(HAS_TRAIT(C, TRAIT_NEARSIGHT)) msg += "\tSubject is nearsighted.\n" healthy = FALSE if(eyes.eye_damage > 30) @@ -290,7 +290,7 @@ SLIME SCANNER 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))) + 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)) @@ -428,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 @@ -550,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..9fb4206845 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!") @@ -107,7 +110,7 @@ to_chat(user, "The safety is [safety ? "on" : "off"].") if(reagents.total_volume) - to_chat(user, "Alt-click to empty it.") + to_chat(user, "You can loose its screws to empty it.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) if(istype(target, tanktype) && target.Adjacent(user)) @@ -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) @@ -241,5 +244,14 @@ var/turf/open/theturf = T theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) - 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.") + user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] by loosing the release valve's screws.") +//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/granters.dm b/code/game/objects/items/granters.dm index 8d0d8d020e..21f6961e5d 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -87,6 +87,33 @@ active = FALSE UpdateButtonIcon() +/obj/item/book/granter/action/origami + granted_action = /datum/action/innate/origami + name = "The Art of Origami" + desc = "A meticulously in-depth manual explaining the art of paper folding." + icon_state = "origamibook" + actionname = "origami" + oneuse = TRUE + remarks = list("Dead-stick stability...", "Symmetry seems to play a rather large factor...", "Accounting for crosswinds... really?", "Drag coefficients of various paper types...", "Thrust to weight ratios?", "Positive dihedral angle?", "Center of gravity forward of the center of lift...") + +/datum/action/innate/origami + name = "Origami Folding" + desc = "Toggles your ability to fold and catch robust paper airplanes." + button_icon_state = "origami_off" + check_flags = NONE + +/datum/action/innate/origami/Activate() + to_chat(owner, "You will now fold origami planes.") + button_icon_state = "origami_on" + active = TRUE + UpdateButtonIcon() + +/datum/action/innate/origami/Deactivate() + to_chat(owner, "You will no longer fold origami planes.") + button_icon_state = "origami_off" + active = FALSE + UpdateButtonIcon() + ///SPELLS/// /obj/item/book/granter/spell @@ -252,12 +279,8 @@ /obj/item/book/granter/spell/barnyard/recoil(mob/living/carbon/user) if(ishuman(user)) to_chat(user,"HORSIE HAS RISEN") - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.item_flags |= NODROP //curses! - magichead.flags_inv &= ~HIDEFACE //so you can still see their face - magichead.voicechange = TRUE //NEEEEIIGHH - if(!user.dropItemToGround(user.wear_mask)) - qdel(user.wear_mask) + var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location()) + user.dropItemToGround(user.wear_mask, TRUE) user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE) qdel(src) else 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/his_grace.dm b/code/game/objects/items/his_grace.dm index 49a5cfaf35..6e977331a6 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -8,7 +8,7 @@ name = "artistic toolbox" desc = "A toolbox painted bright green. Looking at it makes you feel uneasy." icon_state = "his_grace" - item_state = "artistic_toolbox" + item_state = "toolbox_green" lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' icon = 'icons/obj/items_and_weapons.dmi' @@ -90,7 +90,7 @@ do_attack_animation(master, null, src) master.emote("scream") master.remove_status_effect(STATUS_EFFECT_HISGRACE) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) master.Knockdown(60) master.adjustBruteLoss(master.maxHealth) playsound(master, 'sound/effects/splat.ogg', 100, 0) @@ -198,20 +198,20 @@ update_stats() /obj/item/his_grace/proc/update_stats() - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) var/mob/living/master = get_atom_on_turf(src, /mob/living) switch(bloodthirst) if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) if(HIS_GRACE_CONSUME_OWNER > prev_bloodthirst) master.visible_message("[src] enters a frenzy!") if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) if(HIS_GRACE_STARVING > prev_bloodthirst) master.visible_message("[src] is starving!", "[src]'s bloodlust overcomes you. [src] must be fed, or you will become His meal.\ [force_bonus < 15 ? " And still, His power grows.":""]") force_bonus = max(force_bonus, 15) if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) if(HIS_GRACE_FAMISHED > prev_bloodthirst) master.visible_message("[src] is very hungry!", "Spines sink into your hand. [src] must feed immediately.\ [force_bonus < 10 ? " His power grows.":""]") diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 3fda98e074..0e8a9fef9e 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -58,7 +58,7 @@ item_state = "radio" /obj/item/holybeacon/attack_self(mob/user) - if(user.mind && (user.mind.isholy) && !SSreligion.holy_armor_type) + if(user.mind && (user.mind.isholy) && !GLOB.holy_armor_type) beacon_armor(user) else playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1) @@ -71,13 +71,13 @@ display_names += list(initial(A.name) = A) var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names - if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || SSreligion.holy_armor_type) + if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type) return var/index = display_names.Find(choice) var/A = holy_armor_list[index] - SSreligion.holy_armor_type = A + GLOB.holy_armor_type = A var/holy_armor_box = new A SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]") @@ -245,7 +245,7 @@ reskin_holy_weapon(user) /obj/item/nullrod/proc/reskin_holy_weapon(mob/M) - if(SSreligion.holy_weapon_type) + if(GLOB.holy_weapon_type) return var/obj/item/nullrod/holy_weapon var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( @@ -264,7 +264,7 @@ var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new holy_weapon = new A - SSreligion.holy_weapon_type = holy_weapon.type + GLOB.holy_weapon_type = holy_weapon.type SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[choice]") @@ -280,12 +280,19 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' name = "god hand" desc = "This hand of yours glows with an awesome power!" - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE hitsound = 'sound/weapons/sear.ogg' damtype = BURN attack_verb = list("punched", "cross countered", "pummeled") + +/obj/item/nullrod/godhand/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) + + + /obj/item/nullrod/staff icon_state = "godstaff-red" item_state = "godstaff-red" @@ -525,13 +532,14 @@ lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' w_class = WEIGHT_CLASS_HUGE - item_flags = NODROP | ABSTRACT + item_flags = ABSTRACT sharpness = IS_SHARP attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = 'sound/weapons/chainsawhit.ogg' /obj/item/nullrod/chainsaw/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 30, 100, 0, hitsound) /obj/item/nullrod/clown @@ -546,6 +554,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 @@ -553,7 +564,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) . = ..() @@ -573,6 +584,7 @@ lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' slot_flags = ITEM_SLOT_BELT + reach = 2 attack_verb = list("whipped", "lashed") hitsound = 'sound/weapons/chainhit.ogg' @@ -597,12 +609,13 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = ABSTRACT | NODROP + item_flags = ABSTRACT w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP /obj/item/nullrod/armblade/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) /obj/item/nullrod/armblade/tentacle diff --git a/code/game/objects/items/hot_potato.dm b/code/game/objects/items/hot_potato.dm index db7f38ddf3..e7b05d7a01 100644 --- a/code/game/objects/items/hot_potato.dm +++ b/code/game/objects/items/hot_potato.dm @@ -134,7 +134,7 @@ return update_icon() if(sticky) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HOT_POTATO_TRAIT) name = "primed [name]" activation_time = timer + world.time detonation_timerid = addtimer(CALLBACK(src, .proc/detonate), delay, TIMER_STOPPABLE) @@ -147,7 +147,7 @@ /obj/item/hot_potato/proc/deactivate() update_icon() name = initial(name) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HOT_POTATO_TRAIT) deltimer(detonation_timerid) STOP_PROCESSING(SSfastprocess, src) detonation_timerid = null 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 ed930ee480..b9907cbfca 100644 --- a/code/game/objects/items/implants/implant_mindshield.dm +++ b/code/game/objects/items/implants/implant_mindshield.dm @@ -20,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 @@ -38,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 @@ -55,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 6db3699beb..3a4295c61e 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -33,24 +33,8 @@ /obj/item/implant/adrenalin/activate() . = ..() uses-- + imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") to_chat(imp_in, "You feel a sudden surge of energy!") - imp_in.SetSleeping(0) - imp_in.SetStun(0) - imp_in.SetKnockdown(0) - imp_in.SetUnconscious(0) - imp_in.adjustStaminaLoss(-150) - imp_in.stuttering = 0 - imp_in.updatehealth() - imp_in.update_stamina() - imp_in.resting = 0 - imp_in.lying = 0 - imp_in.update_canmove() - - imp_in.reagents.add_reagent("inaprovaline", 3) //let's give another chance to dumb fucks who forget to breathe - 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/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..0d45960767 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -20,6 +20,7 @@ slot_flags = ITEM_SLOT_BELT force = 14 throwforce = 10 + reach = 2 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("flogged", "whipped", "lashed", "disciplined") hitsound = 'sound/weapons/chainhit.ogg' @@ -41,7 +42,7 @@ force = 20 throwforce = 10 hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + attack_verb = list("attacked", "impaled", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = IS_SHARP /obj/item/melee/synthetic_arm_blade/Initialize() @@ -91,8 +92,7 @@ /obj/item/melee/sabre/suicide_act(mob/living/user) user.visible_message("[user] is trying to cut off all [user.p_their()] limbs with [src]! it looks like [user.p_theyre()] trying to commit suicide!") var/i = 0 - var/originally_nodropped = item_flags & NODROP - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, SABRE_SUICIDE_TRAIT) if(iscarbon(user)) var/mob/living/carbon/Cuser = user var/obj/item/bodypart/holding_bodypart = Cuser.get_holding_bodypart_of_item(src) @@ -117,7 +117,7 @@ for(bodypart in limbs_to_dismember) i++ addtimer(CALLBACK(src, .proc/suicide_dismember, user, bodypart), speedbase * i) - addtimer(CALLBACK(src, .proc/manual_suicide, user, originally_nodropped), (5 SECONDS) * i) + addtimer(CALLBACK(src, .proc/manual_suicide, user), (5 SECONDS) * i) return MANUAL_SUICIDE /obj/item/melee/sabre/proc/suicide_dismember(mob/living/user, obj/item/bodypart/affecting) @@ -130,8 +130,29 @@ if(!QDELETED(user)) user.adjustBruteLoss(200) user.death(FALSE) - if(!originally_nodropped) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, SABRE_SUICIDE_TRAIT) + +/obj/item/melee/rapier + name = "plastitanium rapier" + desc = "A impossibly thin blade made of plastitanium with a tip made of diamond. It looks to be able to cut through any armor." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "rapier" + item_state = "rapier" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + force = 25 + throwforce = 35 + block_chance = 0 + armour_penetration = 100 + flags_1 = CONDUCT_1 + obj_flags = UNIQUE_RENAME + w_class = WEIGHT_CLASS_BULKY + sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_- + attack_verb = list("slashed", "cut", "pierces", "pokes") + +/obj/item/melee/rapier/Initialize() + . = ..() + AddComponent(/datum/component/butchering, 20, 65, 0) /obj/item/melee/classic_baton name = "police baton" @@ -156,7 +177,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 +304,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 +351,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/mop.dm b/code/game/objects/items/mop.dm index 44ccd7aad5..7524fc9007 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -15,7 +15,7 @@ var/mopping = 0 var/mopcount = 0 var/mopcap = 5 - var/stamusage = 5 + var/stamusage = 2 force_string = "robust... against germs" var/insertable = TRUE @@ -94,7 +94,7 @@ force = 6 throwforce = 8 throw_range = 4 - stamusage = 2 + stamusage = 1 var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water. var/refill_rate = 1 //Rate per process() tick mop refills itself var/refill_reagent = "water" //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 703de902b6..b5bb4fa233 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -16,6 +16,7 @@ var/obj/item/toy/plush/plush_child var/obj/item/toy/plush/paternal_parent //who initiated creation var/obj/item/toy/plush/maternal_parent //who owns, see love() + var/static/list/breeding_blacklist = typecacheof(/obj/item/toy/plush/carpplushie/dehy_carp) // you cannot have sexual relations with this plush var/list/scorned = list() //who the plush hates var/list/scorned_by = list() //who hates the plush, to remove external references on Destroy() var/heartbroken = FALSE @@ -203,9 +204,9 @@ else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop user.visible_message("[user] is going to break [Kisser] and [src] by bashing them like that.", "[Kisser] passionately embraces [src] in your hands. Look away you perv!") - plop(Kisser) - user.visible_message("Something drops at the feet of [user].", - "The miracle of oh god did that just come out of [src]?!") + if(plop(Kisser)) + user.visible_message("Something drops at the feet of [user].", + "The miracle of oh god did that just come out of [src]?!") //then comes protection, or abstinence if we are catholic else if(Kisser.partner == src && plush_child) @@ -271,7 +272,10 @@ /obj/item/toy/plush/proc/plop(obj/item/toy/plush/Daddy) if(partner != Daddy) - return //we do not have bastards in our toyshop + return FALSE //we do not have bastards in our toyshop + + if(is_type_in_typecache(Daddy, breeding_blacklist)) + return FALSE // some love is forbidden if(prob(50)) //it has my eyes plush_child = new type(get_turf(loc)) @@ -574,10 +578,6 @@ icon_state = "vulken" item_state = "vulken" -/obj/item/toy/plush/snakeplushie/jecca - icon_state = "jecca" - item_state = "jecca" - /obj/item/toy/plush/nukeplushie name = "operative plushie" desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious." @@ -591,26 +591,48 @@ 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." icon_state = "plushie_awake" item_state = "plushie_awake" +/obj/item/toy/plush/awakenedplushie/ComponentInitialize() + . = ..() + AddComponent(/datum/component/edit_complainer) + + +/obj/item/toy/plush/beeplushie + name = "bee plushie" + desc = "A cute toy that resembles an even cuter bee." + icon_state = "plushie_h" + item_state = "plushie_h" + attack_verb = list("stung") + gender = FEMALE + squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1) + /obj/item/toy/plush/mothplushie name = "insect plushie" desc = "An adorable stuffed toy that resembles some kind of insect" - icon_state = "cydia" - item_state = "cydia" - squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1) - -/obj/item/toy/plush/mothplushie/bumble icon_state = "bumble" item_state = "bumble" + squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1) /obj/item/toy/plush/mothplushie/nameko icon_state = "nameko" @@ -635,6 +657,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 +688,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 +763,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 +775,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 +786,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 +821,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 +870,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 +901,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." @@ -847,7 +914,3 @@ item_state = "fermis" attack_verb = list("cuddled", "petpatted", "wigglepurred") squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) - -/obj/item/toy/plush/awakenedplushie/ComponentInitialize() - . = ..() - AddComponent(/datum/component/edit_complainer) 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..15127c2e0e 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -20,7 +20,6 @@ attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time - /obj/item/shield/riot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/melee/baton)) if(cooldown < world.time - 25) @@ -91,7 +90,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 +152,32 @@ 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' + icon = 'icons/obj/items_and_weapons.dmi' + item_state = "metal" + icon_state = "makeshift_shield" + materials = list(MAT_METAL = 18000) + slot_flags = null + block_chance = 35 + force = 10 + throwforce = 7 + +/obj/item/shield/riot/tower + name = "tower shield" + desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking." + armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user + item_state = "metal" + icon_state = "metal" + icon = 'icons/obj/items_and_weapons.dmi' + block_chance = 75 //1/4 shots will hit* + force = 16 + slowdown = 2 + throwforce = 15 //Massive pice of metal + w_class = WEIGHT_CLASS_HUGE + item_flags = SLOWS_WHILE_IN_HAND 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/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index f9d4878fab..01351ab2e2 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -36,6 +36,7 @@ GLOBAL_LIST_INIT(human_recipes, list( \ GLOBAL_LIST_INIT(gondola_recipes, list ( \ new/datum/stack_recipe("gondola mask", /obj/item/clothing/mask/gondola, 1), \ new/datum/stack_recipe("gondola suit", /obj/item/clothing/under/gondola, 2), \ + new/datum/stack_recipe("gondola bedsheet", /obj/item/bedsheet/gondola, 1), \ )) /obj/item/stack/sheet/animalhide/gondola diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 89d939e505..e1ecf6d14d 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" @@ -386,8 +409,10 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ 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), \ - new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \ + null, + new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ null, @@ -399,6 +424,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ 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), \ + null, + new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/holyoil/null), \ )) @@ -416,7 +443,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE - grind_results = list("iron" = 5, "teslium" = 15) + grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1) merge_type = /obj/item/stack/tile/brass /obj/item/stack/tile/brass/narsie_act() diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 34ae4cb5ef..4217a58f81 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -396,7 +396,7 @@ //TODO bloody overlay /obj/item/stack/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) + if(istype(M) && M.dirty < 100) M.dirty += amount /* diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 1f1143e7ce..eb71311c96 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 */ @@ -244,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." @@ -447,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" @@ -464,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" @@ -472,7 +487,7 @@ item_state = "duffel-syndieammo" /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun - desc = "A large duffel bag, packed to the brim with Bulldog shotgun ammo." + desc = "A large duffel bag, packed to the brim with Bulldog shotgun drum magazines." /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun/PopulateContents() for(var/i in 1 to 6) @@ -482,14 +497,14 @@ new /obj/item/ammo_box/magazine/m12g/dragon(src) /obj/item/storage/backpack/duffelbag/syndie/ammo/smg - desc = "A large duffel bag, packed to the brim with C20r magazines." + desc = "A large duffel bag, packed to the brim with C-20r magazines." /obj/item/storage/backpack/duffelbag/syndie/ammo/smg/PopulateContents() for(var/i in 1 to 9) new /obj/item/ammo_box/magazine/smgm45(src) /obj/item/storage/backpack/duffelbag/syndie/c20rbundle - desc = "A large duffel bag containing a C20r, some magazines, and a cheap looking suppressor." + desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor." /obj/item/storage/backpack/duffelbag/syndie/c20rbundle/PopulateContents() new /obj/item/ammo_box/magazine/smgm45(src) @@ -498,7 +513,7 @@ new /obj/item/suppressor/specialoffer(src) /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle - desc = "A large duffel bag containing a Bulldog, several drums, and a collapsed hardsuit." + desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses." /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle/PopulateContents() new /obj/item/ammo_box/magazine/m12g(src) @@ -507,16 +522,7 @@ new /obj/item/clothing/glasses/thermal/syndi(src) /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots." - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() - new /obj/item/clothing/shoes/magboots/syndie(src) - new /obj/item/storage/firstaid/tactical(src) - new /obj/item/gun/ballistic/automatic/l6_saw/toy(src) - new /obj/item/ammo_box/foambox/riot(src) - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots." + desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun, a big jumbo box of riot darts, and a knock-off pair of magboots." /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() new /obj/item/clothing/shoes/magboots/syndie(src) @@ -525,7 +531,7 @@ new /obj/item/ammo_box/foambox/riot(src) /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle - desc = "A large duffel bag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes." + desc = "A large duffel bag containing deadly chemicals, a handheld chem sprayer, Bioterror foam grenade, a Donksoft assault rifle, box of riot grade darts, a dart pistol, and a box of syringes." /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle/PopulateContents() new /obj/item/reagent_containers/spray/chemsprayer/bioterror(src) @@ -547,7 +553,7 @@ new /obj/item/grenade/plastic/x4(src) /obj/item/storage/backpack/duffelbag/syndie/firestarter - desc = "A large duffel bag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment." + desc = "A large duffel bag containing a New Russian pyro backpack sprayer, Elite hardsuit, a Stechkin APS pistol, minibomb, ammo, and other equipment." /obj/item/storage/backpack/duffelbag/syndie/firestarter/PopulateContents() new /obj/item/clothing/under/syndicate/soviet(src) @@ -574,3 +580,16 @@ new /obj/item/clothing/mask/gas/clown_hat(src) new /obj/item/bikehorn(src) new /obj/item/implanter/sad_trombone(src) + +obj/item/storage/backpack/duffelbag/syndie/shredderbundle + desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." + +/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/storage/belt/military(src) + new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 57c77e5983..e3494e36cf 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -541,6 +541,25 @@ /obj/item/ammo_casing/shotgun )) +/obj/item/storage/belt/medolier + name = "medolier" + desc = "A medical bandolier for holding smartdarts." + icon_state = "medolier" + item_state = "medolier" + +/obj/item/storage/belt/medolier/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 15 + STR.display_numerical_stacking = FALSE + STR.can_hold = typecacheof(list( + /obj/item/reagent_containers/syringe/dart + )) + +/obj/item/storage/belt/medolier/full/PopulateContents() + for(var/i in 1 to 16) + new /obj/item/reagent_containers/syringe/dart/(src) + /obj/item/storage/belt/holster name = "shoulder holster" desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." @@ -557,6 +576,8 @@ /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/ammo_box, + /obj/item/toy/gun, + /obj/item/gun/energy/e_gun/mini )) /obj/item/storage/belt/holster/full/PopulateContents() @@ -643,6 +664,32 @@ /obj/item/melee/sabre )) +/obj/item/storage/belt/sabre/rapier + name = "rapier sheath" + desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal." + icon_state = "rsheath" + item_state = "rsheath" + force = 5 + throwforce = 15 + block_chance = 30 + w_class = WEIGHT_CLASS_BULKY + attack_verb = list("bashed", "slashes", "prods", "pokes") + +/obj/item/storage/belt/sabre/rapier/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/melee/rapier + )) + +/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(attack_type == PROJECTILE_ATTACK) + final_block_chance = 0 //To thin to block bullets + return ..() + /obj/item/storage/belt/sabre/examine(mob/user) ..() if(length(contents)) @@ -660,8 +707,8 @@ to_chat(user, "[src] is empty.") /obj/item/storage/belt/sabre/update_icon() - icon_state = "sheath" - item_state = "sheath" + icon_state = initial(icon_state) + item_state = initial(item_state) if(contents.len) icon_state += "-sabre" item_state += "-sabre" @@ -673,3 +720,7 @@ /obj/item/storage/belt/sabre/PopulateContents() new /obj/item/melee/sabre(src) update_icon() + +/obj/item/storage/belt/sabre/rapier/PopulateContents() + new /obj/item/melee/rapier(src) + update_icon() diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index b95d6a897e..df7b203f91 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(!istype(H)) return // If H is the Chaplain, we can set the icon_state of the bible (but only once!) - if(!SSreligion.bible_icon_state && H.job == "Chaplain") + if(!GLOB.bible_icon_state && H.job == "Chaplain") var/dat = "Pick Bible Style

    Pick a bible style

    " for(var/i in 1 to GLOB.biblestates.len) var/icon/bibleicon = icon('icons/obj/storage.dmi', GLOB.biblestates[i]) @@ -64,7 +64,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", /obj/item/storage/book/bible/Topic(href, href_list) if(!usr.canUseTopic(src)) return - if(href_list["seticon"] && SSreligion && !SSreligion.bible_icon_state) + if(href_list["seticon"] && GLOB && !GLOB.bible_icon_state) var/iconi = text2num(href_list["seticon"]) var/biblename = GLOB.biblenames[iconi] var/obj/item/storage/book/bible/B = locate(href_list["src"]) @@ -74,10 +74,11 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(B.icon_state == "honk1" || B.icon_state == "honk2") var/mob/living/carbon/human/H = usr H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK) - SSreligion.bible_icon_state = B.icon_state - SSreligion.bible_item_state = B.item_state + GLOB.bible_icon_state = B.icon_state + GLOB.bible_item_state = B.item_state SSblackbox.record_feedback("text", "religion_book", 1, "[biblename]") usr << browse(null, "window=editicon") @@ -89,7 +90,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", to_chat(user, "[src.deity_name] refuses to heal this metallic taint!") return 0 - var/heal_amt = 10 + var/heal_amt = 5 var/list/hurt_limbs = H.get_damaged_bodyparts(1, 1) if(hurt_limbs.len) @@ -109,7 +110,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) @@ -138,8 +139,8 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", smack = 0 else if(iscarbon(M)) var/mob/living/carbon/C = M - if(!istype(C.head, /obj/item/clothing/head/helmet)) - C.adjustBrainLoss(5, 60) + if(!istype(C.head, /obj/item/clothing/head)) + C.adjustBrainLoss(10, 80) to_chat(C, "You feel dumber.") if(smack) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index c8e96d0b28..4ff63ceeac 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." @@ -702,7 +722,7 @@ new /obj/item/ammo_casing/shotgun/rubbershot(src) /obj/item/storage/box/lethalshot - name = "box of lethal shotgun shots" + name = "box of buckshot (Lethal)" desc = "A box full of lethal shots, designed for riot shotguns." icon_state = "lethalshot_box" illustration = null @@ -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/ammo_casing/shotgun(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/ammo_casing/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 incendiary ammo." + icon_state = "fireshot_box" + illustration = null + +/obj/item/storage/box/fireshot/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,102 @@ 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 + +/obj/item/storage/box/mre //base MRE type. + name = "Nanotrasen MRE Ration Kit Menu 0" + desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning." + icon_state = "mre" + var/can_expire = TRUE + var/spawner_chance = 2 + var/expiration_date + var/expiration_date_min = 2300 + var/expiration_date_max = 2700 + +/obj/item/storage/box/mre/Initialize() + . = ..() + if(can_expire) + expiration_date = rand(expiration_date_min, expiration_date_max) + desc += "\nAn expiry date is listed on it. It reads: [expiration_date]" + var/spess_current_year = GLOB.year_integer + 540 + if(expiration_date < spess_current_year) + var/gross_risk = min(round(spess_current_year - expiration_date * 0.1), 1) + var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1) + for(var/obj/item/reagent_containers/food/snacks/S in contents) + if(prob(gross_risk)) + ENABLE_BITFIELD(S.foodtype, GROSS) + if(prob(toxic_risk)) + ENABLE_BITFIELD(S.foodtype, TOXIC) + +/obj/item/storage/box/mre/menu1 + name = "\improper Nanotrasen MRE Ration Kit Menu 1" + +/obj/item/storage/box/mre/menu1/safe + desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time." + spawner_chance = 0 + can_expire = FALSE + +/obj/item/storage/box/mre/menu1/PopulateContents() + new /obj/item/reagent_containers/food/snacks/breadslice/plain(src) + new /obj/item/reagent_containers/food/snacks/breadslice/creamcheese(src) + new /obj/item/reagent_containers/food/condiment/pack/ketchup(src) + new /obj/item/reagent_containers/food/snacks/chocolatebar(src) + new /obj/item/tank/internals/emergency_oxygen(src) + +/obj/item/storage/box/mre/menu2 + name = "\improper Nanotrasen MRE Ration Kit Menu 2" + +/obj/item/storage/box/mre/menu2/safe + spawner_chance = 0 + desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time." + can_expire = FALSE + +/obj/item/storage/box/mre/menu2/PopulateContents() + new /obj/item/reagent_containers/food/snacks/omelette(src) + new /obj/item/reagent_containers/food/snacks/meat/cutlet/plain(src) + new /obj/item/reagent_containers/food/snacks/fries(src) + new /obj/item/reagent_containers/food/snacks/chocolatebar(src) + new /obj/item/tank/internals/emergency_oxygen(src) + +/obj/item/storage/box/mre/menu3 + name = "\improper Nanotrasen MRE Ration Kit Menu 3" + desc = "The holy grail of MREs. This item contains the fabled MRE pizza and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed." + icon_state = "menu3" + can_expire = FALSE //always fresh, never expired. + spawner_chance = 1 + +/obj/item/storage/box/mre/menu3/PopulateContents() + new /obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni(src) + new /obj/item/reagent_containers/food/snacks/breadslice/plain(src) + new /obj/item/reagent_containers/food/snacks/cheesewedge(src) + new /obj/item/reagent_containers/food/snacks/grown/chili(src) + new /obj/item/reagent_containers/food/drinks/coffee/type2(src) + new /obj/item/tank/internals/emergency_oxygen(src) diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index f4f386b7d0..bca13f2a45 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -38,9 +38,10 @@ /obj/item/storage/briefcase/lawyer folder_path = /obj/item/folder/blue -/obj/item/storage/briefcase/lawyer/family +/obj/item/storage/briefcase/lawyer/family name = "battered briefcase" - desc = "An old briefcase, this one has seen better days in its time. It's clear they don't make them nowadays as good as they used to. The corners are modified with metal trim adding in weight!" + desc = "An old briefcase, this one has seen better days in its time. It's clear they don't make them nowadays as good as they used to. Comes with an added belt clip!" + slot_flags = ITEM_SLOT_BELT /obj/item/storage/briefcase/lawyer/family/PopulateContents() new /obj/item/stamp/law(src) @@ -67,9 +68,8 @@ ..() /obj/item/storage/briefcase/sniperbundle - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding. Smells like L'Air du Temps." + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." force = 10 - /obj/item/storage/briefcase/sniperbundle/PopulateContents() ..() // in case you need any paperwork done after your rampage new /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate(src) @@ -79,3 +79,28 @@ new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/briefcase/modularbundle + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding." + force = 10 + +/obj/item/storage/briefcase/modularbundle/PopulateContents() + new /obj/item/gun/ballistic/automatic/pistol/modular(src) + new /obj/item/suppressor(src) + new /obj/item/ammo_box/magazine/m10mm(src) + new /obj/item/ammo_box/magazine/m10mm/soporific(src) + new /obj/item/ammo_box/c10mm/soporific(src) + new /obj/item/clothing/under/lawyer/blacksuit(src) + new /obj/item/clothing/accessory/waistcoat(src) + new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src) + +/obj/item/storage/briefcase/medical + name = "medical briefcase" + icon_state = "medbriefcase" + desc = "A white with a blue cross brieface, this is ment to hold medical gear that would not be able to normally fit in a bag." + +/obj/item/storage/briefcase/medical/PopulateContents() + new /obj/item/clothing/neck/stethoscope(src) + new /obj/item/healthanalyzer(src) + ..() //In case of paperwork + diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 1a666ce921..e9b074d40c 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -320,3 +320,46 @@ /obj/item/storage/pill_bottle/penis_enlargement/PopulateContents() for(var/i in 1 to 7) new /obj/item/reagent_containers/pill/penis_enlargement(src) + +///////////// +//Organ Box// +///////////// + +/obj/item/storage/belt/organbox + name = "Organ Storge" + desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying" + w_class = WEIGHT_CLASS_BULKY + icon = 'icons/obj/mysterybox.dmi' + icon_state = "organbox_open" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 1 + throw_range = 1 + +/obj/item/storage/belt/organbox/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 16 + STR.max_w_class = WEIGHT_CLASS_BULKY + STR.max_combined_w_class = 20 + STR.can_hold = typecacheof(list( + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/hypospray, + /obj/item/healthanalyzer, + /obj/item/reagent_containers/syringe, + /obj/item/clothing/glasses/hud/health, + /obj/item/hemostat, + /obj/item/scalpel, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/surgical_drapes, + /obj/item/autosurgeon, + /obj/item/organ, + /obj/item/implant, + /obj/item/implantpad, + /obj/item/implantcase, + /obj/item/implanter, + /obj/item/circuitboard/computer/operating, + /obj/item/stack/sheet/mineral/silver, + /obj/item/organ_storage + )) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 9b8d2b4a21..5b99bb85bf 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(rubber_toolbox_icons) + /obj/item/storage/toolbox name = "toolbox" desc = "Danger. Very robust." @@ -16,21 +18,25 @@ hitsound = 'sound/weapons/smash.ogg' var/latches = "single_latch" var/has_latches = TRUE + var/can_rubberify = TRUE -/obj/item/storage/toolbox/Initialize() +/obj/item/storage/toolbox/Initialize(mapload) . = ..() if(has_latches) if(prob(10)) latches = "double_latch" if(prob(1)) latches = "triple_latch" + if(mapload && can_rubberify && prob(5)) + rubberify() update_icon() /obj/item/storage/toolbox/update_icon() ..() cut_overlays() if(has_latches) - add_overlay(latches) + var/icon/I = icon('icons/obj/storage.dmi', latches) + add_overlay(I) /obj/item/storage/toolbox/suicide_act(mob/user) @@ -39,8 +45,6 @@ /obj/item/storage/toolbox/emergency name = "emergency toolbox" - icon_state = "red" - item_state = "toolbox_red" /obj/item/storage/toolbox/emergency/PopulateContents() new /obj/item/crowbar/red(src) @@ -59,6 +63,7 @@ name = "rusty red toolbox" icon_state = "toolbox_red_old" has_latches = FALSE + can_rubberify = FALSE /obj/item/storage/toolbox/mechanical name = "mechanical toolbox" @@ -77,6 +82,7 @@ name = "rusty blue toolbox" icon_state = "toolbox_blue_old" has_latches = FALSE + can_rubberify = FALSE /obj/item/storage/toolbox/mechanical/old/heirloom name = "old, robust toolbox" //this will be named "X family toolbox" @@ -151,6 +157,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF w_class = WEIGHT_CLASS_HUGE attack_verb = list("robusted", "crushed", "smashed") + can_rubberify = FALSE var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab /obj/item/storage/toolbox/brass/ComponentInitialize() @@ -183,12 +190,29 @@ slab_type = /obj/item/clockwork/slab/debug fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug +/obj/item/storage/toolbox/plastitanium + name = "plastitanium toolbox" + desc = "A toolbox made out of plastitanium. Probably packs a massive punch." + total_mass = 5 + icon_state = "blue" + item_state = "toolbox_blue" + w_class = WEIGHT_CLASS_HUGE //heyo no bohing this! + force = 18 //spear damage + can_rubberify = FALSE + +/obj/item/storage/toolbox/plastitanium/afterattack(atom/A, mob/user, proximity) + . = ..() + if(proximity && isobj(A) && !isitem(A)) + var/obj/O = A + //50 total object damage but split up for stuff like damage deflection. + O.take_damage(22) + O.take_damage(10) /obj/item/storage/toolbox/artistic name = "artistic toolbox" desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." icon_state = "green" - item_state = "artistic_toolbox" + item_state = "toolbox_green" w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! /obj/item/storage/toolbox/artistic/ComponentInitialize() @@ -237,9 +261,55 @@ /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!" + desc = "A gold plated toolbox, fancy and harmless due to the gold plating being on cardboard!" icon_state = "gold" item_state = "gold" has_latches = FALSE force = 0 throwforce = 0 + can_rubberify = FALSE + +/obj/item/storage/toolbox/proc/rubberify() + name = "rubber [name]" + desc = replacetext(desc, "Danger", "Bouncy") + desc = replacetext(desc, "robust", "safe") + desc = replacetext(desc, "heavier", "bouncier") + DISABLE_BITFIELD(flags_1, CONDUCT_1) + materials = null + damtype = STAMINA + force += 3 //to compensate the higher stamina K.O. threshold compared to actual health. + throwforce += 3 + attack_verb += "bounced" + hitsound = 'sound/effects/clownstep1.ogg' + if(!GLOB.rubber_toolbox_icons[icon_state]) + generate_rubber_toolbox_icon() + icon = GLOB.rubber_toolbox_icons[icon_state] + AddComponent(/datum/component/bouncy) + . = ..() + +/obj/item/storage/toolbox/proc/generate_rubber_toolbox_icon() + var/icon/new_icon = icon(icon, icon_state) + var/icon/smooth = icon('icons/obj/storage.dmi', "rubber_toolbox_blend") + new_icon.Blend(smooth, ICON_MULTIPLY) + new_icon = fcopy_rsc(new_icon) + GLOB.rubber_toolbox_icons[icon_state] = new_icon + +/obj/item/storage/toolbox/rubber + name = "rubber toolbox" + desc = "Bouncy. Very safe." + flags_1 = null + materials = null + damtype = STAMINA + force = 17 + throwforce = 17 + attack_verb = list("robusted", "bounced") + can_rubberify = FALSE //we are already the future. + +/obj/item/storage/toolbox/rubber/Initialize() + icon_state = pick("blue", "red", "yellow", "green") + item_state = "toolbox_[icon_state]" + if(!GLOB.rubber_toolbox_icons[icon_state]) + generate_rubber_toolbox_icon() + icon = GLOB.rubber_toolbox_icons[icon_state] + . = ..() + AddComponent(/datum/component/bouncy) \ No newline at end of file diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 69c8f7aee9..a6a3cea373 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -2,7 +2,7 @@ /obj/item/storage/box/syndicate/PopulateContents() switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1))) - if("bloodyspai") // 27 tc now this is more right + if("bloodyspai") // 30 tc now this is more right new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set new /obj/item/clothing/mask/chameleon(src) // Goes with above new /obj/item/card/id/syndicate(src) // 2 tc @@ -11,7 +11,7 @@ new /obj/item/multitool/ai_detect(src) // 1 tc new /obj/item/encryptionkey/syndicate(src) // 2 tc new /obj/item/reagent_containers/syringe/mulligan(src) // 4 tc - new /obj/item/switchblade(src) //I'll count this as 2 tc + new /obj/item/switchblade(src) //I'll count this as 5 tc new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals new /obj/item/flashlight/emp(src) // 2 tc new /obj/item/chameleon(src) // 7 tc @@ -25,13 +25,13 @@ new /obj/item/clothing/glasses/thermal/syndi(src) if("bond") // 29 tc - new /obj/item/gun/ballistic/automatic/pistol(src) - new /obj/item/suppressor(src) + new /obj/item/gun/ballistic/automatic/pistol/suppressed(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/clothing/under/chameleon(src) new /obj/item/card/id/syndicate(src) new /obj/item/reagent_containers/syringe/stimulants(src) + new /obj/item/clothing/neck/tie/red(src) if("screwed") // 29 tc new /obj/item/sbeacondrop/bomb(src) @@ -41,7 +41,7 @@ new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) new /obj/item/encryptionkey/syndicate(src) - if("guns") // 28 tc now + if("guns") // 30 tc now new /obj/item/gun/ballistic/revolver(src) new /obj/item/ammo_box/a357(src) new /obj/item/ammo_box/a357(src) @@ -50,39 +50,53 @@ new /obj/item/clothing/gloves/color/latex/nitrile(src) new /obj/item/clothing/mask/gas/clown_hat(src) new /obj/item/clothing/under/suit_jacket/really_black(src) + new /obj/item/screwdriver/power(src) //2 tc item - if("murder") // 28 tc now + if("murder") // 35 tc now new /obj/item/melee/transforming/energy/sword/saber(src) new /obj/item/clothing/glasses/thermal/syndi(src) new /obj/item/card/emag(src) new /obj/item/clothing/shoes/chameleon/noslip(src) new /obj/item/encryptionkey/syndicate(src) new /obj/item/grenade/syndieminibomb(src) + new /obj/item/clothing/glasses/phantomthief/syndicate(src) + new /obj/item/reagent_containers/syringe/stimulants(src) - if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? + if("implant") // 67+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? new /obj/item/implanter/freedom(src) new /obj/item/implanter/uplink/precharged(src) new /obj/item/implanter/emp(src) new /obj/item/implanter/adrenalin(src) new /obj/item/implanter/explosive(src) new /obj/item/implanter/storage(src) + new /obj/item/implanter/radio/syndicate(src) + new /obj/item/implanter/stealth(src) - if("hacker") // 26 tc + if("hacker") // 30 tc new /obj/item/aiModule/syndicate(src) new /obj/item/card/emag(src) new /obj/item/encryptionkey/binary(src) new /obj/item/aiModule/toyAI(src) new /obj/item/multitool/ai_detect(src) + new /obj/item/flashlight/emp(src) + new /obj/item/emagrecharge(src) - if("lordsingulo") // 24 tc - new /obj/item/sbeacondrop(src) - new /obj/item/clothing/suit/space/syndicate/black/red(src) - new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) - new /obj/item/card/emag(src) + if("lordsingulo") // "36" tc aka 23 tc + new /obj/item/sbeacondrop(src) // 14 kinda useless + new /obj/item/clothing/suit/space/syndicate/black/red(src) //2 + new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) //2 + new /obj/item/card/emag(src) //6 + new /obj/item/emagrecharge(src) //2 + new /obj/item/storage/toolbox/syndicate(src) //1 + new /obj/item/card/id/syndicate(src) //2 + new /obj/item/flashlight/emp(src) //2 + new /obj/item/jammer(src) //5 - if("sabotage") // 26 tc now + if("sabotage") // ~28 tc now new /obj/item/grenade/plastic/c4 (src) new /obj/item/grenade/plastic/c4 (src) + new /obj/item/grenade/plastic/x4 (src) + new /obj/item/grenade/plastic/x4 (src) new /obj/item/doorCharge(src) new /obj/item/doorCharge(src) new /obj/item/camera_bug(src) @@ -117,15 +131,15 @@ new /obj/item/grenade/plastic/c4 (src) // 1 tc new /obj/item/card/emag(src) // 6 tc - if("ninja") // 33 tc worth - new /obj/item/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc? + if("ninja") // 40~ tc worth + new /obj/item/katana(src) // Unique , basicly a better esword. 10 tc? new /obj/item/implanter/adrenalin(src) // 8 tc new /obj/item/throwing_star(src) // ~5 tc for all 6 new /obj/item/throwing_star(src) new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) + new /obj/item/implanter/emp(src) + new /obj/item/grenade/smokebomb(src) + new /obj/item/grenade/smokebomb(src) new /obj/item/storage/belt/chameleon(src) // Unique but worth at least 2 tc new /obj/item/card/id/syndicate(src) // 2 tc new /obj/item/chameleon(src) // 7 tc diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index c0e81a7949..bfe630ba01 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,14 +15,17 @@ 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 var/preload_cell_type //if not empty the baton starts with this type of cell /obj/item/melee/baton/get_cell() - return cell + . = cell + if(iscyborg(loc)) + var/mob/living/silicon/robot/R = loc + . = R.get_cell() /obj/item/melee/baton/suicide_act(mob/user) user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!") @@ -44,17 +49,34 @@ /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, explode = TRUE) + var/obj/item/stock_parts/cell/copper_top = get_cell() + if(!copper_top) + switch_status(FALSE, TRUE) + return FALSE + //Note this value returned is significant, as it will determine + //if a stun is applied or not + copper_top.use(min(chrgdeductamt, copper_top.charge), explode) + if(QDELETED(src)) + return FALSE + if(status && (!copper_top || !copper_top.charge || (chargecheck && copper_top.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, FALSE) /obj/item/melee/baton/update_icon() if(status) @@ -65,9 +87,10 @@ icon_state = "[initial(name)]" /obj/item/melee/baton/examine(mob/user) - ..() - if(cell) - to_chat(user, "\The [src] is [round(cell.percent())]% charged.") + . = ..() + var/obj/item/stock_parts/cell/copper_top = get_cell() + if(copper_top) + to_chat(user, "\The [src] is [round(copper_top.percent())]% charged.") else to_chat(user, "\The [src] does not have a power source installed.") @@ -77,7 +100,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 +115,26 @@ 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 - to_chat(user, "[src] is now [status ? "on" : "off"].") - playsound(loc, "sparks", 75, 1, -1) - else - status = 0 - if(!cell) + var/obj/item/stock_parts/cell/copper_top = get_cell() + if(!copper_top || copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY)) + switch_status(FALSE, TRUE) + if(!copper_top) to_chat(user, "[src] does not have a power source!") else to_chat(user, "[src] is out of charge.") - update_icon() + else + switch_status(!status) + to_chat(user, "[src] is now [status ? "on" : "off"].") 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 +171,26 @@ 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 - if(iscyborg(loc)) - var/mob/living/silicon/robot/R = loc - if(!R || !R.cell || !R.cell.use(hitcost)) - return 0 - else - if(!deductcharge(hitcost)) - return 0 + return FALSE + var/stunpwr = stunforce + var/obj/item/stock_parts/cell/our_cell = get_cell() + if(!our_cell) + switch_status(FALSE) + return FALSE + var/stuncharge = our_cell.charge + deductcharge(hitcost, FALSE) + if(QDELETED(src) || QDELETED(our_cell)) //it was rigged + return FALSE + if(stuncharge < hitcost) + if(stuncharge < (hitcost * STUNBATON_CHARGE_LENIENCY)) + L.visible_message("[user] has prodded [L] with [src]. Luckily it was out of charge.", \ + "[user] has prodded you with [src]. Luckily it was out of charge.") + return FALSE + stunpwr *= round(stuncharge/hitcost, 0.1) - 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,12 +207,22 @@ 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]!") + SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) + user.Knockdown(stunforce*3) + playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + deductcharge(hitcost) /obj/item/melee/baton/emp_act(severity) . = ..() if (!(. & EMP_PROTECT_SELF)) - deductcharge(1000 / severity) + switch_status(FALSE) + if(!iscyborg(loc)) + deductcharge(1000 / severity, TRUE, FALSE) //Makeshift stun baton. Replacement for stun gloves. /obj/item/melee/baton/cattleprod @@ -202,12 +239,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..b672eb01ca 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -1,242 +1,244 @@ -/obj/item/tank/jetpack - name = "jetpack (empty)" - desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - distribute_pressure = ONE_ATMOSPHERE * O2STANDARD - actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - var/gas_type = /datum/gas/oxygen - var/on = FALSE - var/stabilizers = FALSE - var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not - var/datum/effect_system/trail_follow/ion/ion_trail - -/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) - - ion_trail = new - ion_trail.set_up(src) - -/obj/item/tank/jetpack/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_jetpack)) - cycle(user) - else if(istype(action, /datum/action/item_action/jetpack_stabilization)) - if(on) - stabilizers = !stabilizers - to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") - else - toggle_internals(user) - - -/obj/item/tank/jetpack/proc/cycle(mob/user) - if(user.incapacitated()) - return - - if(!on) - turn_on() - to_chat(user, "You turn the jetpack on.") - else - turn_off() - to_chat(user, "You turn the jetpack off.") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - -/obj/item/tank/jetpack/proc/turn_on() - on = TRUE - icon_state = "[initial(icon_state)]-on" - ion_trail.start() - -/obj/item/tank/jetpack/proc/turn_off() - on = FALSE - stabilizers = FALSE - icon_state = initial(icon_state) - ion_trail.stop() - -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!on) - return - if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() - return - - var/datum/gas_mixture/removed = air_contents.remove(num) - if(removed.total_moles() < 0.005) - turn_off() - return - - var/turf/T = get_turf(user) - T.assume_air(removed) - - return 1 - -/obj/item/tank/jetpack/suicide_act(mob/user) - if (istype(user, /mob/living/carbon/human/)) - var/mob/living/carbon/human/H = user - H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") - H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") - return (OXYLOSS) - else - ..() - -/obj/item/tank/jetpack/improvised - name = "improvised jetpack" - 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 - gas_type = null //it starts empty - full_speed = FALSE //moves at hardsuit jetpack speeds - -/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user) - if(!on) - return - if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() - return - if(rand(0,250) == 0) - to_chat(user, "You feel your jetpack's engines cut out.") - turn_off() - return - - var/datum/gas_mixture/removed = air_contents.remove(num) - if(removed.total_moles() < 0.005) - turn_off() - return - - var/turf/T = get_turf(user) - T.assume_air(removed) - - return 1 - -/obj/item/tank/jetpack/void - name = "void jetpack (oxygen)" - desc = "It works well in a void." - icon_state = "jetpack-void" - item_state = "jetpack-void" - -/obj/item/tank/jetpack/oxygen - name = "jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - -/obj/item/tank/jetpack/oxygen/harness - name = "jet harness (oxygen)" - 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 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/tank/jetpack/oxygen/captain - name = "\improper Captain's jetpack" - desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." - icon_state = "jetpack-captain" - item_state = "jetpack-captain" - w_class = WEIGHT_CLASS_NORMAL - volume = 90 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. - -/obj/item/tank/jetpack/oxygen/security - name = "security jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." - 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." - icon_state = "jetpack-black" - item_state = "jetpack-black" - 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." - icon_state = "jetpack-mining" - item_state = "jetpack-black" - w_class = WEIGHT_CLASS_NORMAL - actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - volume = 1 - slot_flags = null - gas_type = null - full_speed = FALSE - var/datum/gas_mixture/temp_air_contents - var/obj/item/tank/internals/tank = null - -/obj/item/tank/jetpack/suit/New() - ..() - STOP_PROCESSING(SSobj, src) - temp_air_contents = air_contents - -/obj/item/tank/jetpack/suit/attack_self() - return - -/obj/item/tank/jetpack/suit/cycle(mob/user) - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) - to_chat(user, "\The [src] must be connected to a hardsuit!") - return - - var/mob/living/carbon/human/H = user - if(!istype(H.s_store, /obj/item/tank/internals)) - to_chat(user, "You need a tank in your suit storage!") - return - ..() - -/obj/item/tank/jetpack/suit/turn_on() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - return - var/mob/living/carbon/human/H = loc.loc - tank = H.s_store - air_contents = tank.air_contents - START_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/turn_off() - tank = null - air_contents = temp_air_contents - STOP_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/process() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - turn_off() - return - var/mob/living/carbon/human/H = loc.loc - if(!tank || tank != H.s_store) - turn_off() - 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 - -/mob/proc/get_jetpack() - return - -/mob/living/carbon/get_jetpack() - var/obj/item/tank/jetpack/J = back - if(istype(J)) - return J - -/mob/living/carbon/human/get_jetpack() - var/obj/item/tank/jetpack/J = ..() - if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) - var/obj/item/clothing/suit/space/hardsuit/C = wear_suit - J = C.jetpack - return J +/obj/item/tank/jetpack + name = "jetpack (empty)" + desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' + w_class = WEIGHT_CLASS_BULKY + distribute_pressure = ONE_ATMOSPHERE * O2STANDARD + actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + var/gas_type = /datum/gas/oxygen + var/on = FALSE + var/stabilizers = FALSE + var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not + var/datum/effect_system/trail_follow/ion/ion_trail + +/obj/item/tank/jetpack/New() + ..() + if(gas_type) + air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + + ion_trail = new + ion_trail.set_up(src) + +/obj/item/tank/jetpack/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_jetpack)) + cycle(user) + else if(istype(action, /datum/action/item_action/jetpack_stabilization)) + if(on) + stabilizers = !stabilizers + to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") + else + toggle_internals(user) + +/obj/item/tank/jetpack/proc/cycle(mob/user) + if(user.incapacitated()) + return + + if(!on) + turn_on() + to_chat(user, "You turn the jetpack on.") + else + turn_off() + to_chat(user, "You turn the jetpack off.") + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/tank/jetpack/proc/turn_on() + on = TRUE + icon_state = "[initial(icon_state)]-on" + ion_trail.start() + +/obj/item/tank/jetpack/proc/turn_off() + on = FALSE + stabilizers = FALSE + icon_state = initial(icon_state) + ion_trail.stop() + +/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return + + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return + + var/turf/T = get_turf(user) + T.assume_air(removed) + + return 1 + +/obj/item/tank/jetpack/suicide_act(mob/user) + if (istype(user, /mob/living/carbon/human/)) + var/mob/living/carbon/human/H = user + H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") + H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") + return (OXYLOSS) + else + ..() + +/obj/item/tank/jetpack/improvised + name = "improvised jetpack" + 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 = 30 //normal jetpacks have 70 volume + gas_type = null //it starts empty + full_speed = FALSE //moves at hardsuit jetpack speeds + +/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user) + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return + if(rand(0,250) == 0) + to_chat(user, "You feel your jetpack's engines cut out.") + turn_off() + return + + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return + + var/turf/T = get_turf(user) + T.assume_air(removed) + + return 1 + +/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)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + +/obj/item/tank/jetpack/oxygen/harness + name = "jet harness (oxygen)" + 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 = 50 + throw_range = 7 + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/tank/jetpack/oxygen/captain + name = "\improper Captain's jetpack" + desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." + icon_state = "jetpack-captain" + item_state = "jetpack-captain" + w_class = WEIGHT_CLASS_NORMAL + volume = 90 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. + +/obj/item/tank/jetpack/oxygen/security + name = "security jetpack (oxygen)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." + icon_state = "jetpack-sec" + item_state = "jetpack-sec" + full_speed = FALSE + +/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." + icon_state = "jetpack-black" + item_state = "jetpack-black" + distribute_pressure = 0 + gas_type = /datum/gas/carbon_dioxide + +/obj/item/tank/jetpack/carbondioxide/eva + name = "surplus 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. Rated for less than stellar EVA speeds!" + full_speed = FALSE + +/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." + icon_state = "jetpack-mining" + item_state = "jetpack-black" + w_class = WEIGHT_CLASS_NORMAL + actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + volume = 1 + slot_flags = null + gas_type = null + full_speed = FALSE + var/datum/gas_mixture/temp_air_contents + var/obj/item/tank/internals/tank = null + +/obj/item/tank/jetpack/suit/New() + ..() + STOP_PROCESSING(SSobj, src) + temp_air_contents = air_contents + +/obj/item/tank/jetpack/suit/attack_self() + return + +/obj/item/tank/jetpack/suit/cycle(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) + to_chat(user, "\The [src] must be connected to a hardsuit!") + return + + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/tank/internals)) + to_chat(user, "You need a tank in your suit storage!") + return + ..() + +/obj/item/tank/jetpack/suit/turn_on() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + return + var/mob/living/carbon/human/H = loc.loc + tank = H.s_store + air_contents = tank.air_contents + START_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/turn_off() + tank = null + air_contents = temp_air_contents + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/process() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + turn_off() + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off() + 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 + +/mob/proc/get_jetpack() + return + +/mob/living/carbon/get_jetpack() + var/obj/item/tank/jetpack/J = back + if(istype(J)) + return J + +/mob/living/carbon/human/get_jetpack() + var/obj/item/tank/jetpack/J = ..() + if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/C = wear_suit + J = C.jetpack + return J + 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/taster.dm b/code/game/objects/items/taster.dm index 8363c63c2c..3828beb921 100644 --- a/code/game/objects/items/taster.dm +++ b/code/game/objects/items/taster.dm @@ -6,10 +6,9 @@ w_class = WEIGHT_CLASS_TINY - var/taste_sensitivity = 15 + speech_span = null -/obj/item/taster/get_spans() - return list() + var/taste_sensitivity = 15 /obj/item/taster/afterattack(atom/O, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index fd9972f427..341c85fa1c 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -6,27 +6,22 @@ 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 + 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) + playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + if(do_teleport(user, get_turf(user), 50)) + deductcharge(hitcost) else - if(status) - if(!istype(M) && M.anchored) - return . - else - SEND_SIGNAL(M, COMSIG_LIVING_MINOR_SHOCK) - do_teleport(M, get_turf(M), 15) + 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/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 6cee5def2a..97375221d4 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -34,6 +34,12 @@ icon_state = "crowbar_brass" toolspeed = 0.5 +/obj/item/crowbar/bronze + name = "bronze plated crowbar" + desc = "A bronze plated crowbar." + icon_state = "crowbar_brass" + toolspeed = 0.95 + /obj/item/crowbar/abductor name = "alien crowbar" desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." @@ -42,7 +48,6 @@ icon_state = "crowbar" toolspeed = 0.1 - /obj/item/crowbar/large name = "crowbar" desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 2e8cb569a6..e5808de088 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 @@ -91,6 +86,14 @@ toolspeed = 0.5 random_color = FALSE +/obj/item/screwdriver/bronze + name = "bronze screwdriver" + desc = "A screwdriver plated with bronze." + icon_state = "screwdriver_brass" + item_state = "screwdriver_brass" + toolspeed = 0.95 + random_color = FALSE + /obj/item/screwdriver/abductor name = "alien screwdriver" desc = "An ultrasonic screwdriver." @@ -103,7 +106,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..718035a9a5 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) @@ -363,6 +363,13 @@ icon_state = "brasswelder" item_state = "brasswelder" +/obj/item/weldingtool/bronze + name = "bronze plated welding tool" + desc = "A bronze plated welder." + max_fuel = 21 + toolspeed = 0.95 + icon_state = "brasswelder" + item_state = "brasswelder" /obj/item/weldingtool/experimental/process() ..() diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index 2bf9c93ff9..1a35196bd8 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -69,6 +69,13 @@ random_color = FALSE toolspeed = 0.5 +/obj/item/wirecutters/bronze + name = "bronze plated wirecutters" + desc = "A pair of wirecutters plated with bronze." + icon_state = "cutters_brass" + random_color = FALSE + toolspeed = 0.95 //Wire cutters have 0 time bars though + /obj/item/wirecutters/abductor name = "alien wirecutters" desc = "Extremely sharp wirecutters, made out of a silvery-green metal." diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index dc78e9aace..4fd99e9adf 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -35,6 +35,12 @@ icon_state = "wrench_brass" toolspeed = 0.5 +/obj/item/wrench/bronze + name = "bronze plated wrench" + desc = "A bronze plated wrench." + icon_state = "wrench_brass" + toolspeed = 0.95 + /obj/item/wrench/abductor name = "alien wrench" desc = "A polarized wrench. It causes anything placed between the jaws to turn." @@ -43,7 +49,6 @@ usesound = 'sound/effects/empulse.ogg' toolspeed = 0.1 - /obj/item/wrench/power name = "hand drill" desc = "A simple powered hand drill. It's fitted with a bolt bit." diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index eabd9f1968..9ac5261e5f 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -249,8 +249,8 @@ // Copied from /obj/item/melee/transforming/energy/sword/attackby /obj/item/toy/sword/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/toy/sword)) - 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]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool.") @@ -294,7 +294,7 @@ name = "windup toolbox" desc = "A replica toolbox that rumbles when you turn the key." icon_state = "his_grace" - item_state = "artistic_toolbox" + item_state = "toolbox_green" lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' var/active = FALSE @@ -636,10 +636,13 @@ var/obj/machinery/computer/holodeck/holo = null // Holodeck cards should not be infinite var/list/cards = list() -/obj/item/toy/cards/deck/New() - ..() +/obj/item/toy/cards/deck/Initialize() + . = ..() + populate_deck() + +/obj/item/toy/cards/deck/proc/populate_deck() icon_state = "deck_[deckstyle]_full" - for(var/i = 2; i <= 10; i++) + for(var/i in 2 to 10) cards += "[i] of Hearts" cards += "[i] of Spades" cards += "[i] of Clubs" @@ -664,6 +667,9 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE //ATTACK HAND NOT CALLING PARENT /obj/item/toy/cards/deck/attack_hand(mob/user) + draw_card(user) + +/obj/item/toy/cards/deck/proc/draw_card(mob/user) if(user.lying) return var/choice = null @@ -778,7 +784,7 @@ /obj/item/toy/cards/cardhand/Topic(href, href_list) if(..()) return - if(usr.stat || !ishuman(usr) || !usr.canmove) + if(usr.stat || !ishuman(usr)) return var/mob/living/carbon/human/cardUser = usr var/O = src @@ -941,7 +947,6 @@ newobj.card_attack_verb = sourceobj.card_attack_verb newobj.attack_verb = newobj.card_attack_verb - /* || Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. || */ diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index d4ec9217e7..bf63a96f05 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -350,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)) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index ffbe5c004c..48681c3d6d 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -81,7 +81,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." flags_1 = CONDUCT_1 - item_flags = NODROP | DROPDEL + item_flags = DROPDEL slot_flags = null block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY light_range = 3 @@ -91,6 +91,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) START_PROCESSING(SSobj, src) /obj/item/claymore/highlander/Destroy() @@ -115,10 +116,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,7 +226,10 @@ 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/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) /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!") @@ -255,7 +259,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 user.put_in_hands(S) to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - else if(istype(I, /obj/item/assembly/igniter) && !(I.item_flags & NODROP)) + else if(istype(I, /obj/item/assembly/igniter) && !HAS_TRAIT(I, TRAIT_NODROP)) var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod remove_item_from_storage(user) @@ -418,7 +422,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 item_state = "mounted_chainsaw" lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' - item_flags = NODROP | ABSTRACT | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 24 throwforce = 0 @@ -428,6 +432,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = 'sound/weapons/chainsawhit.ogg' +/obj/item/mounted_chainsaw/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) + /obj/item/mounted_chainsaw/Destroy() var/obj/item/bodypart/part new /obj/item/twohanded/required/chainsaw(get_turf(src)) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 6221416db8..70a05a8d40 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -48,7 +48,12 @@ /obj/hitby(atom/movable/AM) ..() - take_damage(AM.throwforce, BRUTE, "melee", 1, get_dir(src, AM)) + var/throwdamage = AM.throwforce + if(isobj(AM)) + var/obj/O = AM + if(O.damtype == STAMINA) + throwdamage = 0 + take_damage(throwdamage, BRUTE, "melee", 1, get_dir(src, AM)) /obj/ex_act(severity, target) if(resistance_flags & INDESTRUCTIBLE) @@ -241,6 +246,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/objs.dm b/code/game/objects/objs.dm index c1d381b435..6dd8a43130 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -2,6 +2,7 @@ /obj var/crit_fail = FALSE animate_movement = 2 + speech_span = SPAN_ROBOT var/obj_flags = CAN_BE_HIT var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT. @@ -18,8 +19,9 @@ var/acid_level = 0 //how much acid is on that obj var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset. - var/current_skin //Has the item been reskinned? + var/current_skin //the item reskin var/list/unique_reskin //List of options to reskin. + var/always_reskinnable = FALSE // Access levels, used in modules\jobs\access.dm var/list/req_access @@ -203,9 +205,6 @@ if(!anchored || current_size >= STAGE_FIVE) step_towards(src,S) -/obj/get_spans() - return ..() | SPAN_ROBOT - /obj/get_dumping_location(datum/component/storage/source,mob/user) return get_turf(src) @@ -228,26 +227,26 @@ ..() if(obj_flags & UNIQUE_RENAME) to_chat(user, "Use a pen on it to rename it or change its description.") - if(unique_reskin && !current_skin) + if(unique_reskin && (!current_skin || always_reskinnable)) to_chat(user, "Alt-click it to reskin it.") /obj/AltClick(mob/user) . = ..() - if(unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + if(unique_reskin && (!current_skin || always_reskinnable) && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) reskin_obj(user) /obj/proc/reskin_obj(mob/M) if(!LAZYLEN(unique_reskin)) return - to_chat(M, "Reskin options for [name]:") + var/dat = "Reskin options for [name]:\n" for(var/V in unique_reskin) var/output = icon2html(src, M, unique_reskin[V]) - to_chat(M, "[V]: [output]") + dat += "[V]: [output]\n" + to_chat(M, dat) - var/choice = input(M,"Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin - if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src)) - if(!unique_reskin[choice]) - return - current_skin = choice - icon_state = unique_reskin[choice] - to_chat(M, "[src] is now skinned as '[choice].'") + var/choice = input(M, always_reskinnable ? "Choose the a reskin for [src]" : "Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin + if(QDELETED(src) || !choice || (current_skin && !always_reskinnable) || M.incapacitated() || !in_range(M,src) || !unique_reskin[choice] || unique_reskin[choice] == current_skin) + return + current_skin = choice + icon_state = unique_reskin[choice] + to_chat(M, "[src] is now skinned as '[choice]'.") 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/barsigns.dm b/code/game/objects/structures/barsigns.dm index 964f60cb73..1ab28a33de 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -294,6 +294,16 @@ icon = "the_lightbulb" desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." +/datum/barsign/cybersylph + name = "Cyber Sylph's" + icon = "cybersylph" + desc = "A cafe renowed for its out-of-boundaries futuristic insignia." + +/datum/barsign/meow_mix + name = "Meow Mix" + icon = "meow_mix" + desc = "No, we don't serve catnip, officer!" + /datum/barsign/hiddensigns hidden = TRUE diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 89dcc75042..b493f84240 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -225,6 +225,39 @@ LINEN BINS item_color = "ian" dream_messages = list("a dog", "a corgi", "woof", "bark", "arf") +/obj/item/bedsheet/runtime + icon_state = "sheetruntime" + item_color = "runtime" + dream_messages = list("a kitty", "a cat", "meow", "purr", "nya~") + +/obj/item/bedsheet/pirate + name = "pirate's bedsheet" + desc = "It has a Jolly Roger emblem on it and has a faint scent of grog." + icon_state = "sheetpirate" + item_color = "black" + dream_messages = list("doing whatever oneself wants", "cause a pirate is free", "being a pirate", "stealing", "landlubbers", "gold", "a buried treasure", "yarr", "avast", "a swashbuckler", "sailing the Seven Seas", "a parrot", "a monkey", "an island", "a talking skull") + +/obj/item/bedsheet/gondola + name = "gondola bedsheet" + desc = "A precious bedsheet made from the hide of a rare and peculiar critter." + icon_state = "sheetgondola" + item_color = "cargo" + var/g_mouth + var/g_eyes + +/obj/item/bedsheet/gondola/Initialize() + . = ..() + g_mouth = "sheetgondola_mouth[rand(1, 4)]" + g_eyes = "sheetgondola_eyes[rand(1, 4)]" + add_overlay(g_mouth) + add_overlay(g_eyes) + +/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file) + . = ..() + if(!isinhands) + . += mutable_appearance(icon_file, g_mouth) + . += mutable_appearance(icon_file, g_eyes) + /obj/item/bedsheet/cosmos name = "cosmic space bedsheet" desc = "Made from the dreams of those who wonder at the stars." @@ -258,7 +291,6 @@ LINEN BINS var/list/sheets = list() var/obj/item/hidden = null - /obj/structure/bedsheetbin/examine(mob/user) ..() if(amount < 1) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index a6a6c5f699..2c4463928c 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) @@ -147,47 +147,48 @@ /obj/structure/closet/proc/insert(atom/movable/AM) if(contents.len >= storage_capacity) return -1 + if(insertion_allowed(AM)) + AM.forceMove(src) + return TRUE + else + return FALSE +/obj/structure/closet/proc/insertion_allowed(atom/movable/AM) if(ismob(AM)) if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets... - return + return FALSE var/mob/living/L = AM if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs()) - return + return FALSE if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. if(horizontal && L.density) - return + return FALSE if(L.mob_size > max_mob_size) - return + return FALSE var/mobs_stored = 0 for(var/mob/living/M in contents) if(++mobs_stored >= mob_storage_capacity) - return + return FALSE L.stop_pulling() + else if(istype(AM, /obj/structure/closet)) - return + return FALSE else if(istype(AM, /obj/effect)) - return + return FALSE else if(isobj(AM)) - if (istype(AM, /obj/item)) - var/obj/item/I = AM - if (I.item_flags & NODROP) - return + if((!allow_dense && AM.density) || AM.anchored || AM.has_buckled_mobs()) + return FALSE + if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP)) + return TRUE else if(!allow_objects && !istype(AM, /obj/effect/dummy/chameleon)) - return - if(!allow_dense && AM.density) - return - if(AM.anchored || AM.has_buckled_mobs()) - return + return FALSE else - return + return FALSE - AM.forceMove(src) - - return 1 + return TRUE /obj/structure/closet/proc/close(mob/living/user) if(!opened || !can_close(user)) @@ -416,7 +417,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/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index b4cdff4224..8c06af91a4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -106,6 +106,7 @@ new /obj/item/radio/headset/headset_sec(src) new /obj/item/clothing/suit/armor/vest/warden(src) new /obj/item/clothing/head/warden(src) + new /obj/item/clothing/head/warden/drill(src) new /obj/item/clothing/head/beret/sec/navywarden(src) new /obj/item/clothing/suit/armor/vest/warden/alt(src) new /obj/item/clothing/under/rank/warden/navyblue(src) diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 9e88d52444..461e19adf1 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -21,35 +21,62 @@ /obj/structure/dresser/attack_hand(mob/user) . = ..() - if(.) + if(. || !ishuman(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return - if(!Adjacent(user))//no tele-grooming + var/mob/living/carbon/human/H = user + + if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits)) + to_chat(H, "You are not capable of wearing underwear.") return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits)) - to_chat(user, "You are not capable of wearing underwear.") - return + var/list/undergarment_choices = list("Underwear", "Underwear Color", "Undershirt", "Undershirt Color", "Socks", "Socks Color") + if(!UNDIE_COLORABLE(GLOB.underwear_list[H.underwear])) + undergarment_choices -= "Underwear Color" + if(!UNDIE_COLORABLE(GLOB.undershirt_list[H.undershirt])) + undergarment_choices -= "Undershirt Color" + if(!UNDIE_COLORABLE(GLOB.socks_list[H.socks])) + undergarment_choices -= "Socks Color" - var/choice = input(user, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in list("Underwear","Undershirt","Socks") + var/choice = input(H, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in undergarment_choices + if(!H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + var/dye_undie = FALSE + var/dye_shirt = FALSE + var/dye_socks = FALSE + switch(choice) + if("Underwear") + var/new_undies = input(H, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list + if(H.underwear) + H.underwear = new_undies + H.saved_underwear = new_undies + var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[new_undies] + dye_undie = B?.has_color + if("Undershirt") + var/new_undershirt = input(H, "Select your undershirt", "Changing") as null|anything in GLOB.undershirt_list + if(new_undershirt) + H.undershirt = new_undershirt + H.saved_undershirt = new_undershirt + var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[new_undershirt] + dye_shirt = T?.has_color + if("Socks") + var/new_socks = input(H, "Select your socks", "Changing") as null|anything in GLOB.socks_list + if(new_socks) + H.socks = new_socks + H.saved_socks = new_socks + var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[new_socks] + dye_socks = S?.has_color + if(dye_undie || choice == "Underwear Color") + H.undie_color = recolor_undergarment(H, "underwear", H.undie_color) + if(dye_shirt || choice == "Undershirt Color") + H.shirt_color = recolor_undergarment(H, "undershirt", H.shirt_color) + if(dye_socks || choice == "Socks Color") + H.socks_color = recolor_undergarment(H, "socks", H.socks_color) - if(!Adjacent(user)) - return - switch(choice) - if("Underwear") - var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list - if(new_undies) - H.underwear = new_undies + add_fingerprint(H) + H.update_body() - if("Undershirt") - var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in GLOB.undershirt_list - if(new_undershirt) - H.undershirt = new_undershirt - if("Socks") - var/new_socks = input(user, "Select your socks", "Changing") as null|anything in GLOB.socks_list - if(new_socks) - H.socks= new_socks - - add_fingerprint(H) - H.update_body() +/obj/structure/dresser/proc/recolor_undergarment(mob/living/carbon/human/H, garment_type = "underwear", default_color) + var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null + if(!n_color || !H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return default_color + return n_color diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index bd65a8b422..7c73a1fd8c 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -101,6 +101,12 @@ icon_state = "festivus_pole" desc = "During last year's Feats of Strength the Research Director was able to suplex this passing immobile rod into a planter." +/obj/structure/festivus/anchored + name = "suplexed rod" + desc = "A true feat of strength, almost as good as last year." + icon_state = "anchored_rod" + anchored = TRUE + /obj/structure/flora/tree/dead/Initialize() icon_state = "tree_[rand(1, 6)]" . = ..() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 6fac5da2a5..00d1690d86 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -262,7 +262,7 @@ if(isobj(AM)) if(prob(50) && anchored && !broken) var/obj/O = AM - if(O.throwforce != 0)//don't want to let people spam tesla bolts, this way it will break after time + if(O.throwforce != 0 && O.damtype != STAMINA)//don't want to let people spam tesla bolts, this way it will break after time var/turf/T = get_turf(src) var/obj/structure/cable/C = T.get_cable_node() if(C) 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/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index aa55cd81b1..80ffced5a2 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -180,12 +180,13 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "offhand" w_class = WEIGHT_CLASS_HUGE - item_flags = ABSTRACT | NODROP | NOBLUDGEON | DROPDEL + item_flags = ABSTRACT | NOBLUDGEON | DROPDEL resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/obj/machinery/manned_turret/turret /obj/item/gun_control/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) turret = loc if(!istype(turret)) return INITIALIZE_HINT_QDEL diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index ea2e99d371..b15d686b7b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -24,15 +24,13 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user - var/userloc = H.loc - //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments! //this is largely copypasted from there. //handle facial hair (if necessary) if(H.gender == MALE) var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list - if(userloc != H.loc) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return //no tele-grooming if(new_style) H.facial_hair_style = new_style @@ -41,7 +39,7 @@ //handle normal hair var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list - if(userloc != H.loc) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return //no tele-grooming if(new_style) H.hair_style = new_style @@ -90,9 +88,9 @@ /obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) if(BURN) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) /obj/structure/mirror/magic @@ -131,7 +129,7 @@ var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return switch(choice) @@ -140,7 +138,7 @@ if(!newname) return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return H.real_name = newname H.name = newname @@ -156,7 +154,7 @@ if(!newrace) return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return H.set_species(newrace, icon_update=0) @@ -186,7 +184,7 @@ if("gender") if(!(H.gender in list("male", "female"))) //blame the patriarchy return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(H.gender == "male") if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") @@ -207,7 +205,7 @@ if("hair") var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(hairchoice == "Style") //So you just want to use a mirror then? ..() @@ -225,7 +223,7 @@ if(BODY_ZONE_PRECISE_EYES) var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+H.eye_color) as color|null - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(new_eye_color) H.eye_color = sanitize_hexcolor(new_eye_color) 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/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/say.dm b/code/game/say.dm index 0788310038..4ce1d3c710 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(freqtospan, list( return if(message == "" || !message) return - spans |= get_spans() + spans |= speech_span if(!language) language = get_default_language() send_speech(message, 7, src, , spans, message_language=language) @@ -40,10 +40,6 @@ GLOBAL_LIST_INIT(freqtospan, list( var/atom/movable/AM = _AM AM.Hear(rendered, src, message_language, message, , spans, message_mode) -//To get robot span classes, stuff like that. -/atom/movable/proc/get_spans() - return list() - /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE) //This proc uses text() because it is faster than appending strings. Thanks BYOND. //Basic span @@ -87,7 +83,7 @@ GLOBAL_LIST_INIT(freqtospan, list( else return verb_say -/atom/movable/proc/say_quote(input, list/spans=list(), message_mode) +/atom/movable/proc/say_quote(input, list/spans=list(speech_span), message_mode) if(!input) input = "..." @@ -97,7 +93,7 @@ GLOBAL_LIST_INIT(freqtospan, list( var/spanned = attach_spans(input, spans) return "[say_mod(input, message_mode)][spanned ? ", \"[spanned]\"" : ""]" // Citadel edit [spanned ? ", \"[spanned]\"" : ""]" - + /atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode) if(has_language(language)) var/atom/movable/AM = speaker.GetSource() 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..253a6ead90 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -141,6 +141,10 @@ icon_state = "plating" baseturfs = /turf/open/floor/clockwork footstep = FOOTSTEP_PLATING + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + var/dropped_brass var/uses_overlay = TRUE var/obj/effect/clockwork/overlay/floor/realappearence @@ -198,7 +202,10 @@ return /turf/open/floor/clockwork/crowbar_act(mob/living/user, obj/item/I) - if(baseturfs == type) + if(islist(baseturfs)) + if(type in baseturfs) + return TRUE + else if(baseturfs == type) return TRUE user.visible_message("[user] begins slowly prying up [src]...", "You begin painstakingly prying up [src]...") if(I.use_tool(src, user, 70, volume=80)) @@ -207,7 +214,14 @@ return TRUE /turf/open/floor/clockwork/make_plating() - new /obj/item/stack/tile/brass(src) + if(!dropped_brass) + new /obj/item/stack/tile/brass(src) + dropped_brass = TRUE + if(islist(baseturfs)) + if(type in baseturfs) + return + else if(baseturfs == type) + return return ..() /turf/open/floor/clockwork/narsie_act() 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..dfc6972578 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -77,6 +77,27 @@ return ..() +/turf/closed/wall/clockwork/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if(heated && the_rcd.canRturf) + return ..() + +/turf/closed/wall/clockwork/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + if(heated && the_rcd.canRturf) + 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..7110ff4405 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) @@ -450,16 +452,16 @@ /turf/AllowDrop() return TRUE -/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = 0) +/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = NONE) var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses()) // If the vomit combined, apply toxicity and reagents to the old vomit if (QDELETED(V)) V = locate() in src - // Make toxins vomit look different - if(toxvomit) + // Make toxins and blazaam vomit look different + if(toxvomit == VOMIT_PURPLE) + V.icon_state = "vomitpurp_[pick(1,4)]" + else if(toxvomit == VOMIT_TOXIC) V.icon_state = "vomittox_[pick(1,4)]" - if(M.reagents) - clear_reagents_to_vomit_pool(M,V) /proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V) M.reagents.trans_to(V, M.reagents.total_volume / 10) diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 4e342f6ced..bfbf6b5b79 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -164,8 +164,11 @@ vr_human.name = H.name vr_human.real_name = H.real_name vr_human.socks = H.socks + vr_human.socks_color = H.socks_color vr_human.undershirt = H.undershirt + vr_human.shirt_color = H.shirt_color vr_human.underwear = H.underwear + vr_human.undie_color = H.undie_color vr_human.updateappearance(TRUE, TRUE, TRUE) vr_human.give_genitals(TRUE) //CITADEL ADD if(outfit) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 8e1926115f..ae6482abbd 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -4,7 +4,7 @@ var/F = file("[GLOB.log_directory]/[subject].html") WRITE_FILE(F, "[TIME_STAMP("hh:mm:ss", FALSE)] [REF(src)] ([x],[y],[z]) || [src] [message]
    ") -/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) ) +/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) ) set name = "Investigate" set category = "Admin" if(!holder) 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/chat_commands.dm b/code/modules/admin/chat_commands.dm index a97c0bf116..8b824f8fb0 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -78,13 +78,13 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/notify name = "notify" help_text = "Pings the invoker when the round ends" - admin_only = TRUE + admin_only = FALSE /datum/tgs_chat_command/notify/Run(datum/tgs_chat_user/sender, params) if(!SSticker.IsRoundInProgress() && SSticker.HasRoundStarted()) return "[sender.mention], the round has already ended!" LAZYINITLIST(GLOB.round_end_notifiees) - GLOB.round_end_notifiees[sender.mention] = TRUE + GLOB.round_end_notifiees["<@[sender.mention]>"] = TRUE return "I will notify [sender.mention] when the round ends." /datum/tgs_chat_command/sdql @@ -140,4 +140,4 @@ GLOBAL_LIST(round_end_notifiees) log_admin("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") message_admins("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") - return "[params] has been added to the current round's bunker bypass list." \ No newline at end of file + return "[params] has been added to the current round's bunker bypass list." diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 73b8fa61f0..fad7410a6a 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -15,6 +15,9 @@ H.real_name = random_unique_name(H.gender) H.name = H.real_name H.underwear = random_underwear(H.gender) + H.undie_color = random_color() + H.undershirt = random_undershirt(H.gender) + H.shirt_color = random_color() H.skin_tone = random_skin_tone() H.hair_style = random_hair_style(H.gender) H.facial_hair_style = random_facial_hair_style(H.gender) @@ -26,8 +29,8 @@ // Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant. H.dna.features["mcolor"] = random_short_color() H.dna.features["tail_lizard"] = pick(GLOB.tails_list_lizard) - H.dna.features["snout"] = pick(GLOB.snouts_list) - H.dna.features["horns"] = pick(GLOB.horns_list) + H.dna.features["snout"] = pick(GLOB.snouts_list) + H.dna.features["horns"] = pick(GLOB.horns_list) H.dna.features["frills"] = pick(GLOB.frills_list) H.dna.features["spines"] = pick(GLOB.spines_list) H.dna.features["body_markings"] = pick(GLOB.body_markings_list) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 66358dc080..7d74387c43 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -422,7 +422,7 @@ H.equip_to_slot_or_del(I, SLOT_W_UNIFORM) qdel(olduniform) if(droptype == "Yes") - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, ADMIN_TRAIT) else to_chat(H, "You're not kawaii enough for this.") 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 += "
    " + //Gang + if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept) + dat += "" + else + dat += "" + + //Other Roles (black) dat += "
    AlienGangGang
    " 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/debug.dm b/code/modules/admin/verbs/debug.dm index 67b33afcc6..e15613c43d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -29,69 +29,62 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/callproc() set category = "Debug" set name = "Advanced ProcCall" - set waitfor = 0 + set waitfor = FALSE if(!check_rights(R_DEBUG)) return var/datum/target = null - var/targetselected = 0 + var/targetselected = FALSE var/returnval = null - switch(alert("Proc owned by something?",,"Yes","No")) - if("Yes") - targetselected = 1 - var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) - if (!value["class"] || !value["value"]) - return - target = value["value"] - if("No") - target = null - targetselected = 0 - - var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null - if(!procname) - return - - //hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib") - var/testname = procname - if(targetselected) - //Find one of the 3 possible ways they could have written /proc/PROCNAME - if(findtext(procname, "/proc/")) - testname = replacetext(procname, "/proc/", "") - else if(findtext(procname, "/proc")) - testname = replacetext(procname, "/proc", "") - else if(findtext(procname, "proc/")) - testname = replacetext(procname, "proc/", "") - //Clear out any parenthesis if they're a dummy - testname = replacetext(testname, "()", "") - - if(targetselected && !hascall(target,testname)) - to_chat(usr, "Error: callproc(): type [target.type] has no proc named [procname].") - return - else - var/procpath = text2path(procname) - if (!procpath) - to_chat(usr, "Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + if(alert("Proc owned by something?",,"Yes","No") == "Yes") + targetselected = TRUE + var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) + if (!value["class"] || !value["value"]) return + target = value["value"] + + var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null + if(!procpath) + return + + //strip away everything but the proc name + var/list/proclist = splittext(procpath, "/") + if (!length(proclist)) + return + + var/procname = proclist[proclist.len] + var/proctype = ("verb" in proclist) ? "verb" :"proc" + + if(targetselected) + if(!hascall(target, procname)) + to_chat(usr, "Error: callproc(): type [target.type] has no [proctype] named [procpath].") + return + else + procpath = "/[proctype]/[procname]" + if(!text2path(procpath)) + to_chat(usr, "Error: callproc(): [procpath] does not exist.") + return + var/list/lst = get_callproc_args() if(!lst) return if(targetselected) if(!target) - to_chat(usr, "Error: callproc(): owner of proc no longer exists.") + to_chat(usr, "Error: callproc(): owner of proc no longer exists.") return - var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]." log_admin(msg) message_admins(msg) admin_ticket_log(target, msg) - returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc + returnval = WrapAdminProcCall(target, procname, lst) else - //this currently has no hascall protection. wasn't able to get it working. - log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc + var/msg = "[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]." + log_admin(msg) + message_admins(msg) + returnval = WrapAdminProcCall(GLOBAL_PROC, procpath, lst) //calling globals needs full qualified name (e.g /proc/foo) . = get_callproc_returnval(returnval, procname) if(.) to_chat(usr, .) @@ -111,8 +104,8 @@ GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) GLOBAL_PROTECT(AdminProcCallSpamPrevention) /proc/WrapAdminProcCall(datum/target, procname, list/arguments) - if(target && procname == "Del") - to_chat(usr, "Calling Del() is not allowed") + if(target != GLOBAL_PROC && procname == "Del") + to_chat(usr, "Calling Del() is not allowed") return if(target != GLOBAL_PROC && !target.CanProcCall(procname)) @@ -159,7 +152,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) /client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) set category = "Debug" set name = "Atom ProcCall" - set waitfor = 0 + set waitfor = FALSE if(!check_rights(R_DEBUG)) return @@ -168,7 +161,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!procname) return if(!hascall(A,procname)) - to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") + to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") return var/list/lst = get_callproc_args() if(!lst) @@ -177,8 +170,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!A || !IsValidSrc(A)) to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") return - log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + log_admin(msg) message_admins(msg) admin_ticket_log(A, msg) SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -188,8 +181,6 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(.) to_chat(usr, .) - - /client/proc/get_callproc_args() var/argnum = input("Number of arguments","Number:",0) as num|null if(isnull(argnum)) @@ -213,7 +204,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . = "" if(islist(returnval)) var/list/returnedlist = returnval - . = "" + . = "" if(returnedlist.len) var/assoc_check = returnedlist[1] if(istext(assoc_check) && (returnedlist[assoc_check] != null)) @@ -227,11 +218,10 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . += "\n[elem]" else . = "[procname] returned an empty list" - . += "" + . += "" else - . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" - + . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" /client/proc/Cell() set category = "Debug" @@ -841,8 +831,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/pray.dm b/code/modules/admin/verbs/pray.dm index da1b404ea5..d5acb66fdd 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -25,8 +25,8 @@ cross.icon_state = "kingyellow" font_color = "blue" prayer_type = "CHAPLAIN PRAYER" - if(SSreligion.deity) - deity = SSreligion.deity + if(GLOB.deity) + deity = GLOB.deity else if(iscultist(usr)) cross.icon_state = "tome" font_color = "red" @@ -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/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 237d1a6c00..1573204d88 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -30,9 +30,12 @@ var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90) /obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop() - item_flags ^= NODROP + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)) + REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) + else + ADD_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) if(ismob(loc)) - to_chat(loc, "Your vest is now [item_flags & NODROP ? "locked" : "unlocked"].") + to_chat(loc, "Your vest is now [HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "locked" : "unlocked"].") /obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode() switch(mode) @@ -108,20 +111,7 @@ to_chat(loc, "Combat injection is still recharging.") return var/mob/living/carbon/human/M = loc - M.SetSleeping(0) - M.SetUnconscious(0) - M.SetStun(0) - M.SetKnockdown(0) - M.reagents.add_reagent("inaprovaline", 3) - M.reagents.add_reagent("synaptizine", 10) - M.reagents.add_reagent("stimulants", 10) - M.adjustStaminaLoss(-150) - M.stuttering = 0 - M.updatehealth() - M.update_stamina() - M.resting = 0 - M.lying = 0 - M.update_canmove() + 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) diff --git a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm index e2b881d147..a69c8fdeff 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm @@ -17,7 +17,7 @@ var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H if(V) console.AddVest(V) - V.item_flags |= NODROP + ADD_TRAIT(V, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) var/obj/item/storage/backpack/B = locate() in H if(B) 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/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index a14b667069..46d69ba9bb 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -75,7 +75,7 @@ dat+="
    " dat += "Select Agent Vest Disguise
    " - dat += "[vest.item_flags & NODROP ? "Unlock" : "Lock"] Vest
    " + dat += "[HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "Unlock" : "Lock"] Vest
    " else dat += "NO AGENT VEST DETECTED" var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500) @@ -126,8 +126,20 @@ if(vest) vest.flip_mode() -/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0) - var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises +/obj/machinery/abductor/console/proc/SelectDisguise(remote = FALSE) + var/list/disguises2 = list() + for(var/name in disguises) + var/datum/icon_snapshot/snap = disguises[name] + var/image/dummy = image(snap.icon, src, snap.icon_state) + dummy.overlays = snap.overlays + disguises2[name] = dummy + + var/entry_name + if(remote) + entry_name = show_radial_menu(usr, camera.eyeobj, disguises2) + else + entry_name = show_radial_menu(usr, src, disguises2) + var/datum/icon_snapshot/chosen = disguises[entry_name] if(chosen && vest && (remote || in_range(usr,src))) vest.SetDisguise(chosen) diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index e60209cb7b..3cb90d64bb 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -57,7 +57,7 @@ return ..() /mob/living/simple_animal/hostile/blob/proc/blob_chat(msg) - var/spanned_message = say_quote(msg, get_spans()) + var/spanned_message = say_quote(msg) var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]" for(var/M in GLOB.mob_list) if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob)) diff --git a/code/modules/antagonists/blob/blob/blobs/shield.dm b/code/modules/antagonists/blob/blob/blobs/shield.dm index d52c208c71..33e7e4392f 100644 --- a/code/modules/antagonists/blob/blob/blobs/shield.dm +++ b/code/modules/antagonists/blob/blob/blobs/shield.dm @@ -9,6 +9,7 @@ point_return = 4 atmosblock = TRUE 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) @@ -25,10 +26,15 @@ name = "weakened strong blob" desc = "A wall of twitching tendrils." atmosblock = FALSE - armor = list("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + 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/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index ddf745c0f9..d32e38c194 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -210,7 +210,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) src.log_talk(message, LOG_SAY) - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "\[Blob Telepathy\] [name]([blob_reagent_datum.name]) [message_a]" for(var/mob/M in GLOB.mob_list) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 7e0ae3c08c..a1b9b53fe9 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 @@ -269,8 +269,11 @@ prof.protected = protect prof.underwear = H.underwear + prof.undie_color = H.undie_color prof.undershirt = H.undershirt + prof.shirt_color = H.shirt_color prof.socks = H.socks + prof.socks_color = H.socks_color var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store") for(var/slot in slots) @@ -503,8 +506,11 @@ var/list/item_state_list = list() var/underwear + var/undie_color var/undershirt + var/shirt_color var/socks + var/socks_color /datum/changelingprofile/Destroy() qdel(dna) 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 9dbe706ed2..256d3e89e3 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -1,8 +1,9 @@ /obj/effect/proc_holder/changeling/adrenaline name = "Adrenaline Sacs" desc = "We evolve additional sacs of adrenaline throughout our body." - helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body." + helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body. This ability is loud, and might cause our blood to react violently to heat." chemical_cost = 30 + loudness = 2 dna_cost = 2 req_human = 1 req_stat = UNCONSCIOUS @@ -12,21 +13,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.reagents.add_reagent("inaprovaline", 3) //let's give another chance to dumb fucks who forget to breathe - user.adjustStaminaLoss(-150) - user.stuttering = 0 - user.updatehealth() - user.update_stamina() - user.resting = 0 - user.lying = 0 - user.update_canmove() - - return TRUE - + user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "Energy rushes through us.", 0, 0.75, 0) + return TRUE \ No newline at end of file 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 a33dab31c3..1d7382d947 100644 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ b/code/modules/antagonists/changeling/powers/hivemind.dm @@ -10,7 +10,7 @@ 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 = html_decode(stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", "")) @@ -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..4e0595362c 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -155,7 +155,7 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 25 throwforce = 0 //Just to be on the safe side @@ -169,6 +169,7 @@ /obj/item/melee/arm_blade/Initialize(mapload,silent,synthetic) . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc) && !silent) loc.visible_message("A grotesque blade forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!") if(synthetic) @@ -242,7 +243,7 @@ item_state = "tentacle" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL | NOBLUDGEON + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL | NOBLUDGEON flags_1 = NONE w_class = WEIGHT_CLASS_HUGE ammo_type = /obj/item/ammo_casing/magic/tentacle @@ -256,6 +257,7 @@ /obj/item/gun/magic/tentacle/Initialize(mapload, silent) . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) if(!silent) loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!") @@ -344,9 +346,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)) @@ -428,7 +429,7 @@ /obj/item/shield/changeling name = "shield-like mass" desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield." - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL icon = 'icons/obj/items_and_weapons.dmi' icon_state = "ling_shield" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' @@ -439,6 +440,7 @@ /obj/item/shield/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!", "We inflate our hand into a strong shield.", "You hear organic matter ripping and tearing!") @@ -480,13 +482,14 @@ name = "flesh mass" icon_state = "lingspacesuit" desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." - item_flags = NODROP | DROPDEL + item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/oxygen) armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) //No armor at all. /obj/item/clothing/suit/space/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around [loc.p_their()] body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!") START_PROCESSING(SSobj, src) @@ -500,11 +503,15 @@ name = "flesh mass" icon_state = "lingspacehelmet" desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." - item_flags = NODROP | DROPDEL + item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH +/obj/item/clothing/head/helmet/space/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + /***************************************\ |*****************ARMOR*****************| \***************************************/ @@ -530,7 +537,7 @@ name = "chitinous mass" desc = "A tough, hard covering of black chitin." icon_state = "lingarmor" - item_flags = NODROP | DROPDEL + item_flags = DROPDEL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90) flags_inv = HIDEJUMPSUIT @@ -539,6 +546,7 @@ /obj/item/clothing/suit/armor/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!", "We harden our flesh, creating a suit of armor!", "You hear organic matter ripping and tearing!") @@ -546,6 +554,10 @@ name = "chitinous mass" desc = "A tough, hard covering of black chitin with transparent chitin in front." icon_state = "lingarmorhelmet" - item_flags = NODROP | DROPDEL + item_flags = DROPDEL armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90) flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE + +/obj/item/clothing/head/helmet/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index 9f7a36f214..8d571d21e3 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -29,7 +29,7 @@ O.forceMove(get_turf(user)) user.reagents.add_reagent("mutadone", 10) - user.reagents.add_reagent("pen_acid", 20) + user.reagents.add_reagent("pen_jelly", 20) user.reagents.add_reagent("antihol", 10) user.reagents.add_reagent("mannitol", 25) 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 c9b48fa6fc..5a701d8a96 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -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/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index 767c7d2621..795ba772d6 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -11,7 +11,11 @@ /obj/item/clothing/glasses/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/glasses/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/glasses/changeling/attack_hand(mob/user) @@ -23,7 +27,11 @@ /obj/item/clothing/under/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/under/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/under/changeling/attack_hand(mob/user) @@ -35,9 +43,13 @@ /obj/item/clothing/suit/changeling name = "flesh" - item_flags = NODROP allowed = list(/obj/item/changeling) +/obj/item/clothing/suit/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/suit/changeling/attack_hand(mob/user) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) @@ -48,7 +60,10 @@ /obj/item/clothing/head/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/head/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/head/changeling/attack_hand(mob/user) @@ -60,7 +75,11 @@ /obj/item/clothing/shoes/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/shoes/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/shoes/changeling/attack_hand(mob/user) @@ -72,7 +91,11 @@ /obj/item/clothing/gloves/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/gloves/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/gloves/changeling/attack_hand(mob/user) @@ -84,7 +107,11 @@ /obj/item/clothing/mask/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/mask/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/mask/changeling/attack_hand(mob/user) @@ -96,10 +123,14 @@ /obj/item/changeling name = "flesh" - item_flags = NODROP slot_flags = ALL allowed = list(/obj/item/changeling) +/obj/item/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/changeling/attack_hand(mob/user) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index 277aeca48d..54027266e5 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -21,17 +21,17 @@ /obj/item/clothing/head/helmet/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = list("melee" = 70, "bullet" = 80, "laser" = -15, "energy" = 25, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -69,7 +69,7 @@ heat_protection = CHEST|GROIN|LEGS resistance_flags = FIRE_PROOF | ACID_PROOF armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel) + allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/holyoil) /obj/item/clothing/suit/armor/clockwork/Initialize() . = ..() @@ -82,17 +82,17 @@ /obj/item/clothing/suit/armor/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = list("melee" = 70, "bullet" = 80, "laser" = -15, "energy" = 25, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -148,12 +148,12 @@ /obj/item/clothing/gloves/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 80, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 30c84f5312..12af249bee 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -21,8 +21,9 @@ /obj/item/clockwork/construct_chassis/Destroy() GLOB.poi_list -= src - var/list/spawners = GLOB.mob_spawners[name] - LAZYREMOVE(spawners, src) + LAZYREMOVE(GLOB.mob_spawners[name], src) + if(!LAZYLEN(GLOB.mob_spawners[name])) + GLOB.mob_spawners -= name . = ..() /obj/item/clockwork/construct_chassis/examine(mob/user) 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_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm index bd9c52b19f..6268d15d44 100644 --- a/code/modules/antagonists/clockcult/clock_mobs.dm +++ b/code/modules/antagonists/clockcult/clock_mobs.dm @@ -19,6 +19,7 @@ bubble_icon = "clock" light_color = "#E42742" death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' + speech_span = SPAN_ROBOT var/playstyle_string = "You are a bug, yell at whoever spawned you!" var/empower_string = "You have nothing to empower, yell at the coders!" //Shown to the mob when the herald beacon activates @@ -26,9 +27,6 @@ . = ..() update_values() -/mob/living/simple_animal/hostile/clockwork/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/hostile/clockwork/Login() ..() add_servant_of_ratvar(src, TRUE) 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/reflector.dm b/code/modules/antagonists/clockcult/clock_structures/reflector.dm new file mode 100644 index 0000000000..34ad051d19 --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/reflector.dm @@ -0,0 +1,86 @@ +/obj/structure/destructible/clockwork/reflector + name = "reflector" + 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 = "reflector" + unanchored_icon = "reflector_unwrenched" + max_integrity = 40 + construction_value = 5 + layer = WALL_OBJ_LAYER + break_message = "The reflectors's fragile shield shatters into pieces!" + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + light_color = "#DAAA18" + var/list/allowed_projectile_typecache = list( + /obj/item/projectile/beam + ) + + var/ini_dir = null + +/obj/structure/destructible/clockwork/reflector/Initialize() + . = ..() + allowed_projectile_typecache = typecacheof(allowed_projectile_typecache) + +/obj/structure/destructible/clockwork/reflector/ComponentInitialize() + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation)) + +/obj/structure/destructible/clockwork/reflector/bullet_act(obj/item/projectile/P) + if(!anchored || !allowed_projectile_typecache[P.type] || !(P.dir in GLOB.cardinals)) + return ..() + + if(auto_reflect(P, P.dir, get_turf(P), P.Angle) != -1) + return ..() + + return -1 + +/obj/structure/destructible/clockwork/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) + + //Yell at me if this exists already. + + var/real_angle = 0 + + switch(dir) + if(NORTH) + real_angle = 0 + if(EAST) + real_angle = 90 + if(SOUTH) + real_angle = 180 + if(WEST) + real_angle = 270 + + var/incidence = GET_ANGLE_OF_INCIDENCE(real_angle, (P.Angle + 180)) + if(abs(incidence) > 90 && abs(incidence) < 270) + return FALSE + var/new_angle = SIMPLIFY_DEGREES(real_angle + incidence) + P.setAngle(new_angle) + P.ignore_source_check = TRUE + P.range = P.decayedRange + P.decayedRange = max(P.decayedRange--, 0) + return -1 + +/obj/structure/destructible/clockwork/reflector/proc/can_be_rotated(mob/user,rotation_type) + if(anchored) + to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE + + return TRUE + +/obj/structure/destructible/clockwork/reflector/Move() + . = ..() + setDir(ini_dir) + +/obj/structure/destructible/clockwork/reflector/proc/after_rotation(mob/user,rotation_type) + ini_dir = dir + add_fingerprint(user) + + +/obj/structure/destructible/clockwork/reflector/wrench_act(mob/living/user, obj/item/I) + + if(!is_servant_of_ratvar(user)) + return ..() + + anchored = !anchored + to_chat(user, "You [anchored ? "secure" : "unsecure"] \the [src].") + I.play_tool_sound(src) + return TRUE \ No newline at end of file diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 845c66fb33..a5fd516a42 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -339,7 +339,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "disintegrate" item_state = null - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE throwforce = 0 @@ -350,11 +350,13 @@ var/health_cost = 0 //The amount of health taken from the user when invoking the spell var/datum/action/innate/cult/blood_spell/source -/obj/item/melee/blood_magic/New(loc, spell) +/obj/item/melee/blood_magic/Initialize(mapload, spell) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) source = spell uses = source.charges health_cost = source.health_cost - ..() + /obj/item/melee/blood_magic/Destroy() if(!QDELETED(source)) diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index c8d59f54a8..47cf2abf3f 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,70 @@ /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) + return reshape +/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) + return reshape - //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_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index 8452f78ed3..761412e9f8 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -342,10 +342,7 @@ if(cooldown>world.time) to_chat(owner, "You aren't ready to place another blood mark yet!") return - if(owner.orbiting && owner.orbiting.orbiting) - target = owner.orbiting.orbiting - else - target = get_turf(owner) + target = owner.orbiting?.parent || get_turf(owner) if(!target) return C.cult_team.blood_target = target diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 263d4b623e..9a17c3270b 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -64,9 +64,14 @@ /obj/item/melee/cultblade/ghost name = "eldritch sword" force = 19 //can't break normal airlocks - item_flags = NEEDS_PERMIT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | DROPDEL flags_1 = NONE +/obj/item/melee/cultblade/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) + + /obj/item/melee/cultblade/pickup(mob/living/user) ..() if(!iscultist(user)) @@ -298,7 +303,12 @@ item_state = "cult_hoodalt" /obj/item/clothing/head/culthood/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/head/culthood/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) + /obj/item/clothing/suit/cultrobes/alt name = "cultist robes" @@ -307,7 +317,11 @@ item_state = "cultrobesalt" /obj/item/clothing/suit/cultrobes/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/suit/cultrobes/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/clothing/head/magus name = "magus helm" @@ -796,7 +810,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "disintegrate" item_state = null - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE throwforce = 0 throw_range = 0 @@ -805,6 +819,9 @@ var/firing = FALSE var/angle +/obj/item/blood_beam/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/blood_beam/afterattack(atom/A, mob/living/user, flag, params) . = ..() @@ -990,6 +1007,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/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index 923a224b81..1df81a797b 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -94,7 +94,7 @@ visible_message("[src] easily breaks out of [p_their()] handcuffs!", \ "With just a thought your handcuffs fall off.") -/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm index 1fa37f3a51..51e8d9a13b 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 @@ -60,7 +60,7 @@ W.access += get_all_centcom_access() W.assignment = "Highlander" W.registered_name = H.real_name - W.item_flags |= NODROP + ADD_TRAIT(W, TRAIT_NODROP, HIGHLANDER) W.update_label(H.real_name) H.equip_to_slot_or_del(W, SLOT_WEAR_ID) diff --git a/code/modules/antagonists/nukeop/equipment/pinpointer.dm b/code/modules/antagonists/nukeop/equipment/pinpointer.dm index d8dc709975..538feba008 100644 --- a/code/modules/antagonists/nukeop/equipment/pinpointer.dm +++ b/code/modules/antagonists/nukeop/equipment/pinpointer.dm @@ -65,9 +65,13 @@ /obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative. name = "cyborg syndicate pinpointer" desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives." - item_flags = NODROP flags_1 = NONE + +/obj/item/pinpointer/syndicate_cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + /obj/item/pinpointer/syndicate_cyborg/scan_for_target() target = null var/list/possible_targets = list() 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/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 4056ac1cea..112a31f44d 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -1,13 +1,21 @@ -//Harvest; activated ly clicking the target, will try to drain their essence. /mob/living/simple_animal/revenant/ClickOn(atom/A, params) //revenants can't interact with the world directly. - A.examine(src) + var/list/modifiers = params2list(params) + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) + AltClickNoInteract(src, A) + return + if(ishuman(A)) if(A in drained_mobs) to_chat(src, "[A]'s soul is dead and empty." ) else if(in_range(src, A)) Harvest(A) + +//Harvest; activated ly clicking the target, will try to drain their essence. /mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) if(!castcheck(0)) return 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/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 0a4a82b862..9fb2c3e2b7 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -100,6 +100,7 @@ deathmessage = "explodes with a sharp pop!" light_color = LIGHT_COLOR_CYAN hud_type = /datum/hud/swarmer + speech_span = SPAN_ROBOT var/resources = 0 //Resource points, generated by consuming metal/glass var/max_resources = 100 @@ -126,9 +127,6 @@ if(statpanel("Status")) stat("Resources:",resources) -/mob/living/simple_animal/hostile/swarmer/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/hostile/swarmer/emp_act() . = ..() if(. & EMP_PROTECT_SELF) @@ -666,7 +664,7 @@ set_light(0) /mob/living/simple_animal/hostile/swarmer/proc/swarmer_chat(msg) - var/rendered = "Swarm communication - [src] [say_quote(msg, get_spans())]" + var/rendered = "Swarm communication - [src] [say_quote(msg)]" for(var/i in GLOB.mob_list) var/mob/M = i if(isswarmer(M)) 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/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 47823a2dc4..e43c2f6254 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -18,7 +18,7 @@ /datum/antagonist/traitor/on_gain() if(owner.current && isAI(owner.current)) traitor_kind = TRAITOR_AI - + SSticker.mode.traitors += owner owner.special_role = special_role if(give_objectives) @@ -48,7 +48,7 @@ A.verbs -= /mob/living/silicon/ai/proc/choose_modules A.malf_picker.remove_malf_verbs(A) qdel(A.malf_picker) - + SSticker.mode.traitors -= owner if(!silent && owner.current) to_chat(owner.current," You are no longer the [special_role]! ") @@ -244,14 +244,16 @@ return var/mob/traitor_mob=owner.current - to_chat(traitor_mob, "The Syndicate provided you with the following information on how to identify their agents:") - to_chat(traitor_mob, "Code Phrase: [GLOB.syndicate_code_phrase]") - to_chat(traitor_mob, "Code Response: [GLOB.syndicate_code_response]") + var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") + var/responses = jointext(GLOB.syndicate_code_response, ", ") - antag_memory += "Code Phrase: [GLOB.syndicate_code_phrase]
    " - antag_memory += "Code Response: [GLOB.syndicate_code_response]
    " + var/dat = "The Syndicate have provided you with the following codewords to identify fellow agents:\n" + dat += "Code Phrase: [phrases]\n" + dat += "Code Response: [responses]" + to_chat(traitor_mob, dat) - to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.") + antag_memory += "Code Phrase: [phrases]
    " + antag_memory += "Code Response: [responses]
    " /datum/antagonist/traitor/proc/add_law_zero() var/mob/living/silicon/ai/killer = owner.current @@ -356,8 +358,14 @@ return result.Join("
    ") /datum/antagonist/traitor/roundend_report_footer() - return "
    The code phrases were: [GLOB.syndicate_code_phrase]
    \ - The code responses were: [GLOB.syndicate_code_response]
    " + var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") + var/responses = jointext(GLOB.syndicate_code_response, ", ") + + var message = "
    The code phrases were: [phrases]
    \ + The code responses were: [responses]
    " + + return message + /datum/antagonist/traitor/is_gamemode_hero() return SSticker.mode.name == "traitor" 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/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..ef0a422079 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 + 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 @@ -291,6 +285,7 @@ if(do_explosion) explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea? + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though. playsound(location, 'sound/effects/supermatter.ogg', 100, 0) else playsound(location, 'sound/effects/phasein.ogg', 75, 0) @@ -322,14 +317,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,15 +349,22 @@ 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/miasma] && cached_gases[/datum/gas/miasma] > 0) + energy_released /= cached_gases[/datum/gas/miasma]*0.1 + if(cached_gases[/datum/gas/bz] && cached_gases[/datum/gas/bz] > 0) + energy_released *= cached_gases[/datum/gas/bz]*0.1 + 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 + if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide]) + cached_gases[/datum/gas/bz] -= min(pressure,1) + cached_gases[/datum/gas/oxygen] += min(pressure,1) + cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency + cached_gases[/datum/gas/plasma] -= 2*reaction_efficency + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, (reaction_efficency**0.5)*BZ_RESEARCH_AMOUNT) if(energy_released > 0) var/new_heat_capacity = air.heat_capacity() @@ -388,17 +389,17 @@ 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 + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0)) if(stim_energy_change) var/new_heat_capacity = air.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) @@ -418,16 +419,16 @@ /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 + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT) if (nob_formed) var/new_heat_capacity = air.heat_capacity() @@ -449,14 +450,14 @@ /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 + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 0a7b76cc79..3bf54a1178 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_GREEN + 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..1de5b93332 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -28,6 +28,30 @@ 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/examine(mob/user) + . = ..() + to_chat(user,"You can hold Ctrl and click on it to toggle it on and off.") + to_chat(user,"You can hold Alt and click on it to maximize its pressure.") + +/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..3a2321c395 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,21 @@ 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/examine(mob/user) + . = ..() + to_chat(user,"You can hold Ctrl and click on it to toggle it on and off.") + to_chat(user,"You can hold Alt and click on it to maximize its pressure.") + +/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("Volume Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Volume 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 +207,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..ac05c94a78 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -12,6 +12,30 @@ construction_type = /obj/item/pipe/trinary/flippable pipe_state = "filter" +/obj/machinery/atmospherics/components/trinary/filter/examine(mob/user) + . = ..() + to_chat(user,"You can hold Ctrl and click on it to toggle it on and off.") + to_chat(user,"You can hold Alt and click on it to maximize its pressure.") + +/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("Filter, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Filter, [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("Filter, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Filter, [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 +183,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 +214,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 +246,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..fc866c3d6a 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -14,7 +14,31 @@ pipe_state = "mixer" //node 3 is the outlet, nodes 1 & 2 are intakes +/obj/machinery/atmospherics/components/trinary/mixer/examine(mob/user) + . = ..() + to_chat(user,"You can hold Ctrl and click on it to toggle it on and off.") + to_chat(user,"You can hold Alt and click on it to maximize its pressure.") +/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("Mixer, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Mixer, [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("Mixer, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Mixer, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + + //node 3 is the outlet, nodes 1 & 2 are intakes /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..552b9dbd64 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -167,10 +167,11 @@ on = FALSE update_icon() playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. - radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language()) + var/msg = "Patient fully restored." if(autoeject) // Eject if configured. - radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language()) + msg += " Auto ejecting patient now." open_machine() + radio.talk_into(src, msg, radio_channel) return var/datum/gas_mixture/air1 = airs[1] @@ -183,8 +184,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 +199,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 +221,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/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 8a1bae5e68..b52dc158e4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -1,18 +1,22 @@ /obj/machinery/atmospherics/components/unary/thermomachine - name = "thermomachine" - desc = "Heats or cools gas in connected pipes." icon = 'icons/obj/atmospherics/components/thermomachine.dmi' icon_state = "freezer" - var/icon_state_off = "freezer" - var/icon_state_on = "freezer_1" - var/icon_state_open = "freezer-o" + + name = "thermomachine" + desc = "Heats or cools gas in connected pipes." + density = TRUE max_integrity = 300 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) layer = OBJ_LAYER circuit = /obj/item/circuitboard/machine/thermomachine + pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + var/icon_state_off = "freezer" + var/icon_state_on = "freezer_1" + var/icon_state_open = "freezer-o" + var/min_temperature = 0 var/max_temperature = 0 var/target_temperature = T20C @@ -45,6 +49,13 @@ if(showpipe) add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) +/obj/machinery/atmospherics/components/unary/thermomachine/examine(mob/user) + . = ..() + . += "The thermostat is set to [target_temperature]K ([(T0C-target_temperature)*-1]C)." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Efficiency [(heat_capacity/5000)*100]%." + . += "Temperature range [min_temperature]K - [max_temperature]K ([(T0C-min_temperature)*-1]C - [(T0C-max_temperature)*-1]C)." + /obj/machinery/atmospherics/components/unary/thermomachine/process_atmos() ..() if(!on || !nodes[1]) @@ -155,6 +166,16 @@ update_icon() +/obj/machinery/atmospherics/components/unary/thermomachine/CtrlClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + on = !on + update_icon() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was turned [on ? "on" : "off"] [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/unary/thermomachine/freezer name = "freezer" icon_state = "freezer" @@ -174,6 +195,13 @@ if(target_temperature == initial(target_temperature)) target_temperature = min_temperature +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom + name = "cold room freezer" + +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom/Initialize() + . = ..() + target_temperature = T0C-80 + /obj/machinery/atmospherics/components/unary/thermomachine/freezer/RefreshParts() ..() var/L @@ -181,6 +209,15 @@ L += M.rating min_temperature = max(T0C - (initial(min_temperature) + L * 15), TCMB) //73.15K with T1 stock parts +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/AltClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + target_temperature = min_temperature + investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was minimized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/unary/thermomachine/heater name = "heater" icon_state = "heater" @@ -201,3 +238,12 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) L += M.rating max_temperature = T20C + (initial(max_temperature) * L) //573.15K with T1 stock parts + +/obj/machinery/atmospherics/components/unary/thermomachine/heater/AltClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + target_temperature = max_temperature + investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") 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/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 881e25f138..fcfdd7c455 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -497,14 +497,14 @@ W.registered_name = H.real_name W.update_label(W.registered_name, W.assignment) - // The shielded hardsuit is already NODROP + // The shielded hardsuit is already TRAIT_NODROP no_drops += H.get_item_by_slot(SLOT_GLOVES) no_drops += H.get_item_by_slot(SLOT_SHOES) no_drops += H.get_item_by_slot(SLOT_W_UNIFORM) no_drops += H.get_item_by_slot(SLOT_EARS) for(var/i in no_drops) var/obj/item/I = i - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) /datum/outfit/ctf/instagib r_hand = /obj/item/gun/energy/laser/instakill diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 7274f73965..74f81ec9a0 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -68,13 +68,18 @@ GLOB.poi_list |= src LAZYADD(GLOB.mob_spawners[job_description ? job_description : name], src) + /obj/effect/mob_spawn/Destroy() GLOB.poi_list -= src - LAZYREMOVE(GLOB.mob_spawners[job_description ? job_description : name], src) - if(!LAZYLEN(GLOB.mob_spawners[job_description ? job_description : name])) - GLOB.mob_spawners -= job_description ? job_description : name + var/job_name = job_description ? job_description : name + LAZYREMOVE(GLOB.mob_spawners[job_name], src) + if(!LAZYLEN(GLOB.mob_spawners[job_name])) + GLOB.mob_spawners -= job_name return ..() +/obj/effect/mob_spawn/proc/can_latejoin() //If it can be taken from the lobby. + return ghost_usable + /obj/effect/mob_spawn/proc/special(mob/M) 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 b5f0e7a240..bf77d836fb 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -131,6 +131,24 @@ unit_name = "security barrier" export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security) +/datum/export/large/gas_canister + cost = 10 //Base cost of canister. You get more for nice gases inside. + unit_name = "Gas Canister" + export_types = list(/obj/machinery/portable_atmospherics/canister) +/datum/export/large/gas_canister/get_cost(obj/O) + var/obj/machinery/portable_atmospherics/canister/C = O + var/worth = 10 + var/gases = C.air_contents.gases + + worth += gases[/datum/gas/bz]*4 + worth += gases[/datum/gas/stimulum]*25 + worth += gases[/datum/gas/hypernoblium]*1000 + worth += gases[/datum/gas/miasma]*15 + worth += gases[/datum/gas/tritium]*7 + worth += gases[/datum/gas/pluoxium]*6 + worth += gases[/datum/gas/nitryl]*30 + return worth + /datum/export/large/odysseus cost = 5500 unit_name = "working odysseus" 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 ca8f10869d..46cc1fa93c 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, @@ -517,14 +516,16 @@ /datum/supply_pack/security/armory/ballistic name = "Combat Shotguns Crate" - desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, and three Shotgun Bandoliers. Requires Armory access to open." + desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open." cost = 8000 contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/storage/belt/bandolier, /obj/item/storage/belt/bandolier, - /obj/item/storage/belt/bandolier) + /obj/item/storage/belt/bandolier, + /obj/item/storage/box/lethalshot, + /obj/item/storage/box/lethalslugs) crate_name = "combat shotguns crate" /datum/supply_pack/security/armory/dragnetgun @@ -568,7 +569,7 @@ /datum/supply_pack/security/armory/fire name = "Incendiary Weapons Crate" - desc = "Burn, baby burn. Contains three incendiary grenades, three plasma canisters, and a flamethrower. Requires Brige access to open." + desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open." cost = 1500 access = ACCESS_HEADS contains = list(/obj/item/flamethrower/full, @@ -577,7 +578,8 @@ /obj/item/tank/internals/plasma, /obj/item/grenade/chem_grenade/incendiary, /obj/item/grenade/chem_grenade/incendiary, - /obj/item/grenade/chem_grenade/incendiary) + /obj/item/grenade/chem_grenade/incendiary, + /obj/item/storage/box/fireshot) crate_name = "incendiary weapons crate" crate_type = /obj/structure/closet/crate/secure/plasma dangerous = TRUE @@ -630,11 +632,13 @@ /datum/supply_pack/security/armory/riotshotguns name = "Riot Shotgun Crate" - desc = "For when the greytide gets really uppity. Contains three riot Shotguns. Requires Armory access to open." + desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open." cost = 6000 contains = list(/obj/item/gun/ballistic/shotgun/riot, /obj/item/gun/ballistic/shotgun/riot, - /obj/item/gun/ballistic/shotgun/riot) + /obj/item/gun/ballistic/shotgun/riot, + /obj/item/storage/box/rubbershot, + /obj/item/storage/box/beanbag) crate_name = "riot shotgun crate" /datum/supply_pack/security/armory/swat @@ -751,13 +755,24 @@ /datum/supply_pack/engineering/engihardsuit name = "Engineering Hardsuit" - desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and maks!" + desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!" cost = 2500 contains = list(/obj/item/tank/internals/air, /obj/item/clothing/mask/gas, /obj/item/clothing/suit/space/hardsuit/engine) crate_name = "engineering hardsuit" +/datum/supply_pack/engineering/atmoshardsuit + name = "Atmospherics Hardsuit" + desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open." + cost = 5000 + access = ACCESS_CE + contains = list(/obj/item/tank/internals/air, + /obj/item/clothing/mask/gas, + /obj/item/clothing/suit/space/hardsuit/engine/atmos) + crate_name = "atmospherics hardsuit" + crate_type = /obj/structure/closet/crate/secure/engineering + /datum/supply_pack/engineering/industrialrcd name = "Industrial RCD" desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles." @@ -873,8 +888,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 +896,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 +972,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." @@ -1137,7 +1157,7 @@ /datum/supply_pack/materials/bz name = "BZ Canister Crate" desc = "Contains a canister of BZ. Requires Toxins access to open." - cost = 5000 + cost = 7500 // Costs 3 credits more than what you can get for selling it. access = ACCESS_TOX_STORAGE contains = list(/obj/machinery/portable_atmospherics/canister/bz) crate_name = "BZ canister crate" @@ -1536,6 +1556,15 @@ crate_type = /obj/structure/closet/crate/secure/science dangerous = TRUE +/datum/supply_pack/science/tech_slugs + name = "Tech Slug Ammo Shells" + desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all." + cost = 1000 + contains = list(/obj/item/storage/box/techsslug, + /obj/item/storage/box/techsslug) + crate_name = "tech slug crate" + + ////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Service ////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -1543,7 +1572,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 +1596,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 +1612,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." @@ -1704,6 +1748,10 @@ 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!" @@ -1912,6 +1960,17 @@ crate_name = "hydroponics backpack crate" crate_type = /obj/structure/closet/crate/secure +/datum/supply_pack/organic/mre + name = "MRE supply kit (emergency rations)" + desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank." + cost = 2000 + contains = list(/obj/item/storage/box/mre/menu1/safe, + /obj/item/storage/box/mre/menu1/safe, + /obj/item/storage/box/mre/menu2/safe, + /obj/item/storage/box/mre/menu2/safe, + /obj/item/storage/box/mre/menu3) + crate_name = "MRE crate (emergency rations)" + /datum/supply_pack/organic/pizza name = "Pizza Crate" desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!" @@ -2204,7 +2263,8 @@ /obj/item/storage/fancy/cigarettes/cigpack_shadyjims, /obj/item/clothing/mask/gas/syndicate, /obj/item/clothing/neck/necklace/dope, - /obj/item/vending_refill/donksoft) + /obj/item/vending_refill/donksoft, + /obj/item/circuitboard/computer/arcade/amputation) crate_name = "crate" /datum/supply_pack/costumes_toys/foamforce @@ -2656,6 +2716,7 @@ /obj/item/restraints/handcuffs/fake/kinky, /obj/item/clothing/head/kitty/genuine, // Why its illegal /obj/item/clothing/head/kitty/genuine, + /obj/item/storage/pill_bottle/penis_enlargement, /obj/structure/reagent_dispensers/keg/aphro) crate_name = "lewd kit" crate_type = /obj/structure/closet/crate @@ -2673,16 +2734,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, @@ -2690,6 +2751,19 @@ /obj/item/pen/fountain) crate_name = "Paperwork" +/datum/supply_pack/misc/randomised/promiscuous + name = "Promiscuous Organs" + desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick." + cost = 4000 //Only get 2! + contraband = TRUE + var/num_contained = 2 + contains = list(/obj/item/autosurgeon/penis, + /obj/item/autosurgeon/testicles, + /obj/item/autosurgeon/vagina, + /obj/item/autosurgeon/breasts, + /obj/item/autosurgeon/womb) + crate_name = "promiscuous organs" + /datum/supply_pack/misc/toner name = "Toner Crate" desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'" diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 5a33d8bd44..89e221c339 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -29,7 +29,7 @@ var/effectQuiet = FALSE //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc) var/effectMissile = FALSE //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground var/effectCircle = FALSE //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here - var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod. + var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod. var/reversing = FALSE //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom var/landingSound //Admin sound to play when the pod lands var/openingSound //Admin sound to play when the pod opens @@ -76,7 +76,7 @@ /obj/structure/closet/supplypod/tool_interact(obj/item/W, mob/user) if (bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways. - return FALSE + return FALSE else ..() @@ -86,13 +86,15 @@ /obj/structure/closet/supplypod/contents_explosion() //Supplypods also protect their contents from the harmful effects of fucking exploding. return +/obj/structure/closet/supplypod/prevent_content_explosion() //Useful for preventing epicenter explosions from damaging contents + return TRUE + /obj/structure/closet/supplypod/toggle(mob/living/user) //Supplypods shouldn't be able to be manually opened under any circumstances, as the open() proc generates supply order datums return /obj/structure/closet/supplypod/proc/preOpen() //Called before the open() proc. Handles anything that occurs right as the pod lands. var/turf/T = get_turf(src) var/list/B = explosionSize //Mostly because B is more readable than explosionSize :p - var/boomTotal = 0 //A counter used to check if the explosion does nothing if (landingSound) playsound(get_turf(src), landingSound, soundVolume, 0, 0) for (var/mob/living/M in T) @@ -108,10 +110,8 @@ M.gib() //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs M.adjustBruteLoss(damage) - for (var/i in B) - boomTotal += i //Count up all the values of the explosion - if (boomTotal != 0) //If the explosion list isn't all zeroes, call an explosion + if (B[1] || B[2] || B[3] || B[4]) //If the explosion list isn't all zeroes, call an explosion explosion(get_turf(src), B[1], B[2], B[3], flame_range = B[4], silent = effectQuiet, ignorecap = istype(src, /obj/structure/closet/supplypod/centcompod)) //less advanced equipment than bluespace pod, so larger explosion when landing else if (!effectQuiet) //If our explosion list IS all zeroes, we still make a nice explosion sound (unless the effectQuiet var is true) playsound(src, "explosion", landingSound ? 15 : 80, 1) @@ -150,10 +150,10 @@ playsound(get_turf(holder), leavingSound, soundVolume, 0, 0) if (reversing) //If we're reversing, we call the close proc. This sends the pod back up to centcom close(holder) - else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists) - if (style != STYLE_INVISIBLE) + else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists) + if (style != STYLE_INVISIBLE) do_sparks(5, TRUE, holder) //Create some sparks right before closing - qdel(src) //Delete ourselves and the holder + qdel(src) //Delete ourselves and the holder if (holder != src) qdel(holder) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 7c08a3332c..5402353fd4 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -467,6 +467,51 @@ GLOBAL_LIST_EMPTY(asset_datums) "stamp-law" = 'icons/stamp_icons/large_stamp-law.png' ) +/datum/asset/spritesheet/simple/minesweeper + name = "minesweeper" + assets = list( + "1" = 'icons/UI_Icons/minesweeper_tiles/one.png', + "2" = 'icons/UI_Icons/minesweeper_tiles/two.png', + "3" = 'icons/UI_Icons/minesweeper_tiles/three.png', + "4" = 'icons/UI_Icons/minesweeper_tiles/four.png', + "5" = 'icons/UI_Icons/minesweeper_tiles/five.png', + "6" = 'icons/UI_Icons/minesweeper_tiles/six.png', + "7" = 'icons/UI_Icons/minesweeper_tiles/seven.png', + "8" = 'icons/UI_Icons/minesweeper_tiles/eight.png', + "empty" = 'icons/UI_Icons/minesweeper_tiles/empty.png', + "flag" = 'icons/UI_Icons/minesweeper_tiles/flag.png', + "hidden" = 'icons/UI_Icons/minesweeper_tiles/hidden.png', + "mine" = 'icons/UI_Icons/minesweeper_tiles/mine.png', + "minehit" = 'icons/UI_Icons/minesweeper_tiles/minehit.png' + ) + +/datum/asset/spritesheet/simple/pills + name = "pills" + assets = list( + "pill1" = 'icons/UI_Icons/Pills/pill1.png', + "pill2" = 'icons/UI_Icons/Pills/pill2.png', + "pill3" = 'icons/UI_Icons/Pills/pill3.png', + "pill4" = 'icons/UI_Icons/Pills/pill4.png', + "pill5" = 'icons/UI_Icons/Pills/pill5.png', + "pill6" = 'icons/UI_Icons/Pills/pill6.png', + "pill7" = 'icons/UI_Icons/Pills/pill7.png', + "pill8" = 'icons/UI_Icons/Pills/pill8.png', + "pill9" = 'icons/UI_Icons/Pills/pill9.png', + "pill10" = 'icons/UI_Icons/Pills/pill10.png', + "pill11" = 'icons/UI_Icons/Pills/pill11.png', + "pill12" = 'icons/UI_Icons/Pills/pill12.png', + "pill13" = 'icons/UI_Icons/Pills/pill13.png', + "pill14" = 'icons/UI_Icons/Pills/pill14.png', + "pill15" = 'icons/UI_Icons/Pills/pill15.png', + "pill16" = 'icons/UI_Icons/Pills/pill16.png', + "pill17" = 'icons/UI_Icons/Pills/pill17.png', + "pill18" = 'icons/UI_Icons/Pills/pill18.png', + "pill19" = 'icons/UI_Icons/Pills/pill19.png', + "pill20" = 'icons/UI_Icons/Pills/pill20.png', + "pill21" = 'icons/UI_Icons/Pills/pill21.png', + "pill22" = 'icons/UI_Icons/Pills/pill22.png', + ) + /datum/asset/simple/IRV assets = list( "jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js', diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8e4891fb70..9e48591361 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -59,6 +59,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/preferred_map = null var/pda_style = MONO var/pda_color = "#808000" + var/pda_skin = PDA_SKIN_ALT var/uses_glasses_colour = 0 @@ -70,8 +71,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/underwear = "Nude" //underwear type + var/undie_color = "#FFFFFF" var/undershirt = "Nude" //undershirt type + var/shirt_color = "#FFFFFF" var/socks = "Nude" //socks type + var/socks_color = "#FFFFFF" var/backbag = DBACKPACK //backpack type var/hair_style = "Bald" //Hair type var/hair_color = "000" //Hair color @@ -117,6 +121,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) "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, @@ -153,6 +158,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) ) var/list/custom_names = list() + var/preferred_ai_core_display = "Blue" var/prefered_security_department = SEC_DEPT_RANDOM var/custom_species = null @@ -302,10 +308,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 @@ -670,8 +677,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" @@ -682,47 +695,48 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if(pref_species.use_skintones) dat += "Genitals use skintone:[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]" - dat += "Has Penis:" + dat += "

    Penis

    " dat += "[features["has_cock"] == TRUE ? "Yes" : "No"]" - if(features["has_cock"] == TRUE) + if(features["has_cock"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Penis Color:" - dat += "   (Skin tone overriding)
    " + dat += "Penis Color:
    " + dat += "   (Skin tone overriding)
    " else - dat += "Penis Color:" + dat += "Penis Color:
    " dat += "   Change
    " dat += "Penis Shape:[features["cock_shape"]]" dat += "Penis Length:[features["cock_length"]] inch(es)" dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]" - if(features["has_balls"] == TRUE) + if(features["has_balls"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Testicles Color:" + dat += "Testicles Color:
    " dat += "   (Skin tone overriding)
    " else - dat += "Testicles Color:" + dat += "Testicles Color:
    " dat += "   Change
    " + dat += "Testicles showing:[features["balls_shape"]]" dat += APPEARANCE_CATEGORY_COLUMN - dat += "Has Vagina:" + dat += "

    Vagina

    " dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" if(features["has_vag"]) dat += "Vagina Type:[features["vag_shape"]]" if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Vagina Color:" + dat += "Vagina Color:
    " dat += "   (Skin tone overriding)
    " else - dat += "Vagina Color:" + dat += "Vagina Color:
    " dat += "   Change
    " dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]" dat += "" dat += APPEARANCE_CATEGORY_COLUMN - dat += "Has Breasts:" + dat += "

    Breasts

    " dat += "[features["has_breasts"] == TRUE ? "Yes" : "No"]" if(features["has_breasts"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Color:" + dat += "Color:
    " dat += "   (Skin tone overriding)
    " else - dat += "Color:" + dat += "Color:
    " dat += "   Change
    " dat += "Cup Size:[features["breasts_size"]]" dat += "Breast Shape:[features["breasts_shape"]]" @@ -742,6 +756,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
    " dat += "PDA Color:   Change
    " dat += "PDA Style:[pda_style]
    " + dat += "PDA Reskin:[pda_skin]
    " dat += "
    " dat += "Ghost Ears:[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
    " dat += "Ghost Radio:[(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]
    " @@ -1392,10 +1407,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) facial_hair_style = random_facial_hair_style(gender) if("underwear") underwear = random_underwear(gender) + undie_color = random_color() if("undershirt") undershirt = random_undershirt(gender) + shirt_color = random_color() if("socks") socks = random_socks() + socks_color = random_color() if(BODY_ZONE_PRECISE_EYES) eye_color = random_eye_color() if("s_tone") @@ -1458,7 +1476,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 @@ -1501,29 +1519,35 @@ GLOBAL_LIST_EMPTY(preferences_datums) bgstate = next_list_item(bgstate, bgstate_options) if("underwear") - var/new_underwear - if(gender == MALE) - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m - else - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f + var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list if(new_underwear) underwear = new_underwear + if("undie_color") + var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", undie_color) as color|null + if(n_undie_color) + undie_color = n_undie_color + if("undershirt") - var/new_undershirt - if(gender == MALE) - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m - else - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f + var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list if(new_undershirt) undershirt = new_undershirt + if("shirt_color") + var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", shirt_color) as color|null + if(n_shirt_color) + shirt_color = n_shirt_color + if("socks") - var/new_socks - new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list + var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list if(new_socks) socks = new_socks + if("socks_color") + var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", socks_color) as color|null + if(n_socks_color) + socks_color = n_socks_color + if("eyes") var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null if(new_eyes) @@ -1836,7 +1860,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 @@ -1858,7 +1882,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 @@ -1874,7 +1904,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 @@ -1897,7 +1927,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 @@ -1914,7 +1944,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 @@ -1931,8 +1961,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 @@ -1971,6 +2006,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference",pda_color) as color|null if(pickedPDAColor) pda_color = pickedPDAColor + if("pda_skin") + var/pickedPDASkin = input(user, "Choose your PDA reskin.", "Character Preference", pda_skin) as null|anything in GLOB.pda_reskins + if(pickedPDASkin) + pda_skin = pickedPDASkin else switch(href_list["preference"]) @@ -1981,6 +2020,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) arousable = !arousable if("has_cock") features["has_cock"] = !features["has_cock"] + if(features["has_cock"] == FALSE) + features["has_balls"] = FALSE if("has_balls") features["has_balls"] = !features["has_balls"] if("has_ovi") @@ -1995,6 +2036,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["has_breasts"] = !features["has_breasts"] if("has_vag") features["has_vag"] = !features["has_vag"] + if(features["has_vag"] == FALSE) + features["has_womb"] = FALSE if("has_womb") features["has_womb"] = !features["has_womb"] if("exhibitionist") @@ -2221,8 +2264,16 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.hair_style = hair_style character.facial_hair_style = facial_hair_style character.underwear = underwear + + character.saved_underwear = underwear character.undershirt = undershirt + character.saved_undershirt = undershirt character.socks = socks + character.saved_socks = socks + character.undie_color = undie_color + character.shirt_color = shirt_color + character.socks_color = socks_color + character.backbag = backbag diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 39b44f1ab9..b9c5cb7ef9 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -108,6 +108,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["tip_delay"] >> tip_delay S["pda_style"] >> pda_style S["pda_color"] >> pda_color + S["pda_skin"] >> pda_skin //citadel code S["arousable"] >> arousable @@ -144,6 +145,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car be_special = SANITIZE_LIST(be_special) pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) + pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT) screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) @@ -200,6 +202,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["tip_delay"], tip_delay) WRITE_FILE(S["pda_style"], pda_style) WRITE_FILE(S["pda_color"], pda_color) + WRITE_FILE(S["pda_skin"], pda_skin) //citadel code WRITE_FILE(S["screenshake"], screenshake) @@ -263,8 +266,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["hair_style_name"] >> hair_style S["facial_style_name"] >> facial_hair_style S["underwear"] >> underwear + S["undie_color"] >> undie_color S["undershirt"] >> undershirt + S["shirt_color"] >> shirt_color S["socks"] >> socks + S["socks_color"] >> socks_color S["backbag"] >> backbag S["uplink_loc"] >> uplink_spawn_loc S["feature_mcolor"] >> features["mcolor"] @@ -284,6 +290,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 @@ -330,6 +337,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 @@ -383,14 +391,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(gender == MALE) hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_male_list) facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_male_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_m) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_m) else hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_female_list) facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_female_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_f) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_f) + underwear = sanitize_inlist(underwear, GLOB.underwear_list) + undie_color = sanitize_hexcolor(undie_color, 6, 1, initial(undie_color)) + undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) + shirt_color = sanitize_hexcolor(shirt_color, 6, 1, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) + socks_color = sanitize_hexcolor(socks_color, 6, 1, initial(socks_color)) age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) hair_color = sanitize_hexcolor(hair_color, 3, 0) facial_hair_color = sanitize_hexcolor(facial_hair_color, 3, 0) @@ -460,8 +469,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["hair_style_name"] , hair_style) WRITE_FILE(S["facial_style_name"] , facial_hair_style) WRITE_FILE(S["underwear"] , underwear) + WRITE_FILE(S["undie_color"] , undie_color) WRITE_FILE(S["undershirt"] , undershirt) + WRITE_FILE(S["shirt_color"] , shirt_color) WRITE_FILE(S["socks"] , socks) + WRITE_FILE(S["socks_color"] , socks_color) WRITE_FILE(S["backbag"] , backbag) WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc) WRITE_FILE(S["species"] , pref_species.id) @@ -482,6 +494,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/chameleon.dm b/code/modules/clothing/chameleon.dm index e4cc477f11..04a8e17b7b 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -60,7 +60,7 @@ to_chat(owner, "You shouldn't be able to toggle a camogear helmetmask if you're not wearing it") if(new_headgear) // Force drop the item in the headslot, even though - // it's NODROP_1 + // it's TRAIT_NODROP D.dropItemToGround(target, TRUE) qdel(old_headgear) // where is `SLOT_HEAD` defined? WHO KNOWS @@ -226,6 +226,19 @@ CL.flags_cover = initial(PCL.flags_cover) target.icon = initial(picked_item.icon) +/datum/action/item_action/chameleon/change/pda/update_item(obj/item/pda/picked_item) + if(!istype(target, /obj/item/pda)) + return ..() + var/obj/item/pda/P = target + P.name = initial(picked_item.name) + P.desc = initial(picked_item.desc) + P.icon_state = initial(picked_item.icon_state) + P.item_state = initial(picked_item.item_state) + P.item_color = initial(picked_item.item_color) + P.overlays_offsets = initial(picked_item.overlays_offsets) + P.set_new_overlays() + P.update_icon() + /datum/action/item_action/chameleon/change/Trigger() if(!IsAvailable()) return @@ -405,12 +418,12 @@ /obj/item/clothing/head/chameleon/drone // The camohat, I mean, holographic hat projection, is part of the // drone itself. - item_flags = NODROP armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) // which means it offers no protection, it's just air and light /obj/item/clothing/head/chameleon/drone/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src) togglehatmask_action.UpdateButtonIcon() @@ -459,13 +472,13 @@ /obj/item/clothing/mask/chameleon/drone //Same as the drone chameleon hat, undroppable and no protection - item_flags = NODROP armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) // Can drones use the voice changer part? Let's not find out. vchange = 0 /obj/item/clothing/mask/chameleon/drone/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src) togglehatmask_action.UpdateButtonIcon() @@ -584,7 +597,7 @@ /obj/item/pda/chameleon name = "PDA" - var/datum/action/item_action/chameleon/change/chameleon_action + var/datum/action/item_action/chameleon/change/pda/chameleon_action /obj/item/pda/chameleon/Initialize() . = ..() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 746d5da60d..ed3e9f9b89 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -43,6 +43,8 @@ /obj/item/clothing/Initialize() . = ..() + if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) + actions_types += /datum/action/item_action/toggle_voice_box if(ispath(pocket_storage_component_path)) LoadComponent(pocket_storage_component_path) @@ -135,7 +137,7 @@ update_clothes_damaged_state(TRUE) if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it var/mob/M = loc - M.visible_message("[M]'s [name] starts to fall apart!", "Your [name] starts to fall apart!") + to_chat(M, "Your [name] starts to fall apart!") /obj/item/clothing/proc/update_clothes_damaged_state(damaging = TRUE) var/index = "[REF(initial(icon))]-[initial(icon_state)]" @@ -216,6 +218,34 @@ BLIND // can't see anything ..() +/obj/item/clothing/under/CtrlClick(mob/user) + . = ..() + + if (!(item_flags & IN_INVENTORY)) + return + + if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + + if(has_sensor == LOCKED_SENSORS) + to_chat(user, "The controls are locked.") + return + if(has_sensor == BROKEN_SENSORS) + to_chat(user, "The sensors have shorted out!") + return + if(has_sensor <= NO_SENSORS) + to_chat(user, "This suit does not have any sensors.") + return + + sensor_mode = SENSOR_COORDS + + to_chat(user, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.w_uniform == src) + H.update_suit_sensors() + /obj/item/clothing/under/AltClick(mob/user) if(..()) return 1 diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 7f7b3ae0ed..097b10cae5 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) @@ -98,7 +98,7 @@ desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents." icon_state = "purple" item_state = "glasses" - scan_reagents = 1 //You can see reagents while wearing science goggles + scan_reagents = TRUE //You can see reagents while wearing science goggles actions_types = list(/datum/action/item_action/toggle_research_scanner) glass_colour_type = /datum/client_colour/glass_colour/purple resistance_flags = ACID_PROOF @@ -202,7 +202,7 @@ /obj/item/clothing/glasses/sunglasses/reagent name = "beer goggles" desc = "A pair of sunglasses outfitted with apparatus to scan reagents." - scan_reagents = 1 + scan_reagents = TRUE /obj/item/clothing/glasses/sunglasses/garb name = "black gar glasses" @@ -377,11 +377,14 @@ item_state = "godeye" vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS darkness_view = 8 - scan_reagents = 1 - item_flags = NODROP + scan_reagents = TRUE lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE resistance_flags = LAVA_PROOF | FIRE_PROOF +/obj/item/clothing/glasses/godeye/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, EYE_OF_GOD_TRAIT) + /obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, src) && W != src && W.loc == user) if(W.icon_state == "godeye") diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 1b20501f21..e95a836a0d 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -7,6 +7,7 @@ permeability_coefficient = 0.05 item_color="yellow" resistance_flags = NONE + var/can_be_cut = 1 /obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly." @@ -17,6 +18,7 @@ permeability_coefficient = 0.05 item_color="yellow" resistance_flags = NONE + var/can_be_cut = 1 /obj/item/clothing/gloves/color/fyellow/New() ..() @@ -30,6 +32,38 @@ . = ..() siemens_coefficient = pick(0,0,0,0.5,0.5,0.5,0.75) +/obj/item/clothing/gloves/cut + desc = "These gloves would protect the wearer from electric shock.. if the fingers were covered." + name = "fingerless insulated gloves" + icon_state = "yellowcut" + item_state = "yglovescut" + siemens_coefficient = 1 + permeability_coefficient = 1 + resistance_flags = NONE + transfer_prints = TRUE + +/obj/item/clothing/gloves/cut/family + desc = "The old gloves your great grandfather stole from Engineering, many moons ago. They've seen some tough times recently." + name = "fingerless insulated gloves" + +/obj/item/clothing/gloves/color/yellow/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/wirecutters)) + if(can_be_cut && icon_state == initial(icon_state))//only if not dyed + to_chat(user, "You snip the fingertips off of [src].") + I.play_tool_sound(src) + new /obj/item/clothing/gloves/cut(drop_location()) + qdel(src) + ..() + +/obj/item/clothing/gloves/color/fyellow/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/wirecutters)) + if(can_be_cut && icon_state == initial(icon_state))//only if not dyed + to_chat(user, "You snip the fingertips off of [src].") + I.play_tool_sound(src) + new /obj/item/clothing/gloves/cut(drop_location()) + qdel(src) + ..() + /obj/item/clothing/gloves/color/black desc = "These gloves are fire-resistant." name = "black gloves" @@ -184,32 +218,3 @@ /obj/item/clothing/gloves/color/white/redcoat item_color = "redcoat" //Exists for washing machines. Is not different from white gloves in any way. - -/obj/item/clothing/gloves/color/random - name = "random gloves" - desc = "These gloves are supposed to be a random color..." - icon_state = "random_gloves" - item_state = "wgloves" - item_color = "mime" - -/obj/item/clothing/gloves/color/random/Initialize() - ..() - var/list/gloves = list( - /obj/item/clothing/gloves/color/orange = 1, - /obj/item/clothing/gloves/color/red = 1, - /obj/item/clothing/gloves/color/blue = 1, - /obj/item/clothing/gloves/color/purple = 1, - /obj/item/clothing/gloves/color/green = 1, - /obj/item/clothing/gloves/color/grey = 1, - /obj/item/clothing/gloves/color/light_brown = 1, - /obj/item/clothing/gloves/color/brown = 1, - /obj/item/clothing/gloves/color/white = 1, - /obj/item/clothing/gloves/color/rainbow = 1) - - var/obj/item/clothing/gloves/color/selected = pick(gloves) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.equip_to_slot_or_del(new selected(H), SLOT_GLOVES) - else - new selected(loc) - return INITIALIZE_HINT_QDEL 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/helmet.dm b/code/modules/clothing/head/helmet.dm index 8ffcc6eea7..f4b4e4a96d 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -54,6 +54,8 @@ tint = 2 /obj/item/clothing/head/helmet/blueshirt + name = "blue helmet" + desc = "A reliable, blue tinted helmet reminding you that you still owe that engineer a beer." icon_state = "blueshift" item_state = "blueshift" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index b6c5a5417a..23e1825c3d 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -1,3 +1,8 @@ +//defines the drill hat's yelling setting +#define DRILL_DEFAULT "default" +#define DRILL_SHOUTING "shouting" +#define DRILL_YELLING "yelling" +#define DRILL_CANADIAN "canadian" //Chef /obj/item/clothing/head/chefhat @@ -42,6 +47,7 @@ name = "captain's beret" desc = "A beret fit for a leader." icon_state = "capberet" + dynamic_hair_suffix = "" dog_fashion = null @@ -57,6 +63,7 @@ name = "head of personnel's beret" desc = "The symbol of true bureaucratic micromanagement, although in a fancy form." icon_state = "hopberet" + dynamic_hair_suffix = "" dog_fashion = null @@ -114,9 +121,12 @@ /obj/item/clothing/head/beret/highlander desc = "That was white fabric. Was." - item_flags = NODROP dog_fashion = null //THIS IS FOR SLAUGHTER, NOT PUPPIES +/obj/item/clothing/head/beret/highlander/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) + //Security /obj/item/clothing/head/HoS @@ -148,6 +158,73 @@ strip_delay = 60 dog_fashion = /datum/dog_fashion/head/warden +/obj/item/clothing/head/warden/drill + name = "warden's campaign hat" + desc = "A special armored campaign hat with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection. Has the letters 'FMJ' enscribed on its side." + icon_state = "wardendrill" + item_state = "wardendrill" + dog_fashion = null + var/mode = DRILL_DEFAULT + +/obj/item/clothing/head/warden/drill/screwdriver_act(mob/living/carbon/human/user, obj/item/I) + if(..()) + return TRUE + switch(mode) + if(DRILL_DEFAULT) + to_chat(user, "You set the voice circuit to the middle position.") + mode = DRILL_SHOUTING + if(DRILL_SHOUTING) + to_chat(user, "You set the voice circuit to the last position.") + mode = DRILL_YELLING + if(DRILL_YELLING) + to_chat(user, "You set the voice circuit to the first position.") + mode = DRILL_DEFAULT + if(DRILL_CANADIAN) + to_chat(user, "You adjust voice circuit but nothing happens, probably because it's broken.") + return TRUE + +/obj/item/clothing/head/warden/drill/wirecutter_act(mob/living/user, obj/item/I) + if(mode != DRILL_CANADIAN) + to_chat(user, "You broke the voice circuit!") + mode = DRILL_CANADIAN + return TRUE + +/obj/item/clothing/head/warden/drill/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HEAD) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/warden/drill/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + switch (mode) + if(DRILL_SHOUTING) + message += "!" + if(DRILL_YELLING) + message += "!!" + if(DRILL_CANADIAN) + message = " [message]" + var/list/canadian_words = strings("canadian_replacement.json", "canadian") + + for(var/key in canadian_words) + var/value = canadian_words[key] + if(islist(value)) + value = pick(value) + + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") + + if(prob(30)) + message += pick(", eh?", ", EH?") + speech_args[SPEECH_MESSAGE] = message + /obj/item/clothing/head/beret/sec name = "security beret" desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection." @@ -201,3 +278,8 @@ name = "quartermaster's beret" desc = "This headwear shows off your Cargonian leadership" icon_state = "qmberet" + +#undef DRILL_DEFAULT +#undef DRILL_SHOUTING +#undef DRILL_YELLING +#undef DRILL_CANADIAN diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index d9c151a47b..73fde5d50f 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -221,9 +221,12 @@ icon_state = "shamebrero" item_state = "shamebrero" desc = "Once it's on, it never comes off." - item_flags = NODROP dog_fashion = null +/obj/item/clothing/head/sombrero/shamebrero/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) + /obj/item/clothing/head/cone desc = "This cone is trying to warn you of something!" name = "warning cone" @@ -330,9 +333,21 @@ icon_state = "beretblack" dynamic_hair_suffix = "" -/obj/item/clothing/head/frenchberet/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/head/frenchberet/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HEAD) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/frenchberet/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/frenchberet/proc/handle_speech(datum/source, mob/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/french_words = strings("french_replacement.json", "french") for(var/key in french_words) @@ -340,10 +355,10 @@ if(islist(value)) value = pick(value) - M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]") - M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]") - M = replacetextEx(M, " [key]", " [value]") + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") if(prob(3)) - M += pick(" Honh honh honh!"," Honh!"," Zut Alors!") - return trim(M) + message += pick(" Honh honh honh!"," Honh!"," Zut Alors!") + speech_args[SPEECH_MESSAGE] = trim(message) diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index 8f10184f86..9ee2ebcd54 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -5,12 +5,54 @@ slot_flags = ITEM_SLOT_MASK strip_delay = 40 equip_delay_other = 40 + var/modifies_speech = FALSE var/mask_adjusted = 0 var/adjusted_flags = null var/muzzle_var = NORMAL_STYLE mutantrace_variation = NO_MUTANTRACE_VARIATION //most masks have overrides, but not all probably. +/obj/item/clothing/mask/attack_self(mob/user) + if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) + TOGGLE_BITFIELD(clothing_flags, VOICEBOX_DISABLED) + var/status = !CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED) + to_chat(user, "You turn the voice box in [src] [status ? "on" : "off"].") + +/obj/item/clothing/mask/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_WEAR_MASK && modifies_speech) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + var/datum/species/pref_species = H.dna.species + + if(mutantrace_variation) + 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_wear_mask() + +/obj/item/clothing/mask/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/mask/proc/handle_speech() + /obj/item/clothing/mask/worn_overlays(isinhands = FALSE) . = list() if(!isinhands) @@ -20,31 +62,6 @@ IF_HAS_BLOOD_DNA(src) . += mutable_appearance('icons/effects/blood.dmi', "maskblood") -/obj/item/clothing/mask/equipped(mob/user, slot) - ..() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/datum/species/pref_species = H.dna.species - - if(mutantrace_variation) - 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_wear_mask() - - /obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE) ..() if(ismob(loc)) diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index c0752d9799..3960bdadeb 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -20,9 +20,11 @@ flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL mutantrace_variation = MUTANTRACE_VARIATION + modifies_speech = TRUE -/obj/item/clothing/mask/luchador/speechModification(message) - if(copytext(message, 1, 2) != "*") +/obj/item/clothing/mask/luchador/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = replacetext(message, "captain", "CAPITÁN") message = replacetext(message, "station", "ESTACIÓN") message = replacetext(message, "sir", "SEÑOR") @@ -42,7 +44,7 @@ message = uppertext(message) //Things end up looking better this way (no mixed cases), and it fits the macho wrestler image. if(prob(25)) message += " OLE!" - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/clothing/mask/luchador/tecnicos name = "Tecnicos Mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 9476c50603..5dfa7d6047 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -46,10 +46,12 @@ /obj/item/clothing/mask/fakemoustache/italian name = "italian moustache" desc = "Made from authentic Italian moustache hairs. Gives the wearer an irresistable urge to gesticulate wildly." + modifies_speech = TRUE -/obj/item/clothing/mask/fakemoustache/italian/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/mask/fakemoustache/italian/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/italian_words = strings("italian_replacement.json", "italian") for(var/key in italian_words) @@ -57,13 +59,13 @@ if(islist(value)) value = pick(value) - M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]") - M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]") - M = replacetextEx(M, " [key]", " [value]") + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") if(prob(3)) - M += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!") - return trim(M) + message += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!") + speech_args[SPEECH_MESSAGE] = trim(message) /obj/item/clothing/mask/joy name = "joy mask" @@ -73,36 +75,28 @@ /obj/item/clothing/mask/pig name = "pig mask" - desc = "A rubber pig mask." + desc = "A rubber pig mask with a builtin voice modulator." icon_state = "pig" item_state = "pig" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + clothing_flags = VOICEBOX_TOGGLABLE w_class = WEIGHT_CLASS_SMALL - actions_types = list(/datum/action/item_action/toggle_voice_box) - var/voicechange = 0 + modifies_speech = TRUE -/obj/item/clothing/mask/pig/attack_self(mob/user) - voicechange = !voicechange - to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!") +/obj/item/clothing/mask/pig/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("Oink!","Squeeeeeeee!","Oink Oink!") -/obj/item/clothing/mask/pig/speechModification(message) - if(voicechange) - message = pick("Oink!","Squeeeeeeee!","Oink Oink!") - return message - -/obj/item/clothing/mask/spig //needs to be different otherwise you could turn the speedmodification off and on +/obj/item/clothing/mask/pig/cursed //needs to be different otherwise you could turn the speedmodification off and on name = "Pig face" desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" //It's only ever going to be attached to your face. - icon_state = "pig" - item_state = "pig" - flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + flags_inv = HIDEFACIALHAIR + clothing_flags = NONE -/obj/item/clothing/mask/spig/speechModification(message) - if(voicechange) - message = pick("Oink!","Squeeeeeeee!","Oink Oink!") - return message +/obj/item/clothing/mask/pig/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/pighead_curse.ogg', 50, 1) ///frog mask - reeee!! /obj/item/clothing/mask/frog @@ -112,47 +106,55 @@ item_state = "frog" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - var/voicechange = TRUE + clothing_flags = VOICEBOX_TOGGLABLE + modifies_speech = TRUE -/obj/item/clothing/mask/frog/attack_self(mob/user) - voicechange = !voicechange - to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!") - -/obj/item/clothing/mask/frog/speechModification(message) //whenever you speak - if(voicechange) +/obj/item/clothing/mask/frog/handle_speech(datum/source, list/speech_args) //whenever you speak + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) if(prob(5)) //sometimes, the angry spirit finds others words to speak. - message = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") + speech_args[SPEECH_MESSAGE] = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") else - message = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish, - return message + speech_args[SPEECH_MESSAGE] = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish, /obj/item/clothing/mask/frog/cursed - item_flags = NODROP //reee!! + clothing_flags = NONE -/obj/item/clothing/mask/frog/cursed/attack_self(mob/user) - return //no voicebox to alter. +/obj/item/clothing/mask/frog/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) /obj/item/clothing/mask/frog/cursed/equipped(mob/user, slot) var/mob/living/carbon/C = user - if(C.wear_mask == src) - to_chat(user, "[src] was cursed! Ree!!") + if(C.wear_mask == src && HAS_TRAIT_FROM(src, TRAIT_NODROP, CURSED_ITEM_TRAIT)) + to_chat(user, "[src] was cursed! Ree!!") return ..() - /obj/item/clothing/mask/cowmask - name = "Cowface" - desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" + name = "Cow mask with a builtin voice modulator." + desc = "A rubber cow mask," icon = 'icons/mob/mask.dmi' icon_state = "cowmask" item_state = "cowmask" + clothing_flags = VOICEBOX_TOGGLABLE flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + modifies_speech = TRUE -/obj/item/clothing/mask/cowmask/speechModification(message) - if(voicechange) - message = pick("Moooooooo!","Moo!","Moooo!") - return message +/obj/item/clothing/mask/cowmask/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("Moooooooo!","Moo!","Moooo!") + + +/obj/item/clothing/mask/cowmask/cursed + name = "cow face" + desc = "It looks like a cow mask, but closer inspection reveals it's melded onto this persons face!" + flags_inv = HIDEFACIALHAIR + clothing_flags = NONE + +/obj/item/clothing/mask/cowmask/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/cowhead_curse.ogg', 50, 1) /obj/item/clothing/mask/horsehead name = "horse head mask" @@ -161,12 +163,23 @@ item_state = "horsehead" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEYES|HIDEEARS w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + clothing_flags = VOICEBOX_TOGGLABLE -/obj/item/clothing/mask/horsehead/speechModification(message) - if(voicechange) - message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") - return message +/obj/item/clothing/mask/horsehead/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") + + +/obj/item/clothing/mask/horsehead/cursed + name = "horse face" + desc = "It initially looks like a mask, but it's melded into the poor person's face." + clothing_flags = NONE + flags_inv = HIDEFACIALHAIR + +/obj/item/clothing/mask/horsehead/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/horsehead_curse.ogg', 50, 1) /obj/item/clothing/mask/rat name = "rat mask" @@ -285,16 +298,18 @@ item_state = "gondola" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL + modifies_speech = TRUE -/obj/item/clothing/mask/gondola/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/mask/gondola/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/spurdo_words = strings("spurdo_replacement.json", "spurdo") for(var/key in spurdo_words) var/value = spurdo_words[key] if(islist(value)) value = pick(value) - M = replacetextEx(M,regex(uppertext(key),"g"), "[uppertext(value)]") - M = replacetextEx(M,regex(capitalize(key),"g"), "[capitalize(value)]") - M = replacetextEx(M,regex(key,"g"), "[value]") - return trim(M) + message = replacetextEx(message,regex(uppertext(key),"g"), "[uppertext(value)]") + message = replacetextEx(message,regex(capitalize(key),"g"), "[capitalize(value)]") + message = replacetextEx(message,regex(key,"g"), "[value]") + speech_args[SPEECH_MESSAGE] = trim(message) diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 4179e69a45..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) 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/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index a6bcf23a2d..e6554f6125 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -9,7 +9,7 @@ /obj/item/clothing/shoes/combat //basic syndicate combat boots for nuke ops and mob corpses name = "combat boots" desc = "High speed, low drag combat boots." - icon_state = "jackboots" + icon_state = "combat" item_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' @@ -157,7 +157,11 @@ icon_state = "cultalt" /obj/item/clothing/shoes/cult/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/shoes/cult/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/clothing/shoes/cyborg name = "cyborg boots" 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/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index d0820304fe..5a53e2776a 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -27,7 +27,6 @@ armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000) resistance_flags = FIRE_PROOF | ACID_PROOF var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun) - var/list/hands_nodrop = list() var/obj/item/clothing/head/helmet/space/chronos/helmet = null var/obj/effect/chronos_cam/camera = null var/datum/action/innate/chrono_teleport/teleport_now = new @@ -97,8 +96,7 @@ user.anchored = FALSE teleporting = 0 for(var/obj/item/I in user.held_items) - if(I in hands_nodrop) - I.item_flags &= ~NODROP + REMOVE_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) if(camera) camera.remove_target_ui() camera.forceMove(user) @@ -131,11 +129,8 @@ user.ExtinguishMob() - hands_nodrop = list() for(var/obj/item/I in user.held_items) - if(!(I.item_flags & NODROP)) - hands_nodrop += I - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) user.animate_movement = NO_STEPS user.changeNext_move(8 + phase_in_ds) user.notransform = 1 @@ -194,9 +189,9 @@ if(user.head && istype(user.head, /obj/item/clothing/head/helmet/space/chronos)) to_chat(user, "\[ ok \] Mounting /dev/helm") helmet = user.head - helmet.item_flags |= NODROP + ADD_TRAIT(helmet, TRAIT_NODROP, CHRONOSUIT_TRAIT) helmet.suit = src - src.item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, CHRONOSUIT_TRAIT) to_chat(user, "\[ ok \] Starting brainwave scanner") to_chat(user, "\[ ok \] Starting ui display driver") to_chat(user, "\[ ok \] Initializing chronowalk4-view") @@ -215,7 +210,7 @@ activating = 1 var/mob/living/carbon/human/user = src.loc var/hard_landing = teleporting && force - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, CHRONOSUIT_TRAIT) cooldown = world.time + cooldowntime * 1.5 activated = 0 activating = 0 @@ -236,7 +231,7 @@ to_chat(user, "\[ ok \] Unmounting /dev/helmet") to_chat(user, "logout") if(helmet) - helmet.item_flags &= ~NODROP + REMOVE_TRAIT(helmet, TRAIT_NODROP, CHRONOSUIT_TRAIT) helmet.suit = null helmet = null if(camera) diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 176bc81665..b105b72234 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -897,7 +897,7 @@ usermessage("You're already wearing something on your back!", "boldwarning") return FALSE user.equip_to_slot_if_possible(pack,SLOT_BACK,0,0,1) - pack.item_flags |= NODROP + ADD_TRAIT(pack, TRAIT_NODROP, FLIGHTSUIT_TRAIT) resync() user.visible_message("A [pack.name] extends from [user]'s [name] and clamps to [user.p_their()] back!") user.update_inv_wear_suit() @@ -911,7 +911,7 @@ return FALSE if(pack.flight && forced) pack.disable_flight(1) - pack.item_flags &= ~NODROP + REMOVE_TRAIT_FROM(pack, TRAIT_NODROP, FLIGHTSUIT_TRAIT) resync() if(user) user.transferItemToLoc(pack, src, TRUE) @@ -935,14 +935,14 @@ usermessage("You're already wearing something on your feet!", "boldwarning") return FALSE user.equip_to_slot_if_possible(shoes,SLOT_SHOES,0,0,1) - shoes.item_flags |= NODROP + ADD_TRAIT(shoes, TRAIT_NODROP, FLIGHTSUIT_TRAIT) user.visible_message("[user]'s [name] extends a pair of [shoes.name] over [user.p_their()] feet!") user.update_inv_wear_suit() playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) deployedshoes = TRUE /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/retract_flightshoes(forced = FALSE) - shoes.item_flags &= ~NODROP + REMOVE_TRAIT_FROM(shoes, TRAIT_NODROP, FLIGHTSUIT_TRAIT) playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) if(user) user.transferItemToLoc(shoes, src, TRUE) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index c061d756b7..85503c720a 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" @@ -445,7 +444,8 @@ item_color = "medical" flash_protect = 0 armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) - scan_reagents = 1 + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + scan_reagents = TRUE /obj/item/clothing/suit/space/hardsuit/medical icon_state = "hardsuit-medical" @@ -467,7 +467,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) var/obj/machinery/doppler_array/integrated/bomb_radar - scan_reagents = 1 + scan_reagents = TRUE actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner) /obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize() @@ -499,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" @@ -510,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" @@ -532,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" @@ -623,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 = TRUE + 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) @@ -692,7 +731,6 @@ return 1 return 0 - /obj/item/clothing/suit/space/hardsuit/shielded/Destroy() STOP_PROCESSING(SSobj, src) return ..() @@ -728,12 +766,15 @@ icon_state = "ert_medical" item_state = "ert_medical" item_color = "ert_medical" - item_flags = NODROP //Dont want people changing into the other teams gear helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95) slowdown = 0 max_charges = 5 +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) + /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red name = "red shielded hardsuit" icon_state = "ert_security" @@ -750,8 +791,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." @@ -760,7 +799,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" @@ -773,10 +811,6 @@ item_state = "hardsuit0-ert_commander" item_color = "ert_commander" - - - - //////Syndicate Version /obj/item/clothing/suit/space/hardsuit/shielded/syndi @@ -791,7 +825,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..5d718a8173 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 @@ -170,10 +171,13 @@ Contains: item_color = "ert_commander" armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80) strip_delay = 130 - item_flags = NODROP brightness_on = 7 resistance_flags = ACID_PROOF +/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) + /obj/item/clothing/suit/space/hardsuit/ert name = "emergency response team suit" desc = "Standard issue command suit for the ERT." @@ -185,6 +189,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 +203,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 +216,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,7 +230,67 @@ Contains: item_state = "ert_medical" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/med species_exception = list(/datum/species/angel) - tauric = TRUE //Citadel Add for tauric hardsuits + + //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) + 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 + armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + resistance_flags = FIRE_PROOF | ACID_PROOF + + //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" @@ -277,9 +340,12 @@ Contains: armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75) //As whimpy as a space carp brightness_on = 0 //luminosity when on actions_types = list() - item_flags = NODROP mutantrace_variation = NO_MUTANTRACE_VARIATION +/obj/item/clothing/head/helmet/space/hardsuit/carp/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) + /obj/item/clothing/suit/space/hardsuit/carp name = "carp space suit" @@ -291,7 +357,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 8a02245550..7346dc9ea9 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -36,7 +36,7 @@ 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 diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 5d2d4c115a..5eec159462 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -37,6 +37,8 @@ slowdown = 1 /obj/item/clothing/suit/armor/vest/blueshirt + name = "large armor vest" + desc = "A large, yet comfortable piece of armor, protecting you from some threats." icon_state = "blueshift" item_state = "blueshift" @@ -58,6 +60,7 @@ item_state = "hostrench" flags_inv = 0 strip_delay = 80 + unique_reskin = list("Coat" = "hostrench", "Cloak" = "trenchcloak") /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index 173d50ba64..c3276213e1 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -15,7 +15,6 @@ icon_state = "golhood" desc = "A hood for a cloak." body_parts_covered = HEAD - item_flags = NODROP flags_inv = HIDEHAIR|HIDEEARS /obj/item/clothing/neck/cloak/suicide_act(mob/user) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index deaedfec18..bf11d40caf 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -124,6 +124,9 @@ icon_state = "suitjacket_black" item_state = "ro_suit" +/obj/item/clothing/suit/toggle/lawyer/black/syndie + desc = "A snappy dress jacket. Suspiciously has no tags or branding." + armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) //Mime /obj/item/clothing/suit/suspenders diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 9d039e0cb6..dc1b2b6dc3 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -237,7 +237,10 @@ desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseparable. Literally." icon_state = "ponchoshame" item_state = "ponchoshame" - item_flags = NODROP + +/obj/item/clothing/suit/poncho/ponchoshame/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) /obj/item/clothing/suit/whitedress name = "white dress" 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/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 324c16fec7..c239f48b05 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -22,7 +22,11 @@ resistance_flags = NONE /obj/item/clothing/under/color/black/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/under/color/black/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/clothing/under/color/grey name = "grey jumpsuit" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index b8858fdf1a..6f9e77b09f 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -142,6 +142,7 @@ */ /obj/item/clothing/under/rank/security/blueshirt + name = "blue shirt and tie" desc = "I'm a little busy right now, Calhoun." icon_state = "blueshift" item_state = "blueshift" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index bcd9642662..16848e393a 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -1,751 +1,761 @@ -/obj/item/clothing/under/pj/red - name = "red pj's" - desc = "Sleepwear." - icon_state = "red_pyjamas" - item_color = "red_pyjamas" - item_state = "w_suit" - can_adjust = FALSE - -/obj/item/clothing/under/pj/blue - name = "blue pj's" - desc = "Sleepwear." - icon_state = "blue_pyjamas" - item_color = "blue_pyjamas" - item_state = "w_suit" - can_adjust = FALSE - -/obj/item/clothing/under/patriotsuit - name = "Patriotic Suit" - desc = "Motorcycle not included." - icon_state = "ek" - item_state = "ek" - item_color = "ek" - can_adjust = FALSE - -/obj/item/clothing/under/scratch - name = "white suit" - desc = "A white suit, suitable for an excellent host." - icon_state = "scratch" - item_state = "scratch" - item_color = "scratch" - can_adjust = FALSE - -/obj/item/clothing/under/sl_suit - desc = "It's a very amish looking suit." - name = "amish suit" - icon_state = "sl_suit" - item_color = "sl_suit" - can_adjust = FALSE - -/obj/item/clothing/under/roman - name = "\improper Roman armor" - desc = "Ancient Roman armor. Made of metallic and leather straps." - icon_state = "roman" - item_color = "roman" - item_state = "armor" - can_adjust = FALSE - strip_delay = 100 - resistance_flags = NONE - -/obj/item/clothing/under/waiter - name = "waiter's outfit" - desc = "It's a very smart uniform with a special pocket for tip." - icon_state = "waiter" - item_state = "waiter" - item_color = "waiter" - can_adjust = FALSE - -/obj/item/clothing/under/rank/prisoner - name = "prison jumpsuit" - desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." - icon_state = "prisoner" - item_state = "o_suit" - item_color = "prisoner" - has_sensor = LOCKED_SENSORS - sensor_mode = SENSOR_COORDS - random_sensor = FALSE - -/obj/item/clothing/under/rank/mailman - name = "mailman's jumpsuit" - desc = "'Special delivery!'" - icon_state = "mailman" - item_state = "b_suit" - item_color = "mailman" - -/obj/item/clothing/under/rank/psyche - name = "psychedelic jumpsuit" - desc = "Groovy!" - icon_state = "psyche" - item_state = "p_suit" - item_color = "psyche" - -/obj/item/clothing/under/rank/clown/sexy - name = "sexy-clown suit" - desc = "It makes you look HONKable!" - icon_state = "sexyclown" - item_state = "sexyclown" - item_color = "sexyclown" - can_adjust = FALSE - -/obj/item/clothing/under/jabroni - name = "Jabroni Outfit" - desc = "The leather club is two sectors down." - icon_state = "darkholme" - item_state = "darkholme" - item_color = "darkholme" - can_adjust = FALSE - -/obj/item/clothing/under/rank/vice - name = "vice officer's jumpsuit" - desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." - icon_state = "vice" - item_state = "gy_suit" - item_color = "vice" - can_adjust = FALSE - -/obj/item/clothing/under/rank/centcom_officer - desc = "It's a jumpsuit worn by CentCom Officers." - name = "\improper CentCom officer's jumpsuit" - icon_state = "officer" - item_state = "g_suit" - item_color = "officer" - alt_covers_chest = TRUE - -/obj/item/clothing/under/rank/centcom_commander - desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." - name = "\improper CentCom officer's jumpsuit" - icon_state = "centcom" - item_state = "dg_suit" - item_color = "centcom" - -/obj/item/clothing/under/space - name = "\improper NASA jumpsuit" - desc = "It has a NASA logo on it and is made of space-proofed materials." - icon_state = "black" - item_state = "bl_suit" - item_color = "black" - w_class = WEIGHT_CLASS_BULKY - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.02 - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - cold_protection = CHEST | GROIN | LEGS | ARMS //Needs gloves and shoes with cold protection to be fully protected. - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/acj - name = "administrative cybernetic jumpsuit" - icon_state = "syndicate" - item_state = "bl_suit" - item_color = "syndicate" - desc = "A cybernetically enhanced jumpsuit used for administrative duties." - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.01 - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) - cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - can_adjust = FALSE - resistance_flags = FIRE_PROOF | ACID_PROOF - -/obj/item/clothing/under/owl - name = "owl uniform" - desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." - icon_state = "owl" - item_color = "owl" - can_adjust = FALSE - -/obj/item/clothing/under/griffin - name = "griffon uniform" - desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." - icon_state = "griffin" - item_color = "griffin" - can_adjust = FALSE - -/obj/item/clothing/under/cloud - name = "cloud" - desc = "cloud" - icon_state = "cloud" - item_color = "cloud" - can_adjust = FALSE - -/obj/item/clothing/under/gimmick/rank/captain/suit - name = "captain's suit" - desc = "A green suit and yellow necktie. Exemplifies authority." - icon_state = "green_suit" - item_state = "dg_suit" - item_color = "green_suit" - can_adjust = FALSE - -/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit - name = "head of personnel's suit" - desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble." - icon_state = "teal_suit" - item_state = "g_suit" - item_color = "teal_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket - name = "black suit" - desc = "A black suit and red tie. Very formal." - icon_state = "black_suit" - item_state = "bl_suit" - item_color = "black_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket/really_black - name = "executive suit" - desc = "A formal black suit and red tie, intended for the station's finest." - icon_state = "really_black_suit" - item_state = "bl_suit" - item_color = "black_suit" - -/obj/item/clothing/under/suit_jacket/female - name = "executive suit" - desc = "A formal trouser suit for women, intended for the station's finest." - icon_state = "black_suit_fem" - item_state = "black_suit_fem" - item_color = "black_suit_fem" - -/obj/item/clothing/under/suit_jacket/green - name = "green suit" - desc = "A green suit and yellow necktie. Baller." - icon_state = "green_suit" - item_state = "dg_suit" - item_color = "green_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket/red - name = "red suit" - desc = "A red suit and blue tie. Somewhat formal." - icon_state = "red_suit" - item_state = "r_suit" - item_color = "red_suit" - -/obj/item/clothing/under/suit_jacket/charcoal - name = "charcoal suit" - desc = "A charcoal suit and red tie. Very professional." - icon_state = "charcoal_suit" - item_state = "charcoal_suit" - item_color = "charcoal_suit" - -/obj/item/clothing/under/suit_jacket/navy - name = "navy suit" - desc = "A navy suit and red tie, intended for the station's finest." - icon_state = "navy_suit" - item_state = "navy_suit" - item_color = "navy_suit" - -/obj/item/clothing/under/suit_jacket/burgundy - name = "burgundy suit" - desc = "A burgundy suit and black tie. Somewhat formal." - icon_state = "burgundy_suit" - item_state = "burgundy_suit" - item_color = "burgundy_suit" - -/obj/item/clothing/under/suit_jacket/checkered - name = "checkered suit" - desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" - icon_state = "checkered_suit" - item_state = "checkered_suit" - item_color = "checkered_suit" - -/obj/item/clothing/under/suit_jacket/tan - name = "tan suit" - desc = "A tan suit with a yellow tie. Smart, but casual." - icon_state = "tan_suit" - item_state = "tan_suit" - item_color = "tan_suit" - -/obj/item/clothing/under/suit_jacket/white - name = "white suit" - desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!" - icon_state = "white_suit" - item_state = "white_suit" - item_color = "white_suit" - -/obj/item/clothing/under/burial - name = "burial garments" - desc = "Traditional burial garments from the early 22nd century." - icon_state = "burial" - item_state = "burial" - item_color = "burial" - has_sensor = NO_SENSORS - -/obj/item/clothing/under/skirt/black - name = "black skirt" - desc = "A black skirt, very fancy!" - icon_state = "blackskirt" - item_color = "blackskirt" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/blue - name = "blue skirt" - desc = "A blue, casual skirt." - icon_state = "blueskirt" - item_color = "blueskirt" - item_state = "b_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/red - name = "red skirt" - desc = "A red, casual skirt." - icon_state = "redskirt" - item_color = "redskirt" - item_state = "r_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/purple - name = "purple skirt" - desc = "A purple, casual skirt." - icon_state = "purpleskirt" - item_color = "purpleskirt" - item_state = "p_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - - -/obj/item/clothing/under/schoolgirl - name = "blue schoolgirl uniform" - desc = "It's just like one of my Japanese animes!" - icon_state = "schoolgirl" - item_state = "schoolgirl" - item_color = "schoolgirl" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/schoolgirl/red - name = "red schoolgirl uniform" - icon_state = "schoolgirlred" - item_state = "schoolgirlred" - item_color = "schoolgirlred" - -/obj/item/clothing/under/schoolgirl/green - name = "green schoolgirl uniform" - icon_state = "schoolgirlgreen" - item_state = "schoolgirlgreen" - item_color = "schoolgirlgreen" - -/obj/item/clothing/under/schoolgirl/orange - name = "orange schoolgirl uniform" - icon_state = "schoolgirlorange" - item_state = "schoolgirlorange" - item_color = "schoolgirlorange" - -/obj/item/clothing/under/overalls - name = "laborer's overalls" - desc = "A set of durable overalls for getting the job done." - icon_state = "overalls" - item_state = "lb_suit" - item_color = "overalls" - can_adjust = FALSE - -/obj/item/clothing/under/pirate - name = "pirate outfit" - desc = "Yarr." - icon_state = "pirate" - item_state = "pirate" - item_color = "pirate" - can_adjust = FALSE - -/obj/item/clothing/under/soviet - name = "soviet uniform" - desc = "For the Motherland!" - icon_state = "soviet" - item_state = "soviet" - item_color = "soviet" - can_adjust = FALSE - -/obj/item/clothing/under/redcoat - name = "redcoat uniform" - desc = "Looks old." - icon_state = "redcoat" - item_state = "redcoat" - item_color = "redcoat" - can_adjust = FALSE - -/obj/item/clothing/under/kilt - name = "kilt" - desc = "Includes shoes and plaid." - icon_state = "kilt" - item_state = "kilt" - item_color = "kilt" - body_parts_covered = CHEST|GROIN|LEGS|FEET - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/kilt/highlander - desc = "You're the only one worthy of this kilt." - item_flags = NODROP - -/obj/item/clothing/under/sexymime - name = "sexy mime outfit" - desc = "The only time when you DON'T enjoy looking at someone's rack." - icon_state = "sexymime" - item_state = "sexymime" - item_color = "sexymime" - body_parts_covered = CHEST|GROIN|LEGS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/gladiator - name = "gladiator uniform" - desc = "Are you not entertained? Is that not why you are here?" - icon_state = "gladiator" - item_state = "gladiator" - item_color = "gladiator" - body_parts_covered = CHEST|GROIN|ARMS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/gladiator/ash_walker - desc = "This gladiator uniform appears to be covered in ash and fairly dated." - has_sensor = NO_SENSORS - -/obj/item/clothing/under/sundress - name = "sundress" - desc = "Makes you want to frolic in a field of daisies." - icon_state = "sundress" - item_state = "sundress" - item_color = "sundress" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/captainparade - name = "captain's parade uniform" - desc = "A captain's luxury-wear, for special occasions." - icon_state = "captain_parade" - item_state = "by_suit" - item_color = "captain_parade" - can_adjust = FALSE - -/obj/item/clothing/under/hosparademale - name = "head of security's parade uniform" - desc = "A male head of security's luxury-wear, for special occasions." - icon_state = "hos_parade_male" - item_state = "r_suit" - item_color = "hos_parade_male" - can_adjust = FALSE - -/obj/item/clothing/under/hosparadefem - name = "head of security's parade uniform" - desc = "A female head of security's luxury-wear, for special occasions." - icon_state = "hos_parade_fem" - item_state = "r_suit" - item_color = "hos_parade_fem" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/assistantformal - name = "assistant's formal uniform" - desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." - icon_state = "assistant_formal" - item_state = "gy_suit" - item_color = "assistant_formal" - can_adjust = FALSE - -/obj/item/clothing/under/blacktango - name = "black tango dress" - desc = "Filled with Latin fire." - icon_state = "black_tango" - item_state = "wcoat" - item_color = "black_tango" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - body_parts_covered = CHEST|GROIN - -/obj/item/clothing/under/stripeddress - name = "striped dress" - desc = "Fashion in space." - icon_state = "striped_dress" - item_state = "stripeddress" - item_color = "striped_dress" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_FULL - can_adjust = FALSE - -/obj/item/clothing/under/sailordress - name = "sailor dress" - desc = "Formal wear for a leading lady." - icon_state = "sailor_dress" - item_state = "sailordress" - item_color = "sailor_dress" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/redeveninggown - name = "red evening gown" - desc = "Fancy dress for space bar singers." - icon_state = "red_evening_gown" - item_state = "redeveninggown" - item_color = "red_evening_gown" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/maid - name = "maid costume" - desc = "Maid in China." - icon_state = "maid" - item_state = "maid" - item_color = "maid" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/maid/Initialize() - . = ..() - var/obj/item/clothing/accessory/maidapron/A = new (src) - attach_accessory(A) - -/obj/item/clothing/under/janimaid - name = "maid uniform" - desc = "A simple maid uniform for housekeeping." - icon_state = "janimaid" - item_state = "janimaid" - item_color = "janimaid" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/plaid_skirt - name = "red plaid skirt" - desc = "A preppy red skirt with a white blouse." - icon_state = "plaid_red" - item_state = "plaid_red" - item_color = "plaid_red" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/plaid_skirt/blue - name = "blue plaid skirt" - desc = "A preppy blue skirt with a white blouse." - icon_state = "plaid_blue" - item_state = "plaid_blue" - item_color = "plaid_blue" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/plaid_skirt/purple - name = "purple plaid skirt" - desc = "A preppy purple skirt with a white blouse." - icon_state = "plaid_purple" - item_state = "plaid_purple" - item_color = "plaid_purple" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/singery - name = "yellow performer's outfit" - desc = "Just looking at this makes you want to sing." - icon_state = "ysing" - item_state = "ysing" - item_color = "ysing" - body_parts_covered = CHEST|GROIN|ARMS - fitted = NO_FEMALE_UNIFORM - alternate_worn_layer = ABOVE_SHOES_LAYER - can_adjust = FALSE - -/obj/item/clothing/under/singerb - name = "blue performer's outfit" - desc = "Just looking at this makes you want to sing." - icon_state = "bsing" - item_state = "bsing" - item_color = "bsing" - body_parts_covered = CHEST|GROIN|ARMS - alternate_worn_layer = ABOVE_SHOES_LAYER - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/plaid_skirt/green - name = "green plaid skirt" - desc = "A preppy green skirt with a white blouse." - icon_state = "plaid_green" - item_state = "plaid_green" - item_color = "plaid_green" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/jester - name = "jester suit" - desc = "A jolly dress, well suited to entertain your master, nuncle." - icon_state = "jester" - item_color = "jester" - can_adjust = FALSE - -/obj/item/clothing/under/jester/alt - icon_state = "jester2" - -/obj/item/clothing/under/geisha - name = "geisha suit" - desc = "Cute space ninja senpai not included." - icon_state = "geisha" - item_color = "geisha" - body_parts_covered = CHEST|GROIN|ARMS - can_adjust = FALSE - -/obj/item/clothing/under/villain - name = "villain suit" - desc = "A change of wardrobe is necessary if you ever want to catch a real superhero." - icon_state = "villain" - item_color = "villain" - can_adjust = FALSE - -/obj/item/clothing/under/sailor - name = "sailor suit" - desc = "Skipper's in the wardroom drinkin gin'." - icon_state = "sailor" - item_state = "b_suit" - item_color = "sailor" - can_adjust = FALSE - -/obj/item/clothing/under/plasmaman - name = "plasma envirosuit" - desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." - icon_state = "plasmaman" - item_state = "plasmaman" - item_color = "plasmaman" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - can_adjust = FALSE - strip_delay = 80 - var/next_extinguish = 0 - var/extinguish_cooldown = 100 - var/extinguishes_left = 5 - - -/obj/item/clothing/under/plasmaman/examine(mob/user) - ..() - to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") - - -/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) - return - - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message("[H]'s suit automatically extinguishes [H.p_them()]!","Your suit automatically extinguishes you.") - H.ExtinguishMob() - new /obj/effect/particle_effect/water(get_turf(H)) - return 0 - -/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) - ..() - if (istype(E, /obj/item/extinguisher_refill)) - if (extinguishes_left == 5) - to_chat(user, "The inbuilt extinguisher is full.") - return - else - extinguishes_left = 5 - to_chat(user, "You refill the suit's built-in extinguisher, using up the cartridge.") - qdel(E) - return - return - return - -/obj/item/extinguisher_refill - name = "envirosuit extinguisher cartridge" - desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." - icon_state = "plasmarefill" - icon = 'icons/obj/device.dmi' - -/obj/item/clothing/under/rank/security/navyblue/russian - name = "\improper Russian officer's uniform" - desc = "The latest in fashionable russian outfits." - icon_state = "hostanclothes" - item_state = "hostanclothes" - item_color = "hostanclothes" - -/obj/item/clothing/under/mummy - name = "mummy wrapping" - desc = "Return the slab or suffer my stale references." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/scarecrow - name = "scarecrow clothes" - desc = "Perfect camouflage for hiding in botany." - icon_state = "scarecrow" - item_state = "scarecrow" - item_color = "scarecrow" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/draculass - name = "draculass coat" - desc = "A dress inspired by the ancient \"Victorian\" era." - icon_state = "draculass" - item_state = "draculass" - item_color = "draculass" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/drfreeze - name = "doctor freeze's jumpsuit" - desc = "A modified scientist jumpsuit to look extra cool." - icon_state = "drfreeze" - item_state = "drfreeze" - item_color = "drfreeze" - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/lobster - name = "foam lobster suit" - desc = "Who beheaded the college mascot?" - icon_state = "lobster" - item_state = "lobster" - item_color = "lobster" - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/gondola - name = "gondola hide suit" - desc = "Now you're cooking." - icon_state = "gondola" - item_state = "lb_suit" - item_color = "gondola" - can_adjust = FALSE - -/obj/item/clothing/under/skeleton - name = "skeleton jumpsuit" - desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!" - icon_state = "skeleton" - item_state = "skeleton" - item_color = "skeleton" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE +/obj/item/clothing/under/pj/red + name = "red pj's" + desc = "Sleepwear." + icon_state = "red_pyjamas" + item_color = "red_pyjamas" + item_state = "w_suit" + can_adjust = FALSE + +/obj/item/clothing/under/pj/blue + name = "blue pj's" + desc = "Sleepwear." + icon_state = "blue_pyjamas" + item_color = "blue_pyjamas" + item_state = "w_suit" + can_adjust = FALSE + +/obj/item/clothing/under/patriotsuit + name = "Patriotic Suit" + desc = "Motorcycle not included." + icon_state = "ek" + item_state = "ek" + item_color = "ek" + can_adjust = FALSE + +/obj/item/clothing/under/scratch + name = "white suit" + desc = "A white suit, suitable for an excellent host." + icon_state = "scratch" + item_state = "scratch" + item_color = "scratch" + can_adjust = FALSE + +/obj/item/clothing/under/sl_suit + desc = "It's a very amish looking suit." + name = "amish suit" + icon_state = "sl_suit" + item_color = "sl_suit" + can_adjust = FALSE + +/obj/item/clothing/under/roman + name = "\improper Roman armor" + desc = "Ancient Roman armor. Made of metallic and leather straps." + icon_state = "roman" + item_color = "roman" + item_state = "armor" + can_adjust = FALSE + strip_delay = 100 + resistance_flags = NONE + +/obj/item/clothing/under/waiter + name = "waiter's outfit" + desc = "It's a very smart uniform with a special pocket for tip." + icon_state = "waiter" + item_state = "waiter" + item_color = "waiter" + can_adjust = FALSE + +/obj/item/clothing/under/rank/prisoner + name = "prison jumpsuit" + desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." + icon_state = "prisoner" + item_state = "o_suit" + item_color = "prisoner" + has_sensor = LOCKED_SENSORS + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + +/obj/item/clothing/under/rank/mailman + name = "mailman's jumpsuit" + desc = "'Special delivery!'" + icon_state = "mailman" + item_state = "b_suit" + item_color = "mailman" + +/obj/item/clothing/under/rank/psyche + name = "psychedelic jumpsuit" + desc = "Groovy!" + icon_state = "psyche" + item_state = "p_suit" + item_color = "psyche" + +/obj/item/clothing/under/rank/clown/sexy + name = "sexy-clown suit" + desc = "It makes you look HONKable!" + icon_state = "sexyclown" + item_state = "sexyclown" + item_color = "sexyclown" + can_adjust = FALSE + +/obj/item/clothing/under/jabroni + name = "Jabroni Outfit" + desc = "The leather club is two sectors down." + icon_state = "darkholme" + item_state = "darkholme" + item_color = "darkholme" + can_adjust = FALSE + +/obj/item/clothing/under/rank/vice + name = "vice officer's jumpsuit" + desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." + icon_state = "vice" + item_state = "gy_suit" + item_color = "vice" + can_adjust = FALSE + +/obj/item/clothing/under/rank/centcom_officer + desc = "It's a jumpsuit worn by CentCom Officers." + name = "\improper CentCom officer's jumpsuit" + icon_state = "officer" + item_state = "g_suit" + item_color = "officer" + alt_covers_chest = TRUE + +/obj/item/clothing/under/rank/centcom_commander + desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." + name = "\improper CentCom officer's jumpsuit" + icon_state = "centcom" + item_state = "dg_suit" + item_color = "centcom" + +/obj/item/clothing/under/space + name = "\improper NASA jumpsuit" + desc = "It has a NASA logo on it and is made of space-proofed materials." + icon_state = "black" + item_state = "bl_suit" + item_color = "black" + w_class = WEIGHT_CLASS_BULKY + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.02 + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + cold_protection = CHEST | GROIN | LEGS | ARMS //Needs gloves and shoes with cold protection to be fully protected. + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/acj + name = "administrative cybernetic jumpsuit" + icon_state = "syndicate" + item_state = "bl_suit" + item_color = "syndicate" + desc = "A cybernetically enhanced jumpsuit used for administrative duties." + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.01 + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + can_adjust = FALSE + resistance_flags = FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/under/owl + name = "owl uniform" + desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." + icon_state = "owl" + item_color = "owl" + can_adjust = FALSE + +/obj/item/clothing/under/griffin + name = "griffon uniform" + desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." + icon_state = "griffin" + item_color = "griffin" + can_adjust = FALSE + +/obj/item/clothing/under/cloud + name = "cloud" + desc = "cloud" + icon_state = "cloud" + item_color = "cloud" + can_adjust = FALSE + +/obj/item/clothing/under/gimmick/rank/captain/suit + name = "captain's suit" + desc = "A green suit and yellow necktie. Exemplifies authority." + icon_state = "green_suit" + item_state = "dg_suit" + item_color = "green_suit" + can_adjust = FALSE + +/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit + name = "head of personnel's suit" + desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble." + icon_state = "teal_suit" + item_state = "g_suit" + item_color = "teal_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket + name = "black suit" + desc = "A black suit and red tie. Very formal." + icon_state = "black_suit" + item_state = "bl_suit" + item_color = "black_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket/really_black + name = "executive suit" + desc = "A formal black suit and red tie, intended for the station's finest." + icon_state = "really_black_suit" + item_state = "bl_suit" + item_color = "black_suit" + +/obj/item/clothing/under/suit_jacket/female + name = "executive suit" + desc = "A formal trouser suit for women, intended for the station's finest." + icon_state = "black_suit_fem" + item_state = "black_suit_fem" + item_color = "black_suit_fem" + +/obj/item/clothing/under/suit_jacket/green + name = "green suit" + desc = "A green suit and yellow necktie. Baller." + icon_state = "green_suit" + item_state = "dg_suit" + item_color = "green_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket/red + name = "red suit" + desc = "A red suit and blue tie. Somewhat formal." + icon_state = "red_suit" + item_state = "r_suit" + item_color = "red_suit" + +/obj/item/clothing/under/suit_jacket/charcoal + name = "charcoal suit" + desc = "A charcoal suit and red tie. Very professional." + icon_state = "charcoal_suit" + item_state = "charcoal_suit" + item_color = "charcoal_suit" + +/obj/item/clothing/under/suit_jacket/navy + name = "navy suit" + desc = "A navy suit and red tie, intended for the station's finest." + icon_state = "navy_suit" + item_state = "navy_suit" + item_color = "navy_suit" + +/obj/item/clothing/under/suit_jacket/burgundy + name = "burgundy suit" + desc = "A burgundy suit and black tie. Somewhat formal." + icon_state = "burgundy_suit" + item_state = "burgundy_suit" + item_color = "burgundy_suit" + +/obj/item/clothing/under/suit_jacket/checkered + name = "checkered suit" + desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" + icon_state = "checkered_suit" + item_state = "checkered_suit" + item_color = "checkered_suit" + +/obj/item/clothing/under/suit_jacket/tan + name = "tan suit" + desc = "A tan suit with a yellow tie. Smart, but casual." + icon_state = "tan_suit" + item_state = "tan_suit" + item_color = "tan_suit" + +/obj/item/clothing/under/suit_jacket/white + name = "white suit" + desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!" + icon_state = "white_suit" + item_state = "white_suit" + item_color = "white_suit" + +/obj/item/clothing/under/burial + name = "burial garments" + desc = "Traditional burial garments from the early 22nd century." + icon_state = "burial" + item_state = "burial" + item_color = "burial" + has_sensor = NO_SENSORS + +/obj/item/clothing/under/skirt/black + name = "black skirt" + desc = "A black skirt, very fancy!" + icon_state = "blackskirt" + item_color = "blackskirt" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/blue + name = "blue skirt" + desc = "A blue, casual skirt." + icon_state = "blueskirt" + item_color = "blueskirt" + item_state = "b_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/red + name = "red skirt" + desc = "A red, casual skirt." + icon_state = "redskirt" + item_color = "redskirt" + item_state = "r_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/purple + name = "purple skirt" + desc = "A purple, casual skirt." + icon_state = "purpleskirt" + item_color = "purpleskirt" + item_state = "p_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + + +/obj/item/clothing/under/schoolgirl + name = "blue schoolgirl uniform" + desc = "It's just like one of my Japanese animes!" + icon_state = "schoolgirl" + item_state = "schoolgirl" + item_color = "schoolgirl" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/schoolgirl/red + name = "red schoolgirl uniform" + icon_state = "schoolgirlred" + item_state = "schoolgirlred" + item_color = "schoolgirlred" + +/obj/item/clothing/under/schoolgirl/green + name = "green schoolgirl uniform" + icon_state = "schoolgirlgreen" + item_state = "schoolgirlgreen" + item_color = "schoolgirlgreen" + +/obj/item/clothing/under/schoolgirl/orange + name = "orange schoolgirl uniform" + icon_state = "schoolgirlorange" + item_state = "schoolgirlorange" + item_color = "schoolgirlorange" + +/obj/item/clothing/under/overalls + name = "laborer's overalls" + desc = "A set of durable overalls for getting the job done." + icon_state = "overalls" + item_state = "lb_suit" + item_color = "overalls" + can_adjust = FALSE + +/obj/item/clothing/under/pirate + name = "pirate outfit" + desc = "Yarr." + icon_state = "pirate" + item_state = "pirate" + item_color = "pirate" + can_adjust = FALSE + +/obj/item/clothing/under/soviet + name = "soviet uniform" + desc = "For the Motherland!" + icon_state = "soviet" + item_state = "soviet" + item_color = "soviet" + can_adjust = FALSE + +/obj/item/clothing/under/redcoat + name = "redcoat uniform" + desc = "Looks old." + icon_state = "redcoat" + item_state = "redcoat" + item_color = "redcoat" + can_adjust = FALSE + +/obj/item/clothing/under/kilt + name = "kilt" + desc = "Includes shoes and plaid." + icon_state = "kilt" + item_state = "kilt" + item_color = "kilt" + body_parts_covered = CHEST|GROIN|LEGS|FEET + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/kilt/highlander + desc = "You're the only one worthy of this kilt." + +/obj/item/clothing/under/kilt/highlander/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) + +/obj/item/clothing/under/sexymime + name = "sexy mime outfit" + desc = "The only time when you DON'T enjoy looking at someone's rack." + icon_state = "sexymime" + item_state = "sexymime" + item_color = "sexymime" + body_parts_covered = CHEST|GROIN|LEGS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/gladiator + name = "gladiator uniform" + desc = "Are you not entertained? Is that not why you are here?" + icon_state = "gladiator" + item_state = "gladiator" + item_color = "gladiator" + body_parts_covered = CHEST|GROIN|ARMS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/gladiator/ash_walker + desc = "This gladiator uniform appears to be covered in ash and fairly dated." + has_sensor = NO_SENSORS + +/obj/item/clothing/under/sundress + name = "sundress" + desc = "Makes you want to frolic in a field of daisies." + icon_state = "sundress" + item_state = "sundress" + item_color = "sundress" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/captainparade + name = "captain's parade uniform" + desc = "A captain's luxury-wear, for special occasions." + icon_state = "captain_parade" + item_state = "by_suit" + item_color = "captain_parade" + can_adjust = FALSE + +/obj/item/clothing/under/hosparademale + name = "head of security's parade uniform" + desc = "A male head of security's luxury-wear, for special occasions." + icon_state = "hos_parade_male" + item_state = "r_suit" + item_color = "hos_parade_male" + can_adjust = FALSE + +/obj/item/clothing/under/hosparadefem + name = "head of security's parade uniform" + desc = "A female head of security's luxury-wear, for special occasions." + icon_state = "hos_parade_fem" + item_state = "r_suit" + item_color = "hos_parade_fem" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/assistantformal + name = "assistant's formal uniform" + desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." + icon_state = "assistant_formal" + item_state = "gy_suit" + item_color = "assistant_formal" + can_adjust = FALSE + +/obj/item/clothing/under/blacktango + name = "black tango dress" + desc = "Filled with Latin fire." + icon_state = "black_tango" + item_state = "wcoat" + item_color = "black_tango" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + body_parts_covered = CHEST|GROIN + +/obj/item/clothing/under/stripeddress + name = "striped dress" + desc = "Fashion in space." + icon_state = "striped_dress" + item_state = "stripeddress" + item_color = "striped_dress" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_FULL + can_adjust = FALSE + +/obj/item/clothing/under/sailordress + name = "sailor dress" + desc = "Formal wear for a leading lady." + icon_state = "sailor_dress" + item_state = "sailordress" + item_color = "sailor_dress" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/redeveninggown + name = "red evening gown" + desc = "Fancy dress for space bar singers." + icon_state = "red_evening_gown" + item_state = "redeveninggown" + item_color = "red_evening_gown" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/maid + name = "maid costume" + desc = "Maid in China." + icon_state = "maid" + item_state = "maid" + item_color = "maid" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/maid/Initialize() + . = ..() + var/obj/item/clothing/accessory/maidapron/A = new (src) + attach_accessory(A) + +/obj/item/clothing/under/janimaid + name = "maid uniform" + desc = "A simple maid uniform for housekeeping." + icon_state = "janimaid" + item_state = "janimaid" + item_color = "janimaid" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/plaid_skirt + name = "red plaid skirt" + desc = "A preppy red skirt with a white blouse." + icon_state = "plaid_red" + item_state = "plaid_red" + item_color = "plaid_red" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/plaid_skirt/blue + name = "blue plaid skirt" + desc = "A preppy blue skirt with a white blouse." + icon_state = "plaid_blue" + item_state = "plaid_blue" + item_color = "plaid_blue" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/plaid_skirt/purple + name = "purple plaid skirt" + desc = "A preppy purple skirt with a white blouse." + icon_state = "plaid_purple" + item_state = "plaid_purple" + item_color = "plaid_purple" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/singery + name = "yellow performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "ysing" + item_state = "ysing" + item_color = "ysing" + body_parts_covered = CHEST|GROIN|ARMS + fitted = NO_FEMALE_UNIFORM + alternate_worn_layer = ABOVE_SHOES_LAYER + can_adjust = FALSE + +/obj/item/clothing/under/singerb + name = "blue performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "bsing" + item_state = "bsing" + item_color = "bsing" + body_parts_covered = CHEST|GROIN|ARMS + alternate_worn_layer = ABOVE_SHOES_LAYER + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/plaid_skirt/green + name = "green plaid skirt" + desc = "A preppy green skirt with a white blouse." + icon_state = "plaid_green" + item_state = "plaid_green" + item_color = "plaid_green" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/jester + name = "jester suit" + desc = "A jolly dress, well suited to entertain your master, nuncle." + icon_state = "jester" + item_color = "jester" + can_adjust = FALSE + +/obj/item/clothing/under/jester/alt + icon_state = "jester2" + +/obj/item/clothing/under/geisha + name = "geisha suit" + desc = "Cute space ninja senpai not included." + icon_state = "geisha" + item_color = "geisha" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + +/obj/item/clothing/under/villain + name = "villain suit" + desc = "A change of wardrobe is necessary if you ever want to catch a real superhero." + icon_state = "villain" + item_color = "villain" + can_adjust = FALSE + +/obj/item/clothing/under/sailor + name = "sailor suit" + desc = "Skipper's in the wardroom drinkin gin'." + icon_state = "sailor" + item_state = "b_suit" + item_color = "sailor" + can_adjust = FALSE + +/obj/item/clothing/under/plasmaman + name = "plasma envirosuit" + desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." + icon_state = "plasmaman" + item_state = "plasmaman" + item_color = "plasmaman" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + can_adjust = FALSE + strip_delay = 80 + var/next_extinguish = 0 + var/extinguish_cooldown = 100 + var/extinguishes_left = 5 + + +/obj/item/clothing/under/plasmaman/examine(mob/user) + ..() + to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") + + +/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) + if(!istype(H)) + return + + if(H.on_fire) + if(extinguishes_left) + if(next_extinguish > world.time) + return + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H.visible_message("[H]'s suit automatically extinguishes [H.p_them()]!","Your suit automatically extinguishes you.") + H.ExtinguishMob() + new /obj/effect/particle_effect/water(get_turf(H)) + return 0 + +/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) + ..() + if (istype(E, /obj/item/extinguisher_refill)) + if (extinguishes_left == 5) + to_chat(user, "The inbuilt extinguisher is full.") + return + else + extinguishes_left = 5 + to_chat(user, "You refill the suit's built-in extinguisher, using up the cartridge.") + qdel(E) + return + return + return + +/obj/item/extinguisher_refill + name = "envirosuit extinguisher cartridge" + desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." + icon_state = "plasmarefill" + icon = 'icons/obj/device.dmi' + +/obj/item/clothing/under/rank/security/navyblue/russian + name = "\improper Russian officer's uniform" + desc = "The latest in fashionable russian outfits." + icon_state = "hostanclothes" + item_state = "hostanclothes" + item_color = "hostanclothes" + +/obj/item/clothing/under/mummy + name = "mummy wrapping" + desc = "Return the slab or suffer my stale references." + icon_state = "mummy" + item_state = "mummy" + item_color = "mummy" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/scarecrow + name = "scarecrow clothes" + desc = "Perfect camouflage for hiding in botany." + icon_state = "scarecrow" + item_state = "scarecrow" + item_color = "scarecrow" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/draculass + name = "draculass coat" + desc = "A dress inspired by the ancient \"Victorian\" era." + icon_state = "draculass" + item_state = "draculass" + item_color = "draculass" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/drfreeze + name = "doctor freeze's jumpsuit" + desc = "A modified scientist jumpsuit to look extra cool." + icon_state = "drfreeze" + item_state = "drfreeze" + item_color = "drfreeze" + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/lobster + name = "foam lobster suit" + desc = "Who beheaded the college mascot?" + icon_state = "lobster" + item_state = "lobster" + item_color = "lobster" + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/gondola + name = "gondola hide suit" + desc = "Now you're cooking." + icon_state = "gondola" + item_state = "lb_suit" + item_color = "gondola" + can_adjust = FALSE + +/obj/item/clothing/under/skeleton + name = "skeleton jumpsuit" + desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!" + icon_state = "skeleton" + item_state = "skeleton" + item_color = "skeleton" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/gear_harness + name = "gear harness" + desc = "A simple, inconspicuous harness replacement for a jumpsuit." + icon_state = "gear_harness" + item_state = "gear_harness" //We dont use golem do to being a item, item without faces making it default to error suit sprites. + body_parts_covered = CHEST|GROIN \ No newline at end of file diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 29ddb8e800..3e96512bb8 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -21,6 +21,8 @@ CAT_BURGER, CAT_CAKE, CAT_EGG, + CAT_FISH, + CAT_ICE, //Called Frozen CAT_MEAT, CAT_MISCFOOD, CAT_PASTRY, @@ -28,7 +30,6 @@ CAT_PIZZA, CAT_SALAD, CAT_SANDWICH, - CAT_SUSHI, CAT_SOUP, CAT_SPAGHETTI), CAT_CLOTHING) //Clothing subcategories diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 6ada4629d3..ca51fec347 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 @@ -332,28 +365,6 @@ parts = list(/obj/item/camera = 1) category = CAT_MISC -/datum/crafting_recipe/lizardhat - name = "Lizard Cloche Hat" - result = /obj/item/clothing/head/lizard - time = 10 - reqs = list(/obj/item/organ/tail/lizard = 1) - category = CAT_MISC - -/datum/crafting_recipe/lizardhat_alternate - name = "Lizard Cloche Hat" - result = /obj/item/clothing/head/lizard - time = 10 - reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1) - category = CAT_MISC - -/datum/crafting_recipe/kittyears - name = "Kitty Ears" - result = /obj/item/clothing/head/kitty/genuine - time = 10 - reqs = list(/obj/item/organ/tail/cat = 1, - /obj/item/organ/ears/cat = 1) - category = CAT_MISC - /datum/crafting_recipe/skateboard name = "Skateboard" result = /obj/vehicle/ridden/scooter/skateboard @@ -385,7 +396,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 @@ -526,6 +536,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 @@ -602,6 +620,14 @@ category = CAT_MISC +/datum/crafting_recipe/wheelchair + name = "Wheelchair" + result = /obj/vehicle/ridden/wheelchair + reqs = list(/obj/item/stack/sheet/plasteel = 2, + /obj/item/stack/rods = 8) + time = 100 + category = CAT_MISC + /datum/crafting_recipe/rcl name = "Makeshift Rapid Cable Layer" result = /obj/item/twohanded/rcl/ghetto @@ -633,6 +659,28 @@ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) category = CAT_MISC +/datum/crafting_recipe/lizardhat + name = "Lizard Cloche Hat" + result = /obj/item/clothing/head/lizard + time = 10 + reqs = list(/obj/item/organ/tail/lizard = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/lizardhat_alternate + name = "Lizard Cloche Hat" + result = /obj/item/clothing/head/lizard + time = 10 + reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/kittyears + name = "Kitty Ears" + result = /obj/item/clothing/head/kitty/genuine + time = 10 + reqs = list(/obj/item/organ/tail/cat = 1, + /obj/item/organ/ears/cat = 1) + category = CAT_CLOTHING + /datum/crafting_recipe/hudsunsec name = "Security HUDsunglasses" result = /obj/item/clothing/glasses/hud/security/sunglasses @@ -715,23 +763,26 @@ /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 = 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 + 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, @@ -739,3 +790,86 @@ /datum/reagent/water = 15) time = 40 category = CAT_MISC + +/datum/crafting_recipe/bronze_driver + name = "Bronze Plated Screwdriver" + result = /obj/item/screwdriver/bronze + reqs = list(/obj/item/screwdriver = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_welder + name = "Bronze Plated Welding Tool" + result = /obj/item/weldingtool/bronze + reqs = list(/obj/item/weldingtool = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_wirecutters + name = "Bronze Plated Wirecutters" + result = /obj/item/wirecutters/bronze + reqs = list(/obj/item/wirecutters = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_crowbar + name = "Bronze Plated Crowbar" + result = /obj/item/crowbar/bronze + reqs = list(/obj/item/crowbar = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_wrench + name = "Bronze Plated Wrench" + result = /obj/item/wrench/bronze + reqs = list(/obj/item/wrench = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/smartdart + name = "Medical smartdart" + result = /obj/item/reagent_containers/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/sheet/glass = 1, + /obj/item/stack/sheet/plastic = 1) + time = 10 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/medolier + name = "Medolier" + result = /obj/item/storage/belt/medolier + reqs = list(/obj/item/stack/sheet/metal = 2, + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/sheet/plastic = 4) + time = 30 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/smartdartgun + name = "Smart dartgun" + result = /obj/item/gun/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 15, + /obj/item/stack/sheet/glass = 10, + /obj/item/tank/internals = 1, + /obj/item/reagent_containers/glass/beaker = 1, + /obj/item/stack/sheet/plastic = 10, + /obj/item/stack/cable_coil = 2) + time = 150 //It's a gun + category = CAT_WEAPONRY + subcategory = CAT_WEAPON 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/immovable_rod.dm b/code/modules/events/immovable_rod.dm index abf13bcab9..e041d566e9 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -45,6 +45,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 throwforce = 100 density = TRUE anchored = TRUE + var/mob/living/wizard var/z_original = 0 var/destination var/notify = TRUE @@ -99,6 +100,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 /obj/effect/immovablerod/ex_act(severity, target) return 0 +/obj/structure/closet/supplypod/prevent_content_explosion() + return TRUE + /obj/effect/immovablerod/singularity_act() return @@ -140,3 +144,23 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 H.adjustBruteLoss(160) if(L && (L.density || prob(10))) L.ex_act(EXPLODE_HEAVY) + +obj/effect/immovablerod/attack_hand(mob/living/user) + if(ishuman(user)) + var/mob/living/carbon/human/U = user + if(U.job in list("Research Director")) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) + for(var/mob/M in urange(8, src)) + if(!M.stat) + shake_camera(M, 2, 3) + if(wizard) + U.visible_message("[src] transforms into [wizard] as [U] suplexes them!", "As you grab [src], it suddenly turns into [wizard] as you suplex them!") + to_chat(wizard, "You're suddenly jolted out of rod-form as [U] somehow manages to grab you, slamming you into the ground!") + wizard.Stun(60) + wizard.apply_damage(25, BRUTE) + qdel(src) + else + U.visible_message("[U] suplexes [src] into the ground!", "You suplex [src] into the ground!") + new /obj/structure/festivus/anchored(drop_location()) + new /obj/effect/anomaly/flux(drop_location()) + qdel(src) diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm index b01ff4237e..48a9f00423 100644 --- a/code/modules/events/mice_migration.dm +++ b/code/modules/events/mice_migration.dm @@ -32,4 +32,4 @@ P.update_icon() /datum/round_event/mice_migration/start() - SSsqueak.trigger_migration(rand(minimum_mice, maximum_mice)) + SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice)) 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/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index 1407a98518..901337cd52 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -17,6 +17,8 @@ continue if(!H.getorgan(/obj/item/organ/appendix)) //Don't give the disease to some who lacks it, only for it to be auto-cured continue + if(!(MOB_ORGANIC in H.mob_biotypes)) //biotype sleeper bugs strike again, once again making appendicitis pick a target that can't take it + continue var/foundAlready = FALSE //don't infect someone that already has appendicitis for(var/datum/disease/appendicitis/A in H.diseases) foundAlready = TRUE diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index a6e08fbd8c..41ee4246b1 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -50,7 +50,8 @@ var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list H.dropItemToGround(H.get_item_by_slot(i), TRUE) H.equip_to_slot_or_del(I, i) - I.item_flags |= NODROP | DROPDEL + ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT) + I.item_flags |= DROPDEL I.name = "cursed " + I.name for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 5cd5d2c5c6..88f72d27c3 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -689,7 +689,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( chosen = capitalize(pick(speak_messages)) chosen = replacetext(chosen, "%TARGETNAME%", target_name) var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER) - var/message = target.compose_message(person,understood_language,chosen,null,person.get_spans(),face_name = TRUE) + var/message = target.compose_message(person,understood_language,chosen,null,list(person.speech_span),face_name = TRUE) feedback_details += "Type: Talk, Source: [person.real_name], Message: [message]" to_chat(target, message) if(target.client) @@ -705,7 +705,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) humans += H person = pick(humans) - var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",person.get_spans(),face_name = TRUE) + var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",list(person.speech_span),face_name = TRUE) feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]" to_chat(target, message) qdel(src) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 6594146e81..7b1d8be85e 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 @@ -205,6 +204,14 @@ resistance_flags = FREEZE_PROOF isGlass = FALSE +//Used by MREs +/obj/item/reagent_containers/food/drinks/coffee/type2 + name = "\improper Coffee, instant (type 2)" + desc = "Coffee that's been blow dried into a granulated powder. This packet includes self heating water for your nutritional pleasure." + icon = 'icons/obj/food/containers.dmi' + icon_state = "condi_cornoil" + + /obj/item/reagent_containers/food/drinks/ice name = "ice cup" desc = "Careful, cold ice, do not chew." @@ -399,7 +406,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 +430,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 @@ -508,6 +515,13 @@ list_reagents = list("shamblers" = 30) foodtype = SUGAR | JUNKFOOD +/obj/item/reagent_containers/food/drinks/soda_cans/grey_bull + name = "Grey Bull" + desc = "Grey Bull, it gives you gloves!" + icon_state = "energy_drink" + list_reagents = list("grey_bull" = 20) + foodtype = SUGAR | JUNKFOOD + /obj/item/reagent_containers/food/drinks/soda_cans/air name = "canned air" desc = "There is no air shortage. Do not drink." diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 46e637e640..f85668d2b8 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) @@ -202,6 +202,19 @@ desc = "A flask of holy water...it's been sitting in the Necropolis a while though." list_reagents = list("hell_water" = 100) +/obj/item/reagent_containers/food/drinks/holyoil + name = "flask of zelus oil" + desc = "A brass flask of Zelus oil, a viscous fluid with a scenting of brass - this flask may be sipped or thrown." + icon_state = "zelusflask" + list_reagents = list("holyoil" = 30) //Powerfull + volume = 30 + foodtype = NONE + force = 12 //Same as a toolbox + throwforce = 18 + +/obj/item/reagent_containers/food/drinks/holyoil/null + list_reagents = list("holyoil" = 0) + /obj/item/reagent_containers/food/drinks/bottle/vermouth name = "Goldeneye vermouth" desc = "Sweet, sweet dryness~" @@ -330,6 +343,33 @@ icon_state = "fernetbottle" list_reagents = list("fernet" = 100) +/obj/item/reagent_containers/food/drinks/bottle/applejack + name = "Buckin' Bronco's Applejack" + desc = "Kicks like a horse, tastes like an apple!" + icon_state = "applejack_bottle" + list_reagents = list("applejack" = 100) + foodtype = FRUIT + +/obj/item/reagent_containers/food/drinks/bottle/champagne + name = "Eau d' Dandy Brut Champagne" + desc = "Finely sourced from only the most pretentious French vineyards." + icon_state = "champagne_bottle" + list_reagents = list("champagne" = 100) + +/obj/item/reagent_containers/food/drinks/bottle/blazaam + name = "Ginbad's Blazaam" + desc = "You feel like you should give the bottle a good rub before opening." + icon_state = "blazaambottle" + list_reagents = list("blazaam" = 100) + +/obj/item/reagent_containers/food/drinks/bottle/trappist + name = "Mont de Requin Trappistes Bleu" + desc = "Brewed in space-Belgium. Fancy!" + icon_state = "trappistbottle" + volume = 50 + list_reagents = list("trappist" = 50) + + //////////////////////////JUICES AND STUFF /////////////////////// /obj/item/reagent_containers/food/drinks/bottle/orangejuice diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index 9d173a34a5..1e5c2eaf60 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -23,6 +23,7 @@ icon_state = R.glass_icon_state else var/mutable_appearance/reagent_overlay = mutable_appearance(icon, "glassoverlay") + icon_state = "glass_empty" reagent_overlay.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(reagent_overlay) else diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index f9d9a3d85a..132e000893 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -1,10 +1,14 @@ //////////////////////////////////////////////////////////////////////////////// /// Food. //////////////////////////////////////////////////////////////////////////////// +/// Note: When adding food items with dummy parents, make sure to add +/// the parent to the exclusion list in code/__HELPERS/unsorted.dm's +/// get_random_food proc. +//////////////////////////////////////////////////////////////////////////////// /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 +23,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..31e99535d1 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. @@ -24,7 +24,8 @@ "blackpepper" = list("peppermillsmall", "pepper mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("oliveoil", "corn oil bottle", "A delicious oil used in cooking. Made from corn"), "sugar" = list("emptycondiment", "sugar bottle", "Tasty spacey sugar!"), - "mayonnaise" = list("mayonnaise", "mayonnaise jar", "An oily condiment made from egg yolks.")) + "mayonnaise" = list("mayonnaise", "mayonnaise jar", "An oily condiment made from egg yolks."), + "peanut_butter" = list("peanutbutter", "peanut butter jar", "A deliciously and sticky spread made from peanuts.")) var/originalname = "condiment" //Can't use initial(name) for this. This stores the name set by condimasters. /obj/item/reagent_containers/food/condiment/suicide_act(mob/living/carbon/user) @@ -236,7 +237,7 @@ volume = 10 amount_per_transfer_from_this = 10 possible_transfer_amounts = list() - possible_states = list("ketchup" = list("condi_ketchup", "Ketchup", "You feel more American already."), "capsaicin" = list("condi_hotsauce", "Hotsauce", "You can almost TASTE the stomach ulcers now!"), "soysauce" = list("condi_soysauce", "Soy Sauce", "A salty soy-based flavoring"), "frostoil" = list("condi_frostoil", "Coldsauce", "Leaves the tongue numb in it's passage"), "sodiumchloride" = list("condi_salt", "Salt Shaker", "Salt. From space oceans, presumably"), "blackpepper" = list("condi_pepper", "Pepper Mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("condi_cornoil", "Corn Oil", "A delicious oil used in cooking. Made from corn"), "sugar" = list("condi_sugar", "Sugar", "Tasty spacey sugar!")) + possible_states = list("ketchup" = list("condi_ketchup", "Ketchup", "You feel more American already."), "capsaicin" = list("condi_hotsauce", "Hotsauce", "You can almost TASTE the stomach ulcers now!"), "soysauce" = list("condi_soysauce", "Soy Sauce", "A salty soy-based flavoring"), "frostoil" = list("condi_frostoil", "Coldsauce", "Leaves the tongue numb in it's passage"), "sodiumchloride" = list("condi_salt", "Salt Shaker", "Salt. From space oceans, presumably"), "blackpepper" = list("condi_pepper", "Pepper Mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("condi_cornoil", "Corn Oil", "A delicious oil used in cooking. Made from corn"), "sugar" = list("condi_sugar", "Sugar", "Tasty spacey sugar!"), "astrotame" = list("condi_astrotame", "Astrotame", "The sweetness of a thousand sugars but none of the calories.")) /obj/item/reagent_containers/food/condiment/pack/attack(mob/M, mob/user, def_zone) //Can't feed these to people directly. return @@ -286,3 +287,8 @@ name = "hotsauce pack" originalname = "hotsauce" list_reagents = list("capsaicin" = 10) + +/obj/item/reagent_containers/food/condiment/pack/astrotame + name = "astrotame pack" + originalname = "astrotame" + list_reagents = list("astrotame" = 5) 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..7eea6fb9ca 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. @@ -291,19 +291,23 @@ All foods are distributed among various categories. Use common sense. S.reagents.add_reagent(r_id, amount) /obj/item/reagent_containers/food/snacks/microwave_act(obj/machinery/microwave/M) + var/turf/T = get_turf(src) + var/obj/item/result if(cooked_type) - var/obj/item/reagent_containers/food/snacks/S = new cooked_type(get_turf(src)) - if(M) - initialize_cooked_food(S, M.efficiency) + result = new cooked_type(T) + if(istype(M)) + initialize_cooked_food(result, M.efficiency) else - initialize_cooked_food(S, 1) - SSblackbox.record_feedback("tally", "food_made", 1, type) + initialize_cooked_food(result, 1) + SSblackbox.record_feedback("tally", "food_made", 1, result.type) else - new /obj/item/reagent_containers/food/snacks/badrecipe(src) - if(M && M.dirty < 100) + result = new /obj/item/reagent_containers/food/snacks/badrecipe(T) + if(istype(M) && M.dirty < 100) M.dirty++ qdel(src) + return result + /obj/item/reagent_containers/food/snacks/Destroy() if(contents) for(var/atom/movable/something in contents) 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_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 5213cc96e1..e36efe750b 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -340,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." @@ -588,3 +558,19 @@ list_reagents = list("nutriment" = 6, "sodiumchloride" = 2) tastes = list("rice" = 3, "salt" = 1) foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/cannedpeaches + name = "Canned Peaches" + desc = "Just a nice can of ripe peaches swimming in their own juices." + icon_state = "peachcan" + list_reagents = list("peachjuice" = 20, "sugar" = 8, "nutriment" = 2) + filling_color = "#ffdf26" + w_class = WEIGHT_CLASS_NORMAL + tastes = list("peaches" = 7, "tin" = 1) + foodtype = FRUIT | SUGAR + +/obj/item/reagent_containers/food/snacks/cannedpeaches/maint + name = "Maintenance Peaches" + desc = "I have a mouth and I must eat." + icon_state = "peachcanmaint" + tastes = list("peaches" = 1, "tin" = 7) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 435b4a371a..238bb4f86a 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -8,27 +8,34 @@ icon_state = "donut1" bitesize = 5 bonus_reagents = list("sugar" = 1) - list_reagents = list("nutriment" = 3, "sugar" = 2) - var/extra_reagent = null + list_reagents = list("nutriment" = 3, "sprinkles" = 1, "sugar" = 2) filling_color = "#D2691E" tastes = list("donut" = 1) foodtype = JUNKFOOD | GRAIN | FRIED | SUGAR + var/frosted_icon = "donut2" + var/is_frosted = FALSE + var/extra_reagent = null /obj/item/reagent_containers/food/snacks/donut/Initialize() . = ..() if(prob(30)) - icon_state = "donut2" - name = "frosted donut" - reagents.add_reagent("sprinkles", 2) - bonus_reagents = list("sprinkles" = 2, "sugar" = 1) - filling_color = "#FF69B4" + frost_donut() +/obj/item/reagent_containers/food/snacks/donut/proc/frost_donut() + if(is_frosted || !frosted_icon) + return + is_frosted = TRUE + name = "frosted [name]" + icon_state = frosted_icon //delish~! + reagents.add_reagent("sprinkles", 1) + filling_color = "#FF69B4" + return TRUE /obj/item/reagent_containers/food/snacks/donut/checkLiked(fraction, mob/M) //Sec officers always love donuts 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(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM) && !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) @@ -48,18 +55,12 @@ . = ..() extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") reagents.add_reagent("[extra_reagent]", 3) - bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1) - if(prob(30)) - icon_state = "donut2" - name = "frosted chaos donut" - reagents.add_reagent("sprinkles", 2) - bonus_reagents = list("sprinkles" = 2, "[extra_reagent]" = 3, "sugar" = 1) - filling_color = "#FF69B4" /obj/item/reagent_containers/food/snacks/donut/jelly name = "jelly donut" desc = "You jelly?" icon_state = "jdonut1" + frosted_icon = "jdonut2" bonus_reagents = list("sugar" = 1, "vitamin" = 1) extra_reagent = "berryjuice" tastes = list("jelly" = 1, "donut" = 3) @@ -69,12 +70,6 @@ . = ..() if(extra_reagent) reagents.add_reagent("[extra_reagent]", 3) - if(prob(30)) - icon_state = "jdonut2" - name = "frosted jelly Donut" - reagents.add_reagent("sprinkles", 2) - bonus_reagents = list("sprinkles" = 2, "sugar" = 1) - filling_color = "#FF69B4" /obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly name = "jelly donut" @@ -203,7 +198,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..0b12ee4fcf 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -53,6 +53,7 @@ H.adjust_blurriness(1) H.visible_message("[H] is creamed by [src]!", "You've been creamed by [src]!") playsound(H, "desceration", 50, TRUE) + reagents.trans_to(H,15) //Cream pie combat if(!H.creamed) // one layer at a time H.add_overlay(creamoverlay) H.creamed = TRUE @@ -60,8 +61,31 @@ qdel(src) /obj/item/reagent_containers/food/snacks/pie/cream/nostun + list_reagents = list("laughter" = 15) 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." @@ -246,3 +270,24 @@ bonus_reagents = list("nutriment" = 4, "vitamin" = 6) tastes = list("mint" = 1, "pie" = 1) foodtype = GRAIN | FRUIT | SUGAR + +/obj/item/reagent_containers/food/snacks/pie/baklava + name = "baklava" + desc = "A delightful healthy snake made of nut layers with thin bread." + icon_state = "baklava" + slice_path = /obj/item/reagent_containers/food/snacks/baklavaslice + slices_num = 6 + bonus_reagents = list("nutriment" = 2, "vitamin" = 6) + tastes = list("nuts" = 1, "pie" = 1) + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/baklavaslice + name = "baklava dish" + desc = "A portion delightful healthy snake made of nut layers with thin bread" + icon = 'icons/obj/food/piecake.dmi' + icon_state = "baklavaslice" + trash = /obj/item/trash/plate + filling_color = "#1E90FF" + list_reagents = list("nutriment" = 2, "vitamins" = 4) + tastes = list("nuts" = 1, "pie" = 1) + foodtype = GRAIN \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_pizza.dm b/code/modules/food_and_drinks/food/snacks_pizza.dm index 403636db08..74fd7dda65 100644 --- a/code/modules/food_and_drinks/food/snacks_pizza.dm +++ b/code/modules/food_and_drinks/food/snacks_pizza.dm @@ -225,3 +225,12 @@ filling_color = "#FFFFFF" foodtype = GRAIN | VEGETABLES + +// Used by MREs +/obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni + name = "\improper MRE pepperoni pizza slice" + desc = "A freeze dried, dehydrated slice of bread with tomato sauce, pepperoni and cheese." + icon_state = "meatpizzaslice" + filling_color = "#A52A2A" + tastes = list("cardboard" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2) + foodtype = GRAIN | VEGETABLES | DAIRY | MEAT \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm index 88f8848315..17a710ada2 100644 --- a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm +++ b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm @@ -52,15 +52,32 @@ 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/jellysandwich/pbj + name = "\improper PB & J sandwich" + desc = "A grand creation of peanut butter, jelly and bread! An all-american classic." + icon_state = "pbjsandwich" + tastes = list("bread" = 1, "jelly" = 1, "peanuts" = 1) + +/obj/item/reagent_containers/food/snacks/jellysandwich/pbj/cherry + bonus_reagents = list("cherryjelly" = 5, "peanut_butter" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "peanut_butter" = 5, "vitamin" = 2) + foodtype = GRAIN | FRUIT + +/obj/item/reagent_containers/food/snacks/jellysandwich/pbj/slime + bonus_reagents = list("slimejelly" = 5, "peanut_butter" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "slimejelly" = 5, "peanut_butter" = 5, "vitamin" = 2) + foodtype = GRAIN | TOXIC + +/obj/item/reagent_containers/food/snacks/peanutbutter_sandwich + name = "peanut butter sandwich" + desc = "You wish you had some jelly to go with this..." + icon = 'icons/obj/food/burgerbread.dmi' + icon_state = "peanutbuttersandwich" + trash = /obj/item/trash/plate + bitesize = 3 + bonus_reagents = list("peanut_butter" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "peanut_butter" = 5, "vitamin" = 2) + foodtype = GRAIN /obj/item/reagent_containers/food/snacks/notasandwich name = "not-a-sandwich" @@ -93,6 +110,19 @@ list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) foodtype = GRAIN | TOXIC | SUGAR +/obj/item/reagent_containers/food/snacks/peanut_buttertoast + name = "peanut butter toast" + desc = "A slice of toast covered with delicious peanut butter." + icon = 'icons/obj/food/burgerbread.dmi' + icon_state = "peanutbuttertoast" + trash = /obj/item/trash/plate + bitesize = 3 + bonus_reagents = list("peanut_butter" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 1, "peanut_butter" = 5, "vitamin" = 2) + tastes = list("toast" = 1, "peanuts" = 1) + foodtype = GRAIN + + /obj/item/reagent_containers/food/snacks/twobread name = "two bread" desc = "This seems awfully bitter." 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..dd33f696c9 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) @@ -95,7 +94,7 @@ God bless America. else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?! return else - if(is_type_in_typecache(I, deepfry_blacklisted_items) || (I.item_flags & (ABSTRACT | NODROP | DROPDEL))) + if(is_type_in_typecache(I, deepfry_blacklisted_items) || HAS_TRAIT(I, TRAIT_NODROP) || (I.item_flags & (ABSTRACT | DROPDEL))) return ..() else if(!frying && user.transferItemToLoc(I, src)) to_chat(user, "You put [I] into [src].") 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/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index d8d4e843dc..e02c3c1334 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -78,7 +78,7 @@ if(!ignore_clothing) for(var/obj/item/I in C.held_items + C.get_equipped_items()) - if(!(I.item_flags & NODROP)) + if(!HAS_TRAIT(I, TRAIT_NODROP)) to_chat(user, "Subject may not have abiotic items on.") return 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..6fcc5c9cec 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -12,325 +12,343 @@ pass_flags = PASSTABLE light_color = LIGHT_COLOR_YELLOW light_power = 0.9 + var/wire_disabled = FALSE // is its internal wire cut? var/operating = FALSE // Is it on? - var/dirty = 0 // = {0..100} Does it need cleaning? - var/broken = 0 // ={0,1,2} How broken is it??? - var/max_n_of_items = 10 // whatever fat fuck made this a global var needs to look at themselves in the mirror sometime + var/dirty = 0 // 0 to 100 // Does it need cleaning? + var/dirty_anim_playing = FALSE + var/broken = 0 // 0, 1 or 2 // How broken is it??? + var/max_n_of_items = 10 var/efficiency = 0 var/datum/looping_sound/microwave/soundloop + var/list/ingredients = list() // may only contain /atom/movables -//Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. For food, this creates something based on the food's cooked_type + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use") -/******************* -* Initialising -********************/ + // we show the button even if the proc will not work + var/static/list/radial_options = list("eject" = radial_eject, "use" = radial_use) + var/static/list/ai_radial_options = list("eject" = radial_eject, "use" = radial_use, "examine" = radial_examine) /obj/machinery/microwave/Initialize() . = ..() + wires = new /datum/wires/microwave(src) create_reagents(100) soundloop = new(list(src), FALSE) +/obj/machinery/microwave/Destroy() + eject() + if(wires) + QDEL_NULL(wires) + . = ..() + /obj/machinery/microwave/RefreshParts() - var/E - var/max_items = 10 + efficiency = 0 for(var/obj/item/stock_parts/micro_laser/M in component_parts) - E += M.rating + efficiency += M.rating for(var/obj/item/stock_parts/matter_bin/M in component_parts) - max_items = 10 * M.rating - efficiency = E - max_n_of_items = max_items + max_n_of_items = 10 * M.rating + break /obj/machinery/microwave/examine(mob/user) - ..() + . = ..() if(!operating) to_chat(user, "Alt-click [src] to turn it on.") -/******************* -* Item Adding -********************/ + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + to_chat(user, "You're too far away to examine [src]'s contents and display!") + return + if(operating) + to_chat(user, "\The [src] is operating.") + return + + if(length(ingredients)) + if(issilicon(user)) + to_chat(user, "\The [src] camera shows:") + else + to_chat(user, "\The [src] contains:") + var/list/items_counts = new + for(var/i in ingredients) + if(istype(i, /obj/item/stack)) + var/obj/item/stack/S = i + items_counts[S.name] += S.amount + else + var/atom/movable/AM = i + items_counts[AM.name]++ + for(var/O in items_counts) + to_chat(user, "- [items_counts[O]]x [O].") + else + to_chat(user, "\The [src] is empty.") + + if(!(stat & (NOPOWER|BROKEN))) + to_chat(user, "The status display reads:") + to_chat(user, "- Capacity: [max_n_of_items] items.") + to_chat(user, "- Cook time reduced by [(efficiency - 1) * 25]%.") + +/obj/machinery/microwave/update_icon() + if(broken) + icon_state = "mwb" + else if(dirty_anim_playing) + icon_state = "mwbloody1" + else if(dirty == 100) + icon_state = "mwbloody" + else if(operating) + icon_state = "mw1" + else if(panel_open) + icon_state = "mw-o" + else + icon_state = "mw" /obj/machinery/microwave/attackby(obj/item/O, mob/user, params) if(operating) return - if(!broken && dirty<100) - if(default_deconstruction_screwdriver(user, "mw-o", "mw", O)) - return - if(default_unfasten_wrench(user, O)) - return - if(default_deconstruction_crowbar(O)) return - if(src.broken > 0) - if(src.broken == 2 && istype(O, /obj/item/wirecutters)) // If it's broken and they're using a screwdriver - user.visible_message( \ - "[user] starts to fix part of the microwave.", \ - "You start to fix part of the microwave..." \ - ) - if (O.use_tool(src, user, 20)) - user.visible_message( \ - "[user] fixes part of the microwave.", \ - "You fix part of the microwave." \ - ) - src.broken = 1 // Fix it a bit - else if(src.broken == 1 && istype(O, /obj/item/weldingtool)) // If it's broken and they're doing the wrench - user.visible_message( \ - "[user] starts to fix part of the microwave.", \ - "You start to fix part of the microwave..." \ - ) - if (O.use_tool(src, user, 20)) - user.visible_message( \ - "[user] fixes the microwave.", \ - "You fix the microwave." \ - ) - 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 + if(dirty < 100) + if(default_deconstruction_screwdriver(user, icon_state, icon_state, O) || default_unfasten_wrench(user, O)) + update_icon() + return + + if(panel_open && is_wire_tool(O)) + wires.interact(user) + return TRUE + + if(broken > 0) + if(broken == 2 && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a screwdriver + user.visible_message("[user] starts to fix part of \the [src].", "You start to fix part of \the [src]...") + if(O.use_tool(src, user, 20)) + user.visible_message("[user] fixes part of \the [src].", "You fix part of \the [src].") + broken = 1 // Fix it a bit + else if(broken == 1 && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench + user.visible_message("[user] starts to fix part of \the [src].", "You start to fix part of \the [src]...") + if(O.use_tool(src, user, 20)) + user.visible_message("[user] fixes \the [src].", "You fix \the [src].") + broken = 0 + update_icon() + return FALSE //to use some fuel else to_chat(user, "It's broken!") - return 1 - else if(istype(O, /obj/item/reagent_containers/spray/)) + return TRUE + return + + if(istype(O, /obj/item/reagent_containers/spray)) var/obj/item/reagent_containers/spray/clean_spray = O - if(clean_spray.reagents.has_reagent("cleaner",clean_spray.amount_per_transfer_from_this)) - clean_spray.reagents.remove_reagent("cleaner",clean_spray.amount_per_transfer_from_this,1) + if(clean_spray.reagents.has_reagent("cleaner", clean_spray.amount_per_transfer_from_this)) + clean_spray.reagents.remove_reagent("cleaner", clean_spray.amount_per_transfer_from_this,1) playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) - user.visible_message( \ - "[user] has cleaned the microwave.", \ - "You clean the microwave." \ - ) - 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. + user.visible_message("[user] has cleaned \the [src].", "You clean \the [src].") + dirty = 0 + update_icon() else to_chat(user, "You need more space cleaner!") - return 1 + return TRUE - else if(istype(O, /obj/item/soap/)) // If they're trying to clean it then let them + if(istype(O, /obj/item/soap)) var/obj/item/soap/P = O - user.visible_message( \ - "[user] starts to clean the microwave.", \ - "You start to clean the microwave..." \ - ) - if (do_after(user, P.cleanspeed, target = src)) - user.visible_message( \ - "[user] has cleaned the microwave.", \ - "You clean the microwave." \ - ) - src.dirty = 0 // It's clean! - src.broken = 0 // just to be sure - src.icon_state = "mw" - src.container_type = OPENCONTAINER + user.visible_message("[user] starts to clean \the [src].", "You start to clean \the [src]...") + if(do_after(user, P.cleanspeed, target = src)) + user.visible_message("[user] has cleaned \the [src].", "You clean \the [src].") + dirty = 0 + update_icon() + return TRUE - else if(src.dirty==100) // The microwave is all dirty so can't be used! - to_chat(user, "It's dirty!") - return 1 + if(dirty == 100) // The microwave is all dirty so can't be used! + to_chat(user, "\The [src] is dirty!") + return TRUE - else if(istype(O, /obj/item/storage/bag/tray)) + if(istype(O, /obj/item/storage/bag/tray)) var/obj/item/storage/T = O var/loaded = 0 for(var/obj/item/reagent_containers/food/snacks/S in T.contents) - if (contents.len>=max_n_of_items) - to_chat(user, "[src] is full, you can't put anything in!") - return 1 + if(ingredients.len >= max_n_of_items) + to_chat(user, "\The [src] is full, you can't put anything in!") + return TRUE if(SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src)) loaded++ - + ingredients += S if(loaded) - to_chat(user, "You insert [loaded] items into [src].") + to_chat(user, "You insert [loaded] items into \the [src].") + return + if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP) + if(ingredients.len >= max_n_of_items) + to_chat(user, "\The [src] is full, you can't put anything in!") + return TRUE + if(!user.transferItemToLoc(O, src)) + to_chat(user, "\The [O] is stuck to your hand!") + return FALSE - else if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP) - if (contents.len>=max_n_of_items) - to_chat(user, "[src] is full, you can't put anything in!") - return 1 - else - if(!user.transferItemToLoc(O, src)) - to_chat(user, "\the [O] is stuck to your hand, you cannot put it in \the [src]!") - return 0 + ingredients += O + user.visible_message("[user] has added \a [O] to \the [src].", "You add [O] to \the [src].") + return - user.visible_message( \ - "[user] has added \the [O] to \the [src].", \ - "You add \the [O] to \the [src].") - - else - ..() - updateUsrDialog() + ..() /obj/machinery/microwave/AltClick(mob/user) - if(user.canUseTopic(src, BE_CLOSE) && !(operating || broken > 0 || panel_open || !anchored || dirty == 100)) + if(user.canUseTopic(src, !issilicon(usr))) cook() -/******************* -* Microwave Menu -********************/ - -/obj/machinery/microwave/ui_interact(mob/user) // The microwave Menu +/obj/machinery/microwave/ui_interact(mob/user) . = ..() - if(panel_open || !anchored) + + if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user))) + return + if(isAI(user) && (stat & NOPOWER)) return - var/dat = "
    " - if(broken > 0) - dat += "ERROR: 09734014-A2379-D18746 --Bad memory
    Contact your operator or use command line to rebase memory ///git checkout {HEAD} -a commit pull --rebase push {*NEW HEAD*}
    " //Thats how all the git fiddling looks to me - else if(operating) - dat += "Microwaving in progress!
    Please wait...!" - else if(dirty==100) - dat += "ERROR: >> 0 --Response input zero
    Contact your operator of the device manifactor support." - else - var/list/items_counts = new - for (var/obj/O in contents) - if(istype(O, /obj/item/stack/)) - var/obj/item/stack/S = O - items_counts[O.name] += S.amount - else - items_counts[O.name]++ - for (var/O in items_counts) - var/N = items_counts[O] - dat += "[capitalize(O)]: [N]
    " - - if (items_counts.len==0) - dat += "The microwave is empty." + if(!length(ingredients)) + if(isAI(user)) + examine(user) else - dat = "

    Ingredients:

    [dat]" - dat += "Turn on" - dat += "Eject ingredients
    " + to_chat(user, "\The [src] is empty.") + return - var/datum/browser/popup = new(user, "microwave", name, 300, 300) - popup.set_content(dat) - popup.open() + var/choice = show_radial_menu(user, src, isAI(user) ? ai_radial_options : radial_options, require_near = !issilicon(user)) -/*********************************** -* Microwave Menu Handling/Cooking -************************************/ + // post choice verification + if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user))) + return + if(isAI(user) && (stat & NOPOWER)) + return + + usr.set_machine(src) + switch(choice) + if("eject") + eject() + if("use") + cook() + if("examine") + examine(user) + +/obj/machinery/microwave/proc/eject() + for(var/i in ingredients) + var/atom/movable/AM = i + AM.forceMove(drop_location()) + ingredients.Cut() /obj/machinery/microwave/proc/cook() if(stat & (NOPOWER|BROKEN)) return + if(operating || broken > 0 || panel_open || !anchored || dirty == 100) + return + + if(wire_disabled) + audible_message("[src] buzzes.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) + return + + if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure + muck() + return + for(var/obj/O in ingredients) + if(istype(O, /obj/item/reagent_containers/food) || istype(O, /obj/item/grown)) + continue + if(prob(min(dirty * 5, 100))) + start_can_fail() + return + break start() - if (prob(max(5/efficiency-5,dirty*5))) //a clean unupgraded microwave has no risk of failure - muck_start() - if (!microwaving(4)) - muck_finish() - return - muck_finish() - return +/obj/machinery/microwave/proc/turn_on() + visible_message("\The [src] turns on.", "You hear a microwave humming.") + operating = TRUE - else - if(has_extra_item() && prob(min(dirty*5,100)) && !microwaving(4)) - broke() - return + set_light(1.5) + soundloop.start() + update_icon() - if(!microwaving(10)) - abort() - return - stop() +/obj/machinery/microwave/proc/spark() + visible_message("Sparks fly around [src]!") + var/datum/effect_system/spark_spread/s = new + s.set_up(2, 1, src) + s.start() - var/metal = 0 - for(var/obj/item/O in contents) - O.microwave_act(src) - if(O.materials[MAT_METAL]) - metal += O.materials[MAT_METAL] - - if(metal) - visible_message("Sparks fly around [src]!") - if(prob(max(metal/2, 33))) - explosion(loc,0,1,2) - broke() - return - - dropContents() - return - -/obj/machinery/microwave/proc/microwaving(seconds as num) - for (var/i=1 to seconds) - if (stat & (NOPOWER|BROKEN)) - return 0 - use_power(500) - sleep(max(12-2*efficiency,2)) // standard microwave means sleep(10). The better the efficiency, the faster the cooking - return 1 - -/obj/machinery/microwave/proc/has_extra_item() - for (var/obj/O in contents) - if ( \ - !istype(O, /obj/item/reagent_containers/food) && \ - !istype(O, /obj/item/grown) \ - ) - return 1 - return 0 +#define MICROWAVE_NORMAL 0 +#define MICROWAVE_MUCK 1 +#define MICROWAVE_PRE 2 /obj/machinery/microwave/proc/start() - visible_message("The microwave turns on.", "You hear a microwave humming.") - soundloop.start() - operating = TRUE - icon_state = "mw1" - set_light(1.5) - updateUsrDialog() + turn_on() + loop(MICROWAVE_NORMAL, 10) -/obj/machinery/microwave/proc/abort() - operating = FALSE // Turn it off again aferwards - icon_state = "mw" - updateUsrDialog() - set_light(0) - soundloop.stop() +/obj/machinery/microwave/proc/start_can_fail() + turn_on() + loop(MICROWAVE_PRE, 4) -/obj/machinery/microwave/proc/stop() - abort() +/obj/machinery/microwave/proc/muck() + turn_on() + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + dirty_anim_playing = TRUE + update_icon() + loop(MICROWAVE_MUCK, 4) -/obj/machinery/microwave/proc/dispose() - for (var/obj/O in contents) - O.forceMove(drop_location()) - to_chat(usr, "You dispose of the microwave contents.") - updateUsrDialog() +/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2)) // standard wait is 10 + if(stat & (NOPOWER|BROKEN)) + if(MICROWAVE_PRE) + pre_fail() + return + if(!time) + switch(type) + if(MICROWAVE_NORMAL) + loop_finish() + if(MICROWAVE_MUCK) + muck_finish() + if(MICROWAVE_PRE) + pre_success() + return + time-- + use_power(500) + addtimer(CALLBACK(src, .proc/loop, type, time, wait), wait) -/obj/machinery/microwave/proc/muck_start() - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound - icon_state = "mwbloody1" // Make it look dirty!! +/obj/machinery/microwave/proc/loop_finish() + operating = FALSE + + var/metal = 0 + for(var/obj/item/O in ingredients) + O.microwave_act(src) + if(O.materials[MAT_METAL]) + metal += O.materials[MAT_METAL] + + if(metal) + spark() + broken = 2 + if(prob(max(metal / 2, 33))) + explosion(loc, 0, 1, 2) + else + dropContents(ingredients) + ingredients.Cut() + + after_finish_loop() + +/obj/machinery/microwave/proc/pre_fail() + broken = 2 + operating = FALSE + spark() + after_finish_loop() + +/obj/machinery/microwave/proc/pre_success() + loop(MICROWAVE_NORMAL, 10) /obj/machinery/microwave/proc/muck_finish() - visible_message("The microwave gets covered in muck!") - dirty = 100 // Make it dirty so it can't be used util cleaned - icon_state = "mwbloody" // Make it look dirty too - operating = FALSE // Turn it off again aferwards - updateUsrDialog() + visible_message("\The [src] gets covered in muck!") + + dirty = 100 + dirty_anim_playing = FALSE + operating = FALSE + for(var/obj/item/reagent_containers/food/snacks/S in src) if(prob(50)) new /obj/item/reagent_containers/food/snacks/badrecipe(src) qdel(S) + + after_finish_loop() + +/obj/machinery/microwave/proc/after_finish_loop() set_light(0) soundloop.stop() + update_icon() -/obj/machinery/microwave/proc/broke() - var/datum/effect_system/spark_spread/s = new - s.set_up(2, 1, src) - s.start() - icon_state = "mwb" // Make it look all busted up and shit - visible_message("The microwave breaks!") //Let them know they're stupid - broken = 2 // Make it broken so it can't be used util fixed - flags_1 = null //So you can't add condiments - operating = FALSE // Turn it off again aferwards - updateUsrDialog() - set_light(0) - soundloop.stop() - -/obj/machinery/microwave/Topic(href, href_list) - if(..() || panel_open) - return - - usr.set_machine(src) - if(operating) - updateUsrDialog() - return - - switch(href_list["action"]) - if ("cook") - cook() - - if ("dispose") - dispose() - updateUsrDialog() +#undef MICROWAVE_NORMAL +#undef MICROWAVE_MUCK +#undef MICROWAVE_PRE \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 3f917273b4..35ce25bbaf 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -138,6 +138,10 @@ for (var/mob/M in src) M.forceMove(drop_location()) +/obj/machinery/processor/container_resist(mob/living/user) + user.forceMove(drop_location()) + user.visible_message("[user] crawls free of the processor!") + /obj/machinery/processor/slime name = "slime processor" desc = "An industrial grinder with a sticker saying appropriated for science department. Keep hands clear of intake area while operating." diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index b6e3b19640..483055cb0d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -15,11 +15,11 @@ var/max_n_of_items = 1500 var/allow_ai_retrieve = FALSE var/list/initial_contents + var/visible_contents = TRUE /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) @@ -38,11 +38,21 @@ update_icon() /obj/machinery/smartfridge/update_icon() - var/startstate = initial(icon_state) if(!stat) - icon_state = startstate + if(visible_contents) + switch(contents.len) + if(0) + icon_state = "[initial(icon_state)]" + if(1 to 25) + icon_state = "[initial(icon_state)]1" + if(26 to 75) + icon_state = "[initial(icon_state)]2" + if(76 to INFINITY) + icon_state = "[initial(icon_state)]3" + else + icon_state = "[initial(icon_state)]" else - icon_state = "[startstate]-off" + icon_state = "[initial(icon_state)]-off" @@ -51,7 +61,14 @@ ********************/ /obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params) - if(default_deconstruction_screwdriver(user, "smartfridge_open", "smartfridge", O)) + if(user.a_intent == INTENT_HARM) + return ..() + + if(default_deconstruction_screwdriver(user, icon_state, icon_state, O)) + cut_overlays() + if(panel_open) + add_overlay("[initial(icon_state)]-panel") + updateUsrDialog() return if(default_pry_open(O)) @@ -65,49 +82,46 @@ updateUsrDialog() return - if(!stat) - - if(contents.len >= max_n_of_items) - to_chat(user, "\The [src] is full!") - return FALSE - - if(accept_check(O)) - load(O) - user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") - updateUsrDialog() - return TRUE - - if(istype(O, /obj/item/storage/bag)) - var/obj/item/storage/P = O - var/loaded = 0 - for(var/obj/G in P.contents) - if(contents.len >= max_n_of_items) - break - if(accept_check(G)) - load(G) - loaded++ - updateUsrDialog() - - if(loaded) - if(contents.len >= max_n_of_items) - user.visible_message("[user] loads \the [src] with \the [O].", \ - "You fill \the [src] with \the [O].") - else - user.visible_message("[user] loads \the [src] with \the [O].", \ - "You load \the [src] with \the [O].") - if(O.contents.len > 0) - to_chat(user, "Some items are refused.") - return TRUE - else - to_chat(user, "There is nothing in [O] to put in [src]!") - return FALSE - - if(user.a_intent != INTENT_HARM) - to_chat(user, "\The [src] smartly refuses [O].") + if(stat) updateUsrDialog() return FALSE - else - return ..() + + if(contents.len >= max_n_of_items) + to_chat(user, "\The [src] is full!") + return FALSE + + if(accept_check(O)) + load(O) + user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") + updateUsrDialog() + if (visible_contents) + update_icon() + return TRUE + + if(istype(O, /obj/item/storage/bag)) + var/obj/item/storage/P = O + var/loaded = 0 + for(var/obj/G in P.contents) + if(contents.len >= max_n_of_items) + break + if(accept_check(G)) + load(G) + loaded++ + updateUsrDialog() + + if(loaded) + user.visible_message("[user] loads \the [src] with \the [O].", \ + "You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].") + if(O.contents.len > 0) + to_chat(user, "Some items are refused.") + return TRUE + else + to_chat(user, "There is nothing in [O] to put in [src]!") + return FALSE + + to_chat(user, "\The [src] smartly refuses [O].") + updateUsrDialog() + return FALSE @@ -187,6 +201,8 @@ O.forceMove(drop_location()) adjust_item_drop_location(O) break + if (visible_contents) + update_icon() return TRUE for(var/obj/item/O in src) @@ -196,6 +212,8 @@ O.forceMove(drop_location()) adjust_item_drop_location(O) desired-- + if (visible_contents) + update_icon() return TRUE return FALSE @@ -211,6 +229,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 200 + visible_contents = FALSE var/drying = FALSE /obj/machinery/smartfridge/drying_rack/Initialize() @@ -415,6 +434,7 @@ name = "disk compartmentalizer" desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)." icon_state = "disktoaster" + visible_contents = FALSE pass_flags = PASSTABLE /obj/machinery/smartfridge/disks/accept_check(obj/item/O) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index b06a160180..d608a73560 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -332,6 +332,12 @@ /obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type" if(!pizza_preferences[noms.ckey]) pizza_preferences[noms.ckey] = pickweight(pizza_types) + if(noms.has_quirk(/datum/quirk/pineapple_liker)) + pizza_preferences[noms.ckey] = /obj/item/reagent_containers/food/snacks/pizza/pineapple + else if(noms.has_quirk(/datum/quirk/pineapple_hater)) + var/list/pineapple_pizza_liker = pizza_types.Copy() + pineapple_pizza_liker -= /obj/item/reagent_containers/food/snacks/pizza/pineapple + pizza_preferences[noms.ckey] = pickweight(pineapple_pizza_liker) if(noms.mind && noms.mind.assigned_role == "Botanist") pizza_preferences[noms.ckey] = /obj/item/reagent_containers/food/snacks/pizza/dank diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index f41f6cce80..7c44857b1d 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -152,8 +152,8 @@ /datum/chemical_reaction/beepsky_smash name = "Beepksy Smash" id = "beepksysmash" - results = list("beepskysmash" = 4) - required_reagents = list("limejuice" = 2, "whiskey" = 2, "iron" = 1) + results = list("beepskysmash" = 5) + required_reagents = list("limejuice" = 2, "quadruple_sec" = 2, "iron" = 1) /datum/chemical_reaction/doctor_delight name = "The Doctor's Delight" @@ -532,11 +532,18 @@ required_reagents = list("hooch" = 1, "absinthe" = 1, "manlydorf" = 1, "syndicatebomb" = 1) mix_message = "The mixture turns to a sickening froth." +/datum/chemical_reaction/lemonade + name = "Lemonade" + id = "lemonade" + results = list("lemonade" = 5) + required_reagents = list("lemonjuice" = 2, "water" = 2, "sugar" = 1, "ice" = 1) + mix_message = "You're suddenly reminded of home." + /datum/chemical_reaction/arnold_palmer name = "Arnold Palmer" id = "arnold_palmer" results = list("arnold_palmer" = 2) - required_reagents = list("tea" = 1, "lemonjuice" = 1) + required_reagents = list("tea" = 1, "lemonade" = 1) mix_message = "The smells of fresh green grass and sand traps waft through the air as the mixture turns a friendly yellow-orange." /datum/chemical_reaction/chocolate_milk @@ -704,3 +711,87 @@ id = "pinktea" results = list("pinktea" = 5) required_reagents = list("aphro" = 1, "arnold_palmer" = 1, "sugar" = 1) + +/datum/chemical_reaction/blank_paper + name = "Blank Paper" + id = "blank_paper" + results = list("blank_paper" = 3) + required_reagents = list("silencer" = 1, "nothing" = 1, "nuka_cola" = 1) + +/datum/chemical_reaction/wizz_fizz + name = "Wizz Fizz" + id = "wizz_fizz" + results = list("wizz_fizz" = 3) + required_reagents = list("triple_sec" = 1, "sodawater" = 1, "champagne" = 1) + mix_message = "The beverage starts to froth with an almost mystical zeal!" + mix_sound = 'sound/effects/bubbles2.ogg' + +/datum/chemical_reaction/bug_spray + name = "Bug Spray" + id = "bug_spray" + results = list("bug_spray" = 5) + required_reagents = list("triple_sec" = 2, "lemon_lime" = 1, "rum" = 2, "vodka" = 1) + mix_message = "The faint aroma of summer camping trips wafts through the air; but what's that buzzing noise?" + mix_sound = 'sound/creatures/bee.ogg' + +/datum/chemical_reaction/jack_rose + name = "Jack Rose" + id = "jack_rose" + results = list("jack_rose" = 4) + required_reagents = list("grenadine" = 1, "applejack" = 2, "limejuice" = 1) + mix_message = "As the grenadine incorporates, the beverage takes on a mellow, red-orange glow." + +/datum/chemical_reaction/turbo + name = "Turbo" + id = "turbo" + results = list("turbo" = 5) + required_reagents = list("moonshine" = 2, "nitrous_oxide" = 1, "sugar_rush" = 1, "pwr_game" = 1) + +/datum/chemical_reaction/old_timer + name = "Old Timer" + id = "old_timer" + results = list("old_timer" = 6) + required_reagents = list("whiskeysoda" = 3, "parsnipjuice" = 2, "alexander" = 1) + +/datum/chemical_reaction/rubberneck + name = "Rubberneck" + id = "rubberneck" + results = list("rubberneck" = 10) + required_reagents = list("ethanol" = 4, "grey_bull" = 5, "astrotame" = 1) + +/datum/chemical_reaction/duplex + name = "Duplex" + id = "duplex" + results = list("duplex" = 4) + required_reagents = list("hcider" = 2, "applejuice" = 1, "berryjuice" = 1) + +/datum/chemical_reaction/trappist + name = "Trappist" + id = "trappist" + results = list("trappist" = 5) + required_reagents = list("ale" = 2, "holywater" = 2, "sugar" = 1) + +/datum/chemical_reaction/cream_soda + name = "Cream Soda" + id = "cream_soda" + results = list("cream_soda" = 4) + required_reagents = list("sugar" = 2, "sodawater" = 2, "vanilla" = 1) + +/datum/chemical_reaction/blazaam + name = "Blazaam" + id = "blazaam" + results = list("blazaam" = 3) + required_reagents = list("gin" = 2, "peachjuice" = 1, "bluespace" = 1) + +/datum/chemical_reaction/planet_cracker + name = "Planet Cracker" + id = "planet_cracker" + results = list("planet_cracker" = 4) + required_reagents = list("champagne" = 2, "lizardwine" = 2, "eggyolk" = 1, "gold" = 1) + mix_message = "The liquid's color starts shifting as the nanogold is alternately corroded and redeposited." + +/datum/chemical_reaction/red_queen + name = "Red Queen" + id = "red_queen" + results = list("red_queen" = 10) + required_reagents = list("tea" = 6, "mercury" = 2, "blackpepper" = 1, "growthserum" = 1) \ No newline at end of file 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 c16c7268b9..7eff2820c5 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -38,37 +38,6 @@ // see code/module/crafting/table.dm -////////////////////////////////////////////////FISH//////////////////////////////////////////////// - -/datum/crafting_recipe/food/cubancarp - name = "Cuban carp" - reqs = list( - /datum/reagent/consumable/flour = 5, - /obj/item/reagent_containers/food/snacks/grown/chili = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/cubancarp - subcategory = CAT_MEAT - -/datum/crafting_recipe/food/fishandchips - name = "Fish and chips" - reqs = list( - /obj/item/reagent_containers/food/snacks/fries = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/fishandchips - subcategory = CAT_MEAT - -/datum/crafting_recipe/food/fishfingers - name = "Fish fingers" - reqs = list( - /datum/reagent/consumable/flour = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/fishfingers - 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 3dd27ddd01..a6240e5b48 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -116,7 +116,7 @@ result = /obj/item/reagent_containers/food/snacks/jelliedtoast/slime subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/jelliedyoast +/datum/crafting_recipe/food/jelliedtoast name = "Jellied toast" reqs = list( /datum/reagent/consumable/cherryjelly = 5, @@ -125,6 +125,15 @@ result = /obj/item/reagent_containers/food/snacks/jelliedtoast/cherry subcategory = CAT_MISCFOOD +/datum/crafting_recipe/food/peanutbuttertoast + name = "Peanut butter toast" + reqs = list( + /datum/reagent/consumable/peanut_butter = 5, + /obj/item/reagent_containers/food/snacks/breadslice/plain = 1 + ) + result = /obj/item/reagent_containers/food/snacks/peanut_buttertoast + subcategory = CAT_MISCFOOD + /datum/crafting_recipe/food/twobread name = "Two bread" reqs = list( @@ -186,39 +195,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( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index 4b76ca120b..2246d12df4 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -22,7 +22,7 @@ ) result = /obj/item/reagent_containers/food/snacks/donut subcategory = CAT_PASTRY - + /datum/crafting_recipe/food/donut time = 15 name = "Semen donut" @@ -104,7 +104,7 @@ datum/crafting_recipe/food/donut/meat /datum/crafting_recipe/food/rofflewaffles name = "Roffle waffles" reqs = list( - /datum/reagent/mushroomhallucinogen = 5, + /datum/reagent/drug/mushroomhallucinogen = 5, /obj/item/reagent_containers/food/snacks/pastrybase = 2 ) result = /obj/item/reagent_containers/food/snacks/rofflewaffles @@ -205,16 +205,6 @@ datum/crafting_recipe/food/donut/meat ////////////////////////////////////////////OTHER//////////////////////////////////////////// -/datum/crafting_recipe/food/hotdog - name = "Hot dog" - reqs = list( - /datum/reagent/consumable/ketchup = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, - /obj/item/reagent_containers/food/snacks/sausage = 1 - ) - result = /obj/item/reagent_containers/food/snacks/hotdog - subcategory = CAT_PASTRY - /datum/crafting_recipe/food/meatbun name = "Meat bun" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm index 8effc2599a..79d761c2e2 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm @@ -159,3 +159,13 @@ ) result = /obj/item/reagent_containers/food/snacks/pie/frostypie subcategory = CAT_PIE + +/datum/crafting_recipe/food/baklava + name = "Baklava pie" + reqs = list( + /obj/item/reagent_containers/food/snacks/butter = 1, + /obj/item/reagent_containers/food/snacks/tortilla = 4, //Layers + /obj/item/seeds/wheat/oat = 3 + ) + result = /obj/item/reagent_containers/food/snacks/pie/baklava + subcategory = CAT_PIE \ No newline at end of file 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 a2e83a09b4..127b2cc238 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,48 @@ result = /obj/item/reagent_containers/food/snacks/jellysandwich/cherry subcategory = CAT_SANDWICH -/datum/crafting_recipe/food/icecreamsandwich - name = "Icecream sandwich" +/datum/crafting_recipe/food/pbj_slimesandwich + name = "PB&J sandwich" reqs = list( - /datum/reagent/consumable/cream = 5, - /datum/reagent/consumable/ice = 5, - /obj/item/reagent_containers/food/snacks/icecream = 1 + /datum/reagent/toxin/slimejelly = 5, + /datum/reagent/consumable/peanut_butter = 5, + /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, ) - result = /obj/item/reagent_containers/food/snacks/icecreamsandwich + result = /obj/item/reagent_containers/food/snacks/jellysandwich/pbj/slime subcategory = CAT_SANDWICH +/datum/crafting_recipe/food/pbj_slimesandwich/alt + reqs = list( + /obj/item/reagent_containers/food/snacks/jelliedtoast/slime = 1, + /obj/item/reagent_containers/food/snacks/peanut_buttertoast = 1, + ) + +/datum/crafting_recipe/food/pbj_sandwich + name = "PB&J sandwich" + reqs = list( + /datum/reagent/consumable/cherryjelly = 5, + /datum/reagent/consumable/peanut_butter = 5, + /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, + ) + result = /obj/item/reagent_containers/food/snacks/jellysandwich/pbj/cherry + subcategory = CAT_SANDWICH + +/datum/crafting_recipe/food/pbj_sandwich/alt + reqs = list( + /obj/item/reagent_containers/food/snacks/jelliedtoast/cherry = 1, + /obj/item/reagent_containers/food/snacks/peanut_buttertoast = 1, + ) + +/datum/crafting_recipe/peanutbutter_sandwich + name = "Peanut butter sandwich" + reqs = list( + /datum/reagent/consumable/peanut_butter = 5, + /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, + ) + result = /obj/item/reagent_containers/food/snacks/peanutbutter_sandwich + subcategory = CAT_SANDWICH + + /datum/crafting_recipe/food/notasandwich name = "Not a sandwich" reqs = list( @@ -62,7 +94,7 @@ result = /obj/item/reagent_containers/food/snacks/notasandwich subcategory = CAT_SANDWICH -/datum/crafting_recipe/food/notasandwich +/datum/crafting_recipe/food/tunasandwich name = "Tuna sandwich" reqs = list( /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, @@ -72,3 +104,13 @@ ) result = /obj/item/reagent_containers/food/snacks/tuna_sandwich subcategory = CAT_SANDWICH + +/datum/crafting_recipe/food/hotdog + name = "Hot dog" + reqs = list( + /datum/reagent/consumable/ketchup = 5, + /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/reagent_containers/food/snacks/sausage = 1 + ) + result = /obj/item/reagent_containers/food/snacks/hotdog + 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 index 99d48cf69d..9dbf1d684b 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm @@ -7,7 +7,7 @@ /datum/reagent/consumable/rice = 10 ) result = /obj/item/reagent_containers/food/snacks/sushi_rice - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sea_weed name = "Sea Weed Sheet" @@ -17,7 +17,7 @@ /obj/item/reagent_containers/food/snacks/grown/kudzupod = 1, ) result = /obj/item/reagent_containers/food/snacks/sea_weed - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/tuna_can name = "Can of Tuna" @@ -27,7 +27,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1, ) result = /obj/item/reagent_containers/food/snacks/tuna - subcategory = CAT_SUSHI + subcategory = CAT_FISH //////////////////////////Sushi///////////////////////////////// @@ -39,7 +39,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1 ) result = /obj/item/reagent_containers/food/snacks/sashimi - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/riceball name = "Onigiri" @@ -49,7 +49,7 @@ /obj/item/reagent_containers/food/snacks/sushi_rice = 1 ) result = /obj/item/reagent_containers/food/snacks/riceball - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_egg name = "Tobiko" @@ -59,7 +59,7 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 2, ) result = /obj/item/reagent_containers/food/snacks/tobiko - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_basic name = "Funa Hosomaki" @@ -70,7 +70,7 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 3, ) result = /obj/item/reagent_containers/food/snacks/sushie_basic - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_adv name = "Funa Nigiri" @@ -80,7 +80,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1 ) result = /obj/item/reagent_containers/food/snacks/sushie_adv - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_pro name = "Well made Funa Nigiri" @@ -91,4 +91,35 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 1 ) result = /obj/item/reagent_containers/food/snacks/sushie_pro - subcategory = CAT_SUSHI + subcategory = CAT_FISH + +///////////////Gaijin junk///////////////////////////////////// + +/datum/crafting_recipe/food/fishfingers + name = "Fish fingers" + reqs = list( + /datum/reagent/consumable/flour = 5, + /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/fishfingers + subcategory = CAT_FISH + +/datum/crafting_recipe/food/cubancarp + name = "Cuban carp" + reqs = list( + /datum/reagent/consumable/flour = 5, + /obj/item/reagent_containers/food/snacks/grown/chili = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/cubancarp + subcategory = CAT_FISH + +/datum/crafting_recipe/food/fishandchips + name = "Fish and chips" + reqs = list( + /obj/item/reagent_containers/food/snacks/fries = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/fishandchips + subcategory = CAT_FISH \ No newline at end of file diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index 9197e3d044..8953753a89 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -31,18 +31,17 @@ decksize = 50 card_text_file = "strings/cas_black.txt" -/obj/item/toy/cards/deck/cas/Initialize() - . = ..() +/obj/item/toy/cards/deck/cas/populate_deck() var/static/list/cards_against_space = list("cas_white" = world.file2list("strings/cas_white.txt"),"cas_black" = world.file2list("strings/cas_black.txt")) allcards = cards_against_space[card_face] var/list/possiblecards = allcards.Copy() if(possiblecards.len < decksize) // sanity check decksize = (possiblecards.len - 1) var/list/randomcards = list() - while (randomcards.len < decksize) + for(var/x in 1 to decksize) randomcards += pick_n_take(possiblecards) - for(var/i=1 to randomcards.len) - var/cardtext = randomcards[i] + for(var/x in 1 to randomcards.len) + var/cardtext = randomcards[x] var/datum/playingcard/P P = new() P.name = "[cardtext]" @@ -50,7 +49,7 @@ cards += P if(!blanks) return - for(var/x=1 to blanks) + for(var/x in 1 to blanks) var/datum/playingcard/P P = new() P.name = "Blank Card" @@ -58,10 +57,7 @@ cards += P shuffle_inplace(cards) // distribute blank cards throughout deck -/obj/item/toy/cards/deck/cas/attack_hand(mob/user) - . = ..() - if(.) - return +/obj/item/toy/cards/deck/cas/draw_card(mob/user) if(user.lying) return if(cards.len == 0) diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 6466a47e42..cf11b77879 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -303,6 +303,7 @@ h1.alert, h2.alert {color: #000000;} .userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} .danger {color: #ff0000;} .warning {color: #ff0000; font-style: italic;} +.alertwarning {color: #FF0000; font-weight: bold} .boldwarning {color: #ff0000; font-style: italic; font-weight: bold} .announce {color: #228b22; font-weight: bold;} .boldannounce {color: #ff0000; font-weight: bold;} @@ -316,7 +317,11 @@ h1.alert, h2.alert {color: #000000;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} -.nicegreen {color: #14a833;} +.red {color: #FF0000} +.blue {color: #215cff} +.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..33553d765e 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) { @@ -462,15 +471,6 @@ function ehjaxCallback(data) { handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid); } sendVolumeUpdate(); - } else if (data.firebug) { - if (data.trigger) { - internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); - } else { - internalOutput('Loading firebug console...', 'internal'); - } - var firebugEl = document.createElement('script'); - firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; - document.body.appendChild(firebugEl); } else if (data.adminMusic) { if (typeof data.adminMusic === 'string') { var adminMusic = byondDecode(data.adminMusic); 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/peanuts.dm b/code/modules/hydroponics/grown/peanuts.dm new file mode 100644 index 0000000000..2423300cc4 --- /dev/null +++ b/code/modules/hydroponics/grown/peanuts.dm @@ -0,0 +1,30 @@ +/obj/item/seeds/peanutseed + name = "pack of peanut seeds" + desc = "These seeds grow to produce fruits botanically classified as legumes, but mundanely referred as nuts." + icon_state = "seed-peanut" + species = "peanut" + plantname = "Peanut Vines" + product = /obj/item/reagent_containers/food/snacks/grown/peanut + yield = 6 + growthstages = 4 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + reagents_add = list("vitamin" = 0.02, "nutriment" = 0.15, "cooking_oil" = 0.03) + +/obj/item/reagent_containers/food/snacks/grown/peanut + seed = /obj/item/seeds/peanutseed + name = "peanut" + desc = "Peanuts for the peanut gallery!" //get me a better description, boys. + icon_state = "peanut" + filling_color = "#C4AE7A" + bitesize = 100 + foodtype = VEGETABLES + dried_type = /obj/item/reagent_containers/food/snacks/roasted_peanuts + cooked_type = /obj/item/reagent_containers/food/snacks/roasted_peanuts + +/obj/item/reagent_containers/food/snacks/roasted_peanuts + name = "roasted peanuts" + desc = "A handful of roasted peanuts, with or without salt." + icon_state = "roasted_peanuts" + foodtype = VEGETABLES + list_reagents = list("nutriment" = 6, "vitamin" = 1) + juice_results = list("peanut_butter" = 3) \ No newline at end of file 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/root.dm b/code/modules/hydroponics/grown/root.dm index be0a209c9f..090809ca88 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -54,6 +54,7 @@ icon_state = "parsnip" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("parsnipjuice" = 0) wine_power = 35 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/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 a7c58e8669..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) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 86efc4c74a..3975da18b6 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -112,7 +112,7 @@ var/brightness = get_pin_data(IC_INPUT, 2) if(new_color && isnum(brightness)) - brightness = CLAMP(brightness, 0, 4) + brightness = CLAMP(brightness, 0, 10) light_rgb = new_color light_brightness = brightness @@ -411,4 +411,4 @@ if(assembly) assembly.investigate_log("displayed \"[html_encode(stuff_to_display)]\" with [type].", INVESTIGATE_CIRCUIT) else - investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) \ No newline at end of file + investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index fb8fce10b2..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, @@ -552,7 +555,6 @@ ext_cooldown = 1 volume = 100 - container_type = OPENCONTAINER complexity = 20 cooldown_per_use = 1 SECONDS @@ -571,6 +573,10 @@ 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) @@ -605,7 +611,6 @@ 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 - container_type = OPENCONTAINER complexity = 20 cooldown_per_use = 6 SECONDS @@ -628,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) diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm index f9259359a3..7bccbfafcd 100644 --- a/code/modules/integrated_electronics/subtypes/weaponized.dm +++ b/code/modules/integrated_electronics/subtypes/weaponized.dm @@ -215,7 +215,7 @@ 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 = 75 + complexity = 50 w_class = WEIGHT_CLASS_SMALL size = 4 cooldown_per_use = 30 @@ -306,7 +306,7 @@ 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 = 60 + 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) @@ -340,4 +340,4 @@ var/mob/living/carbon/human/H = L H.forcesay(GLOB.hit_appends) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm index 944499470a..f21ff69e8e 100644 --- a/code/modules/jobs/job_types/civilian.dm +++ b/code/modules/jobs/job_types/civilian.dm @@ -18,6 +18,7 @@ Clown minimal_access = list(ACCESS_THEATRE) /datum/job/clown/after_spawn(mob/living/carbon/human/H, mob/M) + . = ..() H.apply_pref_name("clown", M.client) /datum/outfit/job/clown @@ -60,6 +61,7 @@ Clown return H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) /* Mime @@ -174,6 +176,8 @@ Lawyer access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS) minimal_access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS) + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + /datum/outfit/job/lawyer name = "Lawyer" jobtype = /datum/job/lawyer diff --git a/code/modules/jobs/job_types/civilian_chaplain.dm b/code/modules/jobs/job_types/civilian_chaplain.dm index e44347a208..2d190cfe60 100644 --- a/code/modules/jobs/job_types/civilian_chaplain.dm +++ b/code/modules/jobs/job_types/civilian_chaplain.dm @@ -19,19 +19,20 @@ Chaplain minimal_access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE) /datum/job/chaplain/after_spawn(mob/living/H, mob/M) + . = ..() if(H.mind) H.mind.isholy = TRUE var/obj/item/storage/book/bible/booze/B = new - if(SSreligion.religion) - B.deity_name = SSreligion.deity - B.name = SSreligion.bible_name - B.icon_state = SSreligion.bible_icon_state - B.item_state = SSreligion.bible_item_state - to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [SSreligion.deity]. Defer to the Chaplain.") + if(GLOB.religion) + B.deity_name = GLOB.deity + B.name = GLOB.bible_name + B.icon_state = GLOB.bible_icon_state + B.item_state = GLOB.bible_item_state + to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [GLOB.deity]. Defer to the Chaplain.") H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK) - var/nrt = SSreligion.holy_weapon_type || /obj/item/nullrod + var/nrt = GLOB.holy_weapon_type || /obj/item/nullrod var/obj/item/nullrod/N = new nrt(H) H.put_in_hands(N) return @@ -74,9 +75,9 @@ Chaplain else B.name = "The Holy Book of [new_religion]" - SSreligion.religion = new_religion - SSreligion.bible_name = B.name - SSreligion.deity = B.deity_name + GLOB.religion = new_religion + GLOB.bible_name = B.name + GLOB.deity = B.deity_name H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK) diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index e441b3e889..f678700735 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -54,10 +54,15 @@ //can be overridden by antag_rep.txt config var/antag_rep = 10 + var/list/mind_traits // Traits added to the mind of the mob assigned this job + //Only override this proc //H is usually a human unless an /equip override transformed it /datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE) //do actions on H but send messages to M as the key may not have been transferred_yet + if(mind_traits) + for(var/t in mind_traits) + ADD_TRAIT(H.mind, t, JOB_TRAIT) /datum/job/proc/announce(mob/living/carbon/human/H) if(head_announce) diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index e7e0922f62..8d2b9e8681 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -35,6 +35,8 @@ Head of Security ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING, ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + /datum/outfit/job/hos name = "Head of Security" jobtype = /datum/job/hos @@ -92,6 +94,8 @@ Warden access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) //SEE /DATUM/JOB/WARDEN/GET_ACCESS() + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + /datum/job/warden/get_access() var/list/L = list() L = ..() | check_config_for_sec_maint() @@ -145,6 +149,8 @@ Detective access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + /datum/outfit/job/detective name = "Detective" jobtype = /datum/job/detective @@ -198,6 +204,7 @@ Security Officer access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) //BUT SEE /DATUM/JOB/WARDEN/GET_ACCESS() + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) /datum/job/officer/get_access() var/list/L = list() 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/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 8ae63a8a76..699df5de12 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -485,11 +485,11 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums if(href_list["printbible"]) if(cooldown < world.time) var/obj/item/storage/book/bible/B = new /obj/item/storage/book/bible(src.loc) - if(SSreligion.bible_icon_state && SSreligion.bible_item_state) - B.icon_state = SSreligion.bible_icon_state - B.item_state = SSreligion.bible_item_state - B.name = SSreligion.bible_name - B.deity_name = SSreligion.deity + if(GLOB.bible_icon_state && GLOB.bible_item_state) + B.icon_state = GLOB.bible_icon_state + B.item_state = GLOB.bible_item_state + B.name = GLOB.bible_name + B.deity_name = GLOB.deity cooldown = world.time + PRINTER_COOLDOWN else say("Printer currently unavailable, please wait a moment.") diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index ceba29baec..1f55f18823 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -29,6 +29,7 @@ var/list/obj/machinery/atmospherics/atmos_machines = list() var/list/obj/structure/cable/cables = list() var/list/atom/atoms = list() + var/list/area/areas = list() var/list/turfs = block( locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])) @@ -37,6 +38,7 @@ for(var/L in turfs) var/turf/B = L atoms += B + areas |= B.loc for(var/A in B) atoms += A if(istype(A, /obj/structure/cable)) @@ -48,6 +50,7 @@ var/turf/T = L T.air_update_turf(TRUE) //calculate adjacent turfs along the border to prevent runtimes + SSmapping.reg_in_areas_in_z(areas) SSatoms.InitializeAtoms(atoms) SSmachines.setup_template_powernets(cables) SSair.setup_template_machinery(atmos_machines) 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..e02f38b7e3 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" @@ -63,9 +65,12 @@ /obj/item/pickaxe/drill/cyborg name = "cyborg mining drill" desc = "An integrated electric mining drill." - item_flags = NODROP flags_1 = NONE +/obj/item/pickaxe/drill/cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + /obj/item/pickaxe/drill/diamonddrill name = "diamond-tipped mining drill" icon_state = "diamonddrill" @@ -75,12 +80,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 +103,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 +130,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/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index dd7f642243..4a628c5f34 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -112,7 +112,7 @@ GLOBAL_LIST(labor_sheet_values) else if(!(obj_flags & EMAGGED)) Radio.set_frequency(FREQ_SECURITY) - Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY, get_spans(), get_default_language()) + Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY) to_chat(usr, "Shuttle received message and will be sent shortly.") /obj/machinery/mineral/labor_claim_console/proc/check_auth() @@ -144,6 +144,11 @@ GLOBAL_LIST(labor_sheet_values) points += inp.point_value * inp.amount ..() +/obj/machinery/mineral/stacking_machine/laborstacker/attackby(obj/item/I, mob/living/user) + if(istype(I, /obj/item/stack/sheet) && user.canUnEquip(I)) + var/obj/item/stack/sheet/inp = I + points += inp.point_value * inp.amount + return ..() /**********************Point Lookup Console**************************/ /obj/machinery/mineral/labor_points_checker diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 23823e1e18..abcb6d5911 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -143,7 +143,7 @@ //Rod of Asclepius /obj/item/rod_of_asclepius - name = "Rod of Asclepius" + name = "\improper Rod of Asclepius" desc = "A wooden rod about the size of your forearm with a snake carved around it, winding it's way up the sides of the rod. Something about it seems to inspire in you the responsibilty and duty to help others." icon = 'icons/obj/lavaland/artefacts.dmi' icon_state = "asclepius_dormant" @@ -189,7 +189,8 @@ activated() /obj/item/rod_of_asclepius/proc/activated() - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) desc = "A short wooden rod with a mystical snake inseparably gripping itself and the rod to your forearm. It flows with a healing energy that disperses amongst yourself and those around you. " icon_state = "asclepius_active" activated = TRUE @@ -222,9 +223,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 @@ -273,23 +274,12 @@ to_chat(user, "You release the wisp. It begins to bob around your head.") icon_state = "lantern" wisp.orbit(user, 20) - user.update_sight() SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Freed") else to_chat(user, "You return the wisp to the lantern.") - - var/mob/target - if(wisp.orbiting) - target = wisp.orbiting.orbiting - wisp.stop_orbit() - wisp.forceMove(src) - - if (istype(target)) - target.update_sight() - to_chat(target, "Your vision returns to normal.") - icon_state = "lantern-blue" + wisp.forceMove(src) SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") /obj/item/wisp_lantern/Initialize() @@ -302,7 +292,7 @@ qdel(wisp) else wisp.visible_message("[wisp] has a sad feeling for a moment, then it passes.") - ..() + return ..() /obj/effect/wisp name = "friendly wisp" @@ -314,6 +304,25 @@ var/sight_flags = SEE_MOBS var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE +/obj/effect/wisp/orbit(atom/thing, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lockinorbit) + . = ..() + if(ismob(thing)) + RegisterSignal(thing, COMSIG_MOB_UPDATE_SIGHT, .proc/update_user_sight) + var/mob/being = thing + being.update_sight() + to_chat(thing, "The wisp enhances your vision.") + +/obj/effect/wisp/stop_orbit(datum/component/orbiter/orbits) + . = ..() + if(ismob(orbits.parent)) + UnregisterSignal(orbits.parent, COMSIG_MOB_UPDATE_SIGHT) + to_chat(orbits.parent, "Your vision returns to normal.") + +/obj/effect/wisp/proc/update_user_sight(mob/user) + user.sight |= sight_flags + if(!isnull(lighting_alpha)) + user.lighting_alpha = min(user.lighting_alpha, lighting_alpha) + //Red/Blue Cubes /obj/item/warp_cube name = "blue cube" @@ -662,7 +671,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) @@ -781,19 +790,17 @@ var/turf/T = get_turf(src) var/list/contents = T.GetAllContents() var/mob/dead/observer/current_spirits = list() - var/list/orbiters = list() for(var/thing in contents) var/atom/A = thing - if (A.orbiters) - orbiters += A.orbiters + A.transfer_observers_to(src) - for(var/thing in orbiters) - var/datum/orbit/O = thing - if (isobserver(O.orbiter)) - var/mob/dead/observer/G = O.orbiter - ghost_counter++ - G.invisibility = 0 - current_spirits |= G + for(var/i in orbiters?.orbiters) + if(!isobserver(i)) + continue + var/mob/dead/observer/G = i + ghost_counter++ + G.invisibility = 0 + current_spirits |= G for(var/mob/dead/observer/G in spirits - current_spirits) G.invisibility = GLOB.observer_default_invisibility diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index 883f5a034f..c780d57810 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -26,7 +26,9 @@ return /mob/camera/forceMove(atom/destination) + var/oldloc = loc loc = destination + Moved(oldloc, NONE, TRUE) /mob/camera/emote(act, m_type=1, message = null, intentional = FALSE) return diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index d886a41b0f..381dc131e7 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -34,7 +34,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) var/turf/new_turf = get_turf(destination) if (old_turf?.z != new_turf?.z) onTransitZ(old_turf?.z, new_turf?.z) + var/oldloc = loc loc = destination + Moved(oldloc, NONE, TRUE) /mob/dead/Stat() ..() diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 84be6438c0..4ccac5f9d7 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -164,7 +164,7 @@ return var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]]) - if(istype(MS) && MS.attack_ghost(src, latejoinercalling = TRUE)) + if(MS.attack_ghost(src, latejoinercalling = TRUE)) SSticker.queued_players -= src SSticker.queue_delay = 4 qdel(src) @@ -444,6 +444,11 @@ if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE) available_job_count++ for(var/spawner in GLOB.mob_spawners) + if(!LAZYLEN(spawner)) + continue + var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner]) + if(!istype(S) || !S.can_latejoin()) + continue available_job_count++ break @@ -465,6 +470,11 @@ "Security" = list(jobs = list(), titles = GLOB.security_positions, color = "#ff9999"), ) for(var/spawner in GLOB.mob_spawners) + if(!LAZYLEN(spawner)) + continue + var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner]) + if(!istype(S) || !S.can_latejoin()) + continue categorizedJobs["Ghost Role"]["jobs"] += spawner for(var/datum/job/job in SSjob.occupations) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index fc879ed7a8..ffe9a800a1 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -6,8 +6,11 @@ else gender = pick(MALE,FEMALE) underwear = random_underwear(gender) + undie_color = random_color() undershirt = random_undershirt(gender) + shirt_color = random_color() socks = random_socks() + socks_color = random_color() skin_tone = random_skin_tone() hair_style = random_hair_style(gender) facial_hair_style = random_facial_hair_style(gender) @@ -28,7 +31,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/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm index 699c3c97e4..5e24d0630b 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm @@ -59,4 +59,8 @@ 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 + var/center = FALSE //Should we center the sprite? + +/datum/sprite_accessory/underwear + icon = 'icons/mob/underwear.dmi' + var/has_color = FALSE \ 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 index 66c79ea0f0..f8d8d26328 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm @@ -439,6 +439,10 @@ 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" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm index 5a5d37d4e7..524c1f0f13 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm @@ -2,95 +2,132 @@ // Socks Definitions // /////////////////////// -/datum/sprite_accessory/socks - icon = 'icons/mob/underwear.dmi' - -/datum/sprite_accessory/socks/nude +/datum/sprite_accessory/underwear/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/underwear/socks/socks_knee + name = "Knee-high" + icon_state = "socks_knee" + has_color = TRUE -/datum/sprite_accessory/socks/commie_knee - name = "Knee-High (Commie)" +/datum/sprite_accessory/underwear/socks/bee_knee + name = "Knee-high - Bee" + icon_state = "bee_knee" + +/datum/sprite_accessory/underwear/socks/commie_knee + name = "Knee-High - Commie" icon_state = "commie_knee" -/datum/sprite_accessory/socks/usa_knee - name = "Knee-High (Freedom)" +/datum/sprite_accessory/underwear/socks/usa_knee + name = "Knee-High - Freedom" icon_state = "assblastusa_knee" -/datum/sprite_accessory/socks/rainbow_knee - name = "Knee-high (Rainbow)" +/datum/sprite_accessory/underwear/socks/rainbow_knee + name = "Knee-high - Rainbow" icon_state = "rainbow_knee" -/datum/sprite_accessory/socks/striped_knee - name = "Knee-high (Striped)" +/datum/sprite_accessory/underwear/socks/striped_knee + name = "Knee-high - Striped" icon_state = "striped_knee" + has_color = TRUE -/datum/sprite_accessory/socks/thin_knee - name = "Knee-high (Thin)" +/datum/sprite_accessory/underwear/socks/thin_knee + name = "Knee-high - Thin" icon_state = "thin_knee" + has_color = TRUE -/datum/sprite_accessory/socks/uk_knee - name = "Knee-High (UK)" +/datum/sprite_accessory/underwear/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/underwear/socks/socks_norm + name = "Normal" + icon_state = "socks_norm" + has_color = TRUE -/datum/sprite_accessory/socks/black_norm - name = "Normal (Black)" - icon_state = "black_norm" +/datum/sprite_accessory/underwear/socks/bee_norm + name = "Normal - Bee" + icon_state = "bee_norm" -/datum/sprite_accessory/socks/white_norm - name = "Normal (White)" - icon_state = "white_norm" - -/datum/sprite_accessory/socks/pantyhose +/datum/sprite_accessory/underwear/socks/pantyhose name = "Pantyhose" icon_state = "pantyhose" -/datum/sprite_accessory/socks/black_short - name = "Short (Black)" - icon_state = "black_short" +/datum/sprite_accessory/underwear/socks/socks_short + name = "Short" + icon_state = "socks_short" + has_color = TRUE -/datum/sprite_accessory/socks/white_short - name = "Short (White)" - icon_state = "white_short" +/datum/sprite_accessory/underwear/socks/stockings_blue + name = "Stockings - Blue" + icon_state = "stockings_blue" -/datum/sprite_accessory/socks/black_thigh - name = "Thigh-high (Black)" - icon_state = "black_thigh" +/datum/sprite_accessory/underwear/socks/stockings_cyan + name = "Stockings - Cyan" + icon_state = "stockings_cyan" -/datum/sprite_accessory/socks/commie_thigh - name = "Thigh-high (Commie)" +/datum/sprite_accessory/underwear/socks/stockings_dpink + name = "Stockings - Dark Pink" + icon_state = "stockings_dpink" + +/datum/sprite_accessory/underwear/socks/stockings_green + name = "Stockings - Green" + icon_state = "stockings_black" + +/datum/sprite_accessory/underwear/socks/stockings_orange + name = "Stockings - Orange" + icon_state = "stockings_orange" + +/datum/sprite_accessory/underwear/socks/stockings_programmer + name = "Stockings - Programmer" + icon_state = "stockings_lpink" + +/datum/sprite_accessory/underwear/socks/stockings_purple + name = "Stockings - Purple" + icon_state = "stockings_purple" + +/datum/sprite_accessory/underwear/socks/stockings_yellow + name = "Stockings - Yellow" + icon_state = "stockings_yellow" + +/datum/sprite_accessory/underwear/socks/socks_thigh + name = "Thigh-high" + icon_state = "socks_thigh" + has_color = TRUE + +/datum/sprite_accessory/underwear/socks/bee_thigh + name = "Thigh-high - Bee" + icon_state = "bee_thigh" + +/datum/sprite_accessory/underwear/socks/commie_thigh + name = "Thigh-high - Commie" icon_state = "commie_thigh" -/datum/sprite_accessory/socks/usa_thigh - name = "Thigh-high (Freedom)" +/datum/sprite_accessory/underwear/socks/usa_thigh + name = "Thigh-high - Freedom" icon_state = "assblastusa_thigh" -/datum/sprite_accessory/socks/rainbow_thigh - name = "Thigh-high (Rainbow)" +/datum/sprite_accessory/underwear/socks/fishnet + name = "Thigh-high - Fishnet" + icon_state = "fishnet" + +/datum/sprite_accessory/underwear/socks/rainbow_thigh + name = "Thigh-high - Rainbow" icon_state = "rainbow_thigh" -/datum/sprite_accessory/socks/striped_thigh - name = "Thigh-high (Striped)" +/datum/sprite_accessory/underwear/socks/striped_thigh + name = "Thigh-high - Striped" icon_state = "striped_thigh" + has_color = TRUE -/datum/sprite_accessory/socks/thin_thigh - name = "Thigh-high (Thin)" +/datum/sprite_accessory/underwear/socks/thin_thigh + name = "Thigh-high - Thin" icon_state = "thin_thigh" + has_color = TRUE -/datum/sprite_accessory/socks/uk_thigh - name = "Thigh-high (UK)" +/datum/sprite_accessory/underwear/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/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm index 7c66ef51e3..bf63ea09d7 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm @@ -2,307 +2,288 @@ // Undershirt Definitions // //////////////////////////// -/datum/sprite_accessory/undershirt - icon = 'icons/mob/underwear.dmi' - gender = NEUTER - -/datum/sprite_accessory/undershirt/nude +/datum/sprite_accessory/underwear/top/nude name = "Nude" icon_state = null // please make sure they're sorted alphabetically and categorized -/datum/sprite_accessory/undershirt/bluejersey +/datum/sprite_accessory/underwear/top/longjon + name = "Long John Shirt" + icon_state = "ljont" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/longstripe_black + name = "Longsleeve Striped Shirt - Black" + icon_state = "longstripe" + +/datum/sprite_accessory/underwear/top/longstripe_blue + name = "Longsleeve Striped Shirt - Blue" + icon_state = "longstripe_blue" + +/datum/sprite_accessory/underwear/top/shirt + name = "Shirt" + icon_state = "undershirt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bowlingw + name = "Shirt - Bowling" + icon_state = "bowlingw" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bowling + name = "Shirt, Bowling - Red" + icon_state = "bowling" + +/datum/sprite_accessory/underwear/top/bowlingp + name = "Shirt, Bowling - Pink" + icon_state = "bowlingp" + +/datum/sprite_accessory/underwear/top/bowlinga + name = "Shirt, Bowling - Aqua" + icon_state = "bowlinga" + +/datum/sprite_accessory/underwear/top/bluejersey name = "Shirt, Jersey - Blue" icon_state = "shirt_bluejersey" -/datum/sprite_accessory/undershirt/redjersey +/datum/sprite_accessory/underwear/top/redjersey name = "Shirt, Jersey - Red" icon_state = "shirt_redjersey" -/datum/sprite_accessory/undershirt/bluepolo - name = "Shirt, Polo - Blue" - icon_state = "bluepolo" +/datum/sprite_accessory/underwear/top/polo + name = "Shirt - Polo" + icon_state = "polo" + has_color = TRUE -/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 +/datum/sprite_accessory/underwear/top/alienshirt name = "Shirt - Alien" icon_state = "shirt_alien" -/datum/sprite_accessory/undershirt/mondmondjaja +/datum/sprite_accessory/underwear/top/mondmondjaja name = "Shirt - Band" icon_state = "band" -/datum/sprite_accessory/undershirt/shirt_black - name = "Shirt - Black" - icon_state = "shirt_black" +/datum/sprite_accessory/underwear/top/shirt_bee + name = "Shirt - Bee" + icon_state = "bee_shirt" -/datum/sprite_accessory/undershirt/blueshirt - name = "Shirt - Blue" - icon_state = "shirt_blue" - -/datum/sprite_accessory/undershirt/clownshirt +/datum/sprite_accessory/underwear/top/clownshirt name = "Shirt - Clown" icon_state = "shirt_clown" -/datum/sprite_accessory/undershirt/commie +/datum/sprite_accessory/underwear/top/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 +/datum/sprite_accessory/underwear/top/ian name = "Shirt - Ian" icon_state = "ian" -/datum/sprite_accessory/undershirt/ilovent +/datum/sprite_accessory/underwear/top/ilovent name = "Shirt - I Love NT" icon_state = "ilovent" -/datum/sprite_accessory/undershirt/lover +/datum/sprite_accessory/underwear/top/lover name = "Shirt - Lover" icon_state = "lover" -/datum/sprite_accessory/undershirt/matroska +/datum/sprite_accessory/underwear/top/matroska name = "Shirt - Matroska" icon_state = "matroska" -/datum/sprite_accessory/undershirt/meat +/datum/sprite_accessory/underwear/top/meat name = "Shirt - Meat" icon_state = "shirt_meat" -/datum/sprite_accessory/undershirt/nano +/datum/sprite_accessory/underwear/top/nano name = "Shirt - Nanotrasen" icon_state = "shirt_nano" -/datum/sprite_accessory/undershirt/peace +/datum/sprite_accessory/underwear/top/peace name = "Shirt - Peace" icon_state = "peace" -/datum/sprite_accessory/undershirt/pacman +/datum/sprite_accessory/underwear/top/pacman name = "Shirt - Pogoman" icon_state = "pogoman" -/datum/sprite_accessory/undershirt/question +/datum/sprite_accessory/underwear/top/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 +/datum/sprite_accessory/underwear/top/skull name = "Shirt - Skull" icon_state = "shirt_skull" -/datum/sprite_accessory/undershirt/ss13 +/datum/sprite_accessory/underwear/top/ss13 name = "Shirt - SS13" icon_state = "shirt_ss13" + has_color = TRUE -/datum/sprite_accessory/undershirt/stripe +/datum/sprite_accessory/underwear/top/stripe name = "Shirt - Striped" icon_state = "shirt_stripes" -/datum/sprite_accessory/undershirt/tiedye +/datum/sprite_accessory/underwear/top/tiedye name = "Shirt - Tie-dye" icon_state = "shirt_tiedye" -/datum/sprite_accessory/undershirt/uk +/datum/sprite_accessory/underwear/top/uk name = "Shirt - UK" icon_state = "uk" -/datum/sprite_accessory/undershirt/usa +/datum/sprite_accessory/underwear/top/usa name = "Shirt - USA" icon_state = "shirt_assblastusa" -/datum/sprite_accessory/undershirt/shirt_white - name = "Shirt - White" - icon_state = "shirt_white" +/datum/sprite_accessory/underwear/top/shortsleeve + name = "Shirt - Short Sleeved" + icon_state = "shortsleeve" + has_color = TRUE -/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 +/datum/sprite_accessory/underwear/top/blueshirtsport name = "Shirt, Sports - Blue" icon_state = "blueshirtsport" - gender = NEUTER -/datum/sprite_accessory/undershirt/greenshirtsport +/datum/sprite_accessory/underwear/top/greenshirtsport name = "Shirt, Sports - Green" icon_state = "greenshirtsport" - gender = NEUTER -/datum/sprite_accessory/undershirt/redshirtsport +/datum/sprite_accessory/underwear/top/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 +/datum/sprite_accessory/underwear/top/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/underwear/top/tanktop + name = "Tank Top" + icon_state = "tanktop" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_midriff +/datum/sprite_accessory/underwear/top/tanktop_alt + name = "Tank Top - Alt" + icon_state = "tanktop_alt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/tanktop_midriff name = "Tank Top - Midriff" icon_state = "tank_midriff" + has_color = TRUE -/datum/sprite_accessory/undershirt/tank_red - name = "Tank Top - Red" - icon_state = "tank_red" +/datum/sprite_accessory/underwear/top/tanktop_midriff_alt + name = "Tank Top - Midriff Halterneck" + icon_state = "tank_midriff_alt" + has_color = TRUE -/datum/sprite_accessory/undershirt/tankstripe +/datum/sprite_accessory/underwear/top/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/underwear/top/tank_top_sun + name = "Tank top - Sun" + icon_state = "tank_sun" -/datum/sprite_accessory/undershirt/female_red - name = "Bra - Red" - icon_state = "bra_red" +/datum/sprite_accessory/underwear/top/babydoll + name = "Baby-Doll" + icon_state = "babydoll" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_pink - name = "Bra - Pink" - icon_state = "bra_pink" +/datum/sprite_accessory/underwear/top/bra + name = "Bra" + icon_state = "bra" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_kinky +/datum/sprite_accessory/underwear/top/bra_alt + name = "Bra - Alt" + icon_state = "bra_alt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bra_thin + name = "Bra - Thin" + icon_state = "bra_thin" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bra_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 +/datum/sprite_accessory/underwear/top/bra_freedom name = "Bra - Freedom" icon_state = "bra_assblastusa" -/datum/sprite_accessory/undershirt/female_commie +/datum/sprite_accessory/underwear/top/bra_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/underwear/top/bra_beekini + name = "Bra - Bee-kini" + icon_state = "bra_bee-kini" -/datum/sprite_accessory/undershirt/female_black - name = "Bra - Black" - icon_state = "bra_black" - -/datum/sprite_accessory/undershirt/female_uk +/datum/sprite_accessory/underwear/top/bra_uk name = "Bra - UK" icon_state = "bra_uk" -/datum/sprite_accessory/undershirt/female_white - name = "Bra - White" - icon_state = "bra_white" +/datum/sprite_accessory/underwear/top/bra_neko + name = "Bra - Neko" + icon_state = "bra_neko" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_white_neko - name = "Bra, Neko - white" - icon_state = "bra_neko_white" +/datum/sprite_accessory/underwear/top/halterneck_bra + name = "Bra - Halterneck" + icon_state = "halterneck_bra" + has_color = TRUE -/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" +/datum/sprite_accessory/underwear/top/sports_bra + name = "Bra, Sports" icon_state = "sports_bra" + has_color = TRUE -/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" +/datum/sprite_accessory/underwear/top/sports_bra_alt + name = "Bra, Sports - Alt" icon_state = "sports_bra_alt" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_yellow - name = "Bra - Yellow" - icon_state = "bra_yellow" +/datum/sprite_accessory/underwear/top/bra_strapless + name = "Bra, Strapless" + icon_state = "bra_strapless" + has_color = TRUE -/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" +/datum/sprite_accessory/underwear/top/bra_strapless_alt + name = "Bra, Strapless - Alt" icon_state = "bra_blue" + has_color = TRUE -/datum/sprite_accessory/undershirt/swimsuit_green - name = "Swimsuit, Top - Green" - icon_state = "bra_swimming_green" +/datum/sprite_accessory/underwear/top/striped_bra + name = "Bra - Striped" + icon_state = "striped_bra" + has_color = TRUE -/datum/sprite_accessory/undershirt/swimsuit_purple - name = "Swimsuit, Top - Purple" - icon_state = "bra_swimming_purple" \ No newline at end of file +/datum/sprite_accessory/underwear/top/fishnet_sleeves + name = "Fishnet - sleeves" + icon_state = "fishnet_sleeves" + +/datum/sprite_accessory/underwear/top/fishnet_gloves + name = "Fishnet - gloves" + icon_state = "fishnet_gloves" + +/datum/sprite_accessory/underwear/top/fishnet_base + name = "Fishnet - top" + icon_state = "fishnet_body" + +/datum/sprite_accessory/underwear/top/swimsuit + name = "Swimsuit Top" + icon_state = "bra_swimming" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/swimsuit_alt + name = "Swimsuit Top - Strapless" + icon_state = "bra_swimming_alt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/tubetop + name = "Tube Top" + icon_state = "tubetop" + has_color = TRUE \ 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 index 6beed231aa..611547ad4e 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm @@ -1,171 +1,144 @@ /////////////////////////// // Underwear Definitions // /////////////////////////// -/datum/sprite_accessory/underwear - icon = 'icons/mob/underwear.dmi' - gender = NEUTER -/datum/sprite_accessory/underwear/nude +/datum/sprite_accessory/underwear/bottom/nude name = "Nude" icon_state = null -/datum/sprite_accessory/underwear/mankini - name = "Mankini - Green" - icon_state = "mankini_green" +/datum/sprite_accessory/underwear/bottom/mankini + name = "Mankini" + icon_state = "mankini" + has_color = TRUE -/datum/sprite_accessory/underwear/male_kinky - name = "Jockstrap - White" - icon_state = "jockstrap_white" +/datum/sprite_accessory/underwear/bottom/male_kinky + name = "Jockstrap" + icon_state = "jockstrap" + has_color = TRUE -/datum/sprite_accessory/underwear/male_white - name = "Briefs - White" - icon_state = "briefs_white" +/datum/sprite_accessory/underwear/bottom/briefs + name = "Briefs" + icon_state = "briefs" + has_color = TRUE -/datum/sprite_accessory/underwear/male_black - name = "Briefs - Black" - icon_state = "briefs_black" +/datum/sprite_accessory/underwear/bottom/boxers + name = "Boxers" + icon_state = "boxers" + has_color = TRUE -/datum/sprite_accessory/underwear/male_grey - name = "Briefs - Grey" - icon_state = "briefs_grey" +/datum/sprite_accessory/underwear/bottom/male_bee + name = "Boxers - Bee" + icon_state = "bee_shorts" -/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 +/datum/sprite_accessory/underwear/bottom/male_hearts name = "Boxers - Heart" icon_state = "boxers_heart" -/datum/sprite_accessory/underwear/male_stripe +/datum/sprite_accessory/underwear/bottom/male_stripe name = "Boxers - Striped" icon_state = "boxers_striped" -/datum/sprite_accessory/underwear/male_commie +/datum/sprite_accessory/underwear/bottom/male_commie name = "Boxers - Striped Communist" icon_state = "boxers_commie" -/datum/sprite_accessory/underwear/male_usastripe +/datum/sprite_accessory/underwear/bottom/male_usastripe name = "Boxers - Striped Freedom" icon_state = "boxers_assblastusa" -/datum/sprite_accessory/underwear/male_uk +/datum/sprite_accessory/underwear/bottom/male_uk name = "Boxers - Striped UK" icon_state = "boxers_uk" +/datum/sprite_accessory/underwear/bottom/boxer_briefs + name = "Boxer Briefs" + icon_state = "boxer_briefs" + has_color = TRUE -/datum/sprite_accessory/underwear/female_whitealt - name = "Boxer Briefs - White" - icon_state = "boxer_briefs_white" +/datum/sprite_accessory/underwear/bottom/panties + name = "Panties" + icon_state = "panties" + has_color = TRUE -/datum/sprite_accessory/underwear/female_blackalt - name = "Boxer Briefs - Black" - icon_state = "boxer_briefs_black" +/datum/sprite_accessory/underwear/bottom/panties_alt + name = "Panties - Alt" + icon_state = "panties_alt" + has_color = TRUE -/datum/sprite_accessory/underwear/female_pink - name = "Boxer Briefs - Pink" - icon_state = "boxer_briefs_pink" +/datum/sprite_accessory/underwear/bottom/fishnet_lower + name = "Panties - Fishnet" + icon_state = "fishnet_lower" -/datum/sprite_accessory/underwear/female_babyblue - name = "Boxer Briefs - Baby Blue" - icon_state = "boxer_briefs_babyblue" +/datum/sprite_accessory/underwear/bottom/female_beekini + name = "Panties - Bee-kini" + icon_state = "panties_bee-kini" -/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 +/datum/sprite_accessory/underwear/bottom/female_commie name = "Panties - Commie" icon_state = "panties_commie" -/datum/sprite_accessory/underwear/female_usastripe +/datum/sprite_accessory/underwear/bottom/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 +/datum/sprite_accessory/underwear/bottom/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 +/datum/sprite_accessory/underwear/bottom/panties_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/bottom/panties_neko + name = "Panties - Neko" + icon_state = "panties_neko" + has_color = TRUE -/datum/sprite_accessory/underwear/female_white_neko - name = "Panties, Neko - White" - icon_state = "panties_neko_white" +/datum/sprite_accessory/underwear/bottom/panties_slim + name = "Panties - Slim" + icon_state = "panties_slim" + has_color = TRUE -/datum/sprite_accessory/underwear/female_black_neko - name = "Panties, Neko - Black" - icon_state = "panties_neko_black" +/datum/sprite_accessory/underwear/bottom/striped_panties + name = "Panties - Striped" + icon_state = "striped_panties" + has_color = TRUE +/datum/sprite_accessory/underwear/bottom/panties_swimsuit + name = "Panties - Swimsuit" + icon_state = "panties_swimming" + has_color = TRUE -/datum/sprite_accessory/underwear/swimsuit_red +/datum/sprite_accessory/underwear/bottom/panties_thin + name = "Panties - Thin" + icon_state = "panties_thin" + has_color = TRUE + +/datum/sprite_accessory/underwear/bottom/longjon + name = "Long John Bottoms" + icon_state = "ljonb" + has_color = TRUE + +/datum/sprite_accessory/underwear/bottom/swimsuit_red name = "Swimsuit, One Piece - Red" icon_state = "swimming_red" -/datum/sprite_accessory/underwear/swimsuit +/datum/sprite_accessory/underwear/bottom/swimsuit name = "Swimsuit, One Piece - Black" icon_state = "swimming_black" -/datum/sprite_accessory/underwear/swimsuit_blue +/datum/sprite_accessory/underwear/bottom/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/bottom/thong + name = "Thong" + icon_state = "thong" + has_color = TRUE -/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" +/datum/sprite_accessory/underwear/bottom/thong_babydoll + name = "Thong - Alt" + icon_state = "thong_babydoll" + has_color = TRUE diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 55b8891534..fefa032e4f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -429,9 +429,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/orbitsize = (I.Width()+I.Height())*0.5 orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) - if(orbiting && orbiting.orbiting != target) - to_chat(src, "Now orbiting [target].") - var/rot_seg switch(ghost_orbit) @@ -450,10 +447,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/orbit() setDir(2)//reset dir so the right directional sprites show up - ..() + return ..() -/mob/dead/observer/stop_orbit() - ..() +/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits) + . = ..() //restart our floating animation after orbit is done. pixel_y = 0 animate(src, pixel_y = 2, time = 10, loop = -1) @@ -753,7 +750,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp update_icon() -/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return IsAdminGhost(usr) /mob/dead/observer/is_literate() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c2518bfc9b..9569d4826c 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -275,7 +275,7 @@ /mob/proc/canUnEquip(obj/item/I, force) if(!I) return TRUE - if((I.item_flags & NODROP) && !force) + if(HAS_TRAIT(I, TRAIT_NODROP) && !force) return FALSE return TRUE @@ -309,13 +309,13 @@ //DO NOT CALL THIS PROC //use one of the above 3 helper procs //you may override it, but do not modify the args -/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides NODROP_1 for things like wizarditis and admin undress. +/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides TRAIT_NODROP for things like wizarditis and admin undress. //Use no_move if the item is just gonna be immediately moved afterward //Invdrop is used to prevent stuff in pockets dropping. only set to false if it's going to immediately be replaced - if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP_1. + if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for TRAIT_NODROP. return TRUE - if((I.item_flags & NODROP) && !force) + if(HAS_TRAIT(I, TRAIT_NODROP) && !force) return FALSE var/hand_index = get_held_index_of_item(I) 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/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 2a5fdeaa33..cc11c0e8bb 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -138,7 +138,11 @@ name = "blood crawl" desc = "You are unable to hold anything while in this form." icon = 'icons/effects/blood.dmi' - item_flags = NODROP | ABSTRACT + item_flags = ABSTRACT + +/obj/item/bloodcrawl/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B) playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 76b416772e..97b29ca4e1 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -5,6 +5,7 @@ var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE. stat = DEAD //we start dead by default see_invisible = SEE_INVISIBLE_LIVING + speech_span = SPAN_ROBOT /mob/living/brain/Initialize() . = ..() diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 2f3ee10428..dafc6cf5e0 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) @@ -265,7 +265,7 @@ var/list/datum/brain_trauma/possible_traumas = list() for(var/T in subtypesof(brain_trauma_type)) var/datum/brain_trauma/BT = T - if(can_gain_trauma(BT, resilience)) + if(can_gain_trauma(BT, resilience) && initial(BT.random_gain)) possible_traumas += BT if(!LAZYLEN(possible_traumas)) diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm index ce0a09c27f..b7d7e1d7fc 100644 --- a/code/modules/mob/living/brain/say.dm +++ b/code/modules/mob/living/brain/say.dm @@ -10,14 +10,11 @@ ..() -/mob/living/brain/get_spans() - return ..() | SPAN_ROBOT - /mob/living/brain/radio(message, message_mode, list/spans, language) if(message_mode == MODE_HEADSET && istype(container, /obj/item/mmi)) var/obj/item/mmi/R = container if(R.radio) - R.radio.talk_into(src, message, , get_spans(), language) + R.radio.talk_into(src, message, language = language) return ITALICS | REDUCE_RANGE else return ..() 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/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 79eed6b82b..76ede9276c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -103,9 +103,13 @@ name = "\improper royal parasite" desc = "Inject this into one of your grown children to promote her to a Praetorian!" icon_state = "alien_medal" - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL icon = 'icons/mob/alien.dmi' +/obj/item/queenpromote/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user) if(!isalienadult(M) || isalienroyal(M)) to_chat(user, "You may only use this with your adult, non-royal children!") 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/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index b921aea67e..5f1e1a2830 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -4,7 +4,7 @@ if(!message) return - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "Hivemind, [shown_name] [message_a]" for(var/mob/S in GLOB.player_list) if(!S.stat && S.hivecheck()) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ea13255dfe..db7257f0f0 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 @@ -175,11 +175,11 @@ if(start_T && end_T) log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]") - else if(!(I.item_flags & (NODROP | ABSTRACT))) + else if(!CHECK_BITFIELD(I.item_flags, ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP)) 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 @@ -409,14 +409,14 @@ return initial(pixel_y) /mob/living/carbon/proc/accident(obj/item/I) - if(!I || (I.item_flags & (NODROP | ABSTRACT))) + if(!I || (I.item_flags & ABSTRACT) || HAS_TRAIT(I, TRAIT_NODROP)) return //dropItemToGround(I) CIT CHANGE - makes it so the item doesn't drop if the modifier rolls above 100 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) @@ -496,9 +496,12 @@ add_splatter_floor(T) if(stun) adjustBruteLoss(3) + else if(src.reagents.has_reagent("blazaam")) + if(T) + T.add_vomit_floor(src, VOMIT_PURPLE) else if(T) - T.add_vomit_floor(src, toxic)//toxic barf looks different + T.add_vomit_floor(src, VOMIT_TOXIC)//toxic barf looks different T = get_step(T, dir) if (is_blocked_turf(T)) break @@ -759,14 +762,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 @@ -895,6 +898,11 @@ var/obj/item/organ/I = X I.Insert(src) +/mob/living/carbon/proc/update_disabled_bodyparts() + for(var/B in bodyparts) + var/obj/item/bodypart/BP = B + BP.update_disabled() + /mob/living/carbon/vv_get_dropdown() . = ..() . += "---" diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index d8bb90460a..57483f64e7 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -48,18 +48,27 @@ if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment)) affecting.dismember(P.damtype) +/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check) + . = FALSE + if(!skip_throw_mode_check && !in_throw_mode) + return + if(get_active_held_item()) + return + if(restrained()) + return + return TRUE + /mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE) if(!skipcatch) //ugly, but easy - if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode - if(canmove && !restrained()) - if(istype(AM, /obj/item)) - var/obj/item/I = AM - if(isturf(I.loc)) - I.attack_hand(src) - if(get_active_held_item() == I) //if our attack_hand() picks up the item... - visible_message("[src] catches [I]!") //catch that sucker! - throw_mode_off() - return 1 + if(can_catch_item()) + if(istype(AM, /obj/item)) + var/obj/item/I = AM + if(isturf(I.loc)) + I.attack_hand(src) + if(get_active_held_item() == I) //if our attack_hand() picks up the item... + visible_message("[src] catches [I]!") //catch that sucker! + throw_mode_off() + return 1 ..() @@ -224,7 +233,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 +270,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 +286,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 +321,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 +371,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/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 26e19ff376..8550a0887f 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" @@ -93,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 @@ -126,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" @@ -281,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.shown_mood >= 6) //So roundstart people aren't all "happy" and that antags don't show their true happiness. + 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..57dd1af749 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -8,6 +8,7 @@ /mob/living/carbon/human/Initialize() verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee //initialize limbs first create_bodyparts() @@ -251,7 +252,7 @@ var/delay_denominator = 1 if(pocket_item && !(pocket_item.item_flags & ABSTRACT)) - if(pocket_item.item_flags & NODROP) + if(HAS_TRAIT(pocket_item, TRAIT_NODROP)) to_chat(usr, "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!") to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT)) @@ -260,7 +261,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 +500,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 +605,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 +641,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 +658,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) @@ -724,12 +725,12 @@ remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000") cut_overlay(MA) -/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated() || lying ) to_chat(src, "You can't do that right now!") return FALSE if(!Adjacent(M) && (M.loc != src)) - if((be_close == 0) || (dna.check_mutation(TK) && tkMaxRangeCheck(src, M))) + if((be_close == 0) || (!no_tk && (dna.check_mutation(TK) && tkMaxRangeCheck(src, M)))) return TRUE to_chat(src, "You are too far away!") return FALSE @@ -851,19 +852,24 @@ /mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user) //If they dragged themselves and we're currently aggressively grabbing them try to piggyback - if(user == target && can_piggyback(target) && pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS) + if(user == target && can_piggyback(target) && pulling == target && (HAS_TRAIT(src, TRAIT_PACIFISM) || grab_state >= GRAB_AGGRESSIVE) && stat == CONSCIOUS) buckle_mob(target,TRUE,TRUE) . = ..() +/mob/living/carbon/human/proc/piggyback_instant(mob/living/M) + return buckle_mob(M, TRUE, TRUE, FALSE, TRUE) + //Can C try to piggyback at all. /mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C) if(istype(C) && C.stat == CONSCIOUS) return TRUE return FALSE -/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) +/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, bypass_piggybacking = FALSE, no_delay = FALSE) if(!force)//humans are only meant to be ridden through piggybacking and special cases return + if(bypass_piggybacking) + return ..() if(!is_type_in_typecache(M, can_ride_typecache)) M.visible_message("[M] really can't seem to mount [src]...") return @@ -876,7 +882,7 @@ if(can_piggyback(M)) riding_datum.ride_check_ridden_incapacitated = TRUE visible_message("[M] starts to climb onto [src]...") - if(do_after(M, 15, target = src)) + if(no_delay || do_after(M, 15, target = src)) if(can_piggyback(M)) if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE)) M.visible_message("[M] can't hang onto [src]!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1650612443..3dd0fb62c6 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -54,7 +54,12 @@ else visible_message("[src] deflects the projectile!", "You deflect the projectile!") playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) - return 0 + if(!mind.martial_art.reroute_deflection) + return FALSE + else + P.firer = src + P.setAngle(rand(0, 360))//SHING + return FALSE if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself if(P.is_reflectable) @@ -138,7 +143,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 +158,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 +261,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 +619,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() @@ -669,7 +674,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" @@ -696,7 +701,7 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_send += "\t Your [LB.name] [has_trait(TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" + to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/obj/item/I in LB.embedded_objects) to_send += "\t There is \a [I] embedded in your [LB.name]!\n" @@ -711,7 +716,7 @@ to_send += "You're completely exhausted.\n" else to_send += "You feel fatigued.\n" - if(has_trait(TRAIT_SELF_AWARE)) + if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) if(toxloss) if(toxloss > 10) to_send += "You feel sick.\n" @@ -751,7 +756,7 @@ else if(w_uniform) w_uniform.add_fingerprint(M) - ..() + ..() /mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index d1ec7f3e4b..c9d59b84f2 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -22,11 +22,14 @@ var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup var/lip_color = "white" - var/age = 30 //Player's age (pure fluff) + var/age = 30 //Player's age var/underwear = "Nude" //Which underwear the player wants + var/undie_color = "#FFFFFF" var/undershirt = "Nude" //Which undershirt the player wants + var/shirt_color = "#FFFFFF" var/socks = "Nude" //Which socks the player wants + var/socks_color = "#FFFFFF" var/backbag = DBACKPACK //Which backpack type the player has chosen. //Equipment slots 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 7ce3f78da0..56be62c75e 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -10,29 +10,6 @@ else . = ..() -/mob/living/carbon/human/treat_message(message) - message = dna.species.handle_speech(message,src) - if(diseases.len) - for(var/datum/disease/pierrot_throat/D in diseases) - var/list/temp_message = splittext(message, " ") //List each word in the message - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line - pick_list += i - for(var/i=1, ((i <= D.stage) && (i <= temp_message.len)), i++) //Loop for each stage of the disease or until we run out of words - if(prob(3 * D.stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) - continue - temp_message[H] = "HONK" - pick_list -= H //Make sure that you dont HONK the same word twice - message = jointext(temp_message, " ") - message = ..(message) - message = dna.mutations_say_mods(message) - return message - -/mob/living/carbon/human/get_spans() - return ..() | dna.mutations_get_spans() | dna.species_get_spans() - /mob/living/carbon/human/GetVoice() if(istype(wear_mask, /obj/item/clothing/mask/chameleon)) var/obj/item/clothing/mask/chameleon/V = wear_mask @@ -54,7 +31,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 870dfc2ebc..76d8a10474 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -44,6 +44,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/siemens_coeff = 1 //base electrocution coefficient var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded? var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"] + var/list/special_step_sounds //Sounds to override barefeet walkng + var/grab_sound //Special sound for grabbing // species-only traits. Can be found in DNA.dm var/list/species_traits = list() @@ -277,7 +279,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(mutanthands) // Drop items in hands - // If you're lucky enough to have a NODROP_1 item, then it stays. + // If you're lucky enough to have a TRAIT_NODROP item, then it stays. for(var/V in C.held_items) var/obj/item/I = V if(istype(I)) @@ -286,7 +288,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 +302,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 +315,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 +324,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 +464,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) @@ -485,22 +492,45 @@ GLOBAL_LIST_EMPTY(roundstart_races) //Underwear, Undershirts & Socks if(!(NO_UNDERWEAR in species_traits)) if(H.underwear) - var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear] - if(underwear) - standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER) + if(H.hidden_underwear) + H.underwear = "Nude" + else + H.saved_underwear = H.underwear + var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear] + if(B) + var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER) + if(UNDIE_COLORABLE(B)) + MA.color = H.undie_color + standing += MA if(H.undershirt) - var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt] - if(undershirt) - if(H.dna.species.sexes && H.gender == FEMALE) - standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) - else - standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) + if(H.hidden_undershirt) + H.undershirt = "Nude" + else + H.saved_undershirt = H.undershirt + var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt] + if(T) + var/mutable_appearance/MA + if(H.dna.species.sexes && H.gender == FEMALE) + MA = wear_female_version(T.icon_state, T.icon, BODY_LAYER) + else + MA = mutable_appearance(T.icon, T.icon_state, -BODY_LAYER) + if(UNDIE_COLORABLE(T)) + MA.color = H.shirt_color + standing += MA - if(H.socks && H.get_num_legs(FALSE) >= 2 && !(DIGITIGRADE in species_traits)) - var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks] - if(socks) - standing += mutable_appearance(socks.icon, socks.icon_state, -BODY_LAYER) + if(H.socks && H.get_num_legs(FALSE) >= 2) + if(H.hidden_socks) + H.socks = "Nude" + else + H.saved_socks = H.socks + var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks] + if(S) + var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : "" + var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER) + if(UNDIE_COLORABLE(S)) + MA.color = H.socks_color + standing += MA if(standing.len) H.overlays_standing[BODY_LAYER] = standing @@ -752,7 +782,7 @@ 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) @@ -911,11 +941,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) @@ -1042,7 +1072,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) if(SLOT_L_STORE) - if(I.item_flags & NODROP) //Pockets aren't visible, so you can't move NODROP_1 items into them. + if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them. return FALSE if(H.l_store) return FALSE @@ -1058,7 +1088,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) ) return TRUE if(SLOT_R_STORE) - if(I.item_flags & NODROP) + if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.r_store) return FALSE @@ -1075,7 +1105,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) return TRUE return FALSE if(SLOT_S_STORE) - if(I.item_flags & NODROP) + if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.s_store) return FALSE @@ -1136,13 +1166,6 @@ GLOBAL_LIST_EMPTY(roundstart_races) return 1 return FALSE -/datum/species/proc/handle_speech(message, mob/living/carbon/human/H) - return message - -//return a list of spans or an empty list -/datum/species/proc/get_spans() - return list() - /datum/species/proc/check_weakness(obj/item, mob/living/attacker) return FALSE @@ -1153,21 +1176,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) @@ -1196,7 +1219,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) @@ -1225,7 +1248,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 @@ -1272,17 +1295,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)) - . -= 1 + if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP)) + . -= 1.5 - if(H.has_trait(TRAIT_IGNORESLOWDOWN)) + if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN)) ignoreslow = 1 if(!gravity) @@ -1333,9 +1356,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 . @@ -1348,13 +1371,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) @@ -1379,7 +1402,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 @@ -1452,39 +1475,64 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) // CITADEL EDIT slap mouthy gits and booty - var/aim_for_mouth = user.zone_selected == "mouth" - var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item() + 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.") - if (!target.has_trait(TRAIT_NYMPHO)) - stop_wagging_tail(target) - return FALSE + 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(aim_for_groin && (target_on_help_and_unarmed || target_restrained || target_aiming_for_groin)) - playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) - user.visible_message("[user] slaps [target]'s ass!", - "You slap [target]'s ass! ",\ - "You hear a slap.") - if (target.canbearoused) - target.adjustArousalLoss(5) - if (target.getArousalLoss() >= 100 && ishuman(target) && target.has_trait(TRAIT_NYMPHO) && target.has_dna()) - target.mob_climax(forced_climax=TRUE) - if (!target.has_trait(TRAIT_NYMPHO)) - 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 + + 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) @@ -1615,7 +1663,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) @@ -1649,8 +1697,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) @@ -1710,6 +1761,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) @@ -1754,7 +1810,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 @@ -1802,7 +1858,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") @@ -1820,7 +1876,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) @@ -1839,7 +1895,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 @@ -1851,7 +1907,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) @@ -1862,7 +1918,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 @@ -1930,7 +1986,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 434f59e660..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,NOGENITALS) + 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 678d5397ee..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,NOGENITALS) + 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/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index da7de39a03..4a7580e978 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -68,17 +68,17 @@ /obj/item/organ/tongue/dullahan zone = "abstract" + modifies_speech = TRUE -/obj/item/organ/tongue/dullahan/TongueSpeech(var/message) +/obj/item/organ/tongue/dullahan/handle_speech(datum/source, list/speech_args) if(ishuman(owner)) var/mob/living/carbon/human/H = owner if(H.dna.species.id == "dullahan") var/datum/species/dullahan/D = H.dna.species if(isobj(D.myhead.loc)) var/obj/O = D.myhead.loc - O.say(message) - message = "" - return message + O.say(speech_args[SPEECH_MESSAGE]) + speech_args[SPEECH_MESSAGE] = "" /obj/item/organ/ears/dullahan zone = "abstract" 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 87e9f950c4..2c663b4094 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,NOGENITALS) + 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) @@ -30,6 +30,7 @@ var/list/special_names = list("Tarkus") var/human_surname_chance = 3 var/special_name_chance = 5 + var/owner //dobby is a free golem /datum/species/golem/random_name(gender,unique,lastname) var/golem_surname = pick(GLOB.golem_names) @@ -74,10 +75,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 +176,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 @@ -518,6 +519,11 @@ ..() last_banana = world.time last_honk = world.time + RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C) + . = ..() + UnregisterSignal(C, COMSIG_MOB_SAY) /datum/species/golem/bananium/random_name(gender,unique,lastname) var/clown_name = pick(GLOB.clown_names) @@ -566,9 +572,8 @@ /datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H) playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0) -/datum/species/golem/bananium/get_spans() - return list(SPAN_CLOWN) - +/datum/species/golem/bananium/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN /datum/species/golem/runic name = "Runic Golem" @@ -645,14 +650,16 @@ /datum/species/golem/clockwork/on_species_gain(mob/living/carbon/human/H) . = ..() H.faction |= "ratvar" + RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech) /datum/species/golem/clockwork/on_species_loss(mob/living/carbon/human/H) if(!is_servant_of_ratvar(H)) H.faction -= "ratvar" + UnregisterSignal(H, COMSIG_MOB_SAY) . = ..() -/datum/species/golem/clockwork/get_spans() - return SPAN_ROBOT //beep +/datum/species/golem/clockwork/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT //beep /datum/species/golem/clockwork/spec_death(gibbed, mob/living/carbon/human/H) gibbed = !has_corpse ? FALSE : gibbed @@ -698,10 +705,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 +775,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 @@ -807,3 +814,196 @@ /datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) . = ..() C.ventcrawler = initial(C.ventcrawler) + +/datum/species/golem/bronze + name = "Bronze Golem" + id = "bronze golem" + prefix = "Bronze" + special_names = list("Bell") + fixed_mut_color = "cd7f32" + info_text = "As a Bronze Golem, you are very resistant to loud noises, and make loud noises if something hard hits you, however this ability does hurt your hearing." + special_step_sounds = list('sound/machines/clockcult/integration_cog_install.ogg', 'sound/magic/clockwork/fellowship_armory.ogg' ) + attack_verb = "bonk" + mutantears = /obj/item/organ/ears/bronze + var/last_gong_time = 0 + var/gong_cooldown = 150 + +/datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) + if(!(world.time > last_gong_time + gong_cooldown)) + return ..() + if(P.flag == "bullet" || P.flag == "bomb") + gong(H) + return ..() + +/datum/species/golem/bronze/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) + ..() + if(world.time > last_gong_time + gong_cooldown) + gong(H) + +/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) + ..() + if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP) + gong(H) + +/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) + ..() + if(world.time > last_gong_time + gong_cooldown) + gong(H) + +/datum/species/golem/bronze/on_hit(obj/item/projectile/P, mob/living/carbon/human/H) + ..() + if(world.time > last_gong_time + gong_cooldown) + gong(H) + +/datum/species/golem/bronze/proc/gong(mob/living/carbon/human/H) + last_gong_time = world.time + for(var/mob/living/M in get_hearers_in_view(7,H)) + if(M.stat == DEAD) //F + return + if(M == H) + H.show_message("You cringe with pain as your body rings around you!", 2) + H.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE) + H.soundbang_act(2, 0, 100, 1) + H.jitteriness += 7 + var/distance = max(0,get_dist(get_turf(H),get_turf(M))) + switch(distance) + if(0 to 1) + M.show_message("GONG!", 2) + M.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE) + M.soundbang_act(1, 0, 30, 3) + M.confused += 10 + M.jitteriness += 4 + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong) + if(2 to 3) + M.show_message("GONG!", 2) + M.playsound_local(H, 'sound/effects/gong.ogg', 75, TRUE) + M.soundbang_act(1, 0, 15, 2) + M.jitteriness += 3 + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong) + else + M.show_message("GONG!", 2) + M.playsound_local(H, 'sound/effects/gong.ogg', 50, TRUE) + + +/datum/species/golem/cardboard //Faster but weaker, can also make new shells on its own + name = "Cardboard Golem" + id = "cardboard golem" + prefix = "Cardboard" + special_names = list("Box") + info_text = "As a Cardboard Golem, you aren't very strong, but you are a bit quicker and can easily create more brethren by using cardboard on yourself." + species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS) + inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) + fixed_mut_color = "ffffff" + limbs_id = "c_golem" //special sprites + attack_verb = "bash" + armor = 25 + burnmod = 1.25 + heatmod = 2 + speedmod = 1.5 + punchdamagelow = 4 + punchstunthreshold = 7 + punchdamagehigh = 8 + var/last_creation = 0 + var/brother_creation_cooldown = 300 + +/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) + . = ..() + if(user != H) + return FALSE //forced reproduction is rape. + if(istype(I, /obj/item/stack/sheet/cardboard)) + var/obj/item/stack/sheet/cardboard/C = I + if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork + return + if(C.amount < 10) + to_chat(H, "You do not have enough cardboard!") + return FALSE + to_chat(H, "You attempt to create a new cardboard brother.") + if(do_after(user, 30, target = user)) + if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork + return + if(!C.use(10)) + to_chat(H, "You do not have enough cardboard!") + return FALSE + to_chat(H, "You create a new cardboard golem shell.") + create_brother(H.loc) + +/datum/species/golem/cardboard/proc/create_brother(var/location) + new /obj/effect/mob_spawn/human/golem/servant(location, /datum/species/golem/cardboard, owner) + last_creation = world.time + +/datum/species/golem/leather + name = "Leather Golem" + id = "leather golem" + special_names = list("Face", "Man", "Belt") //Ah dude 4 strength 4 stam leather belt AHHH + inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER) + prefix = "Leather" + fixed_mut_color = "624a2e" + info_text = "As a Leather Golem, you are flammable, but you can grab things with incredible ease, allowing all your grabs to start at a strong level." + attack_verb = "whipp" + grab_sound = 'sound/weapons/whipgrab.ogg' + attack_sound = 'sound/weapons/whip.ogg' + +/datum/species/golem/bone + name = "Bone Golem" + id = "bone golem" + say_mod = "rattles" + prefix = "Bone" + limbs_id = "b_golem" + special_names = list("Head", "Broth", "Fracture", "Rattler", "Appetit") + liked_food = GROSS | MEAT | RAW + toxic_food = null + inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID) + mutanttongue = /obj/item/organ/tongue/bone + sexes = FALSE + fixed_mut_color = "ffffff" + attack_verb = "rattl" + species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS) + inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER) + info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice." + var/datum/action/innate/bonechill/bonechill + +/datum/species/golem/bone/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + if(ishuman(C)) + bonechill = new + bonechill.Grant(C) + +/datum/species/golem/bone/on_species_loss(mob/living/carbon/C) + if(bonechill) + bonechill.Remove(C) + ..() + +/datum/action/innate/bonechill + name = "Bone Chill" + desc = "Rattle your bones and strike fear into your enemies!" + check_flags = AB_CHECK_CONSCIOUS + icon_icon = 'icons/mob/actions/actions_spells.dmi' + button_icon_state = "bonechill" + var/cooldown = 600 + var/last_use + var/snas_chance = 3 + +/datum/action/innate/bonechill/Activate() + if(world.time < last_use + cooldown) + to_chat("You aren't ready yet to rattle your bones again") + return + owner.visible_message("[owner] rattles [owner.p_their()] bones harrowingly.", "You rattle your bones") + last_use = world.time + if(prob(snas_chance)) + playsound(get_turf(owner),'sound/magic/RATTLEMEBONES2.ogg', 100) + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + var/mutable_appearance/badtime = mutable_appearance('icons/mob/human_parts.dmi', "b_golem_eyes", -FIRE_LAYER-0.5) + badtime.appearance_flags = RESET_COLOR + H.overlays_standing[FIRE_LAYER+0.5] = badtime + H.apply_overlay(FIRE_LAYER+0.5) + addtimer(CALLBACK(H, /mob/living/carbon/.proc/remove_overlay, FIRE_LAYER+0.5), 25) + else + playsound(get_turf(owner),'sound/magic/RATTLEMEBONES.ogg', 100) + for(var/mob/living/L in orange(7, get_turf(owner))) + if((MOB_UNDEAD in L.mob_biotypes) || isgolem(L) || HAS_TRAIT(L, TRAIT_RESISTCOLD)) + return //Do not affect our brothers + + to_chat(L, "A spine-chilling sound chills you to the bone!") + L.apply_status_effect(/datum/status_effect/bonechill) + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "spooked", /datum/mood_event/spooked) 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..2b487d4349 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -5,6 +5,7 @@ default_color = "00FF90" say_mod = "chirps" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD) + mutantlungs = /obj/item/organ/lungs/slime mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE inherent_traits = list(TRAIT_TOXINLOVER) @@ -594,7 +595,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 13199cdad7..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,NOGENITALS) + 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 3095ca48ae..d7bb151ddc 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -5,7 +5,7 @@ sexes = 0 meat = /obj/item/stack/sheet/mineral/plasma species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS) - inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER) + inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER) inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID) mutantlungs = /obj/item/organ/lungs/plasmaman mutanttongue = /obj/item/organ/tongue/bone/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 c3d1e1aedb..0da4073f1d 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -73,6 +73,9 @@ /datum/species/pod/pseudo_weak id = "podweak" limbs_id = "pod" + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS) + mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "legs") + default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs") light_nutrition_gain_factor = 7.5 light_bruteheal = 0.2 light_burnheal = 0.2 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 9716fc2e22..11a25cea6c 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,NOGENITALS) + 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) @@ -171,12 +171,13 @@ armour_penetration = 35 lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP /obj/item/light_eater/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) /obj/item/light_eater/afterattack(atom/movable/AM, mob/user, proximity) 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 a72c196fdf..135992f3a6 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -6,8 +6,8 @@ blacklisted = 1 sexes = 0 meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton - species_traits = list(NOBLOOD,NOGENITALS) - inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH) + 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, TRAIT_CALCIUM_HEALER) inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID) mutanttongue = /obj/item/organ/tongue/bone damage_overlay_type = ""//let's not show bloody wounds or burns over bones. @@ -21,4 +21,4 @@ /datum/species/skeleton/pirate name = "Space Queen's Skeleton" - inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH) + inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) 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 f553367921..0ebd6e795b 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,NOGENITALS) //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 @@ -28,6 +28,11 @@ /datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) ..() assume_disguise(old_species, H) + RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/species/synth/on_species_loss(mob/living/carbon/human/H) + . = ..() + UnregisterSignal(H, COMSIG_MOB_SAY) /datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) if(chem.id == "synthflesh") @@ -110,18 +115,12 @@ else return ..() - -/datum/species/synth/get_spans() - if(fake_species) - return fake_species.get_spans() - return list() - - -/datum/species/synth/handle_speech(message, mob/living/carbon/human/H) - if(H.health > disguise_fail_health) - if(fake_species) - return fake_species.handle_speech(message,H) - else - return ..() - else - return ..() \ No newline at end of file +/datum/species/synth/proc/handle_speech(datum/source, list/speech_args) + if (isliving(source)) // yeah it's gonna be living but just to be clean + var/mob/living/L = source + if(fake_species && L.health > disguise_fail_health) + switch (fake_species.type) + if (/datum/species/golem/bananium) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN + if (/datum/species/golem/clockwork) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT \ No newline at end of file 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 e757e6dcf4..9dd55c361e 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,49 +239,50 @@ //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(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE) - if(prob(1 * miasma_partialpressure)) - var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) - miasma_disease.name = "Unknown" - ForceContractDisease(miasma_disease, TRUE, TRUE) + if(prob(0.05 * miasma_partialpressure)) + var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) + miasma_disease.name = "Unknown" + ForceContractDisease(miasma_disease, TRUE, TRUE) - //Miasma side effects - switch(miasma_partialpressure) - if(1 to 5) - // At lower pp, give out a little warning - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") - if(prob(5)) - to_chat(src, "There is an unpleasant smell in the air.") - if(5 to 20) - //At somewhat higher pp, warning becomes more obvious - if(prob(15)) - to_chat(src, "You smell something horribly decayed inside this room.") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) - if(15 to 30) - //Small chance to vomit. By now, people have internals on anyway - if(prob(5)) - to_chat(src, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - vomit() - if(30 to INFINITY) - //Higher chance to vomit. Let the horror start - if(prob(25)) - to_chat(src, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - vomit() - else - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") + //Miasma side effects + switch(miasma_partialpressure) + if(1 to 5) + // At lower pp, give out a little warning + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") + if(prob(5)) + to_chat(src, "There is an unpleasant smell in the air.") + if(5 to 20) + //At somewhat higher pp, warning becomes more obvious + if(prob(15)) + to_chat(src, "You smell something horribly decayed inside this room.") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) + if(15 to 30) + //Small chance to vomit. By now, people have internals on anyway + if(prob(5)) + to_chat(src, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + vomit() + if(30 to INFINITY) + //Higher chance to vomit. Let the horror start + if(prob(25)) + to_chat(src, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + vomit() + else + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") //Clear all moods if no miasma at all @@ -292,7 +292,7 @@ - breath.garbage_collect() + GAS_GARBAGE_COLLECT(breath.gases) //BREATH TEMPERATURE handle_breath_temperature(breath) @@ -324,7 +324,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 +345,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.1 /mob/living/carbon/proc/handle_blood() return @@ -551,7 +550,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(drunkenness >= 6) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk) 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) @@ -576,7 +575,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) @@ -589,7 +588,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) @@ -656,8 +655,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put L.damage += d /mob/living/carbon/proc/liver_failure() + reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs 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)) @@ -693,7 +693,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..25bc243f07 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -73,39 +73,21 @@ if(I.loc == src) return TRUE - if(I.anchored) + if(I.anchored || !put_in_hands(I)) blacklistItems[I] ++ return FALSE - // WEAPONS - if(istype(I, /obj/item)) - var/obj/item/W = I - if(W.force >= best_force) - put_in_hands(W) - best_force = W.force - return TRUE - - // CLOTHING - else if(istype(I, /obj/item/clothing)) - var/obj/item/clothing/C = I - monkeyDrop(C) - addtimer(CALLBACK(src, .proc/pickup_and_wear, C), 5) - return TRUE - - // EVERYTHING ELSE + if(I.force >= best_force) + best_force = I.force else - if(!get_item_for_held_index(1) || !get_item_for_held_index(2)) - put_in_hands(I) - return TRUE + addtimer(CALLBACK(src, .proc/pickup_and_wear, I), 5) - blacklistItems[I] ++ - return FALSE + return TRUE -/mob/living/carbon/monkey/proc/pickup_and_wear(var/obj/item/clothing/C) - if(!equip_to_appropriate_slot(C)) - monkeyDrop(get_item_by_slot(C)) // remove the existing item if worn - sleep(5) - equip_to_appropriate_slot(C) +/mob/living/carbon/monkey/proc/pickup_and_wear(obj/item/I) + if(QDELETED(I) || I.loc != src) + return + equip_to_appropriate_slot(I) /mob/living/carbon/monkey/resist_restraints() var/obj/item/I = null @@ -119,7 +101,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]) @@ -133,7 +115,7 @@ /mob/living/carbon/monkey/proc/handle_combat() if(pickupTarget) - if(restrained() || blacklistItems[pickupTarget] || (pickupTarget.item_flags & NODROP)) + if(restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP)) pickupTarget = null else pickupTimer++ @@ -143,7 +125,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 +149,7 @@ battle_screech() retaliate(L) return TRUE - else + else bodyDisposal = locate(/obj/machinery/disposal/) in around if(bodyDisposal) target = L @@ -311,7 +293,8 @@ if(I == pickupTarget) M.visible_message("[src] snatches [pickupTarget] from [M].", "[src] snatched [pickupTarget]!") if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !QDELETED(pickupTarget)) - equip_item(pickupTarget) + if(!equip_item(pickupTarget)) + dropItemToGround(pickupTarget) else M.visible_message("[src] tried to snatch [pickupTarget] from [M], but failed!", "[src] tried to grab [pickupTarget]!") pickpocketing = FALSE 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/say.dm b/code/modules/mob/living/carbon/say.dm index f6e43f487f..452c8f8b78 100644 --- a/code/modules/mob/living/carbon/say.dm +++ b/code/modules/mob/living/carbon/say.dm @@ -1,37 +1,17 @@ -/mob/living/carbon/treat_message(message) - for(var/datum/brain_trauma/trauma in get_traumas()) - message = trauma.on_say(message) - message = ..(message) - var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) - if(!T) //hoooooouaah! - var/regex/tongueless_lower = new("\[gdntke]+", "g") - var/regex/tongueless_upper = new("\[GDNTKE]+", "g") - if(copytext(message, 1, 2) != "*") - message = tongueless_lower.Replace(message, pick("aa","oo","'")) - message = tongueless_upper.Replace(message, pick("AA","OO","'")) - else - message = T.TongueSpeech(message) - if(wear_mask) - message = wear_mask.speechModification(message) - if(head) - message = head.speechModification(message) - return message +/mob/living/carbon/proc/handle_tongueless_speech(mob/living/carbon/speaker, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/static/regex/tongueless_lower = new("\[gdntke]+", "g") + var/static/regex/tongueless_upper = new("\[GDNTKE]+", "g") + if(message[1] != "*") + message = tongueless_lower.Replace(message, pick("aa","oo","'")) + message = tongueless_upper.Replace(message, pick("AA","OO","'")) + speech_args[SPEECH_MESSAGE] = message /mob/living/carbon/can_speak_vocal(message) if(silent) return 0 return ..() -/mob/living/carbon/get_spans() - . = ..() - var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) - if(T) - . |= T.get_spans() - - var/obj/item/I = get_active_held_item() - if(I) - . |= I.get_held_item_speechspans(src) - /mob/living/carbon/could_speak_in_language(datum/language/dt) var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) if(T) @@ -39,10 +19,16 @@ else . = initial(dt.flags) & TONGUELESS_SPEECH -/mob/living/carbon/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) +/mob/living/carbon/hear_intercept(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) . = ..() if(!client) return for(var/T in get_traumas()) var/datum/brain_trauma/trauma = T - message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq) \ No newline at end of file + message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq) + + if (src.mind.has_antag_datum(/datum/antagonist/traitor)) + message = GLOB.syndicate_code_phrase_regex.Replace(message, "$1") + message = GLOB.syndicate_code_response_regex.Replace(message, "$1") + + return message 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..ea0f7ae388 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)) @@ -261,7 +263,7 @@ var/mob/M = AM log_combat(src, M, "grabbed", addition="passive grab") - if(!supress_message) + if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER))) visible_message("[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!") //Cit change - And they thought ERP was bad. if(!iscarbon(src)) M.LAssailant = null @@ -280,6 +282,11 @@ if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN) ContactContractDisease(D) + if(iscarbon(L)) + var/mob/living/carbon/C = L + if(HAS_TRAIT(src, TRAIT_STRONG_GRABBER)) + C.grippedby(src) + //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm /mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1)) @@ -304,7 +311,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 @@ -692,13 +699,13 @@ // The src mob is trying to strip an item from someone // Override if a certain type of mob should be behave differently when stripping items (can't, for example) /mob/living/stripPanelUnequip(obj/item/what, mob/who, where) - if(what.item_flags & NODROP) + if(HAS_TRAIT(what, TRAIT_NODROP)) to_chat(src, "You can't remove \the [what.name], it appears to be stuck!") return 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 @@ -717,7 +724,7 @@ // Override if a certain mob should be behave differently when placing items (can't, for example) /mob/living/stripPanelEquip(obj/item/what, mob/who, where) what = src.get_active_held_item() - if(what && (what.item_flags & NODROP)) + if(what && HAS_TRAIT(what, TRAIT_NODROP)) to_chat(src, "You can't put \the [what.name] on [who], it's stuck to your hand!") return if(what) @@ -812,7 +819,7 @@ /mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering return -/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE @@ -887,7 +894,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 +910,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 +993,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 +1187,39 @@ 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, "regen_jelly" = 10, "stimulants" = 10), + message = "You feel a surge of energy!", + stamina_buffer_boost = 0, //restores stamina buffer rather than just health + scale_stamina_loss_recovery, //defaults to null. if this is set, restores loss * this stamina. make sure it's a fraction. + stamina_loss_recovery_bypass = 0 //amount of stamina loss to ignore during calculation + ) + to_chat(src, message) + 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(min(0, -stamina_boost)) + adjustStaminaLossBuffered(min(0, -stamina_buffer_boost)) + if(scale_stamina_loss_recovery) + adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0)) + 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..e434bc4e95 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) @@ -130,6 +124,18 @@ if(user == anchored || !isturf(user.loc)) return FALSE + //pacifist vore check. + if(user.pulling && HAS_TRAIT(user, TRAIT_PACIFISM) && user.voremode) //they can only do heals, noisy guts, absorbing (technically not harm) + if(ismob(user.pulling)) + var/mob/P = user.pulling + if(src != user) + to_chat(user, "You can't risk digestion!") + return FALSE + else + user.vore_attack(user, P, user) + return + + //normal vore check. if(user.pulling && user.grab_state == GRAB_AGGRESSIVE && user.voremode) if(ismob(user.pulling)) var/mob/P = user.pulling @@ -143,11 +149,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 +216,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 +233,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 +252,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 +278,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 +303,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 +327,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 +397,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 871e33349a..155ff15d5b 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -175,13 +175,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list( else src.log_talk(message, LOG_SAY, forced_by=forced) - message = treat_message(message) + message = treat_message(message) // unfortunately we still need this + var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_SAY, args) + if (sigreturn & COMPONENT_UPPERCASE_SPEECH) + message = uppertext(message) if(!message) return last_words = message - spans |= get_spans() + spans |= speech_span if(language) var/datum/language/L = GLOB.language_datum_instances[language] @@ -229,9 +232,14 @@ GLOBAL_LIST_INIT(department_radio_keys, list( // Recompose message for AI hrefs, language incomprehension. message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode) + message = hear_intercept(message, speaker, message_language, raw_message, radio_freq, spans, message_mode) + show_message(message, 2, deaf_message, deaf_type) return message +/mob/living/proc/hear_intercept(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) + return message + /mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode) var/static/list/eavesdropping_modes = list(MODE_WHISPER = TRUE, MODE_WHISPER_CRIT = TRUE) var/eavesdrop_range = 0 @@ -301,7 +309,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()) @@ -327,6 +335,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return null /mob/living/proc/treat_message(message) + + if(HAS_TRAIT(src, TRAIT_UNINTELLIGIBLE_SPEECH)) + message = unintelligize(message) + if(derpspeech) message = derpspeech(message, stuttering) @@ -389,8 +401,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( else . = ..() -/mob/living/whisper(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null) - say("#[message]", bubble_type, spans, sanitize, language) +/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) + say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced) /mob/living/get_language_holder(shadow=TRUE) if(mind && shadow) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b4524a54e6..1b1eb1a805 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() ..() @@ -332,8 +288,17 @@ /mob/living/silicon/ai/can_interact_with(atom/A) . = ..() + var/turf/ai = get_turf(src) + var/turf/target = get_turf(A) if (.) return + + if(!target) + return + + if ((ai.z != target.z) && !is_station_level(ai.z)) + return FALSE + if (istype(loc, /obj/item/aicard)) var/turf/T0 = get_turf(src) var/turf/T1 = get_turf(A) @@ -823,7 +788,7 @@ return TRUE return ..() -/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(control_disabled || incapacitated()) to_chat(src, "You can't do that right now!") return FALSE @@ -915,9 +880,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/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 928bd63dd1..4ac5c1f0bb 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -49,7 +49,7 @@ else padloc = "(UNKNOWN)" src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]") - send_speech(message, 7, T, "robot", get_spans(), language) + send_speech(message, 7, T, "robot", language = language) to_chat(src, "Holopad transmitted, [real_name] \"[message]\"") else to_chat(src, "No holopad connected.") diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 896d8674be..7fd861bfeb 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -183,7 +183,7 @@ // See software.dm for Topic() -/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(be_close && !in_range(M, src)) to_chat(src, "You are too far away!") return FALSE diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm index 99484f395e..164a3e7389 100644 --- a/code/modules/mob/living/silicon/pai/pai_shell.dm +++ b/code/modules/mob/living/silicon/pai/pai_shell.dm @@ -29,6 +29,13 @@ if(!L.temporarilyRemoveItemFromInventory(card)) to_chat(src, "Error: Unable to expand to mobile form. Chassis is restrained by some device or person.") return FALSE + if(istype(card.loc, /obj/item/integrated_circuit/input/pAI_connector)) + var/obj/item/integrated_circuit/input/pAI_connector/C = card.loc + C.RemovepAI() + C.visible_message("[src] ejects itself from [C]!") + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + C.installed_pai = null + C.push_data() forceMove(get_turf(card)) card.forceMove(src) if(client) 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/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 335645b17e..29fbd39e2c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -580,6 +580,19 @@ else return ..() +/mob/living/silicon/robot/crowbar_act(mob/living/user, obj/item/I) //TODO: make fucking everything up there in that attackby() proc use the proper tool_act() procs. But honestly, who has time for that? 'cause I know for sure that you, the person reading this, sure as hell doesn't. + var/validbreakout = FALSE + for(var/obj/item/dogborg/sleeper/S in held_items) + if(!LAZYLEN(S.contents)) + continue + if(!validbreakout) + visible_message("[user] wedges [I] into the crevice separating [S] from [src]'s chassis, and begins to pry...", "You wedge [I] into the crevice separating [S] from [src]'s chassis, and begin to pry...") + validbreakout = TRUE + S.go_out() + if(validbreakout) + return TRUE + return ..() + /mob/living/silicon/robot/verb/unlock_own_cover() set category = "Robot Commands" set name = "Unlock Cover" @@ -910,7 +923,7 @@ if(DISCONNECT) //Tampering with the wires to_chat(connected_ai, "

    NOTICE - Remote telemetry lost with [name].
    ") -/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(stat || lockcharge || low_power_mode) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 38ad3b8e5a..7b95ced63f 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -119,7 +119,7 @@ if(I.loc != src) I.forceMove(src) modules += I - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CYBORG_ITEM_TRAIT) I.mouse_opacity = MOUSE_OPACITY_OPAQUE if(nonstandard) added_modules += I diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index aca35762de..1d38a3c5a6 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -1,14 +1,10 @@ - -/mob/living/silicon/get_spans() - return ..() | SPAN_ROBOT - /mob/living/proc/robot_talk(message) log_talk(message, LOG_SAY) var/desig = "Default Cyborg" //ezmode for taters if(issilicon(src)) var/mob/living/silicon/S = src desig = trim_left(S.designation + " " + S.job) - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "Robotic Talk, [name] [message_a]" for(var/mob/M in GLOB.player_list) if(M.binarycheck()) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index d0e3fc8b1c..13520774c5 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -12,6 +12,7 @@ possible_a_intents = list(INTENT_HELP, INTENT_HARM) mob_biotypes = list(MOB_ROBOTIC) rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE + speech_span = SPAN_ROBOT var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS var/last_lawchange_announce = 0 @@ -69,6 +70,9 @@ /mob/living/silicon/contents_explosion(severity, target) return +/mob/living/silicon/prevent_content_explosion() + return TRUE + /mob/living/silicon/proc/cancelAlarm() return 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/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index e9978d1e62..ce99e301c5 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -23,6 +23,7 @@ verb_yell = "alarms" initial_language_holder = /datum/language_holder/synthetic bubble_icon = "machine" + speech_span = SPAN_ROBOT faction = list("neutral", "silicon" , "turret") @@ -348,13 +349,10 @@ if((!on) || (!message)) return if(channel && Radio.channels[channel])// Use radio if we have channel key - Radio.talk_into(src, message, channel, get_spans(), get_default_language()) + Radio.talk_into(src, message, channel) else say(message) -/mob/living/simple_animal/bot/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language) . = ..() if(. != 0) 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/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 9a08276999..5e5b486435 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -284,12 +284,8 @@ if(health < maxHealth) adjustBruteLoss(-8) //Fast life regen for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts! - if(D.icon_state != "donut2") - D.name = "frosted donut" - D.icon_state = "donut2" - D.reagents.add_reagent("sprinkles", 2) - D.bonus_reagents = list("sprinkles" = 2, "sugar" = 1) - D.filling_color = "#FF69B4" + if(!D.is_frosted) + D.frost_donut() /mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) ..() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 3a5d02315b..c194233c42 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -28,13 +28,29 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1) childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5) animal_species = /mob/living/simple_animal/pet/dog - var/shaved = 0 - var/obj/item/inventory_head - var/obj/item/inventory_back - var/nofur = 0 //Corgis that have risen past the material plane of existence. gold_core_spawnable = FRIENDLY_SPAWN can_be_held = TRUE collar_type = "corgi" + var/obj/item/inventory_head + var/obj/item/inventory_back + var/shaved = FALSE + var/nofur = FALSE //Corgis that have risen past the material plane of existence. + +/mob/living/simple_animal/pet/dog/corgi/Destroy() + QDEL_NULL(inventory_head) + QDEL_NULL(inventory_back) + return ..() + +/mob/living/simple_animal/pet/dog/corgi/handle_atom_del(atom/A) + if(A == inventory_head) + inventory_head = null + update_corgi_fluff() + regenerate_icons() + if(A == inventory_back) + inventory_back = null + update_corgi_fluff() + regenerate_icons() + return ..() /mob/living/simple_animal/pet/dog/pug name = "\improper pug" @@ -80,23 +96,17 @@ regenerate_icons() /mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user) - user.set_machine(src) - if(user.stat) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return + user.set_machine(src) var/dat = "
    Inventory of [name]

    " - if(inventory_head) - dat += "
    Head: [inventory_head] (Remove)" - else - dat += "
    Head: Nothing" - if(inventory_back) - dat += "
    Back: [inventory_back] (Remove)" - else - dat += "
    Back: Nothing" + dat += "
    Head: [inventory_head]" : "add_inv=head'>Nothing"]" + dat += "
    Back: [inventory_back]" : "add_inv=back'>Nothing"]" + dat += "
    Collar: [pcollar]" : "add_inv=collar'>Nothing"]" - user << browse(dat, text("window=mob[];size=325x500", real_name)) - onclose(user, "mob[real_name]") - return + user << browse(dat, "window=mob[REF(src)];size=325x500") + onclose(user, "mob[REF(src)]") /mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type) var/armorval = 0 @@ -128,7 +138,7 @@ if(do_after(user, 50, target = src)) user.visible_message("[user] shaves [src]'s hair using \the [O].") playsound(loc, 'sound/items/welder2.ogg', 20, 1) - shaved = 1 + shaved = TRUE icon_living = "[initial(icon_living)]_shaved" icon_dead = "[initial(icon_living)]_shaved_dead" if(stat == CONSCIOUS) @@ -147,18 +157,18 @@ L.visible_message("[L] scoops up [src]!") /mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list) - if(usr.stat) + if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + usr << browse(null, "window=mob[REF(src)]") + usr.unset_machine() return //Removing from inventory if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr))) - return var/remove_from = href_list["remove_inv"] switch(remove_from) if(BODY_ZONE_HEAD) if(inventory_head) - inventory_head.forceMove(drop_location()) + usr.put_in_hands(inventory_head) inventory_head = null update_corgi_fluff() regenerate_icons() @@ -167,24 +177,32 @@ return if("back") if(inventory_back) - inventory_back.forceMove(drop_location()) + usr.put_in_hands(inventory_back) inventory_back = null update_corgi_fluff() regenerate_icons() else to_chat(usr, "There is nothing to remove from its [remove_from].") return + if("collar") + if(pcollar) + usr.put_in_hands(pcollar) + pcollar = null + update_corgi_fluff() + regenerate_icons() show_inv(usr) //Adding things to inventory else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr))) - return var/add_to = href_list["add_inv"] switch(add_to) + if("collar") + add_collar(usr.get_active_held_item(), usr) + update_corgi_fluff() + if(BODY_ZONE_HEAD) place_on_head(usr.get_active_held_item(),usr) @@ -229,7 +247,7 @@ show_inv(usr) else - ..() + return ..() //Corgis are supposed to be simpler, so only a select few objects can actually be put //to be compatible with them. The objects are below. @@ -560,7 +578,7 @@ icon_state = "void_puppy" icon_living = "void_puppy" icon_dead = "void_puppy_dead" - nofur = 1 + nofur = TRUE unsuitable_atmos_damage = 0 minbodytemp = TCMB maxbodytemp = T0C + 40 diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index cf3742fcc5..6d3121474c 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -37,6 +37,7 @@ gender = NEUTER mob_biotypes = list(MOB_ROBOTIC) speak_emote = list("chirps") + speech_span = SPAN_ROBOT bubble_icon = "machine" initial_language_holder = /datum/language_holder/drone mob_size = MOB_SIZE_SMALL @@ -92,7 +93,7 @@ var/obj/item/I = new default_hatmask(src) equip_to_slot_or_del(I, SLOT_HEAD) - access_card.item_flags |= NODROP + ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) alert_drones(DRONE_NET_CONNECT) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm index 16bf370f02..7a5967948f 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm @@ -1,13 +1,3 @@ -///////////// -//DRONE SAY// -///////////// -//Drone speach - -/mob/living/simple_animal/drone/get_spans() - return ..() | SPAN_ROBOT - - - //Base proc for anything to call /proc/_alert_drones(msg, dead_can_hear = 0, atom/source, mob/living/faction_checked_mob, exact_faction_match) if (dead_can_hear && source) @@ -31,7 +21,7 @@ /mob/living/simple_animal/drone/proc/drone_chat(msg) - alert_drones("Drone Chat: [name] [say_quote(msg, get_spans())]", TRUE) + alert_drones("Drone Chat: [name] [say_quote(msg)]", TRUE) /mob/living/simple_animal/drone/binarycheck() return TRUE diff --git a/code/modules/mob/living/simple_animal/friendly/panda.dm b/code/modules/mob/living/simple_animal/friendly/panda.dm new file mode 100644 index 0000000000..a7b6143ef5 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/panda.dm @@ -0,0 +1,20 @@ +/mob/living/simple_animal/pet/redpanda + name = "Red panda" + desc = "Wah't a dork." + icon = 'icons/mob/pets.dmi' + icon_state = "red_panda" + icon_living = "red_panda" + icon_dead = "dead_panda" + speak = list("Churip","Chuuriip","Cheep-cheep","Chiteurp","squueeaacipt") + speak_emote = list("chirps", "huff-quacks") + emote_hear = list("squeak-chrips.", "huff-squacks.") + emote_see = list("shakes its head.", "rolls about.") + speak_chance = 1 + turns_per_move = 5 + see_in_dark = 6 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + gold_core_spawnable = FRIENDLY_SPAWN + do_footstep = TRUE diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index 8df0ee83fe..c24dc6857a 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -2,21 +2,30 @@ icon = 'icons/mob/pets.dmi' mob_size = MOB_SIZE_SMALL mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) - var/obj/item/clothing/neck/petcollar/pcollar - var/collar_type - var/unique_pet = FALSE blood_volume = BLOOD_VOLUME_NORMAL + var/unique_pet = FALSE // if the mob can be renamed + var/obj/item/clothing/neck/petcollar/pcollar + var/collar_type //if the mob has collar sprites, define them. + +/mob/living/simple_animal/pet/handle_atom_del(atom/A) + if(A == pcollar) + pcollar = null + return ..() + +/mob/living/simple_animal/pet/proc/add_collar(obj/item/clothing/neck/petcollar/P, mob/user) + if(QDELETED(P) || pcollar) + return + if(!user.transferItemToLoc(P, src)) + return + pcollar = P + regenerate_icons() + to_chat(user, "You put the [P] around [src]'s neck.") + if(P.tagname && !unique_pet) + fully_replace_character_name(null, "\proper [P.tagname]") /mob/living/simple_animal/pet/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar && collar_type) - var/obj/item/clothing/neck/petcollar/P = O - pcollar = P.type - regenerate_icons() - to_chat(user, "You put the [P] around [src]'s neck.") - if(P.tagname && !unique_pet) - real_name = "\proper [P.tagname]" - name = real_name - qdel(P) + add_collar(O, user) return if(istype(O, /obj/item/newspaper)) @@ -35,12 +44,16 @@ pcollar = new(src) regenerate_icons() +/mob/living/simple_animal/pet/Destroy() + QDEL_NULL(pcollar) + return ..() + /mob/living/simple_animal/pet/revive(full_heal = 0, admin_revive = 0) - if(..()) + . = ..() + if(.) if(collar_type) collar_type = "[initial(collar_type)]" regenerate_icons() - . = TRUE /mob/living/simple_animal/pet/death(gibbed) ..(gibbed) @@ -50,7 +63,8 @@ /mob/living/simple_animal/pet/gib() if(pcollar) - new pcollar(drop_location()) + pcollar.forceMove(drop_location()) + pcollar = null ..() /mob/living/simple_animal/pet/regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 701e244f89..1a918766b6 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -596,6 +596,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians /obj/item/guardiancreator/tech/choose/traitor possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support") +/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity() + return !used + /obj/item/guardiancreator/tech/choose random = FALSE 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 a70ca2a8e6..368c5ad4a8 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -348,7 +348,7 @@ if(vore_active) if(isliving(target)) var/mob/living/L = target - if(L.Adjacent(src) && L.devourable) // aggressive check to ensure vore attacks can be made + if(!client && L.Adjacent(src) && L.devourable) // aggressive check to ensure vore attacks can be made if(prob(voracious_chance)) vore_attack(src,L,src) else 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/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index a07e46a289..301b270e36 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -41,6 +41,9 @@ QDEL_NULL(internal) . = ..() +/mob/living/simple_animal/hostile/megafauna/prevent_content_explosion() + return TRUE + /mob/living/simple_animal/hostile/megafauna/death(gibbed) if(health > 0) return 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/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 4fdf431fa0..fc53483eda 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -181,94 +181,85 @@ */ /mob/living/simple_animal/parrot/show_inv(mob/user) user.set_machine(src) - var/dat = "

    Inventory of [name]

    " - if(ears) - dat += "
    Headset: [ears] (Remove)" - else - dat += "
    Headset: Nothing" - user << browse(dat, "window=mob[real_name];size=325x500") - onclose(user, "mob[real_name]") + var/dat = "

    Inventory of [name]

    " + dat += "
    Headset: [ears]" : "add_inv=ears'>Nothing"]" + + user << browse(dat, "window=mob[REF(src)];size=325x500") + onclose(user, "window=mob[REF(src)]") /mob/living/simple_animal/parrot/Topic(href, href_list) - - //Can the usr physically do this? - if(usr.incapacitated() || !usr.Adjacent(loc)) + if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + usr << browse(null, "window=mob[REF(src)]") + usr.unset_machine() return - //Is the usr's mob type able to do this? (lolaliens) - if(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr)) + //Removing from inventory + if(href_list["remove_inv"]) + var/remove_from = href_list["remove_inv"] + switch(remove_from) + if("ears") + if(!ears) + to_chat(usr, "There is nothing to remove from its [remove_from]!") + return + if(!stat) + say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") + ears.forceMove(drop_location()) + ears = null + for(var/possible_phrase in speak) + if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) + possible_phrase = copytext(possible_phrase,3) - //Removing from inventory - if(href_list["remove_inv"]) - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("ears") - if(ears) - if(!stat) - if(available_channels.len) - src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - else - src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - ears.forceMove(src.loc) - ears = null - for(var/possible_phrase in speak) - if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) - possible_phrase = copytext(possible_phrase,3) - else - to_chat(usr, "There is nothing to remove from its [remove_from]!") + //Adding things to inventory + else if(href_list["add_inv"]) + var/add_to = href_list["add_inv"] + if(!usr.get_active_held_item()) + to_chat(usr, "You have nothing in your hand to put on its [add_to]!") + return + switch(add_to) + if("ears") + if(ears) + to_chat(usr, "It's already wearing something!") + return + else + var/obj/item/item_to_add = usr.get_active_held_item() + if(!item_to_add) return - //Adding things to inventory - else if(href_list["add_inv"]) - var/add_to = href_list["add_inv"] - if(!usr.get_active_held_item()) - to_chat(usr, "You have nothing in your hand to put on its [add_to]!") - return - switch(add_to) - if("ears") - if(ears) - to_chat(usr, "It's already wearing something!") + if( !istype(item_to_add, /obj/item/radio/headset) ) + to_chat(usr, "This object won't fit!") return - else - var/obj/item/item_to_add = usr.get_active_held_item() - if(!item_to_add) - return - if( !istype(item_to_add, /obj/item/radio/headset) ) - to_chat(usr, "This object won't fit!") - return + var/obj/item/radio/headset/headset_to_add = item_to_add - var/obj/item/radio/headset/headset_to_add = item_to_add + if(!usr.transferItemToLoc(headset_to_add, src)) + return + ears = headset_to_add + to_chat(usr, "You fit the headset onto [src].") - if(!usr.transferItemToLoc(headset_to_add, src)) - return - src.ears = headset_to_add - to_chat(usr, "You fit the headset onto [src].") + clearlist(available_channels) + for(var/ch in headset_to_add.channels) + switch(ch) + if("Engineering") + available_channels.Add(":e") + if("Command") + available_channels.Add(":c") + if("Security") + available_channels.Add(":s") + if("Science") + available_channels.Add(":n") + if("Medical") + available_channels.Add(":m") + if("Supply") + available_channels.Add(":u") + if("Service") + available_channels.Add(":v") - clearlist(available_channels) - for(var/ch in headset_to_add.channels) - switch(ch) - if("Engineering") - available_channels.Add(":e") - if("Command") - available_channels.Add(":c") - if("Security") - available_channels.Add(":s") - if("Science") - available_channels.Add(":n") - if("Medical") - available_channels.Add(":m") - if("Supply") - available_channels.Add(":u") - if("Service") - available_channels.Add(":v") - - if(headset_to_add.translate_binary) - available_channels.Add(":b") - else - ..() + if(headset_to_add.translate_binary) + available_channels.Add(":b") + else + return ..() /* diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index fcb201d0ad..1f81899d8a 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, no_tk=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/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 161362c187..07985215d8 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -61,7 +61,7 @@ break if(Target in view(1,src)) - if(issilicon(Target)) + if(!CanFeedon(Target)) //If they're not able to be fed upon, ignore them. if(!Atkcool) Atkcool = 1 spawn(45) @@ -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) @@ -600,7 +600,8 @@ phrases += "[M]... friend..." if (nutrition < get_hunger_nutrition()) phrases += "[M]... feed me..." - say (pick(phrases)) + if(!stat) + say (pick(phrases)) /mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it if (is_adult) diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 96e84a1754..a3e2f48b75 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -48,34 +48,58 @@ var/mob/living/simple_animal/slime/S = owner S.Feed() -/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M) +/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M, silent = FALSE) if(!Adjacent(M)) - return 0 + return FALSE if(buckled) Feedstop() - return 0 + return FALSE + + if(issilicon(M)) + return FALSE + + if(isanimal(M)) + var/mob/living/simple_animal/S = M + if(S.damage_coeff[TOX] <= 0 && S.damage_coeff[CLONE] <= 0) //The creature wouldn't take any damage, it must be too weird even for us. + if(silent) + return FALSE + to_chat(src, "[pick("This subject is incompatible", \ + "This subject does not have life energy", "This subject is empty", \ + "I am not satisified", "I can not feed from this subject", \ + "I do not feel nourished", "This subject is not food")]!") + return FALSE if(isslime(M)) + if(silent) + return FALSE to_chat(src, "I can't latch onto another slime...") - return 0 + return FALSE if(docile) + if(silent) + return FALSE to_chat(src, "I'm not hungry anymore...") - return 0 + return FALSE if(stat) + if(silent) + return FALSE to_chat(src, "I must be conscious to do this...") - return 0 + return FALSE if(M.stat == DEAD) + if(silent) + return FALSE to_chat(src, "This subject does not have a strong enough life energy...") - return 0 + return FALSE if(locate(/mob/living/simple_animal/slime) in M.buckled_mobs) + if(silent) + return FALSE to_chat(src, "Another slime is already feeding on this subject...") - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/slime/proc/Feedon(mob/living/M) M.unbuckle_all_mobs(force=1) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in CanFeedon()) 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/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 251739c935..930656228d 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -91,14 +91,15 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( if(!totalMembers.len) return - for(var/X in totalMembers) - var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. - if(!A.pipe_vision_img) - A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) - A.pipe_vision_img.plane = ABOVE_HUD_PLANE - pipes_shown += A.pipe_vision_img - if(client) - client.images += A.pipe_vision_img + if(client) + for(var/X in totalMembers) + var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. + if(in_view_range(client.mob, A)) + if(!A.pipe_vision_img) + A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) + A.pipe_vision_img.plane = ABOVE_HUD_PLANE + client.images += A.pipe_vision_img + pipes_shown += A.pipe_vision_img movement_type |= VENTCRAWLING diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9d662b1673..b098801da8 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) @@ -784,7 +784,7 @@ return 0 //Can the mob use Topic to interact with machines -/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return /mob/proc/faction_check_mob(mob/target, exact_match) @@ -871,13 +871,7 @@ return /mob/proc/update_sight() - for(var/O in orbiters) - var/datum/orbit/orbit = O - var/obj/effect/wisp/wisp = orbit.orbiter - if (istype(wisp)) - sight |= wisp.sight_flags - if(!isnull(wisp.lighting_alpha)) - lighting_alpha = min(lighting_alpha, wisp.lighting_alpha) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) sync_lighting_plane_alpha() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index cb532e4d5e..82e2b11f8e 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 @@ -148,7 +148,7 @@ if(INCORPOREAL_MOVE_BASIC) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_SHADOW) if(prob(50)) @@ -190,7 +190,7 @@ new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles. var/turf/open/floor/stepTurf = get_step(L, direct) @@ -209,7 +209,7 @@ to_chat(L, "Holy energies block your path!") return - L.loc = get_step(L, direct) + L.forceMove(stepTurf) L.setDir(direct) return TRUE diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 9e127d4746..ecb869790c 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -69,16 +69,11 @@ if(name != real_name) alt_name = " (died as [real_name])" - var/K - - if(key) - K = src.key - - var/spanned = src.say_quote(message, get_spans()) + var/spanned = say_quote(message) message = emoji_parse(message) var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]" log_talk(message, LOG_SAY, tag="DEAD") - deadchat_broadcast(rendered, follow_target = src, speaker_key = K) + deadchat_broadcast(rendered, follow_target = src, speaker_key = key) /mob/proc/check_emote(message) if(copytext(message, 1, 2) == "*") diff --git a/code/modules/mob/say_readme.dm b/code/modules/mob/say_readme.dm index 00e0f66246..0e76d9b6ed 100644 --- a/code/modules/mob/say_readme.dm +++ b/code/modules/mob/say_readme.dm @@ -78,10 +78,6 @@ global procs say_quote(input, spans, message_mode) Adds a verb and quotes to a message. Also attaches span classes to a message. Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker. - get_spans(input, spans) - Returns the list of spans that are always applied to messages of this atom. - Always return ..() | + youroutput when overriding this proc! - /mob say_dead(message) Sends a message to all dead people. Does not use Hear(). 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/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 20ad2214cf..99d648d02b 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -44,7 +44,7 @@ return machinery_computer.update_icon() // This thing is not meant to be used on it's own, get topic data from our machinery owner. -//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) // if(!machinery_computer) // return 0 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/gloves.dm b/code/modules/ninja/suit/gloves.dm index 4308120c4f..276de652bc 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -37,6 +37,8 @@ var/mindrain = 200 var/maxdrain = 400 + var/stunforce = 140 //Same as stunbaton, adjustable. + /obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity) if(!candrain || draining) @@ -77,5 +79,5 @@ /obj/item/clothing/gloves/space_ninja/examine(mob/user) ..() - if(item_flags & NODROP) + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)) to_chat(user, "The energy drain mechanism is [candrain?"active":"inactive"].") diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm index 81d37886dd..e97e39643a 100644 --- a/code/modules/ninja/suit/mask.dm +++ b/code/modules/ninja/suit/mask.dm @@ -17,3 +17,46 @@ Contents: item_state = "s-ninja_mask" strip_delay = 120 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + modifies_speech = TRUE + +/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + var/list/temp_message = text2list(message, " ") + var/list/pick_list = list() + for(var/i in 1 to temp_message.len) + pick_list += i + for(var/i in 1 to abs(temp_message.len/3)) + 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) + speech_args[SPEECH_MESSAGE] = message diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm index 270e1f106f..334136cc33 100644 --- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm +++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm @@ -14,12 +14,12 @@ It is possible to destroy the net by the occupant or someone else. mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff. anchored = TRUE//Can't drag/grab the net. layer = ABOVE_ALL_MOB_LAYER - max_integrity = 25 //How much health it has. + max_integrity = 50 //How much health it has. can_buckle = 1 buckle_lying = 0 buckle_prevents_pull = TRUE - var/mob/living/carbon/affecting//Who it is currently affecting, if anyone. - var/mob/living/carbon/master//Who shot web. Will let this person know if the net was successful or failed. + var/mob/living/carbon/affecting //Who it is currently affecting, if anyone. + var/mob/living/carbon/master //Who shot web. Will let this person know if the net was successful or failed. var/check = 15//30 seconds before teleportation. Could be extended I guess. var/success = FALSE @@ -59,6 +59,41 @@ It is possible to destroy the net by the occupant or someone else. continue H.dropItemToGround(W) + var/datum/antagonist/antag_datum + for(var/datum/antagonist/ninja/AD in GLOB.antagonists) //Because only ninjas get capture objectives; They're not doable without the suit. + if(AD.owner == master) + antag_datum = AD + break + + for(var/datum/objective/capture/capture in antag_datum) + if(istype(affecting, /mob/living/carbon/human)) //Humans. + if(affecting.stat == DEAD)//Dead folks are worth less. + capture.captured_amount+=0.5 + continue + capture.captured_amount+=1 + if(istype(affecting, /mob/living/carbon/monkey)) //Monkeys are almost worthless, you failure. + capture.captured_amount+=0.1 + if(istype(affecting, /mob/living/carbon/alien/larva)) //Larva are important for research. + if(affecting.stat == DEAD) + capture.captured_amount+=0.5 + continue + capture.captured_amount+=1 + if(istype(affecting, /mob/living/carbon/alien/humanoid)) //Aliens are worth twice as much as humans. + if(istype(affecting, /mob/living/carbon/alien/humanoid/royal/queen)) //Queens are worth three times as much as humans. + if(affecting.stat == DEAD) + capture.captured_amount+=1.5 + else + capture.captured_amount+=3 + continue + if(affecting.stat == DEAD) + capture.captured_amount+=1 + continue + capture.captured_amount+=2 + + + affecting.revive(1, 1) //Basically a revive and full heal, including limbs/organs + //In case people who have been captured dead want to hang out at the holding area + playsound(affecting, 'sound/effects/sparks4.ogg', 50, 1) new /obj/effect/temp_visual/dir_setting/ninja/phase/out(affecting.drop_location(), affecting.dir) @@ -73,8 +108,9 @@ It is possible to destroy the net by the occupant or someone else. playsound(affecting, 'sound/effects/sparks2.ogg', 50, 1) new /obj/effect/temp_visual/dir_setting/ninja/phase(affecting.drop_location(), affecting.dir) -/obj/structure/energy_net/attack_paw(mob/user) - return attack_hand() +/obj/attack_alien(mob/living/carbon/alien/humanoid/user) + if(attack_generic(user, 15, BRUTE, "melee", 0)) //Aliens normally deal 60 damage to structures. They'd one-shot nets without this. + playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) /obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/living/user) return//We only want our target to be buckled 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 5c19a67284..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,22 +4,7 @@ if(!ninjacost(0,N_ADRENALINE)) var/mob/living/carbon/human/H = affecting - H.SetSleeping(0) - H.SetStun(0) - H.SetKnockdown(0) - H.SetUnconscious(0) - H.adjustStaminaLoss(-150) - H.stuttering = 0 - H.updatehealth() - H.update_stamina() - H.resting = 0 - H.lying = 0 - H.update_canmove() - - H.reagents.add_reagent("inaprovaline", 3) //let's give another chance to dumb fucks who forget to breathe - H.reagents.add_reagent("synaptizine", 10) - H.reagents.add_reagent("omnizine", 10) - H.reagents.add_reagent("stimulants", 10) + 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") diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm index 8c8f92e522..61355ca89b 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm @@ -2,21 +2,32 @@ //Allows the ninja to kidnap people /obj/item/clothing/suit/space/space_ninja/proc/ninjanet() var/mob/living/carbon/human/H = affecting - var/mob/living/carbon/C = input("Select who to capture:","Capture who?",null) as null|mob in oview(H) + var/mob/living/carbon/C + + //If there's only one valid target, let's actually try to capture it, rather than forcing + //the user to fiddle with the dialog displaying a list of one + //Also, let's make this smarter and not list mobs you can't currently net. + var/list/candidates + for(var/mob/M in oview(H)) + if(!M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. + continue + for(var/obj/structure/energy_net/E in get_turf(M))//Check if they are already being affected by an energy net. + if(E.affecting == M) + continue + LAZYADD(candidates, M) + + if(!LAZYLEN(candidates)) + return FALSE + + if(candidates.len == 1) + C = candidates[1] + else + C = input("Select who to capture:","Capture who?",null) as null|mob in candidates + if(QDELETED(C)||!(C in oview(H))) - return 0 + return FALSE - if(!C.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. - to_chat(H, "[C.p_they(TRUE)] will bring no honor to your Clan!") - return - if(locate(/obj/structure/energy_net) in get_turf(C))//Check if they are already being affected by an energy net. - to_chat(H, "[C.p_they(TRUE)] are already trapped inside an energy net!") - return - for(var/turf/T in getline(get_turf(H), get_turf(C))) - if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. - to_chat(H, "You may not use an energy net through solid obstacles!") - return if(!ninjacost(200,N_STEALTH_CANCEL)) H.Beam(C,"n_beam",time=15) H.say("Get over here!", forced = "ninja net") diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index 861ffb9446..10fce3d74e 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -261,4 +261,19 @@ They *could* go in their appropriate files, but this is supposed to be modular spark_system.set_up(5, 0, loc) playsound(src, "sparks", 50, 1) visible_message("[H] electrocutes [src] with [H.p_their()] touch!", "[H] electrocutes you with [H.p_their()] touch!") - electrocute_act(25, H) + electrocute_act(15, H) + + Knockdown(G.stunforce) + adjustStaminaLoss(G.stunforce*0.1, affected_zone = (istype(H) ? H.zone_selected : BODY_ZONE_CHEST)) + apply_effect(EFFECT_STUTTER, G.stunforce) + SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK) + + lastattacker = H.real_name + lastattackerckey = H.ckey + log_combat(H, src, "stunned") + + playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + + if(ishuman(src)) + var/mob/living/carbon/human/Hsrc = src + Hsrc.forcesay(GLOB.hit_appends) diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 6110f2b0c0..b98ef764c0 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -111,15 +111,15 @@ Contents: to_chat(H, "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...") return FALSE affecting = H - item_flags |= NODROP //colons make me go all |= + ADD_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) //colons make me go all |= slowdown = 0 n_hood = H.head - n_hood.item_flags |= NODROP + ADD_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes = H.shoes - n_shoes.item_flags |= NODROP + ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes.slowdown-- n_gloves = H.gloves - n_gloves.item_flags |= NODROP + ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) return TRUE /obj/item/clothing/suit/space/space_ninja/proc/lockIcons(mob/living/carbon/human/H) @@ -131,18 +131,18 @@ Contents: //This proc allows the suit to be taken off. /obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() affecting = null - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) slowdown = 1 icon_state = "s-ninja" if(n_hood)//Should be attached, might not be attached. - n_hood.item_flags &= ~NODROP + REMOVE_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) if(n_shoes) - n_shoes.item_flags &= ~NODROP + REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes.slowdown++ if(n_gloves) n_gloves.icon_state = "s-ninja" n_gloves.item_state = "s-ninja" - n_gloves.item_flags &= ~NODROP + REMOVE_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_gloves.candrain=0 n_gloves.draining=0 diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm deleted file mode 100644 index 79685b9104..0000000000 --- a/code/modules/orbit/orbit.dm +++ /dev/null @@ -1,135 +0,0 @@ -/datum/orbit - var/atom/movable/orbiter - var/atom/orbiting - var/lock = TRUE - var/turf/lastloc - var/lastprocess - -/datum/orbit/New(_orbiter, _orbiting, _lock) - orbiter = _orbiter - orbiting = _orbiting - SSorbit.processing += src - if (!orbiting.orbiters) - orbiting.orbiters = list() - orbiting.orbiters += src - - if (orbiter.orbiting) - orbiter.stop_orbit() - orbiter.orbiting = src - Check() - lock = _lock - -//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping) -/datum/orbit/Destroy(force = FALSE) - SSorbit.processing -= src - if (orbiter) - orbiter.orbiting = null - orbiter = null - if (orbiting) - if (orbiting.orbiters) - orbiting.orbiters -= src - if (!orbiting.orbiters.len)//we are the last orbit, delete the list - orbiting.orbiters = null - orbiting = null - return ..() - -/datum/orbit/proc/Check(turf/targetloc, list/checked_already = list()) - //Avoid infinite loops for people who end up orbiting themself through another orbiter - checked_already[src] = TRUE - if (!orbiter) - qdel(src) - return - if (!orbiting) - orbiter.stop_orbit() - return - if (!orbiter.orbiting) //admin wants to stop the orbit. - orbiter.orbiting = src //set it back to us first - orbiter.stop_orbit() - var/atom/movable/AM = orbiting - if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter) - orbiter.stop_orbit() - return - lastprocess = world.time - if (!targetloc) - targetloc = get_turf(orbiting) - if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc)) - orbiter.stop_orbit() - return - var/turf/old_turf = get_turf(orbiter) - var/turf/new_turf = get_turf(targetloc) - if (old_turf?.z != new_turf?.z) - orbiter.onTransitZ(old_turf?.z, new_turf?.z) - // DO NOT PORT TO FORCEMOVE - MEMECODE WILL KILL MC - orbiter.loc = targetloc - orbiter.update_parallax_contents() - orbiter.update_light() - lastloc = orbiter.loc - for(var/other_orbit in orbiter.orbiters) - var/datum/orbit/OO = other_orbit - //Skip if checked already - if(checked_already[OO]) - continue - OO.Check(targetloc, checked_already) - -/atom/movable/var/datum/orbit/orbiting = null -/atom/var/list/orbiters = null - -//A: atom to orbit -//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) -//clockwise: whether you orbit clockwise or anti clockwise -//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) -//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. -//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts -//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) - -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) - if (!istype(A)) - return - - new/datum/orbit(src, A, lockinorbit) - if (!orbiting) //something failed, and our orbit datum deleted itself - return - var/matrix/initial_transform = matrix(transform) - - //Head first! - if (pre_rotation) - var/matrix/M = matrix(transform) - var/pre_rot = 90 - if(!clockwise) - pre_rot = -90 - M.Turn(pre_rot) - transform = M - - var/matrix/shift = matrix(transform) - shift.Translate(0,radius) - transform = shift - - SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) - - //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit - transform = initial_transform - -/atom/movable/proc/stop_orbit() - SpinAnimation(0,0) - qdel(orbiting) - -/atom/Destroy(force = FALSE) - . = ..() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - if (O.orbiter) - O.orbiter.stop_orbit() - -/atom/movable/Destroy(force = FALSE) - . = ..() - if (orbiting) - stop_orbit() - -/atom/movable/proc/transfer_observers_to(atom/movable/target) - if(orbiters) - for(var/thing in orbiters) - var/datum/orbit/O = thing - if(O.orbiter && isobserver(O.orbiter)) - var/mob/dead/observer/D = O.orbiter - D.ManualFollow(target) 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..4b08ccf608 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -1,3 +1,4 @@ + /obj/item/paperplane name = "paper plane" desc = "Paper, folded in the shape of a plane." @@ -10,8 +11,14 @@ resistance_flags = FLAMMABLE max_integrity = 50 + var/hit_probability = 2//% var/obj/item/paper/internalPaper +/obj/item/paperplane/origami + desc = "Paper, masterfully folded in the shape of a plane." + throwforce = 20 //same as throwing stars, but no chance of embedding. + hit_probability = 100 //guaranteed to cause eye damage when it hits a mob. + /obj/item/paperplane/Initialize(mapload, obj/item/paper/newPaper) . = ..() pixel_y = rand(-8, 8) @@ -22,13 +29,18 @@ color = newPaper.color newPaper.forceMove(src) else - internalPaper = new /obj/item/paper(src) + internalPaper = new(src) update_icon() -/obj/item/paperplane/Destroy() - if(internalPaper) - qdel(internalPaper) +/obj/item/paperplane/handle_atom_del(atom/A) + if(A == internalPaper) internalPaper = null + if(!QDELETED(src)) + qdel(src) + return ..() + +/obj/item/paperplane/Destroy() + QDEL_NULL(internalPaper) return ..() /obj/item/paperplane/suicide_act(mob/living/user) @@ -48,7 +60,7 @@ /obj/item/paperplane/attack_self(mob/user) to_chat(user, "You unfold [src].") - var/atom/movable/internal_paper_tmp = internalPaper + var/obj/item/paper/internal_paper_tmp = internalPaper internal_paper_tmp.forceMove(loc) internalPaper = null qdel(src) @@ -65,7 +77,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) @@ -86,11 +98,18 @@ . = ..(target, range, speed, thrower, FALSE, diagonals_first, callback) /obj/item/paperplane/throw_impact(atom/hit_atom) + if(iscarbon(hit_atom)) + var/mob/living/carbon/C = hit_atom + if(C.can_catch_item(TRUE)) + var/datum/action/innate/origami/origami_action = locate() in C.actions + if(origami_action?.active) //if they're a master of origami and have the ability turned on, force throwmode on so they'll automatically catch the plane. + C.throw_mode_on() + if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman return var/mob/living/carbon/human/H = hit_atom - if(prob(2)) - if((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) + if(prob(hit_probability)) + if(H.is_eyes_covered()) return visible_message("\The [src] hits [H] in the eye!") H.adjust_blurriness(6) @@ -103,9 +122,15 @@ to_chat(user, "Alt-click [src] to fold it into a paper plane.") /obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I) - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK)) return to_chat(user, "You fold [src] into the shape of a plane!") user.temporarilyRemoveItemFromInventory(src) - I = new /obj/item/paperplane(user, src) + var/obj/item/paperplane/plane_type = /obj/item/paperplane + //Origami Master + var/datum/action/innate/origami/origami_action = locate() in user.actions + if(origami_action?.active) + plane_type = /obj/item/paperplane/origami + + I = new plane_type(user, src) user.put_in_hands(I) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index c99b094ab0..a5900aa196 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -25,7 +25,6 @@ pressure_resistance = 2 grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! - var/traitor_unlock_degrees = 0 var/degrees = 0 var/font = PEN_FONT @@ -151,9 +150,6 @@ /* * Sleepypens */ -/obj/item/pen/sleepy - container_type = OPENCONTAINER - /obj/item/pen/sleepy/attack(mob/living/M, mob/user) if(!istype(M)) @@ -167,7 +163,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 9fcdf091a1..3e93d9f42b 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -20,15 +20,15 @@ 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 /obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge) . = ..() - START_PROCESSING(SSobj, src) - create_reagents(5) + if(self_recharge) + START_PROCESSING(SSobj, src) + create_reagents(5, INJECTABLE | DRAINABLE) if (override_maxcharge) maxcharge = override_maxcharge charge = maxcharge @@ -70,8 +70,8 @@ return 100*charge/maxcharge // use power from a cell -/obj/item/stock_parts/cell/use(amount) - if(rigged && amount > 0) +/obj/item/stock_parts/cell/use(amount, can_explode = TRUE) + if(rigged && amount > 0 && can_explode) explode() return 0 if(charge < amount) @@ -104,9 +104,8 @@ return (FIRELOSS) /obj/item/stock_parts/cell/on_reagent_change(changetype) - rigged = !isnull(reagents.has_reagent("plasma", 5)) //has_reagent returns the reagent datum ..() - + rigged = reagents?.has_reagent("plasma", 5) ? TRUE : FALSE //has_reagent returns the reagent datum /obj/item/stock_parts/cell/proc/explode() var/turf/T = get_turf(src.loc) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 1c05b6c11a..f82f0ee8e6 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -89,7 +89,7 @@ if(!cell_connectors) to_chat(user, "This [name] can't support a power cell!") return - if(W.item_flags & NODROP) + if(HAS_TRAIT(W, TRAIT_NODROP)) to_chat(user, "[W] is stuck to your hand!") return user.dropItemToGround(W) @@ -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/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index a04ed08611..d805713fa6 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -90,7 +90,7 @@ /obj/machinery/power/emitter/ComponentInitialize() . = ..() - AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_FLIP ,null,CALLBACK(src, .proc/can_be_rotated)) + AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, null, CALLBACK(src, .proc/can_be_rotated)) /obj/machinery/power/emitter/proc/can_be_rotated(mob/user,rotation_type) if (anchored) @@ -440,10 +440,14 @@ name = "turret controls" icon_state = "offhand" w_class = WEIGHT_CLASS_HUGE - item_flags = ABSTRACT | NODROP | NOBLUDGEON + item_flags = ABSTRACT | NOBLUDGEON resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/delay = 0 +/obj/item/turret_control/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/turret_control/afterattack(atom/targeted_atom, mob/user, proxflag, clickparams) . = ..() var/obj/machinery/power/emitter/E = user.buckled @@ -495,4 +499,4 @@ #undef EMITTER_UNWRENCHED #undef EMITTER_WRENCHED -#undef EMITTER_WELDED \ No newline at end of file +#undef EMITTER_WELDED diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index ad94d577ea..026c39c6cf 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -184,9 +184,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) to_chat(H, "You get headaches just from looking at it.") return -/obj/machinery/power/supermatter_crystal/get_spans() - return list(SPAN_ROBOT) - #define CRITICAL_TEMPERATURE 10000 /obj/machinery/power/supermatter_crystal/proc/get_status() @@ -244,10 +241,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) add_overlay(causality_field, TRUE) var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated." - radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + radio.talk_into(src, speaking, common_channel, language = get_default_language()) for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10) if(damage < explosion_point) // Cutting it a bit close there engineers - radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel) cut_overlay(causality_field, TRUE) final_countdown = FALSE return @@ -258,7 +255,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) speaking = "[DisplayTimeText(i, TRUE)] remain before causality stabilization." else speaking = "[i*0.1]..." - radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + radio.talk_into(src, speaking, common_channel) sleep(10) explode() @@ -295,6 +292,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 +310,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 +348,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 +408,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) @@ -448,27 +456,27 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) alarm() if(damage > emergency_point) - radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel) lastwarning = REALTIMEOFDAY if(!has_reached_emergency) investigate_log("has reached the emergency point for the first time.", INVESTIGATE_SUPERMATTER) message_admins("[src] has reached the emergency point [ADMIN_JMP(src)].") has_reached_emergency = TRUE else if(damage >= damage_archived) // The damage is still going up - radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel) lastwarning = REALTIMEOFDAY - (WARNING_DELAY * 5) else // Phew, we're safe - radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel) lastwarning = REALTIMEOFDAY if(power > POWER_PENALTY_THRESHOLD) - radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel) if(powerloss_inhibitor < 0.5) - radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel) if(combined_gas > MOLE_PENALTY_THRESHOLD) - radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel) if(damage > explosion_point) countdown() @@ -642,6 +650,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) else L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", 2) +//Do not blow up our internal radio +/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target) + return + +/obj/machinery/power/supermatter_crystal/prevent_content_explosion() + return TRUE + /obj/machinery/power/supermatter_crystal/engine is_main_engine = TRUE diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 0a54bcab33..bbad3e08b0 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -33,8 +33,8 @@ return /obj/singularity/energy_ball/Destroy() - if(orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/EB = orbiting.orbiting + if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/EB = orbiting.parent EB.orbiting_balls -= src for(var/ball in orbiting_balls) @@ -146,12 +146,12 @@ . = ..() /obj/singularity/energy_ball/stop_orbit() - if (orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/orbitingball = orbiting.orbiting + if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/orbitingball = orbiting.parent orbitingball.orbiting_balls -= src orbitingball.dissipate_strength = orbitingball.orbiting_balls.len - ..() - if (!loc && !QDELETED(src)) + . = ..() + if (!QDELETED(src)) qdel(src) 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/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm index 154d269cd9..a6b65f79e3 100644 --- a/code/modules/projectiles/ammunition/caseless/_caseless.dm +++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm @@ -6,9 +6,10 @@ /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing moveToNullspace() - return 1 + QDEL_NULL(src) + return TRUE else - return 0 + return FALSE /obj/item/ammo_casing/caseless/update_icon() ..() diff --git a/code/modules/projectiles/ammunition/caseless/rocket.dm b/code/modules/projectiles/ammunition/caseless/rocket.dm index 0b74f6ff8c..9d6befce53 100644 --- a/code/modules/projectiles/ammunition/caseless/rocket.dm +++ b/code/modules/projectiles/ammunition/caseless/rocket.dm @@ -1,5 +1,13 @@ -/obj/item/ammo_casing/caseless/a84mm - desc = "An 84mm anti-armour rocket." +/obj/item/ammo_casing/caseless/rocket + name = "\improper PM-9HE" + desc = "An 84mm High Explosive rocket. Fire at people and pray." + caliber = "84mm" + icon_state = "srm-8" + projectile_type = /obj/item/projectile/bullet/a84mm_he + +/obj/item/ammo_casing/caseless/rocket/hedp + name = "\improper PM-9HEDP" + desc = "An 84mm High Explosive Dual Purpose rocket. Pointy end toward mechs." caliber = "84mm" icon_state = "s-casing-live" projectile_type = /obj/item/projectile/bullet/a84mm diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm index 9b24571d12..c9e60ddc1d 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.5 diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 4a2a354ca6..d5cba6936f 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -59,3 +59,20 @@ S.forceMove(D) D.injector = S ..() + +/obj/item/ammo_casing/syringegun/dart + name = "used air canister" + desc = "A small canister of compressed gas." + projectile_type = /obj/item/projectile/bullet/dart/syringe/dart + firing_effect_type = null + harmful = FALSE + +/obj/item/ammo_casing/syringegun/dart/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/gun/syringe/SG = loc + if(!SG.syringes.len) + return + var/obj/item/reagent_containers/syringe/dart/S = SG.syringes[1] + if(S.emptrig == TRUE) + var/obj/item/projectile/bullet/dart/syringe/dart/D = BB + D.emptrig = TRUE diff --git a/code/modules/projectiles/boxes_magazines/internal/grenade.dm b/code/modules/projectiles/boxes_magazines/internal/grenade.dm index 12325a0299..352d1eb951 100644 --- a/code/modules/projectiles/boxes_magazines/internal/grenade.dm +++ b/code/modules/projectiles/boxes_magazines/internal/grenade.dm @@ -12,6 +12,6 @@ /obj/item/ammo_box/magazine/internal/rocketlauncher name = "grenade launcher internal magazine" - ammo_type = /obj/item/ammo_casing/caseless/a84mm + ammo_type = /obj/item/ammo_casing/caseless/rocket caliber = "84mm" max_ammo = 1 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..98fd774d63 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) @@ -170,7 +170,7 @@ return if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item()) - to_chat(user, "You need both hands free to fire [src]!") + to_chat(user, "You need both hands free to fire \the [src]!") return //DUAL (or more!) WIELDING @@ -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 @@ -422,7 +422,7 @@ if(alight) alight.Remove(user) -/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params) +/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) if(!ishuman(user) || !ishuman(target)) return @@ -438,7 +438,7 @@ semicd = TRUE - if(!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH) + if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH)) if(user) if(user == target) user.visible_message("[user] decided not to shoot.") diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 157cf1f03f..1117bc1000 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -7,6 +7,7 @@ var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine var/casing_ejector = TRUE //whether the gun ejects the chambered casing + var/magazine_wording = "magazine" /obj/item/gun/ballistic/Initialize() . = ..() @@ -57,7 +58,7 @@ if (!magazine && istype(AM, mag_type)) if(user.transferItemToLoc(AM, src)) magazine = AM - to_chat(user, "You load a new magazine into \the [src].") + to_chat(user, "You load a new [magazine_wording] into \the [src].") if(magazine.ammo_count()) playsound(src, "gun_insert_full_magazine", 70, 1) if(!chambered) @@ -72,7 +73,7 @@ to_chat(user, "You cannot seem to get \the [src] out of your hands!") return else if (magazine) - to_chat(user, "There's already a magazine in \the [src].") + to_chat(user, "There's already a [magazine_wording] in \the [src].") if(istype(A, /obj/item/suppressor)) var/obj/item/suppressor/S = A if(!can_suppress) @@ -222,7 +223,7 @@ /obj/item/suppressor name = "suppressor" - desc = "A universal syndicate small-arms suppressor for maximum espionage." + desc = "A syndicate small-arms suppressor for maximum espionage." icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" w_class = WEIGHT_CLASS_TINY @@ -231,6 +232,4 @@ /obj/item/suppressor/specialoffer name = "cheap suppressor" - desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." - icon = 'icons/obj/guns/projectile.dmi' - icon_state = "suppressor" + desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits some weapons." 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/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index aacdd46059..eea4e1bc0b 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -74,25 +74,91 @@ update_icon() chamber_round() -/obj/item/gun/ballistic/automatic/atlauncher - desc = "A pre-loaded, single shot anti-armour launcher." - name = "anti-armour grenade launcher" +/obj/item/gun/ballistic/rocketlauncher + name = "\improper PML-9" + desc = "A reusable rocket propelled grenade launcher. The words \"NT this way\" and an arrow have been written near the barrel." icon_state = "rocketlauncher" item_state = "rocketlauncher" mag_type = /obj/item/ammo_box/magazine/internal/rocketlauncher fire_sound = 'sound/weapons/rocketlaunch.ogg' w_class = WEIGHT_CLASS_BULKY can_suppress = FALSE + pin = /obj/item/firing_pin/implant/pindicate burst_size = 1 fire_delay = 0 - select = 0 - actions_types = list() casing_ejector = FALSE weapon_weight = WEAPON_HEAVY + magazine_wording = "rocket" -/obj/item/gun/ballistic/automatic/atlauncher/attack_self() - return +/obj/item/gun/ballistic/rocketlauncher/unrestricted + pin = /obj/item/firing_pin -/obj/item/gun/ballistic/automatic/atlauncher/update_icon() - ..() - icon_state = "rocketlauncher[magazine ? "-[get_ammo(1)]" : ""]" \ No newline at end of file +/obj/item/gun/ballistic/rocketlauncher/handle_atom_del(atom/A) + if(A == chambered) + chambered = null + if(!QDELETED(magazine)) + QDEL_NULL(magazine) + if(A == magazine) + magazine = null + if(!QDELETED(chambered)) + QDEL_NULL(chambered) + update_icon() + return ..() + +/obj/item/gun/ballistic/rocketlauncher/can_shoot() + return chambered?.BB + +/obj/item/gun/ballistic/rocketlauncher/process_chamber() + if(chambered) + chambered = null + if(magazine) + QDEL_NULL(magazine) + update_icon() + +/obj/item/gun/ballistic/rocketlauncher/attack_self_tk(mob/user) + return //too difficult to remove the rocket with TK + +/obj/item/gun/ballistic/rocketlauncher/attack_self(mob/living/user) + if(magazine) + if(chambered) + chambered.forceMove(magazine) + magazine.stored_ammo.Insert(1, chambered) + chambered = null + else + stack_trace("Removed [magazine] from [src] without a chambered round") + magazine.forceMove(drop_location()) + if(user.is_holding(src)) + user.put_in_hands(magazine) + playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, TRUE) + to_chat(user, "You work the [magazine] out from [src].") + magazine = null + else + to_chat(user, "There's no rocket in [src].") + update_icon() + +/obj/item/gun/ballistic/rocketlauncher/update_icon() + icon_state = "[initial(icon_state)]-[chambered ? "1" : "0"]" + +/obj/item/gun/ballistic/rocketlauncher/suicide_act(mob/living/user) + user.visible_message("[user] aims [src] at the ground! It looks like [user.p_theyre()] performing a sick rocket jump!", \ + "You aim [src] at the ground to perform a bisnasty rocket jump...") + if(can_shoot()) + user.notransform = TRUE + playsound(src, 'sound/vehicles/rocketlaunch.ogg', 80, 1, 5) + animate(user, pixel_z = 300, time = 30, easing = LINEAR_EASING) + sleep(70) + animate(user, pixel_z = 0, time = 5, easing = LINEAR_EASING) + sleep(5) + user.notransform = FALSE + process_fire(user, user, TRUE) + if(!QDELETED(user)) //if they weren't gibbed by the explosion, take care of them for good. + user.gib() + return MANUAL_SUICIDE + else + sleep(5) + shoot_with_empty_chamber(user) + sleep(20) + user.visible_message("[user] looks about the room realizing [user.p_theyre()] still there. [user.p_they(TRUE)] proceed to shove [src] down their throat and choke [user.p_them()]self with it!", \ + "You look around after realizing you're still here, then proceed to choke yourself to death with [src]!") + sleep(20) + return OXYLOSS 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 914f9bc016..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) @@ -117,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) @@ -137,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." @@ -153,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() @@ -207,7 +211,6 @@ "Slick" = "cshotgun_slick" ) - /obj/item/gun/ballistic/shotgun/automatic/combat/compact name = "compact combat shotgun" desc = "A compact version of the semi automatic combat shotgun. For close encounters." @@ -218,7 +221,6 @@ "Slick" = "cshotgunc_slick" ) - //Dual Feed Shotgun /obj/item/gun/ballistic/shotgun/automatic/dual_tube @@ -261,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/special.dm b/code/modules/projectiles/guns/energy/special.dm index c6f0956880..6e2c9dc62a 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -243,7 +243,7 @@ /obj/item/gun/energy/printer name = "cyborg lmg" - desc = "A machinegun that fires 3d-printed flechettes slowly regenerated using a cyborg's internal power source." + desc = "A LMG that fires 3D-printed flechettes. They are slowly resupplied using the cyborg's internal power source." icon_state = "l6closed0" icon = 'icons/obj/guns/projectile.dmi' cell_type = "/obj/item/stock_parts/cell/secborg" 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/guns/misc/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm index 17c0f63955..7bdefe5e91 100644 --- a/code/modules/projectiles/guns/misc/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -116,7 +116,7 @@ new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") target.adjustBruteLoss(-4) target.adjustFireLoss(-4) - target.adjustToxLoss(-1) + target.adjustToxLoss(-1, forced = TRUE) target.adjustOxyLoss(-1) return diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index cc1b321e3a..26e66b1987 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -102,3 +102,23 @@ else to_chat(user, "[src] cannot hold more syringes!") return FALSE + +/obj/item/gun/syringe/dart + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + icon_state = "dartgun" + item_state = "dartgun" + materials = list(MAT_METAL=2000, MAT_GLASS=500) + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE + +/obj/item/gun/syringe/dart/Initialize() + ..() + chambered = new /obj/item/ammo_casing/syringegun/dart(src) + +/obj/item/gun/syringe/dart/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/reagent_containers/syringe/dart)) + ..() + else + to_chat(user, "You can't put the [A] into \the [src]!") + return FALSE 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..bdbf706448 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -6,15 +6,16 @@ /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) +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE, skip = FALSE) if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) // not completely blocked if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..() + if(skip == TRUE) + return reagents.reaction(M, INJECT) reagents.trans_to(M, reagents.total_volume) return TRUE @@ -24,7 +25,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 @@ -37,3 +38,44 @@ /obj/item/projectile/bullet/dart/syringe name = "syringe" icon_state = "syringeproj" + +//I am in a mess of my own making +/obj/item/projectile/bullet/dart/syringe/dart + name = "Smartdart" + icon_state = "dartproj" + damage = 0 + var/emptrig = FALSE + +/obj/item/projectile/bullet/dart/syringe/dart/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..(target, blocked, TRUE) + for(var/datum/reagent/R in reagents.reagent_list) //OD prevention time! + if(istype(R, /datum/reagent/medicine)) //Is this a medicine? + if(M.reagents.has_reagent(R.id)) + if(R.overdose_threshold == 0 || emptrig == TRUE) //Is there a possible OD? + M.reagents.add_reagent(R.id, R.volume) + else + var/transVol = CLAMP(R.volume, 0, (R.overdose_threshold - M.reagents.get_reagent_amount(R.id)) -1) + M.reagents.add_reagent(R.id, transVol) + else + if(!R.overdose_threshold == 0) + var/transVol = CLAMP(R.volume, 0, R.overdose_threshold-1) + M.reagents.add_reagent(R.id, transVol) + else + M.reagents.add_reagent(R.id, R.volume) + + + + target.visible_message("\The [src] beeps!") + to_chat("You feel a tiny prick as a smartdart embeds itself in you with a beep.") + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You see a [src] bounce off you, booping sadly!") + + target.visible_message("\The [src] fails to land on target!") + 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/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index 6518b2a4d5..a62fa25f7d 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -9,9 +9,9 @@ return TRUE /obj/item/projectile/bullet/a84mm - name ="anti-armour rocket" + name ="\improper HEDP rocket" desc = "USE A WEEL GUN" - icon_state= "atrocket" + icon_state= "84mm-hedp" damage = 80 var/anti_armour_damage = 200 armour_penetration = 100 @@ -29,17 +29,17 @@ S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25) return TRUE -/obj/item/projectile/bullet/srmrocket - name ="SRM-8 Rocket" +/obj/item/projectile/bullet/a84mm_he + name ="\improper HE missile" desc = "Boom." icon_state = "missile" damage = 30 ricochets_max = 0 //it's a MISSILE -/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) +/obj/item/projectile/bullet/a84mm_he/on_hit(atom/target, blocked=0) ..() if(!isliving(target)) //if the target isn't alive, so is a wall or something explosion(target, 0, 1, 2, 4) else explosion(target, 0, 0, 2, 4) - return TRUE + return TRUE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 442ef191a9..dc86ab4e6c 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -21,7 +21,9 @@ if(GLOB.chemical_reactions_list) return - var/paths = subtypesof(/datum/chemical_reaction) + + //Randomized need to go last since they need to check against conflicts with normal recipes + var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) GLOB.chemical_reactions_list = list() for(var/path in paths) @@ -29,6 +31,9 @@ var/datum/chemical_reaction/D = new path() var/list/reaction_ids = list() + if(!D.id) + continue + if(D.required_reagents && D.required_reagents.len) for(var/reaction in D.required_reagents) reaction_ids += reaction @@ -53,7 +58,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 +67,8 @@ if(!GLOB.chemical_reactions_list) build_chemical_reactions_list() + reagents_holder_flags = new_flags + /datum/reagents/Destroy() . = ..() var/list/cached_reagents = reagent_list @@ -265,6 +272,9 @@ continue if(!C) C = R.holder.my_atom + if(!R.metabolizing) + R.metabolizing = TRUE + R.on_mob_metabolize(C) if(C && R) if(C.reagent_check(R) != 1) if(can_overdose) @@ -311,12 +321,20 @@ 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 +//Signals that metabolization has stopped, triggering the end of trait-based effects +/datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE) + var/list/cached_reagents = reagent_list + for(var/reagent in cached_reagents) + var/datum/reagent/R = reagent + if(QDELETED(R.holder)) + continue + if(keep_liverless && R.self_consuming) //Will keep working without a liver + continue + if(!C) + C = R.holder.my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(C) /datum/reagents/proc/conditional_update_move(atom/A, Running = 0) var/list/cached_reagents = reagent_list @@ -333,11 +351,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 @@ -471,6 +489,9 @@ if(R.id == reagent) if(my_atom && isliving(my_atom)) var/mob/living/M = my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(M) R.on_mob_delete(M) qdel(R) reagent_list -= R @@ -555,7 +576,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 +620,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 +821,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/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 10282e5e0a..fa9d60a219 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -9,7 +9,6 @@ interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/chem_dispenser - var/cell_type = /obj/item/stock_parts/cell/high var/obj/item/stock_parts/cell/cell var/powerefficiency = 0.1 var/amount = 30 @@ -52,7 +51,8 @@ //these become available once upgraded. var/list/upgrade_reagents = list( "oil", - "ammonia" + "ammonia", + "ash" ) var/list/upgrade_reagents2 = list( @@ -79,7 +79,6 @@ /obj/machinery/chem_dispenser/Initialize() . = ..() - cell = new cell_type dispensable_reagents = sortList(dispensable_reagents) update_icon() @@ -250,13 +249,8 @@ work_animation() . = TRUE if("eject") - if(beaker) - beaker.forceMove(drop_location()) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(beaker) - beaker = null - update_icon() - . = TRUE + replace_beaker(usr) + . = TRUE //no afterattack if("dispense_recipe") if(!is_operational() || QDELETED(cell)) return @@ -269,7 +263,7 @@ if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine var/datum/reagents/R = beaker.reagents var/free = R.maximum_volume - R.total_volume - var/actual = min(round(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free) + var/actual = min(max(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free) if(actual) if(!cell.use(actual / powerefficiency)) say("Not enough energy to complete operation!") @@ -322,14 +316,12 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) var/obj/item/reagent_containers/B = I - . = 1 //no afterattack - if(beaker) - to_chat(user, "A container is already loaded into [src]!") - return + . = TRUE //no afterattack if(!user.transferItemToLoc(B, src)) return - beaker = B + replace_beaker(user, B) to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag)) to_chat(user, "You can't load [I] into [src]!") @@ -381,7 +373,17 @@ dispensable_reagents |= upgrade_reagents3 powerefficiency = round(newpowereff, 0.01) - +/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE /obj/machinery/chem_dispenser/on_deconstruction() cell = null @@ -417,6 +419,12 @@ final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2])) return final_list +/obj/machinery/chem_dispenser/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + /obj/machinery/chem_dispenser/drinks/Initialize() . = ..() AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE) @@ -480,9 +488,16 @@ "tomatojuice", "lemonjuice", "menthol" - ) //prevents the soda machine from obtaining chemical upgrades. . - upgrade_reagents = null - upgrade_reagents2 = null + ) + upgrade_reagents = list( + "mushroomhallucinogen", + "nothing", + "cryoxadone" + ) + upgrade_reagents2 = list( + "banana", + "berryjuice" + ) upgrade_reagents3 = null emagged_reagents = list( "thirteenloko", @@ -534,19 +549,21 @@ "creme_de_menthe", "creme_de_cacao", "triple_sec", - "sake" - )//prevents the booze machine from obtaining chemical upgrades. - upgrade_reagents = null + "sake", + "applejack" + ) + upgrade_reagents = list( + "ethanol", + "fernet" + ) upgrade_reagents2 = null upgrade_reagents3 = null emagged_reagents = list( - "ethanol", "iron", "alexander", "clownstears", "minttoxin", "atomicbomb", - "fernet", "aphro", "aphro+" ) diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index e4c6966cff..a17b1e8190 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -28,13 +28,23 @@ else icon_state = "mixer0b" -/obj/machinery/chem_heater/proc/eject_beaker(mob/user) +/obj/machinery/chem_heater/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + +/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) + if(user && Adjacent(user) && !issiliconoradminghost(user)) user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else beaker = null update_icon() + return TRUE /obj/machinery/chem_heater/RefreshParts() heater_coefficient = 0.1 @@ -58,21 +68,19 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - . = 1 //no afterattack - if(beaker) - to_chat(user, "A container is already loaded into [src]!") + . = TRUE //no afterattack + var/obj/item/reagent_containers/B = I + if(!user.transferItemToLoc(B, src)) return - - if(!user.transferItemToLoc(I, src)) - return - beaker = I - to_chat(user, "You add [I] to [src].") + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() return return ..() /obj/machinery/chem_heater/on_deconstruction() - eject_beaker() + replace_beaker() return ..() /obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ @@ -122,5 +130,5 @@ target_temperature = CLAMP(target, 0, 1000) if("eject") on = FALSE - eject_beaker(usr) + replace_beaker(usr) . = TRUE diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 6327c5ba3a..6401a78141 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -1,3 +1,6 @@ +#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die +#define RANDOM_PILL_STYLE 22 //Dont change this one though + /obj/machinery/chem_master name = "ChemMaster 3000" desc = "Used to separate chemicals and distribute them in a variety of forms." @@ -13,12 +16,24 @@ var/obj/item/storage/pill_bottle/bottle = null var/mode = 1 var/condi = FALSE + var/chosenPillStyle = 1 var/screen = "home" var/analyzeVars[0] var/useramount = 30 // Last used amount + var/list/pillStyles /obj/machinery/chem_master/Initialize() create_reagents(100) + + //Calculate the span tags and ids fo all the available pill icons + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + pillStyles = list() + for (var/x in 1 to PILL_STYLE_COUNT) + var/list/SL = list() + SL["id"] = x + SL["htmltag"] = assets.icon_tag("pill[x]") + pillStyles += list(SL) + . = ..() /obj/machinery/chem_master/Destroy() @@ -60,16 +75,6 @@ else icon_state = "mixer0" -/obj/machinery/chem_master/proc/eject_beaker(mob/user) - if(beaker) - beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(beaker) - else - adjust_item_drop_location(beaker) - beaker = null - update_icon() - /obj/machinery/chem_master/blob_act(obj/structure/blob/B) if (prob(50)) qdel(src) @@ -85,36 +90,49 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - . = 1 // no afterattack + . = TRUE // no afterattack if(panel_open) to_chat(user, "You can't use the [src.name] while its panel is opened!") return - if(beaker) - to_chat(user, "A container is already loaded into [src]!") + var/obj/item/reagent_containers/B = I + if(!user.transferItemToLoc(B, src)) return - if(!user.transferItemToLoc(I, src)) - return - - beaker = I - to_chat(user, "You add [I] to [src].") - src.updateUsrDialog() + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() - else if(!condi && istype(I, /obj/item/storage/pill_bottle)) if(bottle) to_chat(user, "A pill bottle is already loaded into [src]!") return if(!user.transferItemToLoc(I, src)) return - bottle = I to_chat(user, "You add [I] into the dispenser slot.") - src.updateUsrDialog() + updateUsrDialog() else return ..() +/obj/machinery/chem_master/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + +/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE + /obj/machinery/chem_master/on_deconstruction() - eject_beaker() + replace_beaker(usr) if(bottle) bottle.forceMove(drop_location()) adjust_item_drop_location(bottle) @@ -125,9 +143,15 @@ 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) + var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + assets.send(user) ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state) ui.open() +//Insert our custom spritesheet css link into the html +/obj/machinery/chem_master/ui_base_html(html) + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + . = replacetext(html, "", assets.css_tag()) /obj/machinery/chem_master/ui_data(mob/user) var/list/data = list() @@ -138,7 +162,7 @@ data["condi"] = condi data["screen"] = screen data["analyzeVars"] = analyzeVars - + data["chosenPillStyle"] = chosenPillStyle data["isPillBottleLoaded"] = bottle ? 1 : 0 if(bottle) GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) @@ -157,6 +181,9 @@ bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^ data["bufferContents"] = bufferContents + //Calculated at init time as it never changes + data["pillStyles"] = pillStyles + return data /obj/machinery/chem_master/ui_act(action, params) @@ -164,7 +191,7 @@ return switch(action) if("eject") - eject_beaker(usr) + replace_beaker(usr) . = TRUE if("ejectp") @@ -231,6 +258,12 @@ else P = new(drop_location()) P.name = trim("[name] pill") + if(chosenPillStyle == RANDOM_PILL_STYLE) + P.icon_state ="pill[rand(1,21)]" + else + P.icon_state = "pill[chosenPillStyle]" + if(P.icon_state == "pill4") + P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality." adjust_item_drop_location(P) reagents.trans_to(P,vol_each) else @@ -245,6 +278,10 @@ reagents.trans_to(P,10) . = TRUE + if("pillStyle") + var/id = text2num(params["id"]) + chosenPillStyle = id + if("createPatch") var/many = params["many"] if(reagents.total_volume == 0) @@ -393,3 +430,6 @@ name = "CondiMaster 3000" desc = "Used to create condiments and other cooking supplies." condi = TRUE + +#undef PILL_STYLE_COUNT +#undef RANDOM_PILL_STYLE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 5c39cd9db2..1847f1f722 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -19,6 +19,12 @@ var/speed = 1 var/list/holdingitems + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") + var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") + var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + /obj/machinery/reagentgrinder/Initialize() . = ..() holdingitems = list() @@ -51,7 +57,6 @@ if(A == beaker) beaker = null update_icon() - updateUsrDialog() if(holdingitems[A]) holdingitems -= A @@ -67,6 +72,18 @@ else icon_state = "juicer0" +/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE + /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) //You can only screw open empty grinder if(!beaker && !length(holdingitems) && default_deconstruction_screwdriver(user, icon_state, icon_state, I)) @@ -82,17 +99,14 @@ return TRUE if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - if (!beaker) - if(!user.transferItemToLoc(I, src)) - to_chat(user, "[I] is stuck to your hand!") - return TRUE - to_chat(user, "You slide [I] into [src].") - beaker = I - update_icon() - updateUsrDialog() - else - to_chat(user, "There's already a container inside [src].") - return TRUE //no afterattack + var/obj/item/reagent_containers/B = I + . = TRUE + if(!user.transferItemToLoc(B, src)) + return + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + update_icon() + return if(holdingitems.len >= limit) to_chat(user, "[src] is filled to capacity!") @@ -108,8 +122,6 @@ to_chat(user, "You empty [I] into [src].") else to_chat(user, "You fill [src] to the brim.") - - updateUsrDialog() return TRUE if(!I.grind_results && !I.juice_results) @@ -125,104 +137,89 @@ if(user.transferItemToLoc(I, src)) to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE - updateUsrDialog() return FALSE /obj/machinery/reagentgrinder/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave . = ..() - var/is_chamber_empty = FALSE - var/is_beaker_ready = FALSE - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" - if(!operating) - for (var/i in holdingitems) - var/obj/item/O = i - processing_chamber += "\A [O.name]
    " + if(operating || !user.canUseTopic(src, !issilicon(user))) + return - if (!processing_chamber) - is_chamber_empty = TRUE - processing_chamber = "Nothing." - if (!beaker) - beaker_contents = "No beaker attached.
    " - else - is_beaker_ready = TRUE - beaker_contents = "The beaker contains:
    " - var/anything = FALSE - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = TRUE - beaker_contents += "[R.volume] - [R.name]
    " - if(!anything) - beaker_contents += "Nothing
    " + var/list/options = list() - dat = {" - Processing chamber contains:
    - [processing_chamber]
    - [beaker_contents]
    - "} - if (is_beaker_ready) - if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
    " - dat += "Juice the reagents

    " - else if (beaker.reagents.total_volume) - dat += "Mix the reagents

    " - if(length(holdingitems)) - dat += "Eject the reagents
    " - if(beaker) - dat += "Detach the beaker
    " + if(beaker || length(holdingitems)) + options["eject"] = radial_eject + + if(isAI(user)) + if(stat & NOPOWER) + return + options["examine"] = radial_examine + + // if there is no power or it's broken, the procs will fail but the buttons will still show + if(length(holdingitems)) + options["grind"] = radial_grind + options["juice"] = radial_juice + else if(beaker?.reagents.total_volume) + options["mix"] = radial_mix + + var/choice + + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key else - dat += "Please wait..." + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) - var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open(1) - return + // post choice verification + if(operating || (isAI(user) && stat & NOPOWER) || !user.canUseTopic(src, !issilicon(user))) + return -/obj/machinery/reagentgrinder/Topic(href, href_list) - if(..()) - return - var/mob/user = usr - if(!user.canUseTopic(src)) - return - if(stat & (NOPOWER|BROKEN)) - return - user.set_machine(src) - if(operating) - updateUsrDialog() - return - switch(href_list["action"]) - if ("grind") + switch(choice) + if("eject") + eject(user) + if("grind") grind(user) if("juice") juice(user) if("mix") mix(user) - if("eject") - eject(user) - if("detach") - detach(user) - updateUsrDialog() + if("examine") + examine(user) -/obj/machinery/reagentgrinder/proc/detach(mob/user) - if(!beaker) +/obj/machinery/reagentgrinder/examine(mob/user) + . = ..() + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + to_chat(user, "You're too far away to examine [src]'s contents and display!") return - beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(beaker) - beaker = null - update_icon() - updateUsrDialog() + + if(operating) + to_chat(user, "\The [src] is operating.") + return + + if(beaker || length(holdingitems)) + to_chat(user, "\The [src] contains:") + if(beaker) + to_chat(user, "- \A [beaker].") + for(var/i in holdingitems) + var/obj/item/O = i + to_chat(user, "- \A [O.name].") + + if(!(stat & (NOPOWER|BROKEN))) + to_chat(user, "The status display reads:") + to_chat(user, "- Grinding reagents at [speed*100]%.") + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + to_chat(user, "- [R.volume] units of [R.name].") /obj/machinery/reagentgrinder/proc/eject(mob/user) - if(!length(holdingitems)) - return for(var/i in holdingitems) var/obj/item/O = i O.forceMove(drop_location()) holdingitems -= O - updateUsrDialog() + if(beaker) + replace_beaker(user) /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O @@ -240,7 +237,6 @@ /obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE) shake_for(time / speed) - updateUsrDialog() operating = TRUE if(!silent) if(!juicing) @@ -251,11 +247,10 @@ /obj/machinery/reagentgrinder/proc/stop_operating() operating = FALSE - updateUsrDialog() /obj/machinery/reagentgrinder/proc/juice() power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume) return operate_for(50, juicing = TRUE) for(var/obj/item/i in holdingitems) @@ -274,7 +269,7 @@ /obj/machinery/reagentgrinder/proc/grind() power_change() - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume) return operate_for(60) for(var/i in holdingitems) @@ -296,13 +291,13 @@ /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing power_change() - if(!beaker) + if(!beaker || stat & (NOPOWER|BROKEN)) return operate_for(50, juicing = TRUE) addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50) /obj/machinery/reagentgrinder/proc/mix_complete() - if(beaker && beaker.reagents.total_volume) + if(beaker?.reagents.total_volume) //Recipe to make Butter var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1) beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt) 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.dm b/code/modules/reagents/chemistry/reagents.dm index a52bb1ecfe..9bfbffd330 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -33,6 +33,10 @@ var/addiction_stage4_end = 40 var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. var/self_consuming = FALSE + var/metabolizing = FALSE + + + /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() @@ -68,6 +72,14 @@ /datum/reagent/proc/on_mob_delete(mob/living/L) return +// Called when this reagent first starts being metabolized by a liver +/datum/reagent/proc/on_mob_metabolize(mob/living/L) + return + +// Called when this reagent stops being metabolized by a liver +/datum/reagent/proc/on_mob_end_metabolize(mob/living/L) + return + /datum/reagent/proc/on_move(mob/M) return diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 92d9da401b..211fddca26 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) @@ -111,7 +111,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY) return ..() -/datum/reagent/consumable/ethanol/beer/green/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/M) M.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color) /datum/reagent/consumable/ethanol/kahlua @@ -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) @@ -333,7 +333,7 @@ All effects don't start immediately, but rather get worse over time; the rate is id = "grappa" description = "A fine Italian brandy, for when regular wine just isn't alcoholic enough for you." color = "#F8EBF1" - boozepwr = 45 + boozepwr = 60 taste_description = "classy bitter sweetness" glass_icon_state = "grappa" glass_name = "glass of grappa" @@ -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 ..() @@ -379,6 +379,11 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Hooch" glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." +/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M) + if(M.mind && M.mind.assigned_role == "Assistant") + M.heal_bodypart_damage(1,1) + . = TRUE + return ..() || . /datum/reagent/consumable/ethanol/ale name = "Ale" @@ -569,13 +574,13 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up." var/tough_text -/datum/reagent/consumable/ethanol/brave_bull/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M) tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff to_chat(M, "You feel [tough_text]!") M.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment. M.health += 10 -/datum/reagent/consumable/ethanol/brave_bull/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/M) to_chat(M, "You no longer feel [tough_text].") M.maxHealth -= 10 M.health = min(M.health - 10, M.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion @@ -593,7 +598,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." var/obj/effect/light_holder -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M) to_chat(M, "You feel gentle warmth spread through your body!") light_holder = new(M) light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise! @@ -605,7 +610,7 @@ All effects don't start immediately, but rather get worse over time; the rate is light_holder.forceMove(M) return ..() -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/M) to_chat(M, "The warmth in your body fades.") QDEL_NULL(light_holder) @@ -633,25 +638,48 @@ All effects don't start immediately, but rather get worse over time; the rate is color = "#664300" // rgb: 102, 67, 0 boozepwr = 90 //THE FIST OF THE LAW IS STRONG AND HARD quality = DRINK_GOOD - metabolization_rate = 0.8 + metabolization_rate = 0.5 taste_description = "JUSTICE" glass_icon_state = "beepskysmashglass" glass_name = "Beepsky Smash" glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." + overdose_threshold = 40 + var/datum/brain_trauma/special/beepsky/B + +/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/M) + if(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) + metabolization_rate = 0.8 + if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + B = new() + M.gain_trauma(B, TRAUMA_RESILIENCE_ABSOLUTE) + ..() /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/M) - if(M.has_trait(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) + M.Jitter(2) + if(HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + M.adjustStaminaLoss(-10, 0) + if(prob(20)) + new /datum/hallucination/items_other(M) + if(prob(10)) + new /datum/hallucination/stray_bullet(M) + ..() + . = TRUE + +/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_end_metabolize(mob/living/carbon/M) + if(B) + QDEL_NULL(B) return ..() +/datum/reagent/consumable/ethanol/beepsky_smash/overdose_start(mob/living/carbon/M) + if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + M.gain_trauma(/datum/brain_trauma/mild/phobia/security, TRAUMA_RESILIENCE_BASIC) + /datum/reagent/consumable/ethanol/irish_cream name = "Irish Cream" id = "irishcream" description = "Whiskey-imbued cream, what else would you expect from the Irish?" color = "#664300" // rgb: 102, 67, 0 - boozepwr = 70 + boozepwr = 50 quality = DRINK_NICE taste_description = "creamy alcohol" glass_icon_state = "irishcreamglass" @@ -671,10 +699,10 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only." var/dorf_mode -/datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(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 @@ -722,7 +750,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed." shot_glass_icon_state = "b52glass" -/datum/reagent/consumable/ethanol/b52/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M) playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE) /datum/reagent/consumable/ethanol/irishcoffee @@ -947,7 +975,7 @@ All effects don't start immediately, but rather get worse over time; the rate is id = "red_mead" description = "The true Viking drink! Even though it has a strange red color." color = "#C73C00" // rgb: 199, 60, 0 - boozepwr = 51 //Red drinks are stronger + boozepwr = 31 //Red drinks are stronger quality = DRINK_GOOD taste_description = "sweet and salty alcohol" glass_icon_state = "red_meadglass" @@ -960,7 +988,7 @@ All effects don't start immediately, but rather get worse over time; the rate is description = "A Viking drink, though a cheap one." color = "#664300" // rgb: 102, 67, 0 nutriment_factor = 1 * REAGENTS_METABOLISM - boozepwr = 50 + boozepwr = 30 quality = DRINK_NICE taste_description = "sweet, sweet alcohol" glass_icon_state = "meadglass" @@ -1274,7 +1302,7 @@ 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) M.slurring = max(M.slurring,50) @@ -1319,32 +1347,49 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/neurotoxin name = "Neurotoxin" - id = "neurotoxin" description = "A strong neurotoxin that puts the subject into a death-like state." color = "#2E2E61" // rgb: 46, 46, 97 - boozepwr = 0 //custom drunk effect + boozepwr = 50 quality = DRINK_VERYGOOD taste_description = "a numbing sensation" + metabolization_rate = 1 * REAGENTS_METABOLISM glass_icon_state = "neurotoxinglass" glass_name = "Neurotoxin" glass_desc = "A drink that is guaranteed to knock you silly." +/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt() + return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG)) + /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M) - M.Knockdown(60, 1, 0) + M.set_drugginess(50) M.dizziness +=2 - switch(current_cycle) - if(15 to 45) - M.slurring = max(M.slurring,50) - M.slurring += 3 - if(45 to 55) - if(prob(50)) - M.confused = max(M.confused+3,0) - if(55 to 200) - M.set_drugginess(55) - if(200 to INFINITY) - M.adjustToxLoss(2, 0) + M.adjustBrainLoss(1*REM, 150) + if(prob(20)) + M.adjustStaminaLoss(10) + M.drop_all_held_items() + to_chat(M, "You cant feel your hands!") + if(current_cycle > 5) + if(prob(20)) + var/t = pickt() + ADD_TRAIT(M, t, type) + M.adjustStaminaLoss(10) + if(current_cycle > 30) + M.adjustBrainLoss(2*REM) + if(current_cycle > 50 && prob(15)) + if(!M.undergoing_cardiac_arrest() && M.can_heartattack()) + M.set_heartattack(TRUE) + if(M.stat == CONSCIOUS) + M.visible_message("[M] clutches at [M.p_their()] chest as if [M.p_their()] heart stopped!") + . = TRUE + ..() + +/datum/reagent/consumable/ethanol/neurotoxin/on_mob_end_metabolize(mob/living/carbon/M) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_ARM, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_ARM, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_LEG, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_LEG, type) + M.adjustStaminaLoss(10) ..() - . = 1 /datum/reagent/consumable/ethanol/hippies_delight name = "Hippie's Delight" @@ -1468,7 +1513,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "An intimidating and lawful beverage dares you to violate the law and make its day. Still can't drink it on duty, though." /datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/M) - if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes. + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes. M.heal_bodypart_damage(1, 1) M.adjustBruteLoss(-2,0) . = 1 @@ -1487,7 +1532,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Now you are become law, destroyer of clowns." /datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/M) - if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG.. + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG.. M.heal_bodypart_damage(2,2,2) M.adjustBruteLoss(-5,0) M.adjustOxyLoss(-5,0) @@ -1534,7 +1579,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon." shot_glass_icon_state = "shotglassgreen" -/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L) var/heal_points = 10 if(L.health <= 0) heal_points = 20 //heal more if we're in softcrit @@ -1618,7 +1663,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Crevice Spike" glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably." -/datum/reagent/consumable/ethanol/crevice_spike/on_mob_add(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out +/datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15 /datum/reagent/consumable/ethanol/sake @@ -1661,7 +1706,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A creamy, indulgent delight that is stronger than it seems." var/obj/item/shield/mighty_shield -/datum/reagent/consumable/ethanol/alexander/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L) if(ishuman(L)) var/mob/living/carbon/human/thehuman = L for(var/obj/item/shield/theshield in thehuman.contents) @@ -1675,7 +1720,7 @@ All effects don't start immediately, but rather get worse over time; the rate is if(mighty_shield && !(mighty_shield in L.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink. L.reagents.del_reagent("alexander") -/datum/reagent/consumable/ethanol/alexander/on_mob_delete(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/L) if(mighty_shield) mighty_shield.block_chance -= 10 to_chat(L,"You notice [mighty_shield] looks worn again. Weird.") @@ -1796,7 +1841,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.overeatduration = 0 return ..() -/datum/reagent/consumable/ethanol/fanciulli/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(20) . = TRUE @@ -1820,12 +1865,236 @@ All effects don't start immediately, but rather get worse over time; the rate is M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) return ..() -/datum/reagent/consumable/ethanol/branca_menta/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(35) . = TRUE ..() +/datum/reagent/consumable/ethanol/blank_paper + name = "Blank Paper" + id = "blank_paper" + description = "A bubbling glass of blank paper. Just looking at it makes you feel fresh." + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#DCDCDC" // rgb: 220, 220, 220 + boozepwr = 20 + quality = DRINK_GOOD + taste_description = "bubbling possibility" + glass_icon_state = "blank_paper" + glass_name = "glass of blank paper" + glass_desc = "A fizzy cocktail for those looking to start fresh." + +/datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/M) + if(ishuman(M) && M.job == "Mime") + M.heal_bodypart_damage(1,1) + . = 1 + return ..() + +/datum/reagent/consumable/ethanol/champagne //How the hell did we not have champagne already!? + name = "Champagne" + id = "champagne" + description = "A sparkling wine known for its ability to strike fast and hard." + color = "#ffffc1" + boozepwr = 40 + taste_description = "auspicious occasions and bad decisions" + glass_icon_state = "champagne_glass" + glass_name = "Champagne" + glass_desc = "The flute clearly displays the slowly rising bubbles." + +/datum/reagent/consumable/ethanol/wizz_fizz + name = "Wizz Fizz" + id = "wizz_fizz" + description = "A magical potion, fizzy and wild! However the taste, you will find, is quite mild." + color = "#4235d0" //Just pretend that the triple-sec was blue curacao. + boozepwr = 50 + quality = DRINK_GOOD + taste_description = "friendship! It is magic, after all" + glass_icon_state = "wizz_fizz" + glass_name = "Wizz Fizz" + glass_desc = "The glass bubbles and froths with an almost magical intensity." + +/datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/M) + //A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting + if(M?.mind?.has_antag_datum(/datum/antagonist/wizard)) + M.heal_bodypart_damage(1,1,1) + M.adjustOxyLoss(-1,0) + M.adjustToxLoss(-1,0) + return ..() + +/datum/reagent/consumable/ethanol/bug_spray + name = "Bug Spray" + id = "bug_spray" + description = "A harsh, acrid, bitter drink, for those who need something to brace themselves." + color = "#33ff33" + boozepwr = 50 + quality = DRINK_GOOD + taste_description = "the pain of ten thousand slain mosquitos" + glass_icon_state = "bug_spray" + glass_name = "Bug Spray" + glass_desc = "Your eyes begin to water as the sting of alcohol reaches them." + +/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M) +//Bugs should not drink Bug spray. + if(ismoth(M) || isflyperson(M)) + M.adjustToxLoss(1,0) + return ..() + +/datum/reagent/consumable/ethanol/bug_spray/on_mob_add(mob/living/carbon/M) + if(ismoth(M) || isflyperson(M)) + M.emote("scream") + return ..() + +/datum/reagent/consumable/ethanol/applejack + name = "Applejack" + id = "applejack" + description = "The perfect beverage for when you feel the need to horse around." + color = "#ff6633" + boozepwr = 20 + taste_description = "an honest day's work at the orchard" + glass_icon_state = "applejack_glass" + glass_name = "Applejack" + glass_desc = "You feel like you could drink this all neight." + +/datum/reagent/consumable/ethanol/jack_rose + name = "Jack Rose" + id = "jack_rose" + description = "A light cocktail perfect for sipping with a slice of pie." + color = "#ff6633" + boozepwr = 15 + quality = DRINK_NICE + taste_description = "a sweet and sour slice of apple" + glass_icon_state = "jack_rose" + glass_name = "Jack Rose" + glass_desc = "Enough of these, and you really will start to suppose your toeses are roses." + +/datum/reagent/consumable/ethanol/turbo + name = "Turbo" + id = "turbo" + description = "A turbulent cocktail associated with outlaw hoverbike racing. Not for the faint of heart." + color = "#e94c3a" + boozepwr = 85 + quality = DRINK_VERYGOOD + taste_description = "the outlaw spirit" + glass_icon_state = "turbo" + glass_name = "Turbo" + glass_desc = "A turbulent cocktail for outlaw hoverbikers." + +/datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/M) + if(prob(4)) + to_chat(M, "[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]") + M.adjustStaminaLoss(-M.drunkenness * 0.25) + return ..() + +/datum/reagent/consumable/ethanol/old_timer + name = "Old Timer" + id = "old_timer" + description = "An archaic potation enjoyed by old coots of all ages." + color = "#996835" + boozepwr = 35 + quality = DRINK_NICE + taste_description = "simpler times" + glass_icon_state = "old_timer" + glass_name = "Old Timer" + glass_desc = "WARNING! May cause premature aging!" + +/datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/M) + if(prob(20)) + if(ishuman(M)) + var/mob/living/carbon/human/N = M + N.age += 1 + if(N.age > 70) + N.facial_hair_color = "ccc" + N.hair_color = "ccc" + N.update_hair() + if(N.age > 100) + N.become_nearsighted(id) + if(N.gender == MALE) + N.facial_hair_style = "Beard (Very Long)" + N.update_hair() + + if(N.age > 969) //Best not let people get older than this or i might incur G-ds wrath + M.visible_message("[M] becomes older than any man should be.. and crumbles into dust!") + M.dust(0,1,0) + + return ..() + +/datum/reagent/consumable/ethanol/rubberneck + name = "Rubberneck" + id = "rubberneck" + description = "A quality rubberneck should not contain any gross natural ingredients." + color = "#ffe65b" + boozepwr = 60 + quality = DRINK_GOOD + taste_description = "artifical fruityness" + glass_icon_state = "rubberneck" + glass_name = "Rubberneck" + glass_desc = "A popular drink amongst those adhering to an all synthetic diet." + +/datum/reagent/consumable/ethanol/duplex + name = "Duplex" + id = "duplex" + description = "An inseparable combination of two fruity drinks." + color = "#50e5cf" + boozepwr = 25 + quality = DRINK_NICE + taste_description = "green apples and blue raspberries" + glass_icon_state = "duplex" + glass_name = "Duplex" + glass_desc = "To imbibe one component separately from the other is consider a great faux pas." + +/datum/reagent/consumable/ethanol/trappist + name = "Trappist Beer" + id = "trappist" + description = "A strong dark ale brewed by space-monks." + color = "#390c00" + boozepwr = 40 + quality = DRINK_VERYGOOD + taste_description = "dried plums and malt" + glass_icon_state = "trappistglass" + glass_name = "Trappist Beer" + glass_desc = "boozy Catholicism in a glass." + +/datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/M) + if(M.mind.isholy) + M.adjustFireLoss(-2.5, 0) + M.jitteriness = max(0, M.jitteriness-1) + M.stuttering = max(0, M.stuttering-1) + return ..() + +/datum/reagent/consumable/ethanol/blazaam + name = "Blazaam" + id = "blazaam" + description = "A strange drink that few people seem to remember existing. Doubles as a Berenstain remover." + boozepwr = 70 + quality = DRINK_FANTASTIC + taste_description = "alternate realities" + glass_icon_state = "blazaamglass" + glass_name = "Blazaam" + glass_desc = "The glass seems to be sliding between realities. Doubles as a Berenstain remover." + var/stored_teleports = 0 + +/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M) + if(M.drunkenness > 40) + if(stored_teleports) + do_teleport(M, get_turf(M), rand(1,3)) + stored_teleports-- + if(prob(10)) + stored_teleports += rand(2,6) + if(prob(70)) + M.vomit() + return ..() + +/datum/reagent/consumable/ethanol/planet_cracker + name = "Planet Cracker" + id = "planet_cracker" + description = "This jubilant drink celebrates humanity's triumph over the alien menace. May be offensive to non-human crewmembers." + boozepwr = 50 + quality = DRINK_FANTASTIC + taste_description = "triumph with a hint of bitterness" + glass_icon_state = "planet_cracker" + glass_name = "Planet Cracker" + glass_desc = "Although historians believe the drink was originally created to commemorate the end of an important conflict in man's past, its origins have largely been forgotten and it is today seen more as a general symbol of human supremacy." + /datum/reagent/consumable/ethanol/fruit_wine name = "Fruit Wine" id = "fruit_wine" diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index 8ee9449468..ada4cd8d8e 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -187,7 +187,7 @@ description = "will do toxin damage and cause targets to believe they are fully healed." analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed." taste_description = "heaven" - color = "#C8A5DC" + color = "#5e7842" complementary_color = "#CD7794" message_living = ", and you feel alive" @@ -204,7 +204,7 @@ C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest ..() -/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M) +/datum/reagent/blob/regenerative_materia/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = 0 diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 6ec37f3ec4..8aa555944a 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -213,15 +213,15 @@ glass_desc = "White and nutritious goodness!" /datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M) - if(M.getBruteLoss() && prob(20)) - M.heal_bodypart_damage(1,0, 0) + if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER)) + M.heal_bodypart_damage(1.5,0, 0) . = 1 + else + if(M.getBruteLoss() && prob(20)) + M.heal_bodypart_damage(1,0, 0) + . = 1 if(holder.has_reagent("capsaicin")) holder.remove_reagent("capsaicin", 2) - var/datum/dna/Mdna = M.has_dna() - if(Mdna && Mdna.species && (Mdna.species.id == "plasmaman" || Mdna.species.id == "skeleton")) - M.heal_bodypart_damage(1,0, 0) - . = 1 ..() /datum/reagent/consumable/soymilk @@ -305,6 +305,16 @@ ..() . = 1 +/datum/reagent/consumable/lemonade + name = "Lemonade" + id = "lemonade" + description = "Sweet, tangy lemonade. Good for the soul." + quality = DRINK_NICE + taste_description = "sunshine and summertime" + glass_icon_state = "lemonpitcher" + glass_name = "pitcher of lemonade" + glass_desc = "This drink leaves you feeling nostalgic for some reason." + /datum/reagent/consumable/tea/arnold_palmer name = "Arnold Palmer" id = "arnold_palmer" @@ -390,12 +400,12 @@ glass_name = "glass of Nuka Cola" glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland." -/datum/reagent/consumable/nuka_cola/on_mob_add(mob/living/L) +/datum/reagent/consumable/nuka_cola/on_mob_metabolize(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) +/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M) @@ -498,6 +508,34 @@ /datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) ..() + +/datum/reagent/consumable/grey_bull + name = "Grey Bull" + id = "grey_bull" + description = "Grey Bull, it gives you gloves!" + color = "#EEFF00" // rgb: 238, 255, 0 + quality = DRINK_VERYGOOD + taste_description = "carbonated oil" + glass_icon_state = "grey_bull_glass" + glass_name = "glass of Grey Bull" + glass_desc = "Surprisingly it isnt grey." + +/datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/L) + ..() + ADD_TRAIT(L, TRAIT_SHOCKIMMUNE, id) + +/datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_SHOCKIMMUNE, id) + ..() + +/datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/M) + M.Jitter(20) + M.dizziness +=1 + M.drowsyness = 0 + M.AdjustSleeping(-40, FALSE) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + /datum/reagent/consumable/sodawater name = "Soda Water" id = "sodawater" @@ -703,7 +741,7 @@ name = "Triple Citrus" id = "triple_citrus" description = "A solution." - color = "#C8A5DC" + color = "#fff12b" quality = DRINK_NICE taste_description = "extreme bitterness" glass_icon_state = "triplecitrus" //needs own sprite mine are trash @@ -719,6 +757,11 @@ glass_name = "glass of grape juice" glass_desc = "It's grape (soda)!" +/datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/M) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + + /datum/reagent/consumable/milk/chocolate_milk name = "Chocolate Milk" id = "chocolate_milk" @@ -746,6 +789,65 @@ glass_name = "glass of grenadine" glass_desc = "Delicious flavored syrup." +/datum/reagent/consumable/parsnipjuice + name = "Parsnip Juice" + id = "parsnipjuice" + description = "Why..." + color = "#FFA500" + taste_description = "parsnip" + glass_name = "glass of parsnip juice" + +/datum/reagent/consumable/peachjuice //Intended to be extremely rare due to being the limiting ingredients in the blazaam drink + name = "Peach Juice" + id = "peachjuice" + description = "Just peachy." + color = "#E78108" + taste_description = "peaches" + glass_name = "glass of peach juice" + +/datum/reagent/consumable/cream_soda + name = "Cream Soda" + id = "cream_soda" + description = "A classic space-American vanilla flavored soft drink." + color = "#dcb137" + quality = DRINK_VERYGOOD + taste_description = "fizzy vanilla" + glass_icon_state = "cream_soda" + glass_name = "Cream Soda" + glass_desc = "A classic space-American vanilla flavored soft drink." + +/datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/M) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + +/datum/reagent/consumable/red_queen + name = "Red Queen" + id = "red_queen" + description = "DRINK ME." + color = "#e6ddc3" + quality = DRINK_GOOD + taste_description = "wonder" + glass_icon_state = "red_queen" + glass_name = "Red Queen" + glass_desc = "DRINK ME." + var/current_size = 1 + +/datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/H) + if(prob(75)) + return ..() + var/newsize = pick(0.5, 0.75, 1, 1.50, 2) + H.resize = newsize/current_size + current_size = newsize + H.update_transform() + if(prob(40)) + H.emote("sneeze") + ..() + +/datum/reagent/consumable/red_queen/on_mob_end_metabolize(mob/living/M) + M.resize = 1/current_size + M.update_transform() + ..() + /datum/reagent/consumable/pinkmilk name = "Strawberry Milk" id = "pinkmilk" diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index d77756a649..a4586dd997 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -5,7 +5,7 @@ taste_description = "bitterness" var/trippy = TRUE //Does this drug make you trip? -/datum/reagent/drug/on_mob_delete(mob/living/M) +/datum/reagent/drug/on_mob_end_metabolize(mob/living/M) if(trippy) SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "[id]_high") @@ -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) +/datum/reagent/drug/methamphetamine/on_mob_metabolize(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) +/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L) + 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" @@ -251,18 +262,18 @@ taste_description = "salt" // because they're bathsalts? var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage -/datum/reagent/drug/bath_salts/on_mob_add(mob/living/L) +/datum/reagent/drug/bath_salts/on_mob_metabolize(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) +/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) if(rage) QDEL_NULL(rage) ..() @@ -370,9 +381,9 @@ addiction_stage3_end = 40 addiction_stage4_end = 240 -/datum/reagent/drug/skooma/on_mob_add(mob/living/L) +/datum/reagent/drug/skooma/on_mob_metabolize(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 @@ -381,9 +392,9 @@ if(H.dna && H.dna.species) H.dna.species.punchdamagehigh *= 5 -/datum/reagent/drug/skooma/on_mob_delete(mob/living/L) +/datum/reagent/drug/skooma/on_mob_end_metabolize(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 5071150e24..7d0cea0c8f 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) @@ -32,6 +32,8 @@ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood) if (DRINK_FANTASTIC) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic) + if (FOOD_AMAZING) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste) return ..() /datum/reagent/consumable/nutriment @@ -319,7 +321,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 +334,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) @@ -401,7 +403,7 @@ metabolization_rate = 0.2 * REAGENTS_METABOLISM taste_description = "mushroom" -/datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) +/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) switch(current_cycle) if(1 to 5) @@ -431,11 +433,19 @@ taste_description = "childhood whimsy" /datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M) - if(ishuman(M) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden")) + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) M.heal_bodypart_damage(1,1, 0) . = 1 ..() +/datum/reagent/consumable/peanut_butter + name = "Peanut Butter" + id = "peanut_butter" + description = "A popular food paste made from ground dry-roasted peanuts." + color = "#C29261" + nutriment_factor = 15 * REAGENTS_METABOLISM + taste_description = "peanuts" + /datum/reagent/consumable/cornoil name = "Corn Oil" id = "cornoil" @@ -554,14 +564,14 @@ name = "Corn Starch" id = "corn_starch" description = "A slippery solution." - color = "#C8A5DC" + color = "#f7f6e4" taste_description = "slime" /datum/reagent/consumable/corn_syrup name = "Corn Syrup" id = "corn_syrup" description = "Decays into sugar." - color = "#C8A5DC" + color = "#fff882" metabolization_rate = 3 * REAGENTS_METABOLISM taste_description = "sweet slime" @@ -686,7 +696,7 @@ /datum/reagent/consumable/tinlux/reaction_mob(mob/living/M) M.set_light(2) -/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M) +/datum/reagent/consumable/tinlux/on_mob_end_metabolize(mob/living/M) M.set_light(-2) /datum/reagent/consumable/vitfro @@ -711,3 +721,32 @@ nutriment_factor = 5 * REAGENTS_METABOLISM color = "#eef442" // rgb: 238, 244, 66 taste_description = "mournful honking" + +/datum/reagent/consumable/astrotame + name = "Astrotame" + id = "astrotame" + description = "A space age artifical sweetener." + nutriment_factor = 0 + metabolization_rate = 2 * REAGENTS_METABOLISM + reagent_state = SOLID + color = "#FFFFFF" // rgb: 255, 255, 255 + taste_mult = 8 + taste_description = "sweetness" + overdose_threshold = 17 + +/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/M) + if(M.disgust < 80) + M.adjust_disgust(10) + ..() + . = TRUE + +/datum/reagent/consumable/secretsauce + name = "secret sauce" + id = "secret_sauce" + description = "What could it be." + nutriment_factor = 2 * REAGENTS_METABOLISM + color = "#792300" + taste_description = "indescribable" + quality = FOOD_AMAZING + taste_mult = 100 + can_synth = FALSE diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 3970e8157b..fe70db250d 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -18,7 +18,7 @@ name = "Leporazine" id = "leporazine" description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#82b8aa" /datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/M) if(M.bodytemperature > BODYTEMP_NORMAL) @@ -31,7 +31,7 @@ name = "Adminordrazine" id = "adminordrazine" description = "It's magic. We don't have to explain it." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#ffffff" can_synth = FALSE taste_description = "badmins" @@ -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 @@ -213,7 +213,7 @@ name = "Spaceacillin" id = "spaceacillin" description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#f2f2f2" metabolization_rate = 0.1 * REAGENTS_METABOLISM //Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects. @@ -222,7 +222,7 @@ id = "silver_sulfadiazine" description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ffeac9" /datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -366,7 +366,7 @@ to_chat(M, "You feel your wounds fade away to nothing!" ) ..() -/datum/reagent/medicine/mine_salve/on_mob_delete(mob/living/M) +/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = SCREWYHUD_NONE @@ -483,16 +483,24 @@ reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50 - M.adjustToxLoss(-2*REM, 0) + M.adjustToxLoss(-2*REM, 0, healtoxinlover) for(var/datum/reagent/R in M.reagents.reagent_list) if(R != src) M.reagents.remove_reagent(R.id,2) ..() . = 1 +/datum/reagent/medicine/pen_acid/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!" + color = "#91D865" + healtoxinlover = TRUE + /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" id = "sal_acid" @@ -630,12 +638,12 @@ overdose_threshold = 30 addiction_threshold = 25 -/datum/reagent/medicine/morphine/on_mob_add(mob/living/L) +/datum/reagent/medicine/morphine/on_mob_metabolize(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) +/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L) + L.unignore_slowdown(id) ..() /datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/M) @@ -702,14 +710,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 +808,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)) @@ -875,12 +883,12 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 -/datum/reagent/medicine/stimulants/on_mob_add(mob/living/L) +/datum/reagent/medicine/stimulants/on_mob_metabolize(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) +/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/M) @@ -924,7 +932,7 @@ id = "bicaridine" description = "Restores bruising. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#fc2626" overdose_threshold = 30 /datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M) @@ -942,7 +950,7 @@ id = "dexalin" description = "Restores oxygen loss. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#13d2f0" overdose_threshold = 30 /datum/reagent/medicine/dexalin/on_mob_life(mob/living/carbon/M) @@ -960,7 +968,7 @@ id = "kelotane" description = "Restores fire damage. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ffc400" overdose_threshold = 30 /datum/reagent/medicine/kelotane/on_mob_life(mob/living/carbon/M) @@ -978,7 +986,7 @@ id = "antitoxin" description = "Heals toxin damage and removes toxins in the bloodstream. Overdose causes toxin damage." reagent_state = LIQUID - color = "#C8A5DC" + color = "#6aff00" overdose_threshold = 30 taste_description = "a roll of gauze" @@ -999,7 +1007,7 @@ id = "inaprovaline" description = "Stabilizes the breathing of patients. Good for those in critical condition." reagent_state = LIQUID - color = "#C8A5DC" + color = "#5dc1f0" /datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M) if(M.losebreath >= 5) @@ -1011,7 +1019,7 @@ id = "tricordrazine" description = "Has a high chance to heal all types of damage. Overdose instead causes it." reagent_state = LIQUID - color = "#C8A5DC" + color = "#e650c0" overdose_threshold = 30 taste_description = "grossness" @@ -1102,7 +1110,7 @@ M.adjustBruteLoss(-3 * REM, 0) M.adjustFireLoss(-3 * REM, 0) M.adjustOxyLoss(-15 * REM, 0) - M.adjustToxLoss(-3 * REM, 0) + M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) M.adjustStaminaLoss(-30 * REM, 0) @@ -1113,7 +1121,7 @@ /datum/reagent/medicine/earthsblood/overdose_process(mob/living/M) M.hallucination = min(max(0, M.hallucination + 5), 60) - M.adjustToxLoss(5 * REM, 0) + M.adjustToxLoss(8 * REM, 0, TRUE) //Hurts TOXINLOVERS ..() . = 1 @@ -1143,7 +1151,7 @@ name = "Lavaland Extract" id = "lavaland_extract" description = "An extract of lavaland atmospheric and mineral elements. Heals the user in small doses, but is extremely toxic otherwise." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#a1a1a1" overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent can_synth = FALSE @@ -1164,13 +1172,14 @@ name = "Changeling Adrenaline" id = "changelingadrenaline" description = "Reduces the duration of unconciousness, knockdown and stuns. Restores stamina, but deals toxin damage when overdosed." - color = "#C8A5DC" + color = "#918e53" overdose_threshold = 30 /datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/M as mob) M.AdjustUnconscious(-20, 0) M.AdjustStun(-20, 0) M.AdjustKnockdown(-20, 0) + M.AdjustSleeping(-20, 0) M.adjustStaminaLoss(-30, 0) ..() return TRUE @@ -1184,15 +1193,15 @@ name = "Changeling Haste" id = "changelinghaste" description = "Drastically increases movement speed, but deals toxin damage." - color = "#C8A5DC" + color = "#669153" metabolization_rate = 1 -/datum/reagent/medicine/changelinghaste/on_mob_add(mob/living/L) +/datum/reagent/medicine/changelinghaste/on_mob_metabolize(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) +/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) ..() /datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M) @@ -1209,12 +1218,12 @@ color = "#F5F5F5" self_consuming = TRUE -/datum/reagent/medicine/corazone/on_mob_add(mob/living/M) +/datum/reagent/medicine/corazone/on_mob_metabolize(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) +/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M) + REMOVE_TRAIT(M, TRAIT_STABLEHEART, id) ..() /datum/reagent/medicine/muscle_stimulant @@ -1222,13 +1231,13 @@ id = "muscle_stimulant" description = "A potent chemical that allows someone under its influence to be at full physical ability even when under massive amounts of pain." -/datum/reagent/medicine/muscle_stimulant/on_mob_add(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M) . = ..() - M.add_trait(TRAIT_IGNORESLOWDOWN, id) + M.ignore_slowdown(id) -/datum/reagent/medicine/muscle_stimulant/on_mob_delete(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_end_metabolize(mob/living/M) . = ..() - M.remove_trait(TRAIT_IGNORESLOWDOWN, id) + M.unignore_slowdown(id) /datum/reagent/medicine/modafinil name = "Modafinil" @@ -1241,12 +1250,12 @@ taste_description = "salt" // it actually does taste salty var/overdose_progress = 0 // to track overdose progress -/datum/reagent/medicine/modafinil/on_mob_add(mob/living/M) - M.add_trait(TRAIT_SLEEPIMMUNE, id) +/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M) + ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() -/datum/reagent/medicine/modafinil/on_mob_delete(mob/living/M) - M.remove_trait(TRAIT_SLEEPIMMUNE, id) +/datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/M) + 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 5d1593d1e7..42b012d52f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -196,17 +196,22 @@ glass_name = "glass of holy water" glass_desc = "A glass of holy water." -/datum/reagent/water/holywater/on_mob_add(mob/living/L) +/datum/reagent/water/holywater/on_mob_metabolize(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) +/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_HOLY, id) ..() /datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(is_servant_of_ratvar(M)) - to_chat(M, "A darkness begins to spread its unholy tendrils through your mind, purging the Justiciar's influence!") + to_chat(M, "A fog spreads through your mind, purging the Justiciar's influence!") + ..() + +/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(iscultist(M)) + to_chat(M, "A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence") ..() /datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M) @@ -261,7 +266,7 @@ qdel(R) T.Bless() -/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke +/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke name = "Unholy Water" id = "unholywater" description = "Something that shouldn't exist on this plane of existence." @@ -280,7 +285,7 @@ M.AdjustStun(-40, 0) M.AdjustKnockdown(-40, 0) M.adjustStaminaLoss(-10, 0) - M.adjustToxLoss(-2, 0) + M.adjustToxLoss(-2, 0, TRUE) M.adjustOxyLoss(-2, 0) M.adjustBruteLoss(-2, 0) M.adjustFireLoss(-2, 0) @@ -309,6 +314,45 @@ M.adjustBrainLoss(5, 150) holder.remove_reagent(id, 1) +/datum/reagent/fuel/holyoil //Its oil + name = "Zelus Oil" + id = "holyoil" + description = "Oil blessed by a greater being." + taste_description = "metallic oil" + +/datum/reagent/fuel/holyoil/on_mob_life(mob/living/carbon/M) + if(is_servant_of_ratvar(M)) + M.drowsyness = max(M.drowsyness-5, 0) + M.AdjustUnconscious(-60, 0) + M.AdjustStun(-30, 0) + M.AdjustKnockdown(-70, 0) + M.adjustStaminaLoss(-15, 0) + M.adjustToxLoss(-5, 0, TRUE) + M.adjustOxyLoss(-3, 0) + M.adjustBruteLoss(-3, 0) + M.adjustFireLoss(-5, 0) + if(iscultist(M)) + M.AdjustUnconscious(1, 0) + M.AdjustStun(10, 0) + M.AdjustKnockdown(20, 0) + M.adjustStaminaLoss(15, 0) + else + M.adjustToxLoss(3, 0) + M.adjustOxyLoss(2, 0) + M.adjustStaminaLoss(10, 0) + holder.remove_reagent(id, 1) + return TRUE + +//We only get 30u to start with... + +/datum/reagent/fuel/holyoil/reaction_obj(obj/O, reac_volume) + . = ..() + if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + reac_volume = min(reac_volume, M.amount) + new/obj/item/stack/tile/brass(get_turf(M), reac_volume) + M.use(reac_volume) + /datum/reagent/medicine/omnizine/godblood name = "Godblood" id = "godblood" @@ -863,7 +907,7 @@ name = "Sterilizine" id = "sterilizine" description = "Sterilizes wounds in preparation for surgery." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#e6f1f5" // rgb: 200, 165, 220 taste_description = "bitterness" /datum/reagent/space_cleaner/sterilizine/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) @@ -881,7 +925,7 @@ reagent_state = SOLID taste_description = "iron" - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#c2391d" /datum/reagent/iron/on_mob_life(mob/living/carbon/C) if(C.blood_volume < BLOOD_VOLUME_NORMAL) @@ -1076,7 +1120,7 @@ name = "Cryptobiolin" id = "cryptobiolin" description = "Cryptobiolin causes confusion and dizziness." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#7529b3" // rgb: 200, 165, 220 metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "sourness" @@ -1091,7 +1135,7 @@ name = "Impedrezene" id = "impedrezene" description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions." - color = "#C8A5DC" // rgb: 200, 165, 220A + color = "#587a31" // rgb: 200, 165, 220A taste_description = "numbness" /datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M) @@ -1241,14 +1285,14 @@ color = "E1A116" taste_description = "sourness" -/datum/reagent/stimulum/on_mob_add(mob/living/L) +/datum/reagent/stimulum/on_mob_metabolize(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) +/datum/reagent/stimulum/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) ..() /datum/reagent/stimulum/on_mob_life(mob/living/carbon/M) @@ -1266,12 +1310,12 @@ color = "90560B" taste_description = "burning" -/datum/reagent/nitryl/on_mob_add(mob/living/L) +/datum/reagent/nitryl/on_mob_metabolize(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) +/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /////////////////////////Coloured Crayon Powder//////////////////////////// @@ -1410,7 +1454,7 @@ id = "oil" description = "Burns in a small smoky fire, mostly used to get Ash." reagent_state = LIQUID - color = "#C8A5DC" + color = "#292929" taste_description = "oil" /datum/reagent/stable_plasma @@ -1418,7 +1462,7 @@ id = "stable_plasma" description = "Non-flammable plasma locked into a liquid form that cannot ignite or become gaseous/solid." reagent_state = LIQUID - color = "#C8A5DC" + color = "#6b008f" taste_description = "bitterness" taste_mult = 1.5 @@ -1431,7 +1475,7 @@ id = "iodine" description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing." reagent_state = LIQUID - color = "#C8A5DC" + color = "#694600" taste_description = "metal" /datum/reagent/carpet @@ -1439,7 +1483,7 @@ id = "carpet" description = "For those that need a more creative way to roll out a red carpet." reagent_state = LIQUID - color = "#C8A5DC" + color = "#b51d05" taste_description = "carpet" // Your tounge feels furry. /datum/reagent/carpet/reaction_turf(turf/T, reac_volume) @@ -1453,7 +1497,7 @@ id = "bromine" description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption." reagent_state = LIQUID - color = "#C8A5DC" + color = "#b37740" taste_description = "chemicals" /datum/reagent/phenol @@ -1461,7 +1505,7 @@ id = "phenol" description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own." reagent_state = LIQUID - color = "#C8A5DC" + color = "#e6e8ff" taste_description = "acid" /datum/reagent/ash @@ -1469,7 +1513,7 @@ id = "ash" description = "Supposedly phoenixes rise from these, but you've never seen it." reagent_state = LIQUID - color = "#C8A5DC" + color = "#665c56" taste_description = "ash" /datum/reagent/acetone @@ -1477,7 +1521,7 @@ id = "acetone" description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life." reagent_state = LIQUID - color = "#C8A5DC" + color = "#e6e6e6" taste_description = "acid" /datum/reagent/colorful_reagent @@ -1485,7 +1529,7 @@ id = "colorful_reagent" description = "Thoroughly sample the rainbow." reagent_state = LIQUID - color = "#C8A5DC" + color = "#FFFF00" var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") taste_description = "rainbows" var/no_mob_color = FALSE @@ -1515,7 +1559,7 @@ id = "hair_dye" description = "Has a high chance of making you look like a mad scientist." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ff00dd" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code taste_description = "sourness" @@ -1532,7 +1576,7 @@ id = "barbers_aid" description = "A solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" + color = "#fac34b" taste_description = "sourness" /datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -1550,7 +1594,7 @@ id = "concentrated_barbers_aid" description = "A concentrated solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ffaf00" taste_description = "sourness" /datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -1723,7 +1767,7 @@ H.update_transform() ..() -/datum/reagent/growthserum/on_mob_delete(mob/living/M) +/datum/reagent/growthserum/on_mob_end_metabolize(mob/living/M) M.resize = 1/current_size M.update_transform() ..() @@ -1777,12 +1821,12 @@ taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM -/datum/reagent/pax/on_mob_add(mob/living/L) +/datum/reagent/pax/on_mob_metabolize(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) +/datum/reagent/pax/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_PACIFISM, id) ..() /datum/reagent/bz_metabolites @@ -1793,13 +1837,13 @@ taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM -/datum/reagent/bz_metabolites/on_mob_add(mob/living/L) +/datum/reagent/bz_metabolites/on_mob_metabolize(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) +/datum/reagent/bz_metabolites/on_mob_end_metabolize(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) @@ -1814,14 +1858,14 @@ description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." metabolization_rate = 1.5 * REAGENTS_METABOLISM -/datum/reagent/peaceborg/confuse +/datum/reagent/peaceborg_confuse name = "Dizzying Solution" id = "dizzysolution" description = "Makes the target off balance and dizzy" metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "dizziness" -/datum/reagent/peaceborg/confuse/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_confuse/on_mob_life(mob/living/carbon/M) if(M.confused < 6) M.confused = CLAMP(M.confused + 3, 0, 5) if(M.dizziness < 6) @@ -1830,14 +1874,14 @@ to_chat(M, "You feel confused and disorientated.") ..() -/datum/reagent/peaceborg/tire +/datum/reagent/peaceborg_tire name = "Tiring Solution" id = "tiresolution" description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "tiredness" -/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_tire/on_mob_life(mob/living/carbon/M) var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) M.adjustStaminaLoss(10) @@ -1879,4 +1923,4 @@ 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 edf12a3413..6bd165f23e 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 ..() @@ -156,11 +156,11 @@ toxpwr = 0.5 taste_description = "death" -/datum/reagent/toxin/zombiepowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() L.fakedeath(id) -/datum/reagent/toxin/zombiepowder/on_mob_delete(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L) L.cure_fakedeath(id) ..() @@ -178,12 +178,12 @@ toxpwr = 0.8 taste_description = "death" -/datum/reagent/toxin/ghoulpowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(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) +/datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_FAKEDEATH, id) ..() /datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/M) @@ -626,7 +626,7 @@ toxpwr = 0 metabolization_rate = 0.5 * REAGENTS_METABOLISM -/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M) +/datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M) var/toxdamage = current_cycle*3*REM M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", LOG_ATTACK) M.adjustToxLoss(toxdamage) @@ -742,7 +742,7 @@ animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() -/datum/reagent/toxin/rotatium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) 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]"]) for(var/whole_screen in screens) @@ -779,7 +779,7 @@ */ return ..() -/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/skewium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) 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]"]) for(var/whole_screen in screens) @@ -798,7 +798,7 @@ /datum/reagent/toxin/anacea/on_mob_life(mob/living/carbon/M) var/remove_amt = 5 - if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid")) + if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid") || holder.has_reagent("pen_jelly")) remove_amt = 0.5 for(var/datum/reagent/medicine/R in M.reagents.reagent_list) M.reagents.remove_reagent(R.id,remove_amt) @@ -882,8 +882,69 @@ toxpwr = 0 taste_description = "stillness" -/datum/reagent/toxin/mimesbane/on_mob_add(mob/living/L) - L.add_trait(TRAIT_EMOTEMUTE, id) +/datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/L) + ADD_TRAIT(L, TRAIT_EMOTEMUTE, id) -/datum/reagent/toxin/mimesbane/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_EMOTEMUTE, id) +/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id) + +/datum/reagent/toxin/bonehurtingjuice //oof ouch + name = "Bone Hurting Juice" + id = "bonehurtingjuice" + description = "A strange substance that looks a lot like water. Drinking it is oddly tempting. Oof ouch." + color = "#AAAAAA77" //RGBA: 170, 170, 170, 77 + toxpwr = 0 + taste_description = "bone hurting" + overdose_threshold = 20 + +/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M) + M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice) + +/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M) + M.adjustStaminaLoss(7.5, 0) + if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER)) + M.adjustBruteLoss(3.5, 0) + if(prob(12)) + switch(rand(1, 3)) + if(1) + var/list/possible_says = list("oof.", "ouch!", "my bones.", "oof ouch.", "oof ouch my bones.") + M.say(pick(possible_says), forced = /datum/reagent/toxin/bonehurtingjuice) + if(2) + var/list/possible_mes = list("oofs softly.", "looks like their bones hurt.", "grimaces, as though their bones hurt.") + M.say("*custom " + pick(possible_mes), forced = /datum/reagent/toxin/bonehurtingjuice) + if(3) + to_chat(M, "Your bones hurt!") + return ..() + +/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/M) + if(prob(6) && iscarbon(M)) //big oof + var/selected_part + switch(rand(1, 4)) //God help you if the same limb gets picked twice quickly. + if(1) + selected_part = BODY_ZONE_L_ARM + if(2) + selected_part = BODY_ZONE_R_ARM + if(3) + selected_part = BODY_ZONE_L_LEG + if(4) + selected_part = BODY_ZONE_R_LEG + var/obj/item/bodypart/bp = M.get_bodypart(selected_part) + if(M.dna.species.type != /datum/species/skeleton || M.dna.species.type != /datum/species/plasmaman || M.dna.species.type != /datum/species/golem/bone) //We're so sorry skeletons, you're so misunderstood + if(bp) + bp.receive_damage(0, 0, 200) + playsound(M, get_sfx("desceration"), 50, TRUE, -1) + M.visible_message("[M]'s bones hurt too much!!", "Your bones hurt too much!!") + M.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice) + else //SUCH A LUST FOR REVENGE!!! + to_chat(M, "A phantom limb hurts!") + M.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice) + else //you just want to socialize + if(bp) + playsound(M, get_sfx("desceration"), 50, TRUE, -1) + M.visible_message("[M] rattles loudly and flails around!!", "Your bones hurt so much that your missing muscles spasm!!") + M.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice) + bp.receive_damage(200, 0, 0) //But I don't think we should + else + to_chat(M, "Your missing arm aches from wherever you left it.") + M.emote("sigh") + return ..() diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index dc7c32d925..727048a12c 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -94,6 +94,12 @@ results = list("pen_acid" = 6) required_reagents = list("welding_fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1) +/datum/chemical_reaction/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + results = list("pen_jelly" = 2) + required_reagents = list("pen_acid" = 1, "slimejelly" = 1) + /datum/chemical_reaction/sal_acid name = "Salicyclic Acid" id = "sal_acid" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 29863c2b90..b29a1c6809 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -64,8 +64,8 @@ strengthdiv = 8 for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom))) var/deity - if(SSreligion.deity) - deity = SSreligion.deity + if(GLOB.deity) + deity = GLOB.deity else deity = "Christ" to_chat(R, "The power of [deity] compels you!") diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index db5f7b198c..8edca91a91 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -216,7 +216,7 @@ /datum/chemical_reaction/slime/slimefreeze/on_reaction(datum/reagents/holder) var/turf/T = get_turf(holder.my_atom) - T.visible_message("The slime extract begins to vibrate adorably!") + T.visible_message("The slime extract starts to feel extremely cold!") addtimer(CALLBACK(src, .proc/freeze, holder), 50) var/obj/item/slime_extract/M = holder.my_atom deltimer(M.qdel_timer) @@ -227,7 +227,8 @@ if(holder && holder.my_atom) var/turf/open/T = get_turf(holder.my_atom) if(istype(T)) - T.atmos_spawn_air("nitrogen=50;TEMP=2.7") + var/datum/gas/gastype = /datum/gas/nitrogen + T.atmos_spawn_air("[initial(gastype.id)]=50;TEMP=2.7") /datum/chemical_reaction/slime/slimefireproof name = "Slime Fireproof" @@ -370,6 +371,11 @@ /datum/chemical_reaction/slime/slimebloodlust/on_reaction(datum/reagents/holder) for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null)) + if(slime.docile) //Undoes docility, but doesn't make rabid. + slime.visible_message("[slime] forgets its training, becoming wild once again!") + slime.docile = FALSE + slime.update_name() + continue slime.rabid = 1 slime.visible_message("The [slime] is driven into a frenzy!") ..() diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm new file mode 100644 index 0000000000..153372101e --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -0,0 +1,212 @@ +GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related food types + +/proc/build_reagents_to_food() + . = list() + for (var/type in subtypesof(/obj/item/reagent_containers/food)) + var/obj/item/reagent_containers/food/item = new type() + for(var/r in item.list_reagents) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + //dang plant snowflake + for (var/type in subtypesof(/obj/item/seeds)) + var/obj/item/seeds/item = new type() + for(var/r in item.reagents_add) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + + +#define RNGCHEM_INPUT "input" +#define RNGCHEM_CATALYSTS "catalysts" +#define RNGCHEM_OUTPUT "output" + +/datum/chemical_reaction/randomized + name = "semi randomized reaction" + + var/persistent = FALSE + var/persistence_period = 7 //Will reset every x days + var/created //creation timestamp + + var/randomize_container = FALSE + var/list/possible_containers = list() + + var/randomize_req_temperature = TRUE + var/min_temp = 1 + var/max_temp = 600 + + var/randomize_inputs = TRUE + var/min_input_reagent_amount = 1 + var/max_input_reagent_amount = 10 + var/min_input_reagents = 2 + var/max_input_reagents = 5 + var/list/possible_reagents = list() + var/min_catalysts = 0 + var/max_catalysts = 2 + var/list/possible_catalysts = list() + + var/randomize_results = FALSE + var/min_output_reagent_amount = 1 + var/max_output_reagent_amount = 5 + var/min_result_reagents = 1 + var/max_result_reagents = 1 + var/list/possible_results = list() + +/datum/chemical_reaction/randomized/proc/GenerateRecipe() + created = world.time + if(randomize_container) + required_container = pick(possible_containers) + if(randomize_req_temperature) + required_temp = rand(min_temp,max_temp) + is_cold_recipe = pick(TRUE,FALSE) + + if(randomize_results) + results = list() + var/list/remaining_possible_results = GetPossibleReagents(RNGCHEM_OUTPUT) + var/out_reagent_count = min(rand(min_result_reagents,max_result_reagents),remaining_possible_results.len) + for(var/i in 1 to out_reagent_count) + var/r_id = pick_n_take(remaining_possible_results) + results[r_id] = rand(min_output_reagent_amount,max_output_reagent_amount) + + if(randomize_inputs) + var/list/remaining_possible_reagents = GetPossibleReagents(RNGCHEM_INPUT) + var/list/remaining_possible_catalysts = GetPossibleReagents(RNGCHEM_CATALYSTS) + + //We're going to assume we're not doing any weird partial reactions for now. + for(var/reagent_type in results) + remaining_possible_catalysts -= reagent_type + remaining_possible_reagents -= reagent_type + + var/in_reagent_count = min(rand(min_input_reagents,max_input_reagents),remaining_possible_reagents.len) + if(in_reagent_count <= 0) + return FALSE + + required_reagents = list() + for(var/i in 1 to in_reagent_count) + var/r_id = pick_n_take(remaining_possible_reagents) + required_reagents[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + remaining_possible_catalysts -= r_id //Can't have same reagents both as catalyst and reagent. Or can we ? + + required_catalysts = list() + var/in_catalyst_count = min(rand(min_catalysts,max_catalysts),remaining_possible_catalysts.len) + for(var/i in 1 to in_catalyst_count) + var/r_id = pick_n_take(remaining_possible_catalysts) + required_catalysts[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + + return TRUE + +/datum/chemical_reaction/randomized/proc/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT) + return possible_reagents.Copy() + if(RNGCHEM_CATALYSTS) + return possible_catalysts.Copy() + if(RNGCHEM_OUTPUT) + return possible_results.Copy() + +/datum/chemical_reaction/randomized/proc/HasConflicts() + for(var/x in required_reagents) + for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[x]) + if(chem_recipes_do_conflict(R,src)) + return TRUE + return FALSE + +/datum/chemical_reaction/randomized/proc/unwrap_reagent_list(list/textreagents) + . = list() + for(var/R in textreagents) + var/pathR = text2path(R) + if(!pathR) + return null + .[pathR] = textreagents[R] + +/datum/chemical_reaction/randomized/proc/LoadOldRecipe(recipe_data) + created = text2num(recipe_data["timestamp"]) + + var/req_reag = unwrap_reagent_list(recipe_data["required_reagents"]) + if(!req_reag) + return FALSE + required_reagents = req_reag + + var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"]) + if(!req_catalysts) + return FALSE + required_catalysts = req_catalysts + + required_temp = recipe_data["required_temp"] + is_cold_recipe = recipe_data["is_cold_recipe"] + + var/temp_results = unwrap_reagent_list(recipe_data["results"]) + if(!temp_results) + return FALSE + results = temp_results + var/containerpath = text2path(recipe_data["required_container"]) + if(!containerpath) + return FALSE + required_container = containerpath + return TRUE + +/datum/chemical_reaction/randomized/secret_sauce + name = "secret sauce creation" + id = "secretsauce" + persistent = TRUE + persistence_period = 7 //Reset every week + randomize_container = TRUE + possible_containers = list(/obj/item/reagent_containers/glass/bucket) //easy way to ensure no common conflicts + randomize_req_temperature = TRUE + results = list("secret_sauce" =1) + +/datum/chemical_reaction/randomized/secret_sauce/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT,RNGCHEM_CATALYSTS) + var/food_reagent_ids = list() + for(var/key in GLOB.food_reagents) + food_reagent_ids += key + return food_reagent_ids + return ..() + + +/obj/item/paper/secretrecipe + name = "old recipe" + var/recipe_id = "secretsauce" + +/obj/item/paper/secretrecipe/examine(mob/user) //Extra secret + if(isobserver(user)) + return + . = ..() + +/obj/item/paper/secretrecipe/Initialize() + . = ..() + if(SSpersistence.initialized) + UpdateInfo() + else + SSticker.OnRoundstart(CALLBACK(src,.proc/UpdateInfo)) + +/obj/item/paper/secretrecipe/proc/UpdateInfo() + var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id) + if(!recipe) + info = "This recipe is illegible." + var/list/dat = list("
      ") + for(var/rid in recipe.required_reagents) + var/datum/reagent/R = GLOB.chemical_reagents_list[rid] + dat += "
    • [recipe.required_reagents[rid]]u of [R.name]
    • " + dat += "
    " + if(recipe.required_catalysts.len) + dat += "With following present:
      " + for(var/rid in recipe.required_catalysts) + var/datum/reagent/R = GLOB.chemical_reagents_list[rid] + dat += "
    • [recipe.required_catalysts[rid]]u of [R.name]
    • " + dat += "
    " + dat += "Mix slowly" + if(recipe.required_container) + var/obj/item/I = recipe.required_container + dat += " in [initial(I.name)]" + if(recipe.required_temp != 0) + if(recipe.is_cold_recipe) + dat += " below [recipe.required_temp] degrees" + else + dat += " above [recipe.required_temp] degrees" + dat += "." + info = dat.Join("") + update_icon() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm index 22e21b1db0..726175a6c6 100644 --- a/code/modules/reagents/chemistry/recipes/toxins.dm +++ b/code/modules/reagents/chemistry/recipes/toxins.dm @@ -119,3 +119,10 @@ id = "mimesbane" results = list("mimesbane" = 3) required_reagents = list("radium" = 1, "mutetoxin" = 1, "nothing" = 1) + +/datum/chemical_reaction/bonehurtingjuice + name = "Bone Hurting Juice" + id = "bonehurtingjuice" + results = list("bonehurtingjuice" = 5) + required_reagents = list("mutagen" = 1, "itching_powder" = 3, "milk" = 1) + mix_message = "The mixture suddenly becomes clear and looks a lot like water. You feel a strong urge to drink it." 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..9d10b9356a 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 @@ -53,7 +53,7 @@ /obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity) . = ..() - if((!proximity) || !check_allowed_items(target,target_self=1)) + if((!proximity) || !spillable || !check_allowed_items(target,target_self=1)) return if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. @@ -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 ed2ca66aae..280337e686 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -46,6 +46,9 @@ M.visible_message("[user] forces [M] to [apply_method] [src].", \ "[user] forces [M] to [apply_method] [src].") + var/makes_me_think = pick(strings("redpill.json", "redpill_questions")) + if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "[makes_me_think]"), 50) log_combat(user, M, "fed", reagents.log_list()) if(reagents.total_volume) 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..cc83eb28f6 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" @@ -262,3 +259,92 @@ /obj/item/reagent_containers/syringe/get_belt_overlay() return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") + +/obj/item/reagent_containers/syringe/dart + name = "medicinal smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + volume = 20 + amount_per_transfer_from_this = 20 + icon_state = "empty" + item_state = "syringe_empty" + var/emptrig = FALSE + +/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity) + + if(busy) + return + if(!proximity) + return + if(!target.reagents) + return + + var/mob/living/L + if(isliving(target)) + L = target + if(!L.can_inject(user, 1)) + return + + switch(mode) + if(SYRINGE_DRAW) + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "The dart is full!") + return + + if(L) //living mob + to_chat(user, "You can't draw blood using a dart!") + return + + else //if not mob + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty!") + return + + if(!target.is_drawable()) + to_chat(user, "You cannot directly remove reagents from [target]!") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + + to_chat(user, "You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.") + if (reagents.total_volume >= reagents.maximum_volume) + mode=!mode + update_icon() + + if(SYRINGE_INJECT) + src.visible_message("The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!") + +/obj/item/reagent_containers/syringe/dart/attack_self(mob/user) + return + +/obj/item/reagent_containers/syringe/dart/update_icon() + cut_overlays() + var/rounded_vol + + rounded_vol = "empty" + if(reagents && reagents.total_volume) + if(volume/reagents.total_volume == 1) + rounded_vol="full" + + icon_state = "[rounded_vol]" + item_state = "syringe_[rounded_vol]" + if(ismob(loc)) + var/mob/M = loc + var/injoverlay + switch(mode) + if (SYRINGE_DRAW) + injoverlay = "draw" + if (SYRINGE_INJECT) + injoverlay = "ready" + add_overlay(injoverlay) + M.update_inv_hands() + +/obj/item/reagent_containers/syringe/dart/emp_act(severity) + emptrig = TRUE + ..() + +/obj/item/reagent_containers/syringe/dart/bluespace + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + amount_per_transfer_from_this = 50 + volume = 50 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 173fd5a813..0000000000 --- a/code/modules/research/designs/autolathe_designs.dm +++ /dev/null @@ -1,888 +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") - -/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") 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..0300658a84 --- /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") 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/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..65a435a309 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm @@ -0,0 +1,46 @@ +///////////////////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/minesweeper + name = "Computer Design (Minesweeper Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new Minesweeper machine." + id = "arcade_minesweeper" + build_path = /obj/item/circuitboard/computer/arcade/minesweeper + 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/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 3ee7d344dc..7ccc41c232 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -219,7 +219,7 @@ /datum/design/mech_missile_rack name = "Exosuit Weapon (SRM-8 Missile Rack)" - desc = "Allows for the construction of SRM-8 Missile Rack." + desc = "Allows for the construction of an SRM-8 Missile Rack." id = "mech_missile_rack" build_type = MECHFAB build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index aea3a3755f..3a7ef68903 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." @@ -112,6 +92,36 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/medicinalsmartdart + name = "Medicinal Smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + id = "medicinalsmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 100, MAT_PLASTIC = 100, MAT_METAL = 100) + build_path = /obj/item/reagent_containers/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/bluespacesmartdart + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + id = "bluespacesmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 250, MAT_PLASTIC = 250, MAT_METAL = 250, MAT_BLUESPACE = 250) + build_path = /obj/item/reagent_containers/syringe/dart/bluespace + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/smartdartgun + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + id = "smartdartgun" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_PLASTIC = 1000, MAT_METAL = 500) + build_path = /obj/item/gun/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/bluespacebodybag name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." @@ -162,6 +172,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 +192,26 @@ 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 + +/datum/design/organbox + name = "Empty Organ Box" + desc = "A large cool box that can hold large amouts of medical tools or organs." + id = "organbox" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_SILVER= 3500, MAT_GOLD = 3500, MAT_PLASTIC = 5000) + build_path = /obj/item/storage/belt/organbox + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + //////////////////////////////////////// //////////Defibrillator Tech//////////// //////////////////////////////////////// @@ -196,8 +236,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 +247,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 +258,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 +269,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 +279,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 +628,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..59df0f6e85 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -1,471 +1,517 @@ - -///////////////////////////////////////// -/////////////////HUDs//////////////////// -///////////////////////////////////////// - -/datum/design/health_hud - name = "Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." - id = "health_hud" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/health - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/health_hud_prescription - name = "Prescription Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. This one has a prescription lens." - id = "health_hud_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/hud/health/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/health_hud_night - name = "Night Vision Health Scanner HUD" - desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." - id = "health_hud_night" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/hud/health/night - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/security_hud - name = "Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." - id = "security_hud" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/security - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/security_hud_prescription - name = "Prescription Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status. This one has a prescription lens." - id = "security_hud_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/hud/security/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - - -/datum/design/security_hud_night - name = "Night Vision Security HUD" - desc = "A heads-up display which provides id data and vision in complete darkness." - id = "security_hud_night" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) - build_path = /obj/item/clothing/glasses/hud/security/night - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/diagnostic_hud - name = "Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery." - id = "diagnostic_hud" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/diagnostic - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/diagnostic_hud_prescription - name = "Prescription Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery. This one has a prescription lens." - id = "diagnostic_hud_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 350) - build_path = /obj/item/clothing/glasses/hud/diagnostic/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/diagnostic_hud_night - name = "Night Vision Diagnostic HUD" - desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." - id = "diagnostic_hud_night" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) - build_path = /obj/item/clothing/glasses/hud/diagnostic/night - 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" - 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/mesons - name = "Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." - id = "mesons" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/mesons_prescription - name = "Prescription Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition. Prescription lens has been added into this design." - id = "mesons_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/meson/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/engine_goggles - name = "Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." - id = "engine_goggles" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) - build_path = /obj/item/clothing/glasses/meson/engine - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/engine_goggles_prescription - name = "Prescription Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "engine_goggles_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/meson/engine/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/tray_goggles - name = "Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes." - id = "tray_goggles" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson/engine/tray - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/tray_goggles_prescription - name = "Prescription Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "tray_goggles_prescription" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 150) - build_path = /obj/item/clothing/glasses/meson/engine/tray/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/nvgmesons - name = "Night Vision Optical Meson Scanners" - desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." - id = "nvgmesons" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/meson/night - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO - -/datum/design/night_vision_goggles - name = "Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered." - id = "night_visision_goggles" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/night - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY - -/datum/design/night_vision_goggles_glasses - name = "Prescription Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered. Corrects vision." - id = "night_visision_goggles_glasses" - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/night/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/magboots - name = "Magnetic Boots" - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." - id = "magboots" - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) - build_path = /obj/item/clothing/shoes/magboots - 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." - id = "diskplantgene" - build_type = PROTOLATHE - materials = list(MAT_METAL=200, MAT_GLASS=100) - build_path = /obj/item/disk/plantgene - category = list("Electronics") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/roastingstick - name = "Advanced roasting stick" - desc = "A roasting stick for cooking sausages in exotic ovens." - id = "roastingstick" - build_type = PROTOLATHE - materials = list(MAT_METAL=1000, MAT_GLASS=500, MAT_BLUESPACE = 250) - build_path = /obj/item/melee/roastingstick - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/locator - name = "Bluespace locator" - desc = "Used to track portable teleportation beacons and targets with embedded tracking implants." - id = "locator" - build_type = PROTOLATHE - materials = list(MAT_METAL=1000, MAT_GLASS=500, MAT_SILVER = 500) - build_path = /obj/item/locator - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -///////////////////////////////////////// -////////////Janitor Designs////////////// -///////////////////////////////////////// - -/datum/design/advmop - name = "Advanced Mop" - desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." - id = "advmop" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 200) - build_path = /obj/item/mop/advanced - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/blutrash - name = "Trashbag of Holding" - desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." - id = "blutrash" - build_type = PROTOLATHE - materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) - build_path = /obj/item/storage/bag/trash/bluespace - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/buffer - name = "Floor Buffer Upgrade" - desc = "A floor buffer that can be attached to vehicular janicarts." - id = "buffer" - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 200) - build_path = /obj/item/janiupgrade - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/holosign - name = "Holographic Sign Projector" - desc = "A holograpic projector used to project various warning signs." - id = "holosign" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) - build_path = /obj/item/holosign_creator - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/holosignsec - name = "Security Holobarrier Projector" - desc = "A holographic projector that creates holographic security barriers." - id = "holosignsec" - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) - build_path = /obj/item/holosign_creator/security - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/holosignengi - name = "Engineering Holobarrier Projector" - desc = "A holographic projector that creates holographic engineering barriers." - id = "holosignengi" - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) - build_path = /obj/item/holosign_creator/engineering - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/holosignatmos - name = "ATMOS Holofan Projector" - desc = "A holographic projector that creates holographic barriers that prevent changes in atmospheric conditions." - id = "holosignatmos" - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) - build_path = /obj/item/holosign_creator/atmos - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -///////////////////////////////////////// -////////////Tools////////////// -///////////////////////////////////////// - -/datum/design/exwelder - name = "Experimental Welding Tool" - desc = "An experimental welder capable of self-fuel generation." - id = "exwelder" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) - build_path = /obj/item/weldingtool/experimental - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/handdrill - name = "Hand Drill" - desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" - id = "handdrill" - build_type = PROTOLATHE - materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) - build_path = /obj/item/screwdriver/power - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/jawsoflife - name = "Jaws of Life" - desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" - id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP - build_path = /obj/item/crowbar/power - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwrench - name = "Alien Wrench" - desc = "An advanced wrench obtained through Abductor technology." - id = "alien_wrench" - build_path = /obj/item/wrench/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwirecutters - name = "Alien Wirecutters" - desc = "Advanced wirecutters obtained through Abductor technology." - id = "alien_wirecutters" - build_path = /obj/item/wirecutters/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienscrewdriver - name = "Alien Screwdriver" - desc = "An advanced screwdriver obtained through Abductor technology." - id = "alien_screwdriver" - build_path = /obj/item/screwdriver/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/aliencrowbar - name = "Alien Crowbar" - desc = "An advanced crowbar obtained through Abductor technology." - id = "alien_crowbar" - build_path = /obj/item/crowbar/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwelder - name = "Alien Welding Tool" - desc = "An advanced welding tool obtained through Abductor technology." - id = "alien_welder" - build_path = /obj/item/weldingtool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienmultitool - name = "Alien Multitool" - desc = "An advanced multitool obtained through Abductor technology." - id = "alien_multitool" - build_path = /obj/item/multitool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/anomaly_neutralizer - name = "Anomaly Neutralizer" - desc = "An advanced tool capable of instantly neutralizing anomalies, designed to capture the fleeting aberrations created by the engine." - id = "anomaly_neutralizer" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GOLD = 2000, MAT_PLASMA = 5000, MAT_URANIUM = 2000) - build_path = /obj/item/anomaly_neutralizer - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING - -///////////////////////////////////////// -////////////Armour////////////// -///////////////////////////////////////// - -/datum/design/reactive_armour - name = "Reactive Armour Shell" - desc = "An experimental suit of armour capable of utilizing an implanted anomaly core to protect the user." - id = "reactive_armour" - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000) - build_path = /obj/item/reactive_armour_shell - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +///////////////////////////////////////// +/////////////////HUDs//////////////////// +///////////////////////////////////////// + +/datum/design/health_hud + name = "Health Scanner HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." + id = "health_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/health + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/health_hud_prescription + name = "Prescription Health Scanner HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. This one has a prescription lens." + id = "health_hud_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/hud/health/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/health_hud_night + name = "Night Vision Health Scanner HUD" + desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." + id = "health_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/hud/health/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/security_hud + name = "Security HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." + id = "security_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/security + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/security_hud_prescription + name = "Prescription Security HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status. This one has a prescription lens." + id = "security_hud_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/hud/security/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/security_hud_night + name = "Night Vision Security HUD" + desc = "A heads-up display which provides id data and vision in complete darkness." + id = "security_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) + build_path = /obj/item/clothing/glasses/hud/security/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/diagnostic_hud + name = "Diagnostic HUD" + desc = "A HUD used to analyze and determine faults within robotic machinery." + id = "diagnostic_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/diagnostic + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/diagnostic_hud_prescription + name = "Prescription Diagnostic HUD" + desc = "A HUD used to analyze and determine faults within robotic machinery. This one has a prescription lens." + id = "diagnostic_hud_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 350) + build_path = /obj/item/clothing/glasses/hud/diagnostic/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/diagnostic_hud_night + name = "Night Vision Diagnostic HUD" + desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." + id = "diagnostic_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) + build_path = /obj/item/clothing/glasses/hud/diagnostic/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/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/mesons + name = "Optical Meson Scanners" + desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." + id = "mesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/mesons_prescription + name = "Prescription Optical Meson Scanners" + desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition. Prescription lens has been added into this design." + id = "mesons_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/meson/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/engine_goggles + name = "Engineering Scanner Goggles" + desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." + id = "engine_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) + build_path = /obj/item/clothing/glasses/meson/engine + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/engine_goggles_prescription + name = "Prescription Engineering Scanner Goggles" + desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes. Prescription lens has been added into this design." + id = "engine_goggles_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/meson/engine/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/tray_goggles + name = "Optical T-Ray Scanners" + desc = "Used by engineering staff to see underfloor objects such as cables and pipes." + id = "tray_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson/engine/tray + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/tray_goggles_prescription + name = "Prescription Optical T-Ray Scanners" + desc = "Used by engineering staff to see underfloor objects such as cables and pipes. Prescription lens has been added into this design." + id = "tray_goggles_prescription" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 150) + build_path = /obj/item/clothing/glasses/meson/engine/tray/prescription + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/nvgmesons + name = "Night Vision Optical Meson Scanners" + desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." + id = "nvgmesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/meson/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/night_vision_goggles + name = "Night Vision Goggles" + desc = "Goggles that let you see through darkness unhindered." + id = "night_visision_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/night_vision_goggles_glasses + name = "Prescription Night Vision Goggles" + desc = "Goggles that let you see through darkness unhindered. Corrects vision." + id = "night_visision_goggles_glasses" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/night/prescription + 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." + id = "magboots" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) + build_path = /obj/item/clothing/shoes/magboots + 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." + id = "diskplantgene" + build_type = PROTOLATHE + materials = list(MAT_METAL=200, MAT_GLASS=100) + build_path = /obj/item/disk/plantgene + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/roastingstick + name = "Advanced roasting stick" + desc = "A roasting stick for cooking sausages in exotic ovens." + id = "roastingstick" + build_type = PROTOLATHE + materials = list(MAT_METAL=1000, MAT_GLASS=500, MAT_BLUESPACE = 250) + build_path = /obj/item/melee/roastingstick + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/locator + name = "Bluespace locator" + desc = "Used to track portable teleportation beacons and targets with embedded tracking implants." + id = "locator" + build_type = PROTOLATHE + materials = list(MAT_METAL=1000, MAT_GLASS=500, MAT_SILVER = 500) + build_path = /obj/item/locator + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +///////////////////////////////////////// +////////////Janitor Designs////////////// +///////////////////////////////////////// + +/datum/design/advmop + name = "Advanced Mop" + desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." + id = "advmop" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 200) + build_path = /obj/item/mop/advanced + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/blutrash + name = "Trashbag of Holding" + desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." + id = "blutrash" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) + build_path = /obj/item/storage/bag/trash/bluespace + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/buffer + name = "Floor Buffer Upgrade" + desc = "A floor buffer that can be attached to vehicular janicarts." + id = "buffer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 200) + build_path = /obj/item/janiupgrade + 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." + id = "holosign" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) + build_path = /obj/item/holosign_creator + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/holosignsec + name = "Security Holobarrier Projector" + desc = "A holographic projector that creates holographic security barriers." + id = "holosignsec" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) + build_path = /obj/item/holosign_creator/security + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/holosignengi + name = "Engineering Holobarrier Projector" + desc = "A holographic projector that creates holographic engineering barriers." + id = "holosignengi" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) + build_path = /obj/item/holosign_creator/engineering + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/holosignatmos + name = "ATMOS Holofan Projector" + desc = "A holographic projector that creates holographic barriers that prevent changes in atmospheric conditions." + id = "holosignatmos" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) + build_path = /obj/item/holosign_creator/atmos + 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" + desc = "An experimental welder capable of self-fuel generation." + id = "exwelder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) + build_path = /obj/item/weldingtool/experimental + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/handdrill + name = "Hand Drill" + desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" + id = "handdrill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) + build_path = /obj/item/screwdriver/power + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/jawsoflife + name = "Jaws of Life" + desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" + id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP + build_path = /obj/item/crowbar/power + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwrench + name = "Alien Wrench" + desc = "An advanced wrench obtained through Abductor technology." + id = "alien_wrench" + build_path = /obj/item/wrench/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwirecutters + name = "Alien Wirecutters" + desc = "Advanced wirecutters obtained through Abductor technology." + id = "alien_wirecutters" + build_path = /obj/item/wirecutters/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienscrewdriver + name = "Alien Screwdriver" + desc = "An advanced screwdriver obtained through Abductor technology." + id = "alien_screwdriver" + build_path = /obj/item/screwdriver/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/aliencrowbar + name = "Alien Crowbar" + desc = "An advanced crowbar obtained through Abductor technology." + id = "alien_crowbar" + build_path = /obj/item/crowbar/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwelder + name = "Alien Welding Tool" + desc = "An advanced welding tool obtained through Abductor technology." + id = "alien_welder" + build_path = /obj/item/weldingtool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienmultitool + name = "Alien Multitool" + desc = "An advanced multitool obtained through Abductor technology." + id = "alien_multitool" + build_path = /obj/item/multitool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/anomaly_neutralizer + name = "Anomaly Neutralizer" + desc = "An advanced tool capable of instantly neutralizing anomalies, designed to capture the fleeting aberrations created by the engine." + id = "anomaly_neutralizer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GOLD = 2000, MAT_PLASMA = 5000, MAT_URANIUM = 2000) + build_path = /obj/item/anomaly_neutralizer + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +///////////////////////////////////////// +////////////Armour/////////////////////// +///////////////////////////////////////// + +/datum/design/reactive_armour + name = "Reactive Armour Shell" + desc = "An experimental suit of armour capable of utilizing an implanted anomaly core to protect the user." + id = "reactive_armour" + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000) + build_path = /obj/item/reactive_armour_shell + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +///////////////////////////////////////// +////////////Meteor/////////////////////// +///////////////////////////////////////// + +/datum/design/meteor_defence + name = "Meteor Defence" + desc = "A blue print of a early model of the Meteor defence turret." + id = "meteor_defence" + build_type = PROTOLATHE + materials = list(MAT_METAL = 50000, MAT_GLASS = 50000, MAT_SILVER = 8500, MAT_GOLD = 8500, MAT_TITANIUM = 7500, MAT_URANIUM = 7500) + build_path = /obj/machinery/satellite/meteor_shield/sci + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/meteor_disk + name = "Meteor Defence Upgrade Disk" + desc = "A disk containing debugging programming to solve and monitor meteors more effectively." + id = "meteor_disk" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1500, MAT_GLASS = 1500, MAT_SILVER = 2500, MAT_GOLD = 1000) + build_path = /obj/item/disk/meteor + category = list("Electronics") + 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 diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index f2f21396d2..c2cbb5685e 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -7,10 +7,9 @@ materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT) build_path = /obj/item/stack/sheet/plasteel category = list("initial", "Stock Parts") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SECURITY 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 03c0582245..214ef36afe 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -330,8 +330,8 @@ 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." + name = "Suppressor" + desc = "A reverse-engineered suppressor that fits on most small arms with threaded barrels." id = "suppressor" build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 500) 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.dm b/code/modules/research/nanites/nanite_programs.dm index f691c828c9..a06311f26f 100644 --- a/code/modules/research/nanites/nanite_programs.dm +++ b/code/modules/research/nanites/nanite_programs.dm @@ -57,6 +57,7 @@ deactivate() if(passive_enabled) disable_passive_effect() + on_mob_remove() if(nanites) nanites.programs -= src return ..() @@ -107,6 +108,9 @@ if(activated) //apply activation effects if it starts active activate() +datum/nanite_program/proc/on_mob_remove() + return + /datum/nanite_program/proc/toggle() if(!activated) activate() @@ -115,6 +119,7 @@ /datum/nanite_program/proc/activate() activated = TRUE + timer_counter = activation_delay /datum/nanite_program/proc/deactivate() if(passive_enabled) @@ -135,8 +140,10 @@ if(timer && timer_counter > timer) if(timer_type == NANITE_TIMER_DEACTIVATE) deactivate() + return else if(timer_type == NANITE_TIMER_SELFDELETE) qdel(src) + return else if(can_trigger && timer_type == NANITE_TIMER_TRIGGER) trigger() timer_counter = activation_delay @@ -251,4 +258,3 @@ return "Trigger" if(NANITE_TIMER_RESET) return "Reset Activation Timer" - 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..d3a268047e 100644 --- a/code/modules/research/nanites/nanite_programs/healing.dm +++ b/code/modules/research/nanites/nanite_programs/healing.dm @@ -70,9 +70,13 @@ rogue_types = list(/datum/nanite_program/brain_decay) /datum/nanite_program/brain_heal/check_conditions() - if(!host_mob.getBrainLoss()) - return FALSE - return ..() + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + if(length(C.get_traumas())) + return ..() + if(host_mob.getBrainLoss()) + return ..() + return FALSE /datum/nanite_program/brain_heal/active_effect() host_mob.adjustBrainLoss(-1, TRUE) @@ -187,10 +191,14 @@ rogue_types = list(/datum/nanite_program/brain_decay, /datum/nanite_program/brain_misfire) /datum/nanite_program/brain_heal_advanced/check_conditions() - if(!host_mob.getBrainLoss()) - return FALSE - return ..() - + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + if(length(C.get_traumas())) + return ..() + if(host_mob.getBrainLoss()) + return ..() + return FALSE + /datum/nanite_program/brain_heal_advanced/active_effect() host_mob.adjustBrainLoss(-2, TRUE) if(iscarbon(host_mob) && prob(10)) @@ -215,7 +223,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/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 4405401cec..77fb4e1005 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -237,7 +237,11 @@ if(prob(10)) var/list/mob/living/target_hosts = list() for(var/mob/living/L in oview(5, host_mob)) + if(!(MOB_ORGANIC in L.mob_biotypes) && !(MOB_UNDEAD in L.mob_biotypes)) + continue target_hosts += L + if(!target_hosts.len) + return var/mob/living/infectee = pick(target_hosts) if(prob(100 - (infectee.get_permeability_protection() * 100))) //this will potentially take over existing nanites! diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm index 268e6a1be9..2ec2398d88 100644 --- a/code/modules/research/research_disk.dm +++ b/code/modules/research/research_disk.dm @@ -20,3 +20,12 @@ /obj/item/disk/tech_disk/debug/Initialize() . = ..() stored_research = new /datum/techweb/admin + +/obj/item/disk/tech_disk/illegal + name = "Illegal technology disk" + desc = "A technology disk containing schematics for syndicate inspired equipment." + materials = list() + +/obj/item/disk/tech_disk/illegal/Initialize() + . = ..() + stored_research = new /datum/techweb/syndicate diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index dbfca477d6..cd5a190fd6 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -41,6 +41,14 @@ research_points[i] = INFINITY hidden_nodes = list() +/datum/techweb/syndicate + id = "SYNDICATE" + organization = "Syndicate" + +/datum/techweb/syndicate/New() + var/datum/techweb_node/syndicate_basic/Node = new() + research_node(Node, TRUE) + /datum/techweb/science //Global science techweb for RND consoles. id = "SCIENCE" organization = "Nanotrasen" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index aa091d181c..c6487c92f0 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -69,7 +69,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -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) @@ -115,7 +115,7 @@ display_name = "Advanced Surgery" description = "When simple medicine doesn't cut it." prereq_ids = list("adv_biotech") - design_ids = list("surgery_lobotomy", "surgery_reconstruction") + design_ids = list("surgery_lobotomy", "surgery_reconstruction", "organbox") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -203,6 +203,24 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) export_price = 5000 +/datum/techweb_node/basic_meteor_defense + id = "basic_meteor_defense" + display_name = "Meteor Defense Research" + description = "Unlock the potential of the mysterious of why CC decided to not build these around the station themselves." + prereq_ids = list("adv_engi", "high_efficiency") + design_ids = list("meteor_defence", "meteor_console") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +//datum/techweb_node/adv_meteor_defense + //id = "adv_meteor_defense" + //display_name = "Meteor Defense Research" + //description = "New and improved coding and lock on tech for meteor defence!" + //prereq_ids = list("basic_meteor_defense", "adv_datatheory", "emp_adv") + //design_ids = list("meteor_disk") + //research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) + //export_price = 5000 + /////////////////////////Bluespace tech///////////////////////// /datum/techweb_node/bluespace_basic //Bluespace-memery id = "bluespace_basic" @@ -213,23 +231,22 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 -/datum/techweb_node/adv_bluespace - id = "adv_bluespace" - display_name = "Advanced Bluespace Research" - description = "Deeper understanding of how the Bluespace dimension works" - prereq_ids = list("practical_bluespace", "high_efficiency") - design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", - "teleconsole", "bluespace_crystal", "wormholeprojector") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000) - export_price = 5000 - /datum/techweb_node/practical_bluespace id = "practical_bluespace" display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +/datum/techweb_node/adv_bluespace + id = "adv_bluespace" + display_name = "Advanced Bluespace Research" + description = "Deeper understanding of how the Bluespace dimension works" + prereq_ids = list("practical_bluespace", "high_efficiency") + design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "bluespace_crystal") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) export_price = 5000 /datum/techweb_node/bluespace_power @@ -241,7 +258,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 -/datum/techweb_node/bluespace_holding //Bluespace-memery +/datum/techweb_node/bluespace_holding id = "bluespace_holding" display_name = "Bluespace Pockets" description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." @@ -249,6 +266,25 @@ 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 + +/datum/techweb_node/bluespace_portal + id = "bluespace_portal" + display_name = "Bluespace Portals" + description = "Allows for Bluespace Tech to be used tandem with Wormhole tech." + prereq_ids = list("adv_weaponry", "adv_bluespace") + design_ids = list("wormholeprojector") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + +/datum/techweb_node/bluespace_warping + id = "bluespace_warping" + display_name = "Bluespace Teleportation tech" + description = "Traversing through space at an instant with Bluespace." + prereq_ids = list("adv_power", "adv_bluespace") + design_ids = list( "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", "teleconsole", "roastingstick") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + /////////////////////////plasma tech///////////////////////// /datum/techweb_node/basic_plasma id = "basic_plasma" @@ -527,7 +563,7 @@ display_name = "Advanced Mining Technology" description = "Efficiency Level 127" //dumb mc references prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma") - design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv") + design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv", "ore_silo") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 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/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm index 1138f65105..141e6b1fe1 100644 --- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm +++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm @@ -7,7 +7,7 @@ item_state = "bloodgun" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - item_flags = ABSTRACT | DROPDEL | NODROP + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 5 max_charges = 1 //Recharging costs blood. @@ -15,6 +15,10 @@ ammo_type = /obj/item/ammo_casing/magic/bloodchill fire_sound = 'sound/effects/attackblob.ogg' +/obj/item/gun/magic/bloodchill/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) + /obj/item/gun/magic/bloodchill/process() charge_tick++ if(charge_tick < recharge_rate || charges >= max_charges) 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..ff55a87dfa 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!") @@ -188,6 +186,7 @@ Chilling extracts: /obj/item/slimecross/chilling/sepia/do_effect(mob/user) user.visible_message("[src] shatters, freezing time itself!") + allies -= user //support class new /obj/effect/timestop(get_turf(user), 2, 300, allies) ..() @@ -269,7 +268,7 @@ Chilling extracts: addtimer(CALLBACK(src, .proc/boom), 50) /obj/item/slimecross/chilling/oil/proc/boom() - explosion(get_turf(src), -1, -1, 3, 10) //Large radius, but mostly light damage. + explosion(get_turf(src), -1, -1, 10, 0) //Large radius, but mostly light damage, and no flash. qdel(src) /obj/item/slimecross/chilling/black @@ -309,4 +308,4 @@ Chilling extracts: user.visible_message("[src] reflects an array of dazzling colors and light, energy rushing to nearby doors!") for(var/obj/machinery/door/airlock/door in area) new /obj/effect/forcefield/slimewall/rainbow(door.loc) - return ..() + return ..() \ No newline at end of file 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..ce36be8e42 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) @@ -634,6 +633,12 @@ to_chat(user, "The slime is dead!") return + if(M.rabid) //Stops being rabid, but doesn't become truly docile. + to_chat(M, "You absorb the potion, and your rabid hunger finally settles to a normal desire to feed.") + to_chat(user, "You feed the slime the potion, calming its rabid rage.") + M.rabid = FALSE + qdel(src) + return M.docile = 1 M.nutrition = 700 to_chat(M, "You absorb the potion and feel your intense desire to feed melt away.") @@ -703,7 +708,7 @@ imp.implant(SM, user) SM.access_card = new /obj/item/card/id/syndicate(SM) - SM.access_card.item_flags |= NODROP + ADD_TRAIT(SM.access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /obj/item/slimepotion/transference name = "consciousness transference potion" diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index b8d19a7018..92a637ce43 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/plant_disk/Initialize() + . = ..() + var/datum/design/diskplantgene/P = new + blueprints[1] = P + //Free Golems /obj/item/disk/design_disk/golem_shell @@ -70,7 +81,11 @@ /obj/item/stack/sheet/cloth = /datum/species/golem/cloth, /obj/item/stack/sheet/mineral/adamantine = /datum/species/golem/adamantine, /obj/item/stack/sheet/plastic = /datum/species/golem/plastic, - /obj/item/stack/tile/brass = /datum/species/golem/clockwork) + /obj/item/stack/tile/brass = /datum/species/golem/clockwork, + /obj/item/stack/tile/bronze = /datum/species/golem/bronze, + /obj/item/stack/sheet/cardboard = /datum/species/golem/cardboard, + /obj/item/stack/sheet/leather = /datum/species/golem/leather, + /obj/item/stack/sheet/bone = /datum/species/golem/bone) if(istype(I, /obj/item/stack)) var/obj/item/stack/O = I diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm index 86132cf834..1258b9f4b8 100644 --- a/code/modules/shuttle/assault_pod.dm +++ b/code/modules/shuttle/assault_pod.dm @@ -35,7 +35,9 @@ /obj/item/assault_pod/attack_self(mob/living/user) var/target_area - target_area = input("Area to land", "Select a Landing Zone", target_area) in GLOB.teleportlocs + target_area = input("Area to land", "Select a Landing Zone", target_area) as null|anything in GLOB.teleportlocs + if(!target_area) + return var/area/picked_area = GLOB.teleportlocs[target_area] if(!src || QDELETED(src)) return diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 9af4194049..020b4b29ab 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -199,7 +199,7 @@ . = ..() -/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null) +/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null, silent = FALSE) if(!isnum(set_coefficient)) var/security_num = seclevel2num(get_security_level()) switch(security_num) @@ -228,7 +228,8 @@ else SSshuttle.emergencyLastCallLoc = null - priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority") + if(!silent) + priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority") /obj/docking_port/mobile/emergency/cancel(area/signalOrigin) if(mode != SHUTTLE_CALL) @@ -516,10 +517,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 +536,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/shuttle/special.dm b/code/modules/shuttle/special.dm index fd5f2f59fd..d1435a554c 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -165,7 +165,7 @@ var/datum/job/captain/C = new /datum/job/captain access_card.access = C.get_access() access_card.access |= ACCESS_CENT_BAR - access_card.item_flags |= NODROP + ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /mob/living/simple_animal/hostile/alien/maid/barmaid/Destroy() qdel(access_card) 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/barnyard.dm b/code/modules/spells/spell_types/barnyard.dm index 01b24fef98..ccb0280779 100644 --- a/code/modules/spells/spell_types/barnyard.dm +++ b/code/modules/spells/spell_types/barnyard.dm @@ -37,20 +37,15 @@ "Your face starts burning up, but the flames are repulsed by your anti-magic protection!") return - var/list/masks = list(/obj/item/clothing/mask/spig, /obj/item/clothing/mask/cowmask, /obj/item/clothing/mask/horsehead) - var/list/mSounds = list('sound/magic/pighead_curse.ogg', 'sound/magic/cowhead_curse.ogg', 'sound/magic/horsehead_curse.ogg') - var/randM = rand(1,3) + var/list/masks = list(/obj/item/clothing/mask/pig/cursed, /obj/item/clothing/mask/cowmask/cursed, /obj/item/clothing/mask/horsehead/cursed) - - var/choice = masks[randM] - var/obj/item/clothing/mask/magichead = new choice - magichead.item_flags |= NODROP + var/choice = pick(masks) + var/obj/item/clothing/mask/magichead = new choice(get_turf(target)) magichead.flags_inv = null target.visible_message("[target]'s face bursts into flames, and a barnyard animal's head takes its place!", \ "Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!") if(!target.dropItemToGround(target.wear_mask)) qdel(target.wear_mask) target.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, 1, 1) - playsound(get_turf(target), mSounds[randM], 50, 1) target.flash_act() diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index 39066ae4a9..bb3cc1f7e3 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -146,11 +146,14 @@ clothes_req = 0 invocation = "none" invocation_type = "none" + proj_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser proj_lifespan = 10 max_targets = 6 action_icon_state = "magicm" action_background_icon_state = "bg_demon" +/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser + amt_knockdown = 84 /obj/effect/proc_holder/spell/targeted/smoke/disable name = "Paralysing Smoke" @@ -304,7 +307,8 @@ name = "Gauntlet Echo" alpha = 180 amt_dam_brute = 30 - amt_knockdown = 50 + amt_knockdown = 84 + amt_dam_stam = 30 sound = 'sound/weapons/punch3.ogg' /obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut/cast(list/targets,mob/user = usr) 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..a5f371ffc2 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "syndballoon" item_state = null - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 0 throwforce = 0 @@ -15,6 +15,10 @@ throw_speed = 0 var/charges = 1 +/obj/item/melee/touch_attack/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user) if(!iscarbon(user)) //Look ma, no hands return @@ -94,3 +98,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/inflict_handler.dm b/code/modules/spells/spell_types/inflict_handler.dm index da0af7a601..25bdc7c9d2 100644 --- a/code/modules/spells/spell_types/inflict_handler.dm +++ b/code/modules/spells/spell_types/inflict_handler.dm @@ -3,10 +3,12 @@ desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target." var/amt_knockdown = 0 + var/amt_hardstun var/amt_unconscious = 0 var/amt_stun = 0 //set to negatives for healing + var/amt_dam_stam var/amt_dam_fire = 0 var/amt_dam_brute = 0 var/amt_dam_oxy = 0 @@ -41,7 +43,10 @@ target.adjustToxLoss(amt_dam_tox) target.adjustOxyLoss(amt_dam_oxy) //disabling - target.Knockdown(amt_knockdown) + if(!amt_knockdown && amt_dam_stam) + target.adjustStaminaLoss(amt_dam_stam) + else + target.Knockdown(amt_knockdown, override_hardstun = amt_hardstun, amt_dam_stam) target.Unconscious(amt_unconscious) target.Stun(amt_stun) diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index d88ee7fb22..efc80101f6 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -34,7 +34,7 @@ for(var/obj/item/item in hand_items) // I ensouled the nuke disk once. But it's probably a really // mean tactic, so probably should discourage it. - if((item.item_flags & ABSTRACT) || (item.item_flags & NODROP) || SEND_SIGNAL(item, COMSIG_ITEM_IMBUE_SOUL, user)) + if((item.item_flags & ABSTRACT) || HAS_TRAIT(item, TRAIT_NODROP) || SEND_SIGNAL(item, COMSIG_ITEM_IMBUE_SOUL, user)) continue marked_item = item to_chat(M, "You begin to focus your very being into [item]...") diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index bc1fc980bb..13686e2069 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(summoned_guns, list( /obj/item/gun/ballistic/revolver/grenadelauncher, /obj/item/gun/ballistic/revolver/golden, /obj/item/gun/ballistic/automatic/sniper_rifle, + /obj/item/gun/ballistic/rocketlauncher, /obj/item/gun/medbeam, /obj/item/gun/energy/laser/scatter, /obj/item/gun/energy/gravity_gun)) diff --git a/code/modules/spells/spell_types/rod_form.dm b/code/modules/spells/spell_types/rod_form.dm index 06f38b8346..5a532db7ac 100644 --- a/code/modules/spells/spell_types/rod_form.dm +++ b/code/modules/spells/spell_types/rod_form.dm @@ -28,7 +28,6 @@ /obj/effect/immovablerod/wizard var/max_distance = 13 var/damage_bonus = 0 - var/mob/living/wizard var/turf/start_turf notify = FALSE diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm index 2bc347b185..6d46c53a9d 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -25,7 +25,7 @@ for(var/obj/item/item in hand_items) if(item.item_flags & ABSTRACT) continue - if(item.item_flags & NODROP) + if(HAS_TRAIT(item, TRAIT_NODROP)) message += "Though it feels redundant, " marked_item = item message += "You mark [item] for recall.
    " 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/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index aec0e7806b..c4d2c34a71 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -28,7 +28,8 @@ sound = 'sound/magic/magic_missile.ogg' /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile - amt_knockdown = 60 + amt_knockdown = 120 + amt_hardstun = 5 sound = 'sound/magic/mm_hit.ogg' /obj/effect/proc_holder/spell/targeted/genetic/mutate @@ -262,7 +263,7 @@ action_icon_state = "repulse" -/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 40) +/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, stun_amt = 50) var/list/thrownatoms = list() var/atom/throwtarget var/distfromcaster @@ -286,14 +287,14 @@ if(distfromcaster == 0) if(isliving(AM)) var/mob/living/M = AM - M.Knockdown(100) + M.Knockdown(100, override_hardstun = 20) M.adjustBruteLoss(5) to_chat(M, "You're slammed into the floor by [user]!") else new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own if(isliving(AM)) var/mob/living/M = AM - M.Knockdown(stun_amt) + M.Knockdown(stun_amt, override_hardstun = stun_amt * 0.2) to_chat(M, "You're thrown back by [user]!") AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. 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/station_goals/shield.dm b/code/modules/station_goals/shield.dm index 44746e595e..98f5534d06 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -134,6 +134,31 @@ speed_process = TRUE var/kill_range = 14 +/obj/machinery/satellite/meteor_shield/sci + name = "\improper Meteor Shield Satellite" + desc = "A station made meteor point-defense satellite." + mode = "M-SHIELD" + +/obj/item/disk/meteor + name = "Meteor Shield Upgrade Disk" + desc = "A floppy disk that allows meteor shields to fire at longer ranges and lowers meteor drawing from gravitational fields.." + +/obj/machinery/satellite/meteor_shield/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/disk/meteor)) + to_chat(user, "The disk uploads better tracking and rang modification software.") + kill_range = 17 + else + return ..() + +/obj/machinery/satellite/meteor_shield/sci/toggle(user) + if(!..(user)) + return FALSE + if(obj_flags & EMAGGED) + if(active) + change_meteor_chance(8) + else + change_meteor_chance(0.125) + /obj/machinery/satellite/meteor_shield/proc/space_los(meteor) for(var/turf/T in getline(src,meteor)) if(!isspaceturf(T)) @@ -177,4 +202,4 @@ obj_flags |= EMAGGED to_chat(user, "You access the satellite's debug mode, increasing the chance of meteor strikes.") if(active) - change_meteor_chance(2) + change_meteor_chance(4) 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 dfdf0fde69..a97a133685 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -21,7 +21,7 @@ var/held_index = 0 //are we a hand? if so, which one! var/is_pseudopart = FALSE //For limbs that don't really exist, eg chainsaws - var/disabled = FALSE //If TRUE, limb is as good as missing + var/disabled = BODYPART_NOT_DISABLED //If disabled, limb is as good as missing var/body_damage_coeff = 1 //Multiplier of the limb's damage that gets applied to the mob var/stam_damage_coeff = 0.5 var/brutestate = 0 @@ -48,7 +48,7 @@ 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) @@ -88,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!",\ @@ -189,7 +189,7 @@ if(stamina > DAMAGE_PRECISION) owner.update_stamina() consider_processing() - check_disabled() + update_disabled() return update_bodypart_damage_state() //Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. @@ -209,7 +209,7 @@ if(owner && updating_health) owner.updatehealth() consider_processing() - check_disabled() + update_disabled() return update_bodypart_damage_state() //Returns total damage. @@ -220,15 +220,33 @@ return total //Checks disabled status thresholds -/obj/item/bodypart/proc/check_disabled() - if(!can_dismember() || owner.has_trait(TRAIT_NODISMEMBER)) + +//Checks disabled status thresholds +/obj/item/bodypart/proc/update_disabled() + set_disabled(is_disabled()) + +/obj/item/bodypart/proc/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS)) + return BODYPART_DISABLED_PARALYSIS + if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER)) + . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled + if((get_damage(TRUE) >= max_damage)) + return BODYPART_DISABLED_DAMAGE + if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) + return BODYPART_NOT_DISABLED + else + return BODYPART_NOT_DISABLED + +/obj/item/bodypart/proc/check_disabled() //This might be depreciated and should be safe to remove. + if(!can_dismember() || HAS_TRAIT(owner, TRAIT_NODISMEMBER)) return if(!disabled && (get_damage(TRUE) >= max_damage)) set_disabled(TRUE) else if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) set_disabled(FALSE) -/obj/item/bodypart/proc/set_disabled(new_disabled = TRUE) + +/obj/item/bodypart/proc/set_disabled(new_disabled) if(disabled == new_disabled) return disabled = new_disabled @@ -261,7 +279,6 @@ icon = DEFAULT_BODYPART_ICON_ORGANIC else if(status == BODYPART_ROBOTIC) icon = DEFAULT_BODYPART_ICON_ROBOTIC - body_markings = null if(owner) owner.updatehealth() @@ -285,13 +302,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 @@ -336,17 +354,18 @@ 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_icon = Smark.icon body_markings = lowertext(H.dna.features.["mam_body_markings"]) - if(MATRIXED) - markings_color = list(colorlist) + auxmarking = lowertext(H.dna.features.["mam_body_markings"]) else body_markings = "plain" - markings_color = (H.dna.features.["mcolor"]) + auxmarking = "plain" + markings_color = list(colorlist) + else body_markings = null - markings_color = "" + auxmarking = null if(!dropping_limb && H.dna.check_mutation(HULK)) mutation_color = "00aa00" @@ -361,6 +380,7 @@ 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. @@ -385,6 +405,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) @@ -392,9 +414,13 @@ . += 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 && status != BODYPART_ROBOTIC) - if(use_digitigrade == NOT_DIGITIGRADE) - . += image(body_markings_icon, "[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(body_markings_icon, "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) @@ -417,8 +443,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 @@ -447,14 +471,17 @@ 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/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) else if(species_id == "husk" && use_digitigrade) 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(body_markings_icon, "[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(body_markings_icon, "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) . += marking @@ -464,7 +491,7 @@ 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/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir) else @@ -477,40 +504,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/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir) else 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/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) else if(species_id == "husk" && use_digitigrade) 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(body_markings_icon, "[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(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 @@ -534,6 +564,11 @@ max_stamina_damage = 200 var/obj/item/cavity_item +/obj/item/bodypart/chest/can_dismember(obj/item/I) + if(!((owner.stat == DEAD) || owner.InFullCritical())) + return FALSE + return ..() + /obj/item/bodypart/chest/Destroy() if(cavity_item) qdel(cavity_item) @@ -589,13 +624,27 @@ px_y = 0 stam_heal_tick = 2 -/obj/item/bodypart/l_arm/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/l_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_arm/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") if(held_index) owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) if(owner.hud_used) var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] if(L) @@ -640,18 +689,33 @@ stam_heal_tick = 2 max_stamina_damage = 50 -/obj/item/bodypart/r_arm/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/r_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_arm/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") if(held_index) owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) if(owner.hud_used) var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] if(R) R.update_icon() + /obj/item/bodypart/r_arm/monkey icon = 'icons/mob/animal_parts.dmi' icon_state = "default_monkey_r_arm" @@ -688,11 +752,24 @@ stam_heal_tick = 2 max_stamina_damage = 50 -/obj/item/bodypart/l_leg/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/l_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_leg/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + /obj/item/bodypart/l_leg/digitigrade name = "left digitigrade leg" @@ -735,11 +812,23 @@ max_stamina_damage = 50 stam_heal_tick = 2 -/obj/item/bodypart/r_leg/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/r_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_leg/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") /obj/item/bodypart/r_leg/digitigrade name = "right digitigrade leg" 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/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index e57f8f686b..72874e0308 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -29,7 +29,7 @@ /datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST) if(tool) - if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || (tool.item_flags & NODROP) || istype(tool, /obj/item/organ)) + if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || HAS_TRAIT(tool, TRAIT_NODROP) || istype(tool, /obj/item/organ)) to_chat(user, "You can't seem to fit [tool] in [target]'s [target_zone]!") return 0 var/obj/item/electronic_assembly/EA = tool 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/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index ad07ce7238..cb004ce599 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -89,7 +89,7 @@ holder = item - holder.item_flags |= NODROP + ADD_TRAIT(holder, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) holder.resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF holder.slot_flags = null holder.materials = null @@ -129,11 +129,14 @@ holder = null if(contents.len == 1) Extend(contents[1]) - else // TODO: make it similar to borg's storage-like module selection - var/obj/item/choise = input("Activate which item?", "Arm Implant", null, null) as null|anything in items_list - if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && istype(choise) && (choise in contents)) - // This monster sanity check is a nice example of how bad input() is. - Extend(choise) + else + var/list/choice_list = list() + for(var/obj/item/I in items_list) + choice_list[I] = getFlatIcon(I) + var/obj/item/choice = show_radial_menu(owner, owner, choice_list) + if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && (choice in contents)) + // This monster sanity check is a nice example of how bad input is. + Extend(choice) else Retract() diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 0302dd2cae..ea336bea19 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -46,7 +46,7 @@ /obj/item/organ/cyberimp/chest/reviver name = "Reviver implant" - desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + desc = "This implant will attempt to revive and heal you if you lose consciousness. For the faint of heart!" icon_state = "chest_implant" implant_color = "#AD0000" slot = ORGAN_SLOT_HEART_AID diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 6d1aebc6a3..06d523721d 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -51,8 +51,7 @@ active = !active if(active) for(var/obj/item/I in owner.held_items) - if(!(I.item_flags & NODROP)) - stored_items += I + stored_items += I var/list/L = owner.get_empty_held_indexes() if(LAZYLEN(L) == owner.held_items.len) @@ -62,7 +61,7 @@ else for(var/obj/item/I in stored_items) to_chat(owner, "Your [owner.get_held_index_name(owner.get_held_index_of_item(I))]'s grip tightens.") - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, ANTI_DROP_IMPLANT_TRAIT) else release_items() @@ -83,10 +82,9 @@ to_chat(owner, "Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!") stored_items = list() - /obj/item/organ/cyberimp/brain/anti_drop/proc/release_items() for(var/obj/item/I in stored_items) - I.item_flags &= ~NODROP + REMOVE_TRAIT(I, TRAIT_NODROP, ANTI_DROP_IMPLANT_TRAIT) stored_items = list() diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm index 787175e05d..0ba6fd7fcd 100644 --- a/code/modules/surgery/organs/autosurgeon.dm +++ b/code/modules/surgery/organs/autosurgeon.dm @@ -98,3 +98,28 @@ /obj/item/autosurgeon/reviver starting_organ = /obj/item/organ/cyberimp/chest/reviver + +/obj/item/autosurgeon/penis + desc = "A single use autosurgeon that contains a penis. A screwdriver can be used to remove it, but implants can't be placed back in." + uses = 1 + starting_organ = /obj/item/organ/genital/penis + +/obj/item/autosurgeon/testicles + desc = "A single use autosurgeon that contains a set of testicles. A screwdriver can be used to remove it, but implants can't be placed back in." + uses = 1 + starting_organ = /obj/item/organ/genital/testicles + +/obj/item/autosurgeon/vagina + desc = "A single use autosurgeon that contains a vagina. A screwdriver can be used to remove it, but implants can't be placed back in." + uses = 1 + starting_organ = /obj/item/organ/genital/vagina + +/obj/item/autosurgeon/breasts + desc = "A single use autosurgeon that contains a set of breasts. A screwdriver can be used to remove it, but implants can't be placed back in." + uses = 1 + starting_organ = /obj/item/organ/genital/breasts + +/obj/item/autosurgeon/womb + desc = "A single use autosurgeon that contains a womb. A screwdriver can be used to remove it, but implants can't be placed back in." + uses = 1 + starting_organ = /obj/item/organ/genital/womb \ No newline at end of file diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index c54d3bb532..8e191a41a9 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) @@ -94,3 +94,9 @@ H.dna.features["ears"] = "None" H.dna.species.mutant_bodyparts -= "ears" H.update_body() + +/obj/item/organ/ears/bronze + name = "tin ears" + desc = "The robust ears of a bronze golem. " + damage_multiplier = 0.1 //STRONK + bang_protect = 1 //Fear me weaklings. 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/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..ef358c48da 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,68 +278,69 @@ 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 + H.reagents.add_reagent("stimulum", max(0, 5 - existing)) + 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]) + if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE) - //Miasma sickness - if(prob(0.5 * miasma_pp)) - var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) - miasma_disease.name = "Unknown" - miasma_disease.try_infect(owner) + //Miasma sickness + if(prob(0.05 * miasma_pp)) + var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) + miasma_disease.name = "Unknown" + miasma_disease.try_infect(owner) - // Miasma side effects - switch(miasma_pp) - if(1 to 5) - // At lower pp, give out a little warning - SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") - if(prob(5)) - to_chat(owner, "There is an unpleasant smell in the air.") - if(5 to 15) - //At somewhat higher pp, warning becomes more obvious - if(prob(15)) - to_chat(owner, "You smell something horribly decayed inside this room.") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) - if(15 to 30) - //Small chance to vomit. By now, people have internals on anyway - if(prob(5)) - to_chat(owner, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - owner.vomit() - if(30 to INFINITY) - //Higher chance to vomit. Let the horror start - if(prob(15)) - to_chat(owner, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - owner.vomit() - else - SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") + // Miasma side effects + switch(miasma_pp) + if(1 to 5) + // At lower pp, give out a little warning + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") + if(prob(5)) + to_chat(owner, "There is an unpleasant smell in the air.") + if(5 to 15) + //At somewhat higher pp, warning becomes more obvious + if(prob(15)) + to_chat(owner, "You smell something horribly decayed inside this room.") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) + if(15 to 30) + //Small chance to vomit. By now, people have internals on anyway + if(prob(5)) + to_chat(owner, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + owner.vomit() + if(30 to INFINITY) + //Higher chance to vomit. Let the horror start + if(prob(15)) + to_chat(owner, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + owner.vomit() + else + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") - // In a full miasma atmosphere with 101.34 pKa, about 10 disgust per breath, is pretty low compared to threshholds - // Then again, this is a purely hypothetical scenario and hardly reachable - owner.adjust_disgust(0.1 * miasma_pp) + // In a full miasma atmosphere with 101.34 pKa, about 10 disgust per breath, is pretty low compared to threshholds + // 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 +364,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 +376,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) @@ -444,3 +443,14 @@ heat_level_1_threshold = 400 // better adapted for heat, obv. Lavaland standard is 300 heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3 +/obj/item/organ/lungs/slime + name = "vacuole" + desc = "A large organelle designed to store oxygen and other important gasses." + + safe_toxins_max = 0 //We breathe this to gain POWER. + +/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) + . = ..() + if (breath.gases[/datum/gas/plasma]) + var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma]) + owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you. 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..ccfc21f878 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -8,6 +8,7 @@ var/list/languages_possible var/say_mod = null var/taste_sensitivity = 15 // lower is more sensitive. + var/modifies_speech = FALSE var/static/list/languages_possible_base = typecacheof(list( /datum/language/common, /datum/language/draconic, @@ -17,30 +18,32 @@ /datum/language/beachbum, /datum/language/ratvar, /datum/language/aphasia, + /datum/language/slime, )) /obj/item/organ/tongue/Initialize(mapload) . = ..() languages_possible = languages_possible_base -/obj/item/organ/tongue/get_spans() - return list() - -/obj/item/organ/tongue/proc/TongueSpeech(var/message) - return message +/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args) /obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = say_mod + if (modifies_speech) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + M.UnregisterSignal(M, COMSIG_MOB_SAY) /obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = initial(M.dna.species.say_mod) + UnregisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + M.RegisterSignal(M, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech) /obj/item/organ/tongue/could_speak_in_language(datum/language/dt) - . = is_type_in_typecache(dt, languages_possible) + return is_type_in_typecache(dt, languages_possible) /obj/item/organ/tongue/lizard name = "forked tongue" @@ -48,14 +51,16 @@ icon_state = "tonguelizard" say_mod = "hisses" taste_sensitivity = 10 // combined nose + tongue, extra sensitive + modifies_speech = TRUE -/obj/item/organ/tongue/lizard/TongueSpeech(var/message) - var/regex/lizard_hiss = new("s+", "g") - var/regex/lizard_hiSS = new("S+", "g") - if(copytext(message, 1, 2) != "*") +/obj/item/organ/tongue/lizard/handle_speech(datum/source, list/speech_args) + var/static/regex/lizard_hiss = new("s+", "g") + var/static/regex/lizard_hiSS = new("S+", "g") + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = lizard_hiss.Replace(message, "sss") message = lizard_hiSS.Replace(message, "SSS") - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/fly name = "proboscis" @@ -63,14 +68,16 @@ icon_state = "tonguefly" say_mod = "buzzes" taste_sensitivity = 25 // you eat vomit, this is a mercy + modifies_speech = TRUE -/obj/item/organ/tongue/fly/TongueSpeech(var/message) - var/regex/fly_buzz = new("z+", "g") - var/regex/fly_buZZ = new("Z+", "g") - if(copytext(message, 1, 2) != "*") +/obj/item/organ/tongue/fly/handle_speech(datum/source, list/speech_args) + var/static/regex/fly_buzz = new("z+", "g") + var/static/regex/fly_buZZ = new("Z+", "g") + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = fly_buzz.Replace(message, "zzz") message = fly_buZZ.Replace(message, "ZZZ") - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/abductor name = "superlingual matrix" @@ -78,9 +85,11 @@ icon_state = "tongueayylmao" say_mod = "gibbers" taste_sensitivity = 101 // ayys cannot taste anything. + modifies_speech = TRUE -/obj/item/organ/tongue/abductor/TongueSpeech(var/message) +/obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args) //Hacks + var/message = speech_args[SPEECH_MESSAGE] var/mob/living/carbon/human/user = usr var/rendered = "[user.name]: [message]" user.log_talk(message, LOG_SAY, tag="abductor") @@ -96,7 +105,7 @@ for(var/mob/M in GLOB.dead_mob_list) var/link = FOLLOW_LINK(M, user) to_chat(M, "[link] [rendered]") - return "" + speech_args[SPEECH_MESSAGE] = "" /obj/item/organ/tongue/zombie name = "rotting tongue" @@ -104,9 +113,10 @@ icon_state = "tonguezombie" say_mod = "moans" taste_sensitivity = 32 + modifies_speech = TRUE -/obj/item/organ/tongue/zombie/TongueSpeech(var/message) - var/list/message_list = splittext(message, " ") +/obj/item/organ/tongue/zombie/handle_speech(datum/source, list/speech_args) + var/list/message_list = splittext(speech_args[SPEECH_MESSAGE], " ") var/maxchanges = max(round(message_list.len / 1.5), 2) for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) @@ -119,7 +129,7 @@ if(prob(20) && message_list.len > 3) message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") - return jointext(message_list, " ") + speech_args[SPEECH_MESSAGE] = jointext(message_list, " ") /obj/item/organ/tongue/alien name = "alien tongue" @@ -127,6 +137,7 @@ icon_state = "tonguexeno" say_mod = "hisses" taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED + modifies_speech = TRUE // not really, they just hiss var/static/list/languages_possible_alien = typecacheof(list( /datum/language/xenocommon, /datum/language/common, @@ -138,9 +149,8 @@ . = ..() languages_possible = languages_possible_alien -/obj/item/organ/tongue/alien/TongueSpeech(var/message) +/obj/item/organ/tongue/alien/handle_speech(datum/source, list/speech_args) playsound(owner, "hiss", 25, 1, 1) - return message /obj/item/organ/tongue/bone name = "bone \"tongue\"" @@ -149,7 +159,7 @@ say_mod = "rattles" attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned") taste_sensitivity = 101 // skeletons cannot taste anything - + modifies_speech = TRUE var/chattering = FALSE var/phomeme_type = "sans" var/list/phomeme_types = list("sans", "papyrus") @@ -158,29 +168,20 @@ . = ..() phomeme_type = pick(phomeme_types) -/obj/item/organ/tongue/bone/TongueSpeech(var/message) - . = message - - if(chattering) - //Annoy everyone nearby with your chattering. - chatter(message, phomeme_type, usr) - -/obj/item/organ/tongue/bone/get_spans() - . = ..() - // Feature, if the tongue talks directly, it will speak with its span +/obj/item/organ/tongue/bone/handle_speech(datum/source, list/speech_args) + if (chattering) + chatter(speech_args[SPEECH_MESSAGE], phomeme_type, source) switch(phomeme_type) if("sans") - . |= SPAN_SANS + speech_args[SPEECH_SPANS] |= SPAN_SANS if("papyrus") - . |= SPAN_PAPYRUS + speech_args[SPEECH_SPANS] |= SPAN_PAPYRUS /obj/item/organ/tongue/bone/plasmaman name = "plasma bone \"tongue\"" desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech." icon_state = "tongueplasma" - -/obj/item/organ/tongue/bone/plasmaman/get_spans() - return + modifies_speech = FALSE /obj/item/organ/tongue/robot name = "robotic voicebox" @@ -189,10 +190,18 @@ icon_state = "tonguerobot" say_mod = "states" attack_verb = list("beeped", "booped") + modifies_speech = TRUE taste_sensitivity = 25 // not as good as an organic tongue + var/electronics_magic = TRUE /obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt) - . = TRUE // THE MAGIC OF ELECTRONICS + return ..() || electronics_magic -/obj/item/organ/tongue/robot/get_spans() - return ..() | SPAN_ROBOT +/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT + +/obj/item/organ/tongue/robot/ipc + name = "positronic voicebox" + say_mod = "beeps" + desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms." + electronics_magic = FALSE \ No newline at end of file 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/surgery/surgery.dm b/code/modules/surgery/surgery.dm index c9a3871511..b013e7f252 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -49,9 +49,14 @@ var/datum/surgery_step/S = get_surgery_step() if(S) - if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src, try_to_fail)) - return 1 - return 0 + var/obj/item/tool = user.get_active_held_item() + if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) + return TRUE + if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache + return TRUE + if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it + to_chat(user, "This step requires a different tool!") + return TRUE /datum/surgery/proc/get_surgery_step() var/step_type = steps[status] diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 517dfb412a..db7445e0b0 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "retractor" materials = list(MAT_METAL=6000, MAT_GLASS=3000) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY @@ -33,6 +34,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "hemostat" materials = list(MAT_METAL=5000, MAT_GLASS=2500) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "pinched") @@ -66,6 +68,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "cautery" materials = list(MAT_METAL=2500, MAT_GLASS=750) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("burnt") @@ -102,6 +105,7 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' materials = list(MAT_METAL=10000, MAT_GLASS=6000) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL @@ -151,6 +155,7 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) + item_flags = SURGICAL_TOOL attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP_ACCURATE @@ -209,6 +214,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' throwhitsound = 'sound/weapons/pierce.ogg' + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL @@ -278,6 +284,7 @@ desc = "A container for holding body parts." icon = 'icons/obj/storage.dmi' icon_state = "evidenceobj" + item_flags = SURGICAL_TOOL /obj/item/organ_storage/afterattack(obj/item/I, mob/user, proximity) . = ..() diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 0c3a75e362..8251c450a3 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -49,6 +49,20 @@ if(!ui || ui.status != UI_INTERACTIVE) return 1 // If UI is not interactive or usr calling Topic is not the UI user, bail. + /** + * public + * + * Called on an object when a tgui object is being created, allowing you to customise the html + * For example: inserting a custom stylesheet that you need in the head + * + * For this purpose, some tags are available in the html, to be parsed out with replacetext + * (customheadhtml) - Additions to the head tag + * + * required html the html base text + * + **/ +/datum/proc/ui_base_html(html) + return html /** * private diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index c471f872c3..9b94295414 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -198,11 +198,19 @@ **/ /datum/tgui/proc/get_html(var/inline) var/html + html = SStgui.basehtml + + //Allow the src object to override the html if needed + html = src_object.ui_base_html(html) + //Strip out any remaining custom tags that are used in ui_base_html + html = replacetext(html, "", "") + // Poplate HTML with JSON if we're supposed to inline. if(inline) - html = replacetextEx(SStgui.basehtml, "{}", get_json(initial_data)) - else - html = SStgui.basehtml + html = replacetextEx(html, "{}", get_json(initial_data)) + + + //Setup for tgui stuff, including styles html = replacetextEx(html, "\[ref]", "[REF(src)]") html = replacetextEx(html, "\[style]", style) return html diff --git a/code/modules/unit_tests/reagent_recipe_collisions.dm b/code/modules/unit_tests/reagent_recipe_collisions.dm index 31027c2cd3..20e875422f 100644 --- a/code/modules/unit_tests/reagent_recipe_collisions.dm +++ b/code/modules/unit_tests/reagent_recipe_collisions.dm @@ -11,57 +11,5 @@ for(var/i2 in (i+1) to reactions.len) var/datum/chemical_reaction/r1 = reactions[i] var/datum/chemical_reaction/r2 = reactions[i2] - if(recipes_do_conflict(r1, r2)) + if(chem_recipes_do_conflict(r1, r2)) Fail("Chemical recipe conflict between [r1.type] and [r2.type]") - -/datum/unit_test/reagent_recipe_collisions/proc/recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2) - //do the non-list tests first, because they are cheaper - if(r1.required_container != r2.required_container) - return FALSE - if(r1.is_cold_recipe == r2.is_cold_recipe) - if(r1.required_temp != r2.required_temp) - //one reaction requires a more extreme temperature than the other, so there is no conflict - return FALSE - else - var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2 - var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1 - if(cold_one.required_temp < warm_one.required_temp) - //the range of temperatures does not overlap, so there is no conflict - return FALSE - - //find the reactions with the shorter and longer required_reagents list - var/datum/chemical_reaction/long_req - var/datum/chemical_reaction/short_req - if(r1.required_reagents.len > r2.required_reagents.len) - long_req = r1 - short_req = r2 - else if(r1.required_reagents.len < r2.required_reagents.len) - long_req = r2 - short_req = r1 - else - //if they are the same length, sort instead by the length of the catalyst list - //this is important if the required_reagents lists are the same - if(r1.required_catalysts.len > r2.required_catalysts.len) - long_req = r1 - short_req = r2 - else - long_req = r2 - short_req = r1 - - - //check if the shorter reaction list is a subset of the longer one - var/list/overlap = r1.required_reagents & r2.required_reagents - if(overlap.len != short_req.required_reagents.len) - //there is at least one reagent in the short list that is not in the long list, so there is no conflict - return FALSE - - //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list - //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine - //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict - var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts - if(short_minus_long_catalysts.len) - //there is at least one unique catalyst for the short reaction, so there is no conflict - return FALSE - - //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise - return TRUE \ No newline at end of file diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm index 2e91879006..b008682745 100644 --- a/code/modules/uplink/uplink_devices.dm +++ b/code/modules/uplink/uplink_devices.dm @@ -57,4 +57,3 @@ /obj/item/pen/uplink/Initialize(mapload, owner, tc_amount = 20) . = ..() AddComponent(/datum/component/uplink, owner, TRUE, FALSE, null, tc_amount) - traitor_unlock_degrees = 360 diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 798b495cfd..13dcf5a12b 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -85,18 +85,18 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) return pick(4;0.75,2;0.5,1;0.25) /datum/uplink_item/proc/purchase(mob/user, datum/component/uplink/U) - var/atom/A = spawn_item(item, user) + var/atom/A = spawn_item(item, user, U) if(purchase_log_vis && U.purchase_log) U.purchase_log.LogPurchase(A, src, cost) -/datum/uplink_item/proc/spawn_item(spawn_item, mob/user) - if(!spawn_item) +/datum/uplink_item/proc/spawn_item(spawn_path, mob/user, datum/component/uplink/U) + if(!spawn_path) return var/atom/A - if(ispath(spawn_item)) - A = new spawn_item(get_turf(user)) + if(ispath(spawn_path)) + A = new spawn_path(get_turf(user)) else - A = spawn_item + A = spawn_path if(ishuman(user) && istype(A, /obj/item)) var/mob/living/carbon/human/H = user if(H.put_in_hands(A)) @@ -109,72 +109,206 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/discounts category = "Discounted Gear" -// Nuclear Operative (Special Offers) -/datum/uplink_item/nukeoffer - category = "Special Offers" +//All bundles and telecrystals +/datum/uplink_item/bundles_TC + category = "Bundles and Telecrystals" surplus = 0 - include_modes = list(/datum/game_mode/nuclear) cant_discount = TRUE -/datum/uplink_item/nukeoffer/c20r - name = "C-20r bundle" - desc = "Old faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." - item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle - cost = 14 // normally 16 - -/datum/uplink_item/nukeoffer/bulldog - name = "Bulldog bundle" - desc = "Lean and mean: Optimised for people that want to get up close and personal. Contains the popular \ - Bulldog shotgun, two 12g drums, and a pair of Thermal imaging goggles." - item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle - cost = 13 // normally 16 - -/datum/uplink_item/nukeoffer/medical - name = "Medical bundle" - desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a Donksoft machine gun, \ - a box of ammo, and a pair of magboots to rescue your friends in no-gravity environments." - item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - cost = 15 // normally 20 - -/datum/uplink_item/nukeoffer/sniper - name = "Sniper bundle" - desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollow-point \ - a soporific knockout magazine, a free surplus supressor, and a worn out suit and tie." - item = /obj/item/storage/briefcase/sniperbundle - cost = 20 // normally 26 - -/datum/uplink_item/nukeoffer/chemical +/datum/uplink_item/bundles_TC/chemical name = "Bioterror bundle" - desc = "For the madman: Contains Bioterror spray, Bioterror grenade, chemicals, syringe gun, box of syringes,\ - Donksoft assault rifle, and some darts. Remember: Seal suit and equip internals before use." + desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \ + box of syringes, Donksoft assault rifle, and some riot darts. Remember: Seal suit and equip internals before use." item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle cost = 30 // normally 42 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/nukeoffer/firestarter +/datum/uplink_item/bundles_TC/bulldog + name = "Bulldog bundle" + desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, a 12g buckshot drum, a 12g taser slug drum and a pair of Thermal imaging goggles." + item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle + cost = 13 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/c20r + name = "C-20r bundle" + desc = "Old Faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." + item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle + cost = 14 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/cybernetics_bundle + name = "Cybernetic Implants Bundle" + desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." + item = /obj/item/storage/box/cyber_implants + cost = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/medical + name = "Medical bundle" + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ + a Donksoft LMG, a box of riot darts and a pair of magboots to rescue your friends in no-gravity environments." + item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle + cost = 15 // normally 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/modular + name = "Modular Pistol Kit" + desc = "A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ + Includes a suit jacket that is padded with a robust liner." + item = /obj/item/storage/briefcase/modularbundle + cost = 12 + +/datum/uplink_item/bundles_TC/shredder + name = "Shredder bundle" + desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ + You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" + item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle + cost = 30 // normally 41 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/sniper + name = "Sniper bundle" + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ + two soporific knockout magazines, a free surplus supressor, and a sharp-looking tactical turtleneck suit. \ + We'll throw in a free red tie if you order NOW." + item = /obj/item/storage/briefcase/sniperbundle + cost = 20 // normally 26 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/firestarter name = "Spetsnaz Pyro bundle" - desc = "For systematic suppression of carbon lifeforms in close range: Contains a specialist Pyrotechnic equipment, foreign pistol, two magazines, a pipebomb, and a stimulant syringe." + desc = "For systematic suppression of carbon lifeforms in close quarters: Contains a lethal New Russian backpack spray, Elite hardsuit, \ + Stechkin APS pistol, two magazines, a minibomb and a stimulant syringe. \ + Order NOW and comrade Boris will throw in an extra tracksuit." item = /obj/item/storage/backpack/duffelbag/syndie/firestarter cost = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/bundle + name = "Syndicate Bundle" + desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ + These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ + you will receive. May contain discontinued and/or exotic items." + item = /obj/item/storage/box/syndicate + cost = 20 + exclude_modes = list(/datum/game_mode/nuclear) + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/surplus + name = "Syndicate Surplus Crate" + desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 50 TC." + item = /obj/structure/closet/crate + cost = 20 + player_minimum = 25 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cant_discount = TRUE + var/starting_crate_value = 50 + +/datum/uplink_item/bundles_TC/surplus/super + name = "Super Surplus Crate" + desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 125 TC." + cost = 40 + player_minimum = 40 + starting_crate_value = 125 + +/datum/uplink_item/bundles_TC/surplus/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) + + var/crate_value = starting_crate_value + var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user, U) + if(U.purchase_log) + U.purchase_log.LogPurchase(C, src, cost) + while(crate_value) + var/category = pick(uplink_items) + var/item = pick(uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + + if(!I.surplus || prob(100 - I.surplus)) + continue + if(crate_value < I.cost) + continue + crate_value -= I.cost + var/obj/goods = new I.item(C) + if(U.purchase_log) + U.purchase_log.LogPurchase(goods, I, 0) + return C + +/datum/uplink_item/bundles_TC/random + name = "Random Item" + desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." + item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech + cost = 0 + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = U.uplink_items + var/list/possible_items = list() + for(var/category in uplink_items) + for(var/item in uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + if(src == I || !I.item) + continue + if(U.telecrystals < I.cost) + continue + if(I.limited_stock == 0) + continue + possible_items += I + + if(possible_items.len) + var/datum/uplink_item/I = pick(possible_items) + SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) + U.MakePurchase(user, I) + +/datum/uplink_item/bundles_TC/telecrystal + name = "1 Raw Telecrystal" + desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal + cost = 1 + surplus = 0 + cant_discount = TRUE + // Don't add telecrystals to the purchase_log since + // it's just used to buy more items (including itself!) + purchase_log_vis = FALSE + +/datum/uplink_item/bundles_TC/telecrystal/five + name = "5 Raw Telecrystals" + desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/five + cost = 5 + +/datum/uplink_item/bundles_TC/telecrystal/twenty + name = "20 Raw Telecrystals" + desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/twenty + cost = 20 // Dangerous Items /datum/uplink_item/dangerous category = "Conspicuous and Dangerous Weapons" -/datum/uplink_item/dangerous/pistol - name = "Stechkin Pistol" - desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ - with suppressors." - item = /obj/item/gun/ballistic/automatic/pistol - cost = 7 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/rawketlawnchair + name = "84mm Rocket Propelled Grenade Launcher" + desc = "A reusable rocket propelled grenade launcher preloaded with a low-yield 84mm HE round. \ + Guaranteed to send your target out with a bang or your money back!" + item = /obj/item/gun/ballistic/rocketlauncher + cost = 8 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/revolver - name = "Syndicate Revolver" - desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers." - item = /obj/item/gun/ballistic/revolver - cost = 13 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/antitank + name = "Anti Tank Pistol" + desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ + this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ + Uses sniper ammo. \ + Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." + item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate + cost = 14 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/dangerous/pie_cannon name = "Banana Cream Pie Cannon" @@ -184,6 +318,42 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/bananashield + name = "Bananium Energy Shield" + desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ + by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ + and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." + item = /obj/item/shield/energy/bananium + cost = 16 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/clownsword + name = "Bananium Energy Sword" + desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ + impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." + item = /obj/item/melee/transforming/energy/sword/bananium + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/bioterror + name = "Biohazardous Chemical Sprayer" + desc = "A handheld chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ + Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ + Use with extreme caution, to prevent exposure to yourself and your fellow operatives." + item = /obj/item/reagent_containers/spray/chemsprayer/bioterror + cost = 20 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/throwingweapons + name = "Box of Throwing Weapons" + desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ + throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." + item = /obj/item/storage/box/syndie_kit/throwing_weapons + cost = 3 + /datum/uplink_item/dangerous/shotgun name = "Bulldog Shotgun" desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \ @@ -202,86 +372,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 40 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/carbine - name = "M-90gl Carbine" - desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ - with a togglable 40mm under-barrel grenade launcher." - item = /obj/item/gun/ballistic/automatic/m90 - cost = 18 - surplus = 50 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/machinegun - name = "L6 Squad Automatic Weapon" - desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ - This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." - item = /obj/item/gun/ballistic/automatic/l6_saw - cost = 18 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/grenadier - name = "Grenadier's belt" - desc = "A belt of a large variety of lethally dangerous and destructive grenades." - item = /obj/item/storage/belt/grenade/full - include_modes = list(/datum/game_mode/nuclear) - cost = 22 - surplus = 0 - -/datum/uplink_item/dangerous/sniper - name = "Sniper Rifle" - desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" - item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate - cost = 16 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/bolt_action - name = "Surplus Rifle" - desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." - item = /obj/item/gun/ballistic/shotgun/boltaction - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/crossbow - name = "Miniature Energy Crossbow" - desc = "A short bow mounted across a tiller in miniature. Small enough to \ - fit into a pocket or slip into a bag unnoticed. It will synthesize \ - and fire bolts tipped with a paralyzing toxin that will briefly stun \ - targets and cause them to slur as if inebriated. It can produce an \ - infinite number of bolts, but takes time to automatically recharge \ - after each shot." - item = /obj/item/gun/energy/kinetic_accelerator/crossbow - cost = 12 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/flamethrower - name = "Flamethrower" - desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ - stations. Make a statement by roasting the filth in their own greed. Use with caution." - item = /obj/item/flamethrower/full/tank - cost = 4 - surplus = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/sword - name = "Energy Sword" - desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ - pocketed when inactive. Activating it produces a loud, distinctive noise." - item = /obj/item/melee/transforming/energy/sword/saber - cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/clownsword - name = "Bananium Energy Sword" - desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ - impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." - item = /obj/item/melee/transforming/energy/sword/bananium - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/dangerous/doublesword name = "Double-Bladed Energy Sword" desc = "The double-bladed energy sword does slightly more damage than a standard energy sword and will deflect \ @@ -294,6 +384,99 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/doublesword/get_discount() return pick(4;0.8,2;0.65,1;0.5) +/datum/uplink_item/dangerous/cxneb + name = "Dragon's Tooth Non-Eutactic Blade" + desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ + the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ + generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ + This particular model has a polychromic hardlight generator, allowing you to murder in style! \ + The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." + item = /obj/item/melee/transforming/energy/sword/cx/traitor + cost = 8 + +/datum/uplink_item/dangerous/sword + name = "Energy Sword" + desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ + pocketed when inactive. Activating it produces a loud, distinctive noise." + item = /obj/item/melee/transforming/energy/sword/saber + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/shield + name = "Energy Shield" + desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ + against other attacks. Pair with an Energy Sword for a killer combination." + item = /obj/item/shield/energy + cost = 16 + surplus = 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/rapier + name = "Rapier" + desc = "A fancy rapier with a diamond tip piercing anything that it comes into contack with. \ + The rapier comes with its own shielf, this is rather noticeable as only the captain is known to carry a shielf. \ + The shielf itself can be used to block melee attacks only. Its also jet black colours." + item = /obj/item/storage/belt/sabre/rapier + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/flamethrower + name = "Flamethrower" + desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ + stations. Make a statement by roasting the filth in their own greed. Use with caution." + item = /obj/item/flamethrower/full/tank + cost = 4 + surplus = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/flechettegun + name = "Flechette Launcher" + desc = "A compact bullpup that fires micro-flechettes.\ + Flechettes have very poor performance idividually, but can be very deadly in numbers. \ + Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." + item = /obj/item/gun/ballistic/automatic/flechette + cost = 12 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/rapid + name = "Gloves of the North Star" + desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." + item = /obj/item/clothing/gloves/rapid + cost = 8 + +/datum/uplink_item/dangerous/guardian + name = "Holoparasites" + desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ + organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host." + item = /obj/item/storage/box/syndie_kit/guardian + cost = 15 + refundable = TRUE + cant_discount = TRUE + surplus = 0 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + player_minimum = 25 + restricted = TRUE + refund_path = /obj/item/guardiancreator/tech/choose/traitor + +/datum/uplink_item/dangerous/machinegun + name = "L6 Squad Automatic Weapon" + desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ + This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." + item = /obj/item/gun/ballistic/automatic/l6_saw + cost = 18 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/carbine + name = "M-90gl Carbine" + desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ + with a toggleable 40mm underbarrel grenade launcher." + item = /obj/item/gun/ballistic/automatic/m90 + cost = 18 + surplus = 50 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/dangerous/powerfist name = "Power Fist" desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\ @@ -303,42 +486,40 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/melee/powerfist cost = 8 -/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, \ - security's energy weapons, and silicon lifeforms when you're in a tight spot." - item = /obj/item/storage/box/syndie_kit/emp - cost = 2 +/datum/uplink_item/dangerous/sniper + name = "Sniper Rifle" + desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" + item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate + cost = 16 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/syndicate_minibomb - name = "Syndicate Minibomb" - desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ - in addition to dealing high amounts of damage to nearby personnel." - item = /obj/item/grenade/syndieminibomb - cost = 6 +/datum/uplink_item/dangerous/pistol + name = "Stechkin Pistol" + desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ + with suppressors." + item = /obj/item/gun/ballistic/automatic/pistol + cost = 7 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/dangerous/bombanana - name = "Bombanana" - desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ - a few seconds after the banana is eaten." - item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana - cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/bolt_action + name = "Surplus Rifle" + desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." + item = /obj/item/gun/ballistic/shotgun/boltaction + cost = 2 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/tearstache - name = "Teachstache Grenade" - desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ - remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." - item = /obj/item/grenade/chem_grenade/teargas/moustache - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/revolver + name = "Syndicate Revolver" + desc = "A brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers." + item = /obj/item/gun/ballistic/revolver/syndie + cost = 13 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" - desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." + desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade darts with a 20-round magazine." item = /obj/item/gun/ballistic/automatic/c20r/toy cost = 5 surplus = 0 @@ -353,65 +534,134 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/dangerous/viscerators - name = "Viscerator Delivery Grenade" - desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ - any non-operatives in the area." - item = /obj/item/grenade/spawnergrenade/manhacks - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/foampistol + name = "Toy Pistol with Riot Darts" + desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ + darts effective at incapacitating a target." + item = /obj/item/gun/ballistic/automatic/toy/pistol/riot + cost = 3 + surplus = 10 -/datum/uplink_item/dangerous/bioterrorfoam - name = "Chemical Foam Grenade" - desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ - mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ - using additional spore toxin. Ensure suit is sealed before use." - item = /obj/item/grenade/chem_grenade/bioterrorfoam - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +// Stealthy Weapons +/datum/uplink_item/stealthy_weapons + category = "Stealthy and Inconspicuous Weapons" -/datum/uplink_item/dangerous/bioterror - name = "Biohazardous Chemical Sprayer" - desc = "A chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ - Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ - Use with extreme caution, to prevent exposure to yourself and your fellow operatives." - item = /obj/item/reagent_containers/spray/chemsprayer/bioterror - cost = 20 +/datum/uplink_item/stealthy_weapons/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) surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/stealthy_weapons/virus_grenade - name = "Fungal Tuberculosis Grenade" - desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ - 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 - surplus = 35 +/datum/uplink_item/stealthy_weapons/cqc + name = "CQC Manual" + desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." + item = /obj/item/book/granter/martial/cqc include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE + cost = 13 + surplus = 0 -/datum/uplink_item/dangerous/guardian - name = "Holoparasites" - desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ - organic host as a home base and source of fuel." - item = /obj/item/storage/box/syndie_kit/guardian - cost = 18 +/datum/uplink_item/stealthy_weapons/dart_pistol + name = "Dart Pistol" + desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ + space a small item can." + item = /obj/item/gun/syringe/syndicate + cost = 4 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/dehy_carp + name = "Dehydrated Space Carp" + desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ + your hand before use so it knows not to kill you." + item = /obj/item/toy/plush/carpplushie/dehy_carp + cost = 1 + +/datum/uplink_item/stealthy_weapons/edagger + name = "Energy Dagger" + desc = "A dagger made of energy that looks and functions as a pen when off." + item = /obj/item/pen/edagger + cost = 2 + +/datum/uplink_item/stealthy_weapons/martialarts + name = "Martial Arts Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ + deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." + item = /obj/item/book/granter/martial/carp + cost = 17 surplus = 0 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - player_minimum = 25 - restricted = TRUE -/datum/uplink_item/dangerous/buzzkill - name = "Buzzkill Grenade Box" - desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ - with random toxins. Courtesy of the BLF and Tiger Cooperative." - item = /obj/item/storage/box/syndie_kit/bee_grenades - cost = 15 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/stealthy_weapons/crossbow + name = "Miniature Energy Crossbow" + desc = "A short bow mounted across a tiller in miniature. Small enough to \ + fit into a pocket or slip into a bag unnoticed. It will synthesize \ + and fire bolts tipped with a paralyzing toxin that will briefly stun \ + targets and cause them to slur as if inebriated. It can produce an \ + infinite number of bolts, but takes time to automatically recharge \ + after each shot." + item = /obj/item/gun/energy/kinetic_accelerator/crossbow + cost = 12 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/traitor_chem_bottle + name = "Poison Kit" + desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." + item = /obj/item/storage/box/syndie_kit/chemical + cost = 6 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/romerol_kit + name = "Romerol" + desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. \ + On death, these nodules take control of the dead body, causing limited revivification, \ + along with slurred speech, aggression, and the ability to infect others with this agent." + item = /obj/item/storage/box/syndie_kit/romerol + cost = 25 + cant_discount = TRUE + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/sleepy_pen + name = "Sleepy Pen" + desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ + strong anesthetic and a chemical that prevents the target from speaking. \ + The pen holds one dose of the mixture, and can be refilled with any chemicals. Note that before the target \ + falls asleep, they will be able to move and act." + item = /obj/item/pen/sleepy + cost = 4 + exclude_modes = list(/datum/game_mode/nuclear) + +datum/uplink_item/stealthy_weapons/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_weapons/suppressor + name = "Suppressor" + desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. \ + It is compatible with many small ballistic guns including the Stechkin and C-20r, but not revolvers or energy guns." + item = /obj/item/suppressor + cost = 1 + surplus = 10 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/soap + name = "Syndicate Soap" + desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ + You can also drop it underfoot to slip people." + item = /obj/item/soap/syndie + cost = 1 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/soap_clusterbang + name = "Slipocalypse Clusterbang" + desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" + item = /obj/item/grenade/clusterbuster/soap + cost = 6 // Ammunition /datum/uplink_item/ammo @@ -428,56 +678,70 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/ammo/pistolap name = "10mm Armour Piercing Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are less effective at injuring the target but penetrate protective gear." + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are less effective at injuring the target but penetrate protective gear." item = /obj/item/ammo_box/magazine/m10mm/ap cost = 2 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/ammo/pistolfire - name = "10mm Incendiary Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with incendiary rounds which ignite the target." - item = /obj/item/ammo_box/magazine/m10mm/fire - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/ammo/pistolhp name = "10mm Hollow Point Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are more damaging but ineffective against armour." + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are more damaging but ineffective against armour." item = /obj/item/ammo_box/magazine/m10mm/hp cost = 3 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/ammo/pistolaps - name = "9mm Handgun Magazine" - desc = "An additional 15-round 9mm magazine, compatible with the Stetchkin APS pistol, found in the Spetsnaz Pyro bundle." - item = /obj/item/ammo_box/magazine/pistolm9mm +/datum/uplink_item/ammo/pistolfire + name = "10mm Incendiary Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + Loaded with incendiary rounds which inflict little damage, but ignite the target." + item = /obj/item/ammo_box/magazine/m10mm/fire cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/bolt_action - name = "Surplus Rifle Clip" - desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." - item = /obj/item/ammo_box/a762 - cost = 1 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/revolver - name = ".357 Speed Loader" - desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ - For when you really need a lot of things dead." - item = /obj/item/ammo_box/a357 - cost = 4 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/ammo/pistolzzz + name = "10mm Soporific Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ + NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." + item = /obj/item/ammo_box/magazine/m10mm/soporific + cost = 2 + /datum/uplink_item/ammo/shotgun cost = 2 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/shotgun/bag + name = "12g Ammo Duffel Bag" + desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." + item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun + cost = 12 + /datum/uplink_item/ammo/shotgun/buck name = "12g Buckshot Drum" desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy." item = /obj/item/ammo_box/magazine/m12g +/datum/uplink_item/ammo/shotgun/dragon + name = "12g Dragon's Breath Drum" + desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \ + 'I'm a fire starter, twisted fire starter!'" + item = /obj/item/ammo_box/magazine/m12g/dragon + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/shotgun/meteor + name = "12g Meteorslug Shells" + desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \ + Great for blasting airlocks off their frames and knocking down enemies." + item = /obj/item/ammo_box/magazine/m12g/meteor + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/shotgun/scatter + 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 = 4 // most armor has less laser protection then bullet + /datum/uplink_item/ammo/shotgun/slug name = "12g Slug Drum" desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \ @@ -492,54 +756,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/m12g/stun include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/shotgun/dragon - name = "12g Dragon's Breath Drum" - desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \ - 'I'm a fire starter, twisted fire starter!'" - item = /obj/item/ammo_box/magazine/m12g/dragon - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/shotgun/meteor - name = "12g Meteorslug Shells" - desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \ - Great for blasting airlocks off their frames." - item = /obj/item/ammo_box/magazine/m12g/meteor - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/shotgun/scatter - 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 - -/datum/uplink_item/ammo/shotgun/bag - name = "12g Ammo Duffel Bag" - desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." - item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun - cost = 12 - -/datum/uplink_item/ammo/smg - name = ".45 SMG Magazine" - desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun. \ - These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." - item = /obj/item/ammo_box/magazine/smgm45 - cost = 3 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/smg/bag - name = ".45 Ammo Duffel Bag" - desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." - item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg - cost = 20 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/carbine - name = "5.56mm Toploader Magazine" - desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ - These bullets pack less punch than 1.95mm rounds, but they still offer more power than .45 ammo." - item = /obj/item/ammo_box/magazine/m556 +/datum/uplink_item/ammo/revolver + name = ".357 Speed Loader" + desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ + For when you really need a lot of things dead." + item = /obj/item/ammo_box/a357 cost = 4 - include_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/ammo/a40mm name = "40mm Grenade" @@ -549,35 +772,19 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/machinegun - cost = 6 - surplus = 0 +/datum/uplink_item/ammo/smg/bag + name = ".45 Ammo Duffel Bag" + desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." + item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg + cost = 20 //instead of 27 TC include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/machinegun/basic - name = "1.95x129mm Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ - By the time you need to use this, you'll already be on a pile of corpses." - item = /obj/item/ammo_box/magazine/mm195x129 - -/datum/uplink_item/ammo/machinegun/hollow - name = "1.95x129mm (Hollow-Point) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ - with the unarmored masses of crew." - item = /obj/item/ammo_box/magazine/mm195x129/hollow - -/datum/uplink_item/ammo/machinegun/ap - name = "1.95x129mm (Armor Penetrating) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ - to puncture even the most durable armor." - item = /obj/item/ammo_box/magazine/mm195x129/ap - cost = 9 - -/datum/uplink_item/ammo/machinegun/incen - name = "1.95x129mm (Incendiary) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ - mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." - item = /obj/item/ammo_box/magazine/mm195x129/incen +/datum/uplink_item/ammo/smg + name = ".45 SMG Magazine" + desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun." + item = /obj/item/ammo_box/magazine/smgm45 + cost = 3 + include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/sniper cost = 4 @@ -588,12 +795,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) desc = "An additional standard 6-round magazine for use with .50 sniper rifles." item = /obj/item/ammo_box/magazine/sniper_rounds -/datum/uplink_item/ammo/sniper/soporific - name = ".50 Soporific Magazine" - desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" - item = /obj/item/ammo_box/magazine/sniper_rounds/soporific - cost = 6 - /datum/uplink_item/ammo/sniper/penetrator name = ".50 Penetrator Magazine" desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ @@ -601,9 +802,93 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator cost = 5 +/datum/uplink_item/ammo/sniper/soporific + name = ".50 Soporific Magazine" + desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" + item = /obj/item/ammo_box/magazine/sniper_rounds/soporific + cost = 6 + +/datum/uplink_item/ammo/carbine + name = "5.56mm Toploader Magazine" + desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ + These bullets pack less punch than 7.12x82mm rounds, but they still offer more power than .45 ammo." + item = /obj/item/ammo_box/magazine/m556 + cost = 4 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/machinegun + cost = 6 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/machinegun/basic + name = "1.95x129mm Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ + By the time you need to use this, you'll already be standing on a pile of corpses" + item = /obj/item/ammo_box/magazine/mm195x129 + +/datum/uplink_item/ammo/machinegun/ap + name = "1.95x129mm (Armor Penetrating) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ + to puncture even the most durable armor." + item = /obj/item/ammo_box/magazine/mm195x129/ap + cost = 9 + +/datum/uplink_item/ammo/machinegun/hollow + name = "1.95x129mm (Hollow-Point) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ + with the unarmored masses of crew." + item = /obj/item/ammo_box/magazine/mm195x129/hollow + +/datum/uplink_item/ammo/machinegun/incen + name = "1.95x129mm (Incendiary) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ + mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." + item = /obj/item/ammo_box/magazine/mm195x129/incen + +/datum/uplink_item/ammo/rocket + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/rocket/basic + name = "84mm HE Rocket" + desc = "A low-yield anti-personnel HE rocket. Gonna take you out in style!" + item = /obj/item/ammo_casing/caseless/rocket + cost = 4 + +/datum/uplink_item/ammo/rocket/hedp + name = "84mm HEDP Rocket" + desc = "A high-yield HEDP rocket; extremely effective against armored targets, as well as surrounding personnel. \ + Strike fear into the hearts of your enemies." + item = /obj/item/ammo_casing/caseless/rocket/hedp + cost = 6 + +/datum/uplink_item/ammo/pistolaps + name = "9mm Handgun Magazine" + desc = "An additional 15-round 9mm magazine, compatible with the Stechkin APS pistol, found in the Spetsnaz Pyro bundle." + item = /obj/item/ammo_box/magazine/pistolm9mm + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/flechetteap + name = "Armor Piercing Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." + item = /obj/item/ammo_box/magazine/flechette + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/flechettes + name = "Serrated Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ + These flechettes are highly likely to sever arteries, and even limbs." + item = /obj/item/ammo_box/magazine/flechette/s + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/ammo/toydarts name = "Box of Riot Darts" - desc = "A box of 40 Donksoft foam riot darts, for reloading any compatible foam dart gun. Don't forget to share!" + desc = "A box of 40 Donksoft riot darts, for reloading any compatible foam dart magazine. Don't forget to share!" item = /obj/item/ammo_box/foambox/riot cost = 2 surplus = 0 @@ -616,12 +901,184 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 6 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/ammo/bolt_action + name = "Surplus Rifle Clip" + desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." + item = /obj/item/ammo_box/a762 + cost = 1 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/explosives + category = "Grenades and Explosives" + +/datum/uplink_item/explosives/bioterrorfoam + name = "Bioterror Foam Grenade" + desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ + mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ + using additional spore toxin. Ensure suit is sealed before use." + item = /obj/item/grenade/chem_grenade/bioterrorfoam + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/bombanana + name = "Bombanana" + desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ + a few seconds after the banana is eaten." + item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana + cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/buzzkill + name = "Buzzkill Grenade Box" + desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ + with random toxins. Courtesy of the BLF and Tiger Cooperative." + item = /obj/item/storage/box/syndie_kit/bee_grenades + cost = 15 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/c4 + name = "Composition C-4" + desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ + an assembly to it in order to alter the way it detonates. It can be attached to almost all objects and has a modifiable timer with a \ + minimum setting of 10 seconds." + item = /obj/item/grenade/plastic/c4 + cost = 1 + +/datum/uplink_item/explosives/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + item = /obj/item/storage/backpack/duffelbag/syndie/c4 + cost = 9 //10% discount! + cant_discount = TRUE + +/datum/uplink_item/explosives/x4bag + name = "Bag of X-4 explosives" + desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ + X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ + For when you want a controlled explosion that leaves a wider, deeper, hole." + item = /obj/item/storage/backpack/duffelbag/syndie/x4 + cost = 4 // + cant_discount = TRUE + +/datum/uplink_item/explosives/clown_bomb_clownops + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/detomatix + name = "Detomatix PDA Cartridge" + desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ + detonate PDAs of crewmembers who have their message feature enabled. \ + The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer." + item = /obj/item/cartridge/virus/syndicate + cost = 5 + restricted = TRUE + +/datum/uplink_item/explosives/emp + name = "EMP Grenades and Implanter Kit" + desc = "A box that contains five EMP grenades and an EMP implant with three uses. Useful to disrupt communications, \ + security's energy weapons and silicon lifeforms when you're in a tight spot." + item = /obj/item/storage/box/syndie_kit/emp + cost = 2 + +/datum/uplink_item/explosives/virus_grenade + name = "Fungal Tuberculosis Grenade" + desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ + 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 = 8 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/explosives/grenadier + name = "Grenadier's belt" + desc = "A belt containing 26 lethally dangerous and destructive grenades. Comes with an extra multitool and screwdriver." + item = /obj/item/storage/belt/grenade/full + include_modes = list(/datum/game_mode/nuclear) + cost = 22 + surplus = 0 + +/datum/uplink_item/explosives/pizza_bomb + name = "Pizza Bomb" + desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ + opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" + item = /obj/item/pizzabox/bomb + cost = 6 + surplus = 8 + +/datum/uplink_item/explosives/syndicate_bomb + name = "Syndicate Bomb" + desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/bomb + cost = 11 + +/datum/uplink_item/explosives/syndicate_detonator + name = "Syndicate Detonator" + desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ + and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ + Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ + the blast radius before using the detonator." + item = /obj/item/syndicatedetonator + cost = 3 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/syndicate_minibomb + name = "Syndicate Minibomb" + desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ + in addition to dealing high amounts of damage to nearby personnel." + item = /obj/item/grenade/syndieminibomb + cost = 6 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/tearstache + name = "Teachstache Grenade" + desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ + remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." + item = /obj/item/grenade/chem_grenade/teargas/moustache + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/viscerators + name = "Viscerator Delivery Grenade" + desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ + any non-operatives in the area." + item = /obj/item/grenade/spawnergrenade/manhacks + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + + //Support and Mechs /datum/uplink_item/support category = "Support and Mechanized Exosuits" surplus = 0 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/support/clown_reinforcement + name = "Clown Reinforcements" + desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." + item = /obj/item/antag_spawner/nuke_ops/clown + cost = 20 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + restricted = TRUE + /datum/uplink_item/support/reinforcement name = "Reinforcements" desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ @@ -634,7 +1091,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/support/reinforcement/assault_borg name = "Syndicate Assault Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel." + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ + Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault refundable = TRUE cost = 65 @@ -642,27 +1100,21 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/support/reinforcement/medical_borg name = "Syndicate Medical Cyborg" - desc = "A combat medic cyborg, with potent healing reagents and a medical beam gun, but limited offensive potential." + desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ + It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ + Thanks to its organ storage bag, it can perform surgery as well as any humanoid." item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical refundable = TRUE cost = 35 restricted = TRUE /datum/uplink_item/support/gygax - name = "Gygax Exosuit" + name = "Dark Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ - for hit-and-run style attacks. This model lacks a method of space propulsion, and therefore it is \ - advised to utilize the drop pod if you wish to make use of it." + for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." item = /obj/mecha/combat/gygax/dark/loaded cost = 80 -/datum/uplink_item/support/mauler - name = "Mauler Exosuit" - desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring, \ - and deployable smoke." - item = /obj/mecha/combat/marauder/mauler/loaded - cost = 140 - /datum/uplink_item/support/honker name = "Dark H.O.N.K." desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." @@ -670,148 +1122,104 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 80 include_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/support/clown_reinforcement - name = "Clown Reinforcements" - desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." - item = /obj/item/antag_spawner/nuke_ops/clown - cost = 20 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -// Stealthy Weapons -/datum/uplink_item/stealthy_weapons - category = "Stealthy and Inconspicuous Weapons" - -/datum/uplink_item/stealthy_weapons/martialarts - name = "Martial Arts Scroll" - desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ - deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." - item = /obj/item/book/granter/martial/carp - cost = 17 - surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/cqc - name = "CQC Manual" - desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." - item = /obj/item/book/granter/martial/cqc - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cost = 13 - surplus = 0 - -/datum/uplink_item/stealthy_weapons/throwingweapons - name = "Box of Throwing Weapons" - desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ - throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." - item = /obj/item/storage/box/syndie_kit/throwing_weapons - cost = 3 - -/datum/uplink_item/stealthy_weapons/edagger - name = "Energy Dagger" - desc = "A dagger made of energy that looks and functions as a pen when off." - item = /obj/item/pen/edagger - cost = 2 - -/datum/uplink_item/stealthy_weapons/foampistol - name = "Toy Gun with Riot Darts" - desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ - darts effective at incapacitating a target." - item = /obj/item/gun/ballistic/automatic/toy/pistol/riot - cost = 3 - surplus = 10 - -/datum/uplink_item/stealthy_weapons/sleepy_pen - name = "Sleepy Pen" - desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ - strong anesthetic and a chemical that prevents the target from speaking. \ - The pen holds one dose of the mixture, and can be refilled. Note that before the target \ - falls asleep, they will be able to move and act." - item = /obj/item/pen/sleepy - cost = 4 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/soap - name = "Syndicate Soap" - desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ - You can also drop it underfoot to slip people." - item = /obj/item/soap/syndie - cost = 1 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/traitor_chem_bottle - name = "Poison Kit" - desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." - item = /obj/item/storage/box/syndie_kit/chemical - cost = 6 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/romerol_kit - name = "Romerol" - desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent." - item = /obj/item/storage/box/syndie_kit/romerol - cost = 25 - cant_discount = TRUE - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/dart_pistol - name = "Dart Pistol" - desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ - space a small item can." - item = /obj/item/gun/syringe/syndicate - cost = 4 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/detomatix - name = "Detomatix PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ - detonate PDAs of crewmembers who have their message feature enabled. \ - 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 - restricted = TRUE - -/datum/uplink_item/stealthy_weapons/suppressor - name = "Universal Suppressor" - 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 - surplus = 10 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/pizza_bomb - name = "Pizza Bomb" - desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ - opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" - item = /obj/item/pizzabox/bomb - cost = 6 - surplus = 8 - -/datum/uplink_item/stealthy_weapons/dehy_carp - name = "Dehydrated Space Carp" - desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ - your hand before use so it knows not to kill you." - item = /obj/item/toy/plush/carpplushie/dehy_carp - cost = 1 - -/datum/uplink_item/stealthy_weapons/soap_clusterbang - name = "Slipocalypse Clusterbang" - desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" - item = /obj/item/grenade/clusterbuster/soap - cost = 6 +/datum/uplink_item/support/mauler + name = "Mauler Exosuit" + desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ + and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." + item = /obj/mecha/combat/marauder/mauler/loaded + cost = 140 // Stealth Items /datum/uplink_item/stealthy_tools category = "Stealth and Camouflage Items" +/datum/uplink_item/stealthy_tools/agent_card + name = "Agent Identification Card" + desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ + from other identification cards. The access is cumulative, so scanning one card does not erase the \ + access gained from another. In addition, they can be forged to display a new assignment and name. \ + This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ + with these cards." + item = /obj/item/card/id/syndicate + cost = 2 + +/datum/uplink_item/stealthy_tools/ai_detector + name = "Artificial Intelligence Detector" + desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ + activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ + an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ + blind spots can help you identify escape routes." + item = /obj/item/multitool/ai_detect + cost = 1 + /datum/uplink_item/stealthy_tools/chameleon name = "Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Due to budget cuts, the shoes don't provide protection against slipping." item = /obj/item/storage/box/syndie_kit/chameleon cost = 2 exclude_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/stealthy_tools/chameleon_proj + name = "Chameleon Projector" + desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ + move the projector from their hand. Disguised users move slowly, and projectiles pass over them." + item = /obj/item/chameleon + cost = 7 + +/datum/uplink_item/stealthy_tools/codespeak_manual + name = "Codespeak Manual" + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. \ + This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." + item = /obj/item/codespeak_manual/unlimited + cost = 3 + +/datum/uplink_item/stealthy_tools/combatbananashoes + name = "Combat Banana Shoes" + desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ + can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ + squeak significantly louder." + item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat + cost = 6 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/emplight + name = "EMP Flashlight" + desc = "A small, self-recharging, short-ranged EMP device disguised as a working flashlight. \ + Useful for disrupting headsets, cameras, doors, lockers and borgs during stealth operations. \ + Attacking a target with this flashlight will direct an EM pulse at it and consumes a charge." + item = /obj/item/flashlight/emp + cost = 2 + surplus = 30 + +/datum/uplink_item/stealthy_tools/failsafe + name = "Failsafe Uplink Code" + desc = "When entered the uplink will self-destruct immidiately." + item = /obj/effect/gibspawner/generic + cost = 1 + surplus = 0 + restricted = TRUE + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/failsafe/spawn_item(spawn_path, mob/user, datum/component/uplink/U) + if(!U) + return + U.failsafe_code = U.generate_code() + to_chat(user, "The new failsafe code for this uplink is now : [U.failsafe_code].") + if(user.mind) + user.mind.store_memory("Failsafe code for [U.parent] : [U.failsafe_code]") + return U.parent //For log icon + +/datum/uplink_item/stealthy_tools/mulligan + name = "Mulligan" + 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 = 3 + surplus = 30 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/stealthy_tools/syndigaloshes name = "No-Slip Chameleon Shoes" desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ @@ -827,50 +1235,22 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) exclude_modes = list() include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/stealthy_tools/combatbananashoes - name = "Combat Banana Shoes" - desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ - can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ - squeak significantly louder." - item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat - cost = 6 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/stealthy_tools/jammer + name = "Radio Jammer" + desc = "This device will disrupt any nearby outgoing radio communication when activated. Does not affect binary chat." + item = /obj/item/jammer + cost = 5 -/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 \ - when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ - 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 - restricted = TRUE - -/datum/uplink_item/stealthy_tools/agent_card - name = "Agent Identification Card" - desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ - from other identification cards. The access is cumulative, so scanning one card does not erase the \ - access gained from another. In addition, they can be forged to display a new assignment and name. \ - This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ - with these cards." - item = /obj/item/card/id/syndicate - cost = 2 - -/datum/uplink_item/stealthy_tools/chameleon_proj - name = "Chameleon Projector" - desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ - move the projector from their hand. Disguised users move slowly, and projectiles pass over them." - item = /obj/item/chameleon - cost = 7 - -/datum/uplink_item/stealthy_tools/camera_bug - name = "Camera Bug" - desc = "Enables you to view all cameras on the network and track a target. Bugging cameras allows you \ - to disable them remotely." - item = /obj/item/camera_bug - cost = 1 - surplus = 90 +/*/datum/uplink_item/stealthy_tools/syndi_borer + name = "Syndicate Brain Slug" + desc = "A small cortical borer, modified to be completely loyal to the owner. \ + Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \ + to assist their host." + item = /obj/item/antag_spawner/syndi_borer + refundable = TRUE + cost = 10 + surplus = 20 //Let's not have this be too common + exclude_modes = list(/datum/game_mode/nuclear) */ /datum/uplink_item/stealthy_tools/smugglersatchel name = "Smuggler's Satchel" @@ -881,46 +1261,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 surplus = 30 -/datum/uplink_item/stealthy_tools/stimpack - name = "Stimpack" - desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ - 5 minutes after injection." - item = /obj/item/reagent_containers/syringe/stimulants - cost = 5 - surplus = 90 - -/datum/uplink_item/stealthy_tools/mulligan - name = "Mulligan" - 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 - surplus = 30 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/emplight - name = "EMP Flashlight" - desc = "A small, self-charging, short-ranged EMP device disguised as a flashlight. \ - Useful for disrupting headsets, cameras, and borgs during stealth operations." - item = /obj/item/flashlight/emp - cost = 2 - surplus = 30 - -/datum/uplink_item/stealthy_tools/cutouts - name = "Adaptive Cardboard Cutouts" - desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. This pack contains three as well as a \ - crayon for changing their appearances." - item = /obj/item/storage/box/syndie_kit/cutouts - cost = 1 - surplus = 20 - -/datum/uplink_item/stealthy_tools/fakenucleardisk - name = "Decoy Nuclear Authentication Disk" - desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. Don't try to give this to us to complete your objective, we know better!" - item = /obj/item/disk/nuclear/fake - cost = 1 - surplus = 1 - //Space Suits and Hardsuits /datum/uplink_item/suits category = "Space Suits and Hardsuits" @@ -928,7 +1268,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/space_suit name = "Syndicate Space Suit" - desc = "This red and black syndicate space suit is less encumbering than Nanotrasen variants, \ + desc = "This red and black Syndicate space suit is less encumbering than Nanotrasen variants, \ fits inside bags, and has a weapon slot. Nanotrasen crew members are trained to report red space suit \ sightings, however." item = /obj/item/storage/box/syndie_kit/space @@ -936,7 +1276,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/hardsuit name = "Syndicate Hardsuit" - desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ + desc = "The feared suit of a Syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ that runs off standard atmospheric tanks. Toggling the suit in and out of \ combat mode will allow you all the mobility of a loose fitting uniform without sacrificing armoring. \ Additionally the suit is collapsible, making it small enough to fit within a backpack. \ @@ -947,8 +1287,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/hardsuit/elite name = "Elite Syndicate Hardsuit" - desc = "An upgraded, elite version of the syndicate hardsuit. It features fireproofing, and also \ - provides the user with superior armor and mobility compared to the standard syndicate hardsuit." + desc = "An upgraded, elite version of the Syndicate hardsuit. It features fireproofing, and also \ + provides the user with superior armor and mobility compared to the standard Syndicate hardsuit." item = /obj/item/clothing/suit/space/hardsuit/syndi/elite cost = 8 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -956,7 +1296,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/hardsuit/shielded name = "Shielded Syndicate Hardsuit" - desc = "An upgraded version of the standard syndicate hardsuit. It features a built-in energy shielding system. \ + desc = "An upgraded version of the standard Syndicate hardsuit. It features a built-in energy shielding system. \ The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire." item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi cost = 30 @@ -967,39 +1307,66 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/device_tools category = "Devices and Tools" -/datum/uplink_item/device_tools/emag - name = "Cryptographic Sequencer" - desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ - in electronic devices, subverts intended functions, and easily breaks security mechanisms." - item = /obj/item/card/emag +/datum/uplink_item/device_tools/cutouts + name = "Adaptive Cardboard Cutouts" + desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \ + This pack contains three as well as a crayon for changing their appearances." + item = /obj/item/storage/box/syndie_kit/cutouts + cost = 1 + surplus = 20 + +/datum/uplink_item/device_tools/assault_pod + name = "Assault Pod Targeting Device" + desc = "Use this to select the landing zone of your assault pod." + item = /obj/item/assault_pod + cost = 30 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/device_tools/binary + name = "Binary Translator Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ + 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 = 2 + surplus = 75 + restricted = TRUE + +/datum/uplink_item/device_tools/magboots + name = "Blood-Red Magboots" + desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ + during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ + 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." + item = /obj/item/clothing/shoes/magboots/syndie + cost = 2 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/device_tools/compressionkit + name = "Bluespace Compression Kit" + desc = "A modified version of a BSRPED that can be used to reduce the size of most items while retaining their original functions! \ + Does not work on storage items. \ + Recharge using bluespace crystals. \ + Comes with 5 charges." + item = /obj/item/compressionkit + cost = 5 + +/datum/uplink_item/device_tools/briefcase_launchpad + name = "Briefcase Launchpad" + desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ + Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." + surplus = 0 + item = /obj/item/storage/briefcase/launchpad cost = 6 -/datum/uplink_item/device_tools/toolbox - name = "Full Syndicate Toolbox" - desc = "The syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ - multitool and combat gloves that are resistant to shocks and heat." - item = /obj/item/storage/toolbox/syndicate +/datum/uplink_item/device_tools/camera_bug + name = "Camera Bug" + desc = "Enables you to view all cameras on the main network, set up motion alerts and track a target. \ + Bugging cameras allows you to disable them remotely." + item = /obj/item/camera_bug cost = 1 - -/datum/uplink_item/device_tools/surgerybag - name = "Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, and a muzzle." - 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" - 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 + surplus = 90 /datum/uplink_item/device_tools/military_belt name = "Chest Rig" @@ -1008,18 +1375,142 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 1 exclude_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/device_tools/emag + name = "Cryptographic Sequencer" + desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ + in electronic devices, subverts intended functions, and easily breaks security mechanisms." + item = /obj/item/card/emag + cost = 6 + +/datum/uplink_item/device_tools/emagrecharge + name = "Electromagnet Charging Device" + desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." + item = /obj/item/emagrecharge + cost = 2 + +/datum/uplink_item/device_tools/fakenucleardisk + name = "Decoy Nuclear Authentication Disk" + desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. \ + Don't try to give this to us to complete your objective, we know better!" + item = /obj/item/disk/nuclear/fake + cost = 1 + surplus = 1 + +/datum/uplink_item/device_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 \ + when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ + 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 = 2 + restricted = TRUE + +/datum/uplink_item/device_tools/toolbox + name = "Full Syndicate Toolbox" + desc = "The Syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ + multitool and combat gloves that are resistant to shocks and heat." + item = /obj/item/storage/toolbox/syndicate + cost = 1 + +/datum/uplink_item/device_tools/syndie_glue + name = "Glue" + desc = "A cheap bottle of one use syndicate brand super glue. \ + Use on any item to make it undroppable. \ + Be careful not to glue an item you're already holding!" + item = /obj/item/syndie_glue + cost = 2 + +/datum/uplink_item/device_tools/hacked_module + name = "Hacked AI Law Upload Module" + desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ + Be careful with wording, as artificial intelligences may look for loopholes to exploit." + item = /obj/item/aiModule/syndicate + cost = 9 + +/datum/uplink_item/device_tools/medgun + name = "Medbeam Gun" + desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ + operatives in the fight, even while under fire. Don't cross the streams!" + item = /obj/item/gun/medbeam + cost = 15 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/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/singularity_beacon + name = "Power Beacon" + desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ + active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ + in containment. Because of its size, it cannot be carried. Ordering this \ + sends you a small beacon that will teleport the larger beacon to your location upon activation." + item = /obj/item/sbeacondrop + cost = 14 + +/datum/uplink_item/device_tools/powersink + name = "Power Sink" + desc = "When screwed to wiring attached to a power grid and activated, this large device lights up and places excessive \ + load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ + traditional bags and boxes. Caution: Will explode if the powernet contains sufficient amounts of energy." + item = /obj/item/powersink + cost = 6 + +/datum/uplink_item/device_tools/rad_laser + name = "Radioactive Microlaser" + desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ + powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ + of humanoids. It has two settings: intensity, which controls the power of the radiation, \ + and wavelength, which controls the delay before the effect kicks in." + item = /obj/item/healthanalyzer/rad_laser + cost = 3 + +/datum/uplink_item/device_tools/stimpack + name = "Stimpack" + desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ + 5 minutes after injection." + item = /obj/item/reagent_containers/syringe/stimulants + cost = 5 + surplus = 90 + /datum/uplink_item/device_tools/medkit name = "Syndicate Combat Medic Kit" desc = "This first aid kit is a suspicious brown and red. Included is a combat stimulant injector \ - for rapid healing, a medical HUD for quick identification of injured personnel, \ + for rapid healing, a medical night vision HUD for quick identification of injured personnel, \ and other supplies helpful for a field medic." item = /obj/item/storage/firstaid/tactical cost = 4 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/device_tools/surgerybag + name = "Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ + a Syndicate brand MMI, a straitjacket, and a muzzle." + item = /obj/item/storage/backpack/duffelbag/syndie/surgery + cost = 3 + +/datum/uplink_item/device_tools/surgerybag_adv + name = "Advanced Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all advanced 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 = 10 + +/datum/uplink_item/device_tools/encryptionkey + name = "Syndicate Encryption Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ + as well as talk on an encrypted Syndicate channel with other agents that have the same key." + item = /obj/item/encryptionkey/syndicate + cost = 2 + surplus = 75 + restricted = TRUE + /datum/uplink_item/device_tools/syndietome name = "Syndicate Tome" - desc = "Using rare artifacts acquired at great cost, the syndicate has reverse engineered \ + desc = "Using rare artifacts acquired at great cost, the Syndicate has reverse engineered \ the seemingly magical books of a certain cult. Though lacking the esoteric abilities \ of the originals, these inferior copies are still quite useful, being able to provide \ both weal and woe on the battlefield, even if they do occasionally bite off a finger." @@ -1035,223 +1526,36 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/clothing/glasses/thermal/syndi cost = 4 -/datum/uplink_item/device_tools/binary - name = "Binary Translator Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ - 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 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/encryptionkey - name = "Syndicate Encryption Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ - as well as talk on an encrypted Syndicate channel with other agents that have the same key." - item = /obj/item/encryptionkey/syndicate - cost = 2 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/ai_detector - name = "Artificial Intelligence Detector" - desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ - activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ - an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ - blind spots can help you identify escape routes." - item = /obj/item/multitool/ai_detect - cost = 1 - -/datum/uplink_item/device_tools/hacked_module - name = "Hacked AI Law Upload Module" - desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ - Be careful with wording, as artificial intelligences may look for loopholes to exploit." - item = /obj/item/aiModule/syndicate - cost = 9 - -/datum/uplink_item/device_tools/briefcase_launchpad - name = "Briefcase Launchpad" - desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ - Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." - surplus = 0 - item = /obj/item/storage/briefcase/launchpad - cost = 6 - -/datum/uplink_item/device_tools/magboots - name = "Blood-Red Magboots" - desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ - during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ - 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." - item = /obj/item/clothing/shoes/magboots/syndie - cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/c4 - name = "Composition C-4" - desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ - an assembly to it in order to alter the way it detonates. It has a modifiable timer with a \ - minimum setting of 10 seconds." - item = /obj/item/grenade/plastic/c4 - cost = 1 - -/datum/uplink_item/device_tools/c4bag - name = "Bag of C-4 explosives" - desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." - item = /obj/item/storage/backpack/duffelbag/syndie/c4 - cost = 9 //10% discount! - cant_discount = TRUE - -/datum/uplink_item/device_tools/x4bag - name = "Bag of X-4 explosives" - desc = "Contains 3 X-4 plastic explosives. Similar, but more powerful than C-4. X-4 can be placed on a solid surface, such as a wall or window, and it will \ - blast through the wall, injuring anything on the opposite side, while being safer to the user. For when you want a wider, deeper, hole." - item = /obj/item/storage/backpack/duffelbag/syndie/x4 - cost = 4 // - cant_discount = TRUE - -/datum/uplink_item/device_tools/powersink - name = "Power Sink" - desc = "When screwed to wiring attached to a power grid and activated, this large device places excessive \ - load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ - traditional bags and boxes." - item = /obj/item/powersink - cost = 6 - -/datum/uplink_item/device_tools/singularity_beacon - name = "Power Beacon" - desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ - active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ - in containment. Because of its size, it cannot be carried. Ordering this \ - sends you a small beacon that will teleport the larger beacon to your location upon activation." - item = /obj/item/sbeacondrop - cost = 14 - -/datum/uplink_item/device_tools/syndicate_bomb - name = "Syndicate Bomb" - desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/bomb - cost = 11 - -/datum/uplink_item/device_tools/clown_bomb_clownops - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/syndicate_detonator - name = "Syndicate Detonator" - desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ - and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ - Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ - the blast radius before using the detonator." - item = /obj/item/syndicatedetonator - cost = 3 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/rad_laser - name = "Radioactive Microlaser" - desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ - powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ - of humanoids. It has two settings: intensity, which controls the power of the radiation, \ - and wavelength, which controls how long the radiation delay is." - item = /obj/item/healthanalyzer/rad_laser - cost = 3 - -/datum/uplink_item/device_tools/assault_pod - name = "Assault Pod Targeting Device" - desc = "Use to select the landing zone of your assault pod." - item = /obj/item/assault_pod - cost = 30 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -/datum/uplink_item/device_tools/shield - name = "Energy Shield" - desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ - against other attacks. Pair with an Energy Sword for a killer combination." - item = /obj/item/shield/energy - cost = 16 - surplus = 20 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/bananashield - name = "Bananium Energy Shield" - desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ - by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ - and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." - item = /obj/item/shield/energy/bananium - cost = 16 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/medgun - name = "Medbeam Gun" - desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ - operatives in the fight, even while under fire." - item = /obj/item/gun/medbeam - cost = 15 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/device_tools/potion 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 + 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 = 2 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE -/datum/uplink_item/device_tools/telecrystal - name = "Raw Telecrystal" - desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal - cost = 1 - surplus = 0 - cant_discount = TRUE - // Don't add telecrystals to the purchase_log since - // it's just used to buy more items (including itself!) - purchase_log_vis = FALSE - -/datum/uplink_item/device_tools/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/device_tools/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 - -/datum/uplink_item/device_tools/jammer - name = "Radio Jammer" - desc = "This device will disrupt any nearby outgoing radio communication when activated." - item = /obj/item/jammer - cost = 5 - -/datum/uplink_item/device_tools/codespeak_manual - name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." - item = /obj/item/codespeak_manual/unlimited - cost = 3 // Implants /datum/uplink_item/implants category = "Implants" surplus = 50 +/datum/uplink_item/implants/adrenal + name = "Adrenal Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ + cocktail which removes all incapacitating effects, lets the user run faster and has a mild healing effect." + item = /obj/item/storage/box/syndie_kit/imp_adrenal + cost = 8 + player_minimum = 25 + +/datum/uplink_item/implants/antistun + name = "CNS Rebooter Implant" + desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." + item = /obj/item/autosurgeon/anti_stun + cost = 12 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/implants/freedom name = "Freedom Implant" desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ @@ -1259,30 +1563,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/box/syndie_kit/imp_freedom cost = 5 -/datum/uplink_item/implants/uplink - name = "Uplink Implant" - desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals, must be charged by the use of physical telecrystals. Undetectable (except via surgery), and excellent for escaping confinement." - item = /obj/item/storage/box/syndie_kit/imp_uplink - cost = 4 - // An empty uplink is kinda useless. - surplus = 0 - restricted = TRUE - -/datum/uplink_item/implants/adrenal - name = "Adrenal Implant" - desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ - cocktail which has a mild healing effect along with removing all stuns and increasing movement speed." - item = /obj/item/storage/box/syndie_kit/imp_adrenal - cost = 8 - player_minimum = 25 - -/datum/uplink_item/implants/storage - name = "Storage Implant" - desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ - pocket capable of storing two items." - item = /obj/item/storage/box/syndie_kit/imp_storage - cost = 8 - /datum/uplink_item/implants/microbomb name = "Microbomb Implant" desc = "An implant injected into the body, and later activated either manually or automatically upon death. \ @@ -1303,53 +1583,57 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/implants/radio name = "Internal Syndicate Radio Implant" - desc = "An implant injected into the body, allowing the use of an internal syndicate radio. Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." + desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \ + Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." item = /obj/item/storage/box/syndie_kit/imp_radio cost = 4 restricted = TRUE +/datum/uplink_item/implants/reviver + name = "Reviver Implant" + desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." + item = /obj/item/autosurgeon/reviver + cost = 8 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/implants/stealthimplant name = "Stealth Implant" - desc = "This one-of-a-kind implant will make you almost invisible if you play your cards right." + desc = "This one-of-a-kind implant will make you almost invisible as long as you don't don't excessively move around. \ + On activation, it will conceal you inside a chameleon cardboard box that is only revealed once someone bumps into it." item = /obj/item/implanter/stealth cost = 8 -// Cybernetics -/datum/uplink_item/cyber_implants - category = "Cybernetic Implants" - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/implants/storage + name = "Storage Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ + pocket capable of storing two regular-sized items." + item = /obj/item/storage/box/syndie_kit/imp_storage + cost = 8 -/datum/uplink_item/cyber_implants/thermals +/datum/uplink_item/implants/thermals name = "Thermal Eyes" desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." item = /obj/item/autosurgeon/thermal_eyes cost = 8 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/cyber_implants/xray +/datum/uplink_item/implants/uplink + name = "Uplink Implant" + desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals and must be charged by the use of physical telecrystals. \ + Undetectable (except via surgery), and excellent for escaping confinement." + item = /obj/item/storage/box/syndie_kit/imp_uplink + cost = 4 + // An empty uplink is kinda useless. + surplus = 0 + restricted = TRUE + +/datum/uplink_item/implants/xray name = "X-ray Vision Implant" desc = "These cybernetic eyes will give you X-ray vision. Comes with an autosurgeon." item = /obj/item/autosurgeon/xray_eyes cost = 10 - -/datum/uplink_item/cyber_implants/antistun - name = "CNS Rebooter Implant" - desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." - item = /obj/item/autosurgeon/anti_stun - cost = 12 - -/datum/uplink_item/cyber_implants/reviver - name = "Reviver Implant" - desc = "This implant will attempt to revive you if you lose consciousness. Comes with an autosurgeon." - item = /obj/item/autosurgeon/reviver - cost = 8 - -/datum/uplink_item/cyber_implants/bundle - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." - item = /obj/item/storage/box/cyber_implants - cost = 40 - cant_discount = TRUE + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) // Role-specific items /datum/uplink_item/role_restricted @@ -1357,23 +1641,63 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) surplus = 0 -/datum/uplink_item/role_restricted/reverse_revolver - name = "Reverse Revolver" - desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ - The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." - cost = 14 - item = /obj/item/storage/box/hug/reverse_revolver +/datum/uplink_item/role_restricted/ancient_jumpsuit + name = "Ancient Jumpsuit" + desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." + item = /obj/item/clothing/under/color/grey/glorf + cost = 20 + restricted_roles = list("Assistant") + +/datum/uplink_item/role_restricted/pie_cannon + name = "Banana Cream Pie Cannon" + desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" + cost = 10 + item = /obj/item/pneumatic_cannon/pie/selfcharge restricted_roles = list("Clown") -/datum/uplink_item/role_restricted/reverse_bear_trap - name = "Reverse Bear Trap" - desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ - violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ - head after three seconds uninterrupted." - cost = 5 - item = /obj/item/reverse_bear_trap +/datum/uplink_item/role_restricted/blastcannon + name = "Blast Cannon" + desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ + withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ + blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ + disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." + item = /obj/item/gun/blastcannon + cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. + restricted_roles = list("Research Director", "Scientist") + +/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 = 3 + +/datum/uplink_item/role_restricted/clown_bomb + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so. \ + The bomb core can be pried out and manually detonated with other explosives." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 restricted_roles = list("Clown") +/* +/datum/uplink_item/role_restricted/clowncar + name = "Clown Car" + desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ + Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ + You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ + someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ + are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" + item = /obj/vehicle/sealed/car/clowncar + cost = 15 + restricted_roles = list("Clown") +*/ + /datum/uplink_item/role_restricted/clumsyDNA name = "Clumsy Clown DNA" desc = "A DNA injector that has been loaded with the clown gene that makes people clumsy.. \ @@ -1382,42 +1706,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/dnainjector/clumsymut 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." - cost = 12 - item = /obj/item/storage/box/syndie_kit/mimery - restricted_roles = list("Mime") - -/datum/uplink_item/role_restricted/ez_clean_bundle - name = "EZ Clean Grenade Bundle" - desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. The acid only affects carbon-based creatures." - item = /obj/item/storage/box/syndie_kit/ez_clean - cost = 6 - surplus = 20 - restricted_roles = list("Janitor") - -/datum/uplink_item/role_restricted/kitchen_gun - name = "Kitchen Gun (TM)" - desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" - cost = 10 - surplus = 40 - restricted_roles = list("Cook", "Janitor") - item = /obj/item/storage/box/syndie_kit/kitchen_gun - -/datum/uplink_item/role_restricted/kitchen_gun_ammo - name = "Kitchen Gun (TM) .45 Magazine" - desc = "An extra eight bullets for an extra eight uses of Kitchen Gun (TM)!" - cost = 1 - restricted_roles = list("Cook", "Janitor") - item = /obj/item/ammo_box/magazine/m45/kitchengun - -/datum/uplink_item/role_restricted/explosive_hot_potato - name = "Exploding Hot Potato" - desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." - item = /obj/item/hot_potato/syndicate - cost = 4 - restricted_roles = list("Cook", "Botanist", "Clown", "Mime") +/datum/uplink_item/role_restricted/haunted_magic_eightball + name = "Haunted Magic Eightball" + desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. \ + Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." + item = /obj/item/toy/eightball/haunted + cost = 2 + restricted_roles = list("Curator") + limited_stock = 1 //please don't spam deadchat /datum/uplink_item/role_restricted/his_grace name = "His Grace" @@ -1430,42 +1726,78 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) restricted_roles = list("Chaplain") surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain -/datum/uplink_item/role_restricted/pie_cannon - name = "Banana Cream Pie Cannon" - desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" - cost = 10 - item = /obj/item/pneumatic_cannon/pie/selfcharge - restricted_roles = list("Clown") +/datum/uplink_item/role_restricted/explosive_hot_potato + name = "Exploding Hot Potato" + desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. \ + The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." + item = /obj/item/hot_potato/syndicate + cost = 4 + restricted_roles = list("Cook", "Botanist", "Clown", "Mime") -/datum/uplink_item/role_restricted/ancient_jumpsuit - name = "Ancient Jumpsuit" - desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." - item = /obj/item/clothing/under/color/grey/glorf - cost = 20 - restricted_roles = list("Assistant") +/datum/uplink_item/role_restricted/ez_clean_bundle + name = "EZ Clean Grenade Bundle" + desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. \ + The acid only affects carbon-based creatures." + item = /obj/item/storage/box/syndie_kit/ez_clean + cost = 6 + surplus = 20 + restricted_roles = list("Janitor") /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 = 5 // Has synda tools + gloves + a robust weapon - restricted_roles = list("Assistant", "Curator") //Curator do to being made of gold - It fits the theme + cost = 3 // Has syndie tools + gloves + a robust weapon + restricted_roles = list("Assistant", "Curator") //Curator due to this 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 +/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." + cost = 12 + item = /obj/item/storage/box/syndie_kit/mimery + restricted_roles = list("Mime") -/datum/uplink_item/role_restricted/haunted_magic_eightball - name = "Haunted Magic Eightball" - desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." - item = /obj/item/toy/eightball/haunted +/datum/uplink_item/role_restricted/ultrahonkpins + 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/ultra cost = 2 - restricted_roles = list("Curator") - limited_stock = 1 //please don't spam deadchat + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/pressure_mod + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. \ + Occupies 35% mod capacity." + item = /obj/item/borg/upgrade/modkit/indoors + cost = 5 //you need two for full damage, so total of 10 for maximum damage + limited_stock = 2 //you can't use more than two! + restricted_roles = list("Shaft Miner") + +/datum/uplink_item/role_restricted/kitchen_gun + name = "Kitchen Gun (TM)" + desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \ + Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" + cost = 10 + surplus = 40 + restricted_roles = list("Cook", "Janitor") + item = /obj/item/storage/box/syndie_kit/kitchen_gun + +/datum/uplink_item/role_restricted/kitchen_gun_ammo + name = "Kitchen Gun (TM) .45 Magazine" + desc = "An extra eight bullets for an extra eight uses of Kitchen Gun (TM)!" + cost = 1 + restricted_roles = list("Cook", "Janitor") + item = /obj/item/ammo_box/magazine/m45/kitchengun + +/datum/uplink_item/role_restricted/magillitis_serum + name = "Magillitis Serum Autoinjector" + desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. \ + Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." + item = /obj/item/reagent_containers/hypospray/magillitis + cost = 15 + restricted_roles = list("Geneticist", "Chief Medical Officer") /datum/uplink_item/role_restricted/modified_syringe_gun name = "Modified Syringe Gun" @@ -1481,67 +1813,85 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 12 restricted_roles = list("Chemist", "Chief Medical Officer") -/datum/uplink_item/role_restricted/magillitis_serum - name = "Magillitis Serum Autoinjector" - desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." - item = /obj/item/reagent_containers/hypospray/magillitis - cost = 15 - restricted_roles = list("Geneticist", "Chief Medical Officer") - -/datum/uplink_item/role_restricted/pressure_mod - name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity." - item = /obj/item/borg/upgrade/modkit/indoors - cost = 5 //you need two for full damage, so total of 10 for maximum damage - limited_stock = 2 //you can't use more than two! - restricted_roles = list("Shaft Miner") - -/datum/uplink_item/role_restricted/blastcannon - name = "Blast Cannon" - desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ - withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ - blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ - disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." - item = /obj/item/gun/blastcannon - cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. - restricted_roles = list("Research Director", "Scientist") - -/datum/uplink_item/device_tools/clown_bomb - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 +/datum/uplink_item/role_restricted/reverse_bear_trap + name = "Reverse Bear Trap" + desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ + violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ + head after three seconds uninterrupted." + cost = 5 + item = /obj/item/reverse_bear_trap restricted_roles = list("Clown") -/datum/uplink_item/device_tools/honkpins //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 +/datum/uplink_item/role_restricted/reverse_revolver + name = "Reverse Revolver" + desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ + The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." + cost = 14 + item = /obj/item/storage/box/hug/reverse_revolver restricted_roles = list("Clown") -/* -/datum/uplink_item/role_restricted/clowncar - name = "Clown Car" - desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ - Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ - You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ - someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ - are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" - item = /obj/vehicle/sealed/car/clowncar - cost = 15 +/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") -*/ + // Pointless /datum/uplink_item/badass category = "(Pointless) Badassery" surplus = 0 +/datum/uplink_item/badass/costumes/obvious_chameleon + name = "Broken Chameleon Kit" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Please note that this kit did NOT pass quality control." + item = /obj/item/storage/box/syndie_kit/chameleon/broken + +/datum/uplink_item/badass/costumes + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cost = 4 + cant_discount = TRUE + +/datum/uplink_item/badass/costumes/centcom_official + name = "CentCom Official Costume" + desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. \ + Radio headset does not include encryption key. No gun included." + item = /obj/item/storage/box/syndie_kit/centcom_costume + +/datum/uplink_item/badass/costumes/clown + name = "Clown Costume" + desc = "Nothing is more terrifying than clowns with fully automatic weaponry." + item = /obj/item/storage/backpack/duffelbag/clown/syndie + +/datum/uplink_item/badass/plastitanium_toolbox + name = "Plastitanium Toolbox" + desc = "A very high impact toolbox. Excels at destroying stationary structures." + item = /obj/item/storage/toolbox/plastitanium + cost = 2 //18 damage on mobs, 50 on objects, 4.5 stam/hit + +/datum/uplink_item/badass/balloon + name = "Syndicate Balloon" + desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ + Can blow the deepest of covers." + item = /obj/item/toy/syndicateballoon + cost = 20 + cant_discount = TRUE + +/datum/uplink_item/badass/syndiecash + name = "Syndicate Briefcase Full of Cash" + desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ + and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ + manufactured to pack a little bit more of a punch if your client needs some convincing." + item = /obj/item/storage/secure/briefcase/syndie + cost = 1 + +/datum/uplink_item/badass/phantomthief + name = "Syndicate Mask" + desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" + item = /obj/item/clothing/glasses/phantomthief/syndicate + cost = 2 + /datum/uplink_item/badass/syndiecards name = "Syndicate Playing Cards" desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \ @@ -1551,128 +1901,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 1 surplus = 40 -/datum/uplink_item/badass/syndiecash - name = "Syndicate Briefcase Full of Cash" - desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ - and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ - manufactured to pack a little bit more of a punch if your client needs some convincing." - item = /obj/item/storage/secure/briefcase/syndie - cost = 1 - /datum/uplink_item/badass/syndiecigs name = "Syndicate Smokes" desc = "Strong flavor, dense smoke, infused with omnizine." item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate cost = 2 - -/datum/uplink_item/badass/balloon - name = "Syndicate Balloon" - desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ - Can blow the deepest of covers." - item = /obj/item/toy/syndicateballoon - cost = 20 - cant_discount = TRUE - -/datum/uplink_item/badass/costumes - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cost = 4 - cant_discount = TRUE - -/datum/uplink_item/badass/costumes/centcom_official - name = "CentCom Official Costume" - desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. Radio headset does not include key. No gun included." - item = /obj/item/storage/box/syndie_kit/centcom_costume - -/datum/uplink_item/badass/costumes/clown - name = "Clown Costume" - desc = "Nothing is more terrifying than clowns with fully automatic weaponry." - item = /obj/item/storage/backpack/duffelbag/clown/syndie - -/datum/uplink_item/badass/costumes/obvious_chameleon - name = "Broken Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! Please note that this kit did NOT pass quality control." - item = /obj/item/storage/box/syndie_kit/chameleon/broken - -/datum/uplink_item/badass/rapid - name = "Gloves of the North Star" - desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." - item = /obj/item/clothing/gloves/rapid - cost = 8 - -/datum/uplink_item/badass/bundle - name = "Syndicate Bundle" - desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ - These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ - you will receive." - item = /obj/item/storage/box/syndicate - cost = 20 - exclude_modes = list(/datum/game_mode/nuclear) - cant_discount = TRUE - -/datum/uplink_item/badass/surplus - name = "Syndicate Surplus Crate" - desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 50 TC." - item = /obj/structure/closet/crate - cost = 20 - player_minimum = 25 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cant_discount = TRUE - var/starting_crate_value = 50 - -/datum/uplink_item/badass/surplus/super - name = "Super Surplus Crate" - desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 125 TC." - cost = 40 - player_minimum = 40 - starting_crate_value = 125 - -/datum/uplink_item/badass/surplus/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) - - var/crate_value = starting_crate_value - var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user) - if(U.purchase_log) - U.purchase_log.LogPurchase(C, src, cost) - while(crate_value) - var/category = pick(uplink_items) - var/item = pick(uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - - if(!I.surplus || prob(100 - I.surplus)) - continue - if(crate_value < I.cost) - continue - crate_value -= I.cost - var/obj/goods = new I.item(C) - if(U.purchase_log) - U.purchase_log.LogPurchase(goods, I, 0) - return C - -/datum/uplink_item/badass/random - name = "Random Item" - desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." - item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech - cost = 0 - cant_discount = TRUE - -/datum/uplink_item/badass/random/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = U.uplink_items - var/list/possible_items = list() - for(var/category in uplink_items) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(src == I || !I.item) - continue - if(U.telecrystals < I.cost) - continue - if(I.limited_stock == 0) - continue - possible_items += I - - if(possible_items.len) - var/datum/uplink_item/I = pick(possible_items) - SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) - U.MakePurchase(user, I) diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index be59a6df65..54bc03bcf3 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -31,6 +31,19 @@ occupant_actions = list() generate_actions() +/obj/vehicle/examine(mob/user) + ..() + if(resistance_flags & ON_FIRE) + to_chat(user, "It's on fire!") + var/healthpercent = obj_integrity/max_integrity * 100 + switch(healthpercent) + if(50 to 99) + to_chat(user, "It looks slightly damaged.") + if(25 to 50) + to_chat(user, "It appears heavily damaged.") + if(0 to 25) + to_chat(user, "It's falling apart!") + /obj/vehicle/proc/is_key(obj/item/I) return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index 25a337bc22..8fe7322579 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -4,8 +4,8 @@ max_buckled_mobs = 1 buckle_lying = FALSE default_driver_move = FALSE - var/legs_required = 2 - var/arms_requires = 0 //why not? + var/legs_required = 1 + var/arms_required = 0 //why not? /obj/vehicle/ridden/Initialize() . = ..() @@ -31,6 +31,9 @@ /obj/vehicle/ridden/post_buckle_mob(mob/living/M) add_occupant(M) + if(M.get_num_legs() < legs_required) + to_chat(M, "You don't have enough legs to operate the pedals!") + unbuckle_mob(M) return ..() /obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm new file mode 100644 index 0000000000..137242c547 --- /dev/null +++ b/code/modules/vehicles/wheelchair.dm @@ -0,0 +1,110 @@ +/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic) Then ported by Fermis from tg! + name = "wheelchair" + desc = "A chair with big wheels. It looks like you can move in this on your own." + icon = 'icons/obj/vehicles.dmi' + icon_state = "wheelchair" + layer = OBJ_LAYER + max_integrity = 100 + armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo + legs_required = 0 //You'll probably be using this if you don't have legs + canmove = TRUE + density = FALSE //Thought I couldn't fix this one easily, phew + arms_required = 1 + +/obj/vehicle/ridden/wheelchair/Initialize() + . = ..() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 0 + D.set_vehicle_dir_layer(SOUTH, OBJ_LAYER) + D.set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER) + D.set_vehicle_dir_layer(EAST, OBJ_LAYER) + D.set_vehicle_dir_layer(WEST, OBJ_LAYER) + +/obj/vehicle/ridden/wheelchair/ComponentInitialize() //Since it's technically a chair I want it to have chair properties + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null) + +/obj/vehicle/ridden/wheelchair/obj_destruction(damage_flag) + new /obj/item/stack/rods(drop_location(), 1) + new /obj/item/stack/sheet/metal(drop_location(), 1) + ..() + +/obj/vehicle/ridden/wheelchair/Destroy() + if(has_buckled_mobs()) + var/mob/living/carbon/H = buckled_mobs[1] + unbuckle_mob(H) + return ..() + +/obj/vehicle/ridden/wheelchair/driver_move(mob/living/user, direction) + if(istype(user)) + if(canmove && (user.get_num_arms() < arms_required)) + to_chat(user, "You don't have enough arms to operate the wheels!") + canmove = FALSE + addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20) + return FALSE + var/datum/component/riding/D = GetComponent(/datum/component/riding) + //1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have + //if that made no sense this simply makes the wheelchair speed change along with movement speed delay + D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag) + return ..() + +/obj/vehicle/ridden/wheelchair/Moved() + . = ..() + cut_overlays() + playsound(src, 'sound/effects/roll.ogg', 75, 1) + if(has_buckled_mobs()) + handle_rotation_overlayed() + + +/obj/vehicle/ridden/wheelchair/post_buckle_mob(mob/living/user) + . = ..() + handle_rotation_overlayed() + +/obj/vehicle/ridden/wheelchair/post_unbuckle_mob() + . = ..() + cut_overlays() + +/obj/vehicle/ridden/wheelchair/setDir(newdir) + ..() + handle_rotation(newdir) + +/obj/vehicle/ridden/wheelchair/wrench_act(mob/living/user, obj/item/I) //Attackby should stop it attacking the wheelchair after moving away during decon + to_chat(user, "You begin to detach the wheels...") + if(I.use_tool(src, user, 40, volume=50)) + to_chat(user, "You detach the wheels and deconstruct the chair.") + new /obj/item/stack/rods(drop_location(), 6) + new /obj/item/stack/sheet/metal(drop_location(), 4) + qdel(src) + return TRUE + +/obj/vehicle/ridden/wheelchair/proc/handle_rotation(direction) + if(has_buckled_mobs()) + handle_rotation_overlayed() + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + buckled_mob.setDir(direction) + +/obj/vehicle/ridden/wheelchair/proc/handle_rotation_overlayed() + cut_overlays() + var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir) + add_overlay(V) + + + +/obj/vehicle/ridden/wheelchair/proc/can_be_rotated(mob/living/user) + return TRUE + +/obj/vehicle/ridden/wheelchair/proc/can_user_rotate(mob/living/user) + var/mob/living/L = user + if(istype(L)) + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return FALSE + if(isobserver(user) && CONFIG_GET(flag/ghost_interaction)) + return TRUE + return FALSE + +/obj/vehicle/ridden/wheelchair/the_whip/driver_move(mob/living/user, direction) + if(istype(user)) + var/datum/component/riding/D = GetComponent(/datum/component/riding) + D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / user.get_num_arms() + return ..() diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 735967440f..55cd0a196e 100644 --- a/code/modules/vending/boozeomat.dm +++ b/code/modules/vending/boozeomat.dm @@ -33,6 +33,9 @@ /obj/item/reagent_containers/food/drinks/beer = 6) contraband = list(/obj/item/reagent_containers/food/drinks/mug/tea = 12, /obj/item/reagent_containers/food/drinks/bottle/fernet = 5) + premium = list(/obj/item/reagent_containers/glass/bottle/ethanol = 4, + /obj/item/reagent_containers/food/drinks/bottle/champagne = 5, + /obj/item/reagent_containers/food/drinks/bottle/trappist = 5) product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" req_access = list(ACCESS_BAR) diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index f61c392ff7..3da3398aad 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -16,7 +16,8 @@ contraband = list(/obj/item/reagent_containers/food/drinks/soda_cans/thirteenloko = 6, /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 6) premium = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1, - /obj/item/reagent_containers/food/drinks/soda_cans/air = 1) + /obj/item/reagent_containers/food/drinks/soda_cans/air = 1, + /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1) refill_canister = /obj/item/vending_refill/cola /obj/item/vending_refill/cola diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index 33e839c039..749a3b7c2b 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -11,6 +11,7 @@ /obj/item/clothing/suit/apron/chef = 2, /obj/item/reagent_containers/food/condiment/pack/ketchup = 5, /obj/item/reagent_containers/food/condiment/pack/hotsauce = 5, + /obj/item/reagent_containers/food/condiment/pack/astrotame = 5, /obj/item/reagent_containers/food/condiment/saltshaker = 5, /obj/item/reagent_containers/food/condiment/peppermill = 5, /obj/item/reagent_containers/glass/bowl = 30) diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 5ff07cc842..523606aa6a 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -23,14 +23,19 @@ /obj/item/reagent_containers/glass/bottle/salglu_solution = 3, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/toxin = 3, - /obj/item/reagent_containers/syringe/antiviral = 6) + /obj/item/reagent_containers/syringe/antiviral = 6, + /obj/item/storage/briefcase/medical = 2) contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6) premium = list(/obj/item/storage/box/hug/medical = 1, /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, - /obj/item/wrench/medical = 1) + /obj/item/wrench/medical = 1, + /obj/item/storage/belt/medolier/full = 2, + /obj/item/gun/syringe/dart = 2, + /obj/item/storage/briefcase/medical = 2) + armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical @@ -41,4 +46,4 @@ /obj/machinery/vending/medical/syndicate_access name = "\improper SyndiMed Plus" - req_access = list(ACCESS_SYNDICATE) \ No newline at end of file + req_access = list(ACCESS_SYNDICATE) diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 018eb09d86..514bbd8730 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -10,7 +10,8 @@ /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/charcoal = 2, - /obj/item/reagent_containers/medspray/sterilizine = 1) + /obj/item/reagent_containers/medspray/sterilizine = 1, + /obj/item/reagent_containers/syringe/dart = 10) contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2) premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2) diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 9aa11c7bfb..4594048256 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -23,6 +23,7 @@ /obj/item/seeds/lime = 3, /obj/item/seeds/onion = 3, /obj/item/seeds/orange = 3, + /obj/item/seeds/peanutseed = 3, /obj/item/seeds/pineapple = 3, /obj/item/seeds/potato = 3, /obj/item/seeds/poppy = 3, diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 7e90a5ce18..aaa1cf3b6f 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -14,8 +14,13 @@ /obj/item/flashlight/seclite = 4, /obj/item/restraints/legcuffs/bola/energy = 7) contraband = list(/obj/item/clothing/glasses/sunglasses = 2, - /obj/item/storage/fancy/donut_box = 2) - premium = list(/obj/item/coin/antagtoken = 1) + /obj/item/storage/fancy/donut_box = 2, + /obj/item/ssword_kit = 1) + premium = list(/obj/item/coin/antagtoken = 1, + /obj/item/clothing/head/helmet/blueshirt = 1, + /obj/item/clothing/suit/armor/vest/blueshirt = 1, + /obj/item/clothing/under/rank/security/blueshirt = 1, + /obj/item/ssword_kit = 1) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 8b56ccf00d..9a2455f56d 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -4,7 +4,7 @@ humans, butchering all other living things to \ sustain the zombie, smashing open airlock doors and opening \ child-safe caps on bottles." - item_flags = NODROP | ABSTRACT | DROPDEL + item_flags = ABSTRACT | DROPDEL resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF icon = 'icons/effects/blood.dmi' icon_state = "bloodhand_left" @@ -14,7 +14,9 @@ force = 21 // Just enough to break airlocks with melee attacks damtype = "brute" - var/removing_airlock = FALSE +/obj/item/zombie_hand/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) /obj/item/zombie_hand/equipped(mob/user, slot) . = ..() diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt index 628e08f8f1..cba9a01e73 100644 --- a/config/spaceRuinBlacklist.txt +++ b/config/spaceRuinBlacklist.txt @@ -45,3 +45,7 @@ #_maps/RandomRuins/SpaceRuins/way_home.dmm #_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm #_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm +#_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm +#_maps/RandomRuins/SpaceRuins/bigape.dmm +#_maps/RandomRuins/SpaceRuins/arcade.dmm +#_maps/RandomRuins/SpaceRuins/spacehermit.dmm diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css deleted file mode 100644 index 820537e32b..0000000000 --- a/goon/browserassets/css/browserOutput.css +++ /dev/null @@ -1,362 +0,0 @@ -/***************************************** -* -* GLOBAL STYLES -* -******************************************/ -html, body { - padding: 0; - margin: 0; - height: 100%; - color: #000000; -} -body { - background: #fff; - font-family: Verdana, sans-serif; - font-size: 9pt; - line-height: 1.4; - overflow-x: hidden; - overflow-y: scroll; - word-wrap: break-word; -} - -em { - font-style: normal; - font-weight: bold; -} - -img { - margin: 0; - padding: 0; - line-height: 1; -} -img.icon { - width: 16px; - height: 16px; -} - -a {color: #0000ff;} -a.visited {color: #ff00ff;} -a:visited {color: #ff00ff;} -a.popt {text-decoration: none;} - -/***************************************** -* -* OUTPUT NOT RELATED TO ACTUAL MESSAGES -* -******************************************/ -#loading { - position: fixed; - width: 300px; - height: 150px; - text-align: center; - left: 50%; - top: 50%; - margin: -75px 0 0 -150px; -} -#loading i {display: block; padding-bottom: 3px;} - -#messages { - font-size: 14px; - padding: 3px; - margin: 0; - word-wrap: break-word; -} -#newMessages { - position: fixed; - display: block; - bottom: 0; - right: 0; - padding: 8px; - background: #ddd; - text-decoration: none; - font-variant: small-caps; - font-size: 1.1em; - font-weight: bold; - color: #333; -} -#newMessages:hover {background: #ccc;} -#newMessages i {vertical-align: middle; padding-left: 3px;} -#ping { - position: fixed; - top: 0; - right: 40px; - width: 45px; - background: #ddd; - height: 30px; - padding: 8px 0 2px 0; -} -#ping i {display: block; text-align: center;} -#ping .ms { - display: block; - text-align: center; - font-size: 8pt; - padding-top: 2px; -} -#options { - position: fixed; - top: 0; - right: 0; -} -#options a { - background: #ddd; - height: 30px; - padding: 5px 0; - display: block; - color: #333; - text-decoration: none; - line-height: 28px; - border-top: 1px solid #b4b4b4; -} -#options a:hover {background: #ccc;} -#options .toggle { - width: 40px; - background: #ccc; - border-top: 0; - float: right; - text-align: center; -} -#options .sub {clear: both; display: none; width: 160px;} -#options .sub.scroll {overflow-y: scroll;} -#options .sub a {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} -#options .sub span { - display: block; - line-height: 30px; - float: left; -} -#options .sub i { - display: block; - padding: 0 5px; - font-size: 1.1em; - width: 22px; - text-align: center; - line-height: 30px; - float: right; -} -#options .decreaseFont {border-top: 0;} - -/* POPUPS */ -.popup { - position: fixed; - top: 50%; - left: 50%; - background: #ddd; -} -.popup .close { - position: absolute; - background: #aaa; - top: 0; - right: 0; - color: #333; - text-decoration: none; - z-index: 2; - padding: 0 10px; - height: 30px; - line-height: 30px; -} -.popup .close:hover {background: #999;} -.popup .head { - background: #999; - color: #ddd; - padding: 0 10px; - height: 30px; - line-height: 30px; - text-transform: uppercase; - font-size: 0.9em; - font-weight: bold; - border-bottom: 2px solid green; -} -.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} -.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} -.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} -.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} - -.changeFont {padding: 10px;} -.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} -.changeFont a:hover {background: #ccc;} - -.highlightPopup {padding: 10px; text-align: center;} -.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} -.highlightPopup input.highlightColor {background-color: #FFFF00;} -.highlightPopup input.highlightTermSubmit {margin-top: 5px;} - -/* ADMIN CONTEXT MENU */ -.contextMenu { - background-color: #ddd; - position: fixed; - margin: 2px; - width: 150px; -} -.contextMenu a { - display: block; - padding: 2px 5px; - text-decoration: none; - color: #333; -} - -.contextMenu a:hover { - background-color: #ccc; -} - -/* ADMIN FILTER MESSAGES MENU */ -.filterMessages {padding: 5px;} -.filterMessages div {padding: 2px 0;} -.filterMessages input {} -.filterMessages label {} - -.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} - - -/***************************************** -* -* OUTPUT ACTUALLY RELATED TO MESSAGES -* -******************************************/ - -/* MOTD */ -.motd {color: #638500; font-family: Verdana, sans-serif;} -.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} -.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} - -/* ADD HERE FOR BOLD */ -.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} - -/* ADD HERE FOR ITALIC */ -.italic, .italics, .emote {font-style: italic;} - -/* OUTPUT COLORS */ -.highlight {background: yellow;} - -h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} -h1.alert, h2.alert {color: #000000;} - -em {font-style: normal; font-weight: bold;} - -.adminobserverooc {color: #0099cc; font-weight: bold;} -.adminooc {color: #b82e00; font-weight: bold;} -.adminobserver {color: #996600; font-weight: bold;} -.admin {color: #386aff; font-weight: bold;} -/* SAY CLASSES */ -.say {} -.deadsay {color: #5c00e6;} -.siliconsay {font-family: 'Courier New', Courier, monospace;} -/* RADIO CLASSES */ -.radio {color: #008000;} - -.syndradio {color: #6d3f40;} -.centradio {color: #686868;} - -.aiprivradio {color: #ff00ff;} -.comradio {color: #948f02;} - -.secradio {color: #a30000;} -.engradio {color: #fb5613;} -.medradio {color: #337296;} -.sciradio {color: #993399;} -.supradio {color: #a8732b;} -.servadio {color: #6eaa2c;} - -.attack {color: #ff0000;} -.disarm {color: #990000;} -.passive {color: #660000;} - -.selecteddna {color: #ffffff; background-color: #001B1B} -.alert {color: #ff0000;} -.userdanger {color: #ff0000; font-weight: bold; font-size: 3;} -.danger {color: #ff0000;} -.warning {color: #ff0000; font-style: italic;} -.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} -.announce {color: #228b22; font-weight: bold;} -.boldannounce {color: #ff0000; font-weight: bold;} -.greenannounce {color: #00ff00; font-weight: bold;} -.rose {color: #ff5050;} -.info {color: #0000CC;} -.notice {color: #000099;} -.boldnotice {color: #000099; font-weight: bold;} -.adminnotice {color: #0000ff;} -.unconscious {color: #0000ff; font-weight: bold;} -.suicide {color: #ff5050; font-style: italic;} -.green {color: #03ff39;} -.shadowling {color: #3b2769;} -.cult {color: #960000;} -.cultitalic {color: #960000; font-style: italic;} -.cultlarge {color: #960000; font-weight: bold; font-size: 3;} -.narsie {color: #960000; font-weight: bold; font-size: 125px;} -.narsiesmall {color: #960000; font-weight: bold; font-size: 6;} -.colossus {color: #7F282A; font-size: 5;} -.hierophant {color: #660099; font-weight: bold; font-style: italic;} -.hierophant_warning {color: #660099; font-style: italic;} -.purple {color: #5e2d79;} -.holoparasite {color: #35333a;} -.holoparasitebold {color: #35333a; font-weight: bold;} - -.revennotice {color: #1d2953;} -.revenboldnotice {color: #1d2953; font-weight: bold;} -.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;} -.revenminor {color: #823abb} -.revenwarning {color: #760fbb; font-style: italic;} -.revendanger {color: #760fbb; font-weight: bold; font-size: 3;} -.umbra {color: #5000A0;} -.umbra_bold {color: #5000A0; font-weight: bold;} -.umbra_italics {color: #5000A0; font-style: italic;} -.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} -.umbra_large {color: #5000A0; font-size: 3;} - -.brass {color: #BE8700;} -.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} -.large_brass {color: #BE8700; font-size: 3;} -.big_brass {color: #BE8700; font-size: 3; font-weight: bold; font-style: italic;} -.ratvar {color: #BE8700; font-size: 6; font-weight: bold; font-style: italic;} -.alloy {color: #42474D;} -.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} -.large_alloy {color: #42474D; font-size: 3;} -.nezbere_large {color: #42474D; font-size: 3; font-weight: bold; font-style: italic;} -.nezbere {color: #42474D; font-weight: bold; font-style: italic;} -.nezbere_small {color: #42474D;} -.sevtug_large {color: #AF0AAF; font-size: 3; font-weight: bold; font-style: italic;} -.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} -.sevtug_small {color: #AF0AAF;} -.inathneq_large {color: #1E8CE1; font-size: 3; font-weight: bold; font-style: italic;} -.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} -.inathneq_small {color: #1E8CE1;} -.nzcrentr_large {color: #DAAA18; font-size: 3; font-weight: bold; font-style: italic;} -.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;} -.nzcrentr_small {color: #DAAA18;} -.neovgre_large {color: #6E001A; font-size: 3; font-weight: bold; font-style: italic;} -.neovgre {color: #6E001A; font-weight: bold; font-style: italic;} -.neovgre_small {color: #6E001A;} - -.newscaster {color: #800000;} -.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} - -.alien {color: #543354;} -.noticealien {color: #00c000;} -.alertalien {color: #00c000; font-weight: bold;} -.borer {color: #543354; font-style: italic;} -.changeling {color: #800080; font-style: italic;} - -.interface {color: #330033;} - -.sans {font-family: "Comic Sans MS", cursive, sans-serif;} -.papyrus {font-family: "Papyrus", cursive, sans-serif;} -.robot {font-family: "Courier New", cursive, sans-serif;} - -.command_headset {font-weight: bold; font-size: 3;} -.big {font-size: 3;} -.reallybig {font-size: 4;} -.greentext {color: #00FF00; font-size: 3;} -.redtext {color: #FF0000; font-size: 3;} -.clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} - -big img.icon {width: 32px; height: 32px;} - -.memo {color: #638500; text-align: center;} -.memoedit {text-align: center; font-size: 2;} -.abductor {color: #800080; font-style: italic;} - -.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} -.connectionClosed.restored {background: green;} -.internal.boldnshit {color: blue; font-weight: bold;} - -/* HELPER CLASSES */ -.text-normal {font-weight: normal; font-style: normal;} -.hidden {display: none; visibility: hidden;} \ No newline at end of file diff --git a/goon/browserassets/css/font-awesome.css b/goon/browserassets/css/font-awesome.css deleted file mode 100644 index cc99d7b337..0000000000 --- a/goon/browserassets/css/font-awesome.css +++ /dev/null @@ -1,788 +0,0 @@ -@font-face{font-family:'FontAwesome';src:url('fontawesome-webfont.eot');src:url('fontawesome-webfont.eot') format('embedded-opentype'),url('fontawesome-webfont.woff') format('woff'),url('fontawesome-webfont.ttf') format('truetype'),url('fontawesome-webfont.svg') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;} -[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;} -.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;} -a [class^="icon-"],a [class*=" icon-"]{display:inline;} -[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;} -.icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;} -.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;} -[class^="icon-"].hide,[class*=" icon-"].hide{display:none;} -.icon-muted{color:#eeeeee;} -.icon-light{color:#ffffff;} -.icon-dark{color:#333333;} -.icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -.icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} -.icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;} -.pull-right{float:right;} -.pull-left{float:left;} -[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;} -[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;} -[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;} -.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;} -.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;} -.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;} -.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;} -.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;} -.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;} -.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;} -.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;} -.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;} -.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;} -.icon-stack .icon-stack-base{font-size:2em;*line-height:1em;} -.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;} -a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;} -@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);} -.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);} -.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);} -.icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);} -.icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);} -a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;} -.icon-glass:before{content:"\f000";} -.icon-music:before{content:"\f001";} -.icon-search:before{content:"\f002";} -.icon-envelope-alt:before{content:"\f003";} -.icon-heart:before{content:"\f004";} -.icon-star:before{content:"\f005";} -.icon-star-empty:before{content:"\f006";} -.icon-user:before{content:"\f007";} -.icon-film:before{content:"\f008";} -.icon-th-large:before{content:"\f009";} -.icon-th:before{content:"\f00a";} -.icon-th-list:before{content:"\f00b";} -.icon-ok:before{content:"\f00c";} -.icon-remove:before{content:"\f00d";} -.icon-zoom-in:before{content:"\f00e";} -.icon-zoom-out:before{content:"\f010";} -.icon-power-off:before,.icon-off:before{content:"\f011";} -.icon-signal:before{content:"\f012";} -.icon-gear:before,.icon-cog:before{content:"\f013";} -.icon-trash:before{content:"\f014";} -.icon-home:before{content:"\f015";} -.icon-file-alt:before{content:"\f016";} -.icon-time:before{content:"\f017";} -.icon-road:before{content:"\f018";} -.icon-download-alt:before{content:"\f019";} -.icon-download:before{content:"\f01a";} -.icon-upload:before{content:"\f01b";} -.icon-inbox:before{content:"\f01c";} -.icon-play-circle:before{content:"\f01d";} -.icon-rotate-right:before,.icon-repeat:before{content:"\f01e";} -.icon-refresh:before{content:"\f021";} -.icon-list-alt:before{content:"\f022";} -.icon-lock:before{content:"\f023";} -.icon-flag:before{content:"\f024";} -.icon-headphones:before{content:"\f025";} -.icon-volume-off:before{content:"\f026";} -.icon-volume-down:before{content:"\f027";} -.icon-volume-up:before{content:"\f028";} -.icon-qrcode:before{content:"\f029";} -.icon-barcode:before{content:"\f02a";} -.icon-tag:before{content:"\f02b";} -.icon-tags:before{content:"\f02c";} -.icon-book:before{content:"\f02d";} -.icon-bookmark:before{content:"\f02e";} -.icon-print:before{content:"\f02f";} -.icon-camera:before{content:"\f030";} -.icon-font:before{content:"\f031";} -.icon-bold:before{content:"\f032";} -.icon-italic:before{content:"\f033";} -.icon-text-height:before{content:"\f034";} -.icon-text-width:before{content:"\f035";} -.icon-align-left:before{content:"\f036";} -.icon-align-center:before{content:"\f037";} -.icon-align-right:before{content:"\f038";} -.icon-align-justify:before{content:"\f039";} -.icon-list:before{content:"\f03a";} -.icon-indent-left:before{content:"\f03b";} -.icon-indent-right:before{content:"\f03c";} -.icon-facetime-video:before{content:"\f03d";} -.icon-picture:before{content:"\f03e";} -.icon-pencil:before{content:"\f040";} -.icon-map-marker:before{content:"\f041";} -.icon-adjust:before{content:"\f042";} -.icon-tint:before{content:"\f043";} -.icon-edit:before{content:"\f044";} -.icon-share:before{content:"\f045";} -.icon-check:before{content:"\f046";} -.icon-move:before{content:"\f047";} -.icon-step-backward:before{content:"\f048";} -.icon-fast-backward:before{content:"\f049";} -.icon-backward:before{content:"\f04a";} -.icon-play:before{content:"\f04b";} -.icon-pause:before{content:"\f04c";} -.icon-stop:before{content:"\f04d";} -.icon-forward:before{content:"\f04e";} -.icon-fast-forward:before{content:"\f050";} -.icon-step-forward:before{content:"\f051";} -.icon-eject:before{content:"\f052";} -.icon-chevron-left:before{content:"\f053";} -.icon-chevron-right:before{content:"\f054";} -.icon-plus-sign:before{content:"\f055";} -.icon-minus-sign:before{content:"\f056";} -.icon-remove-sign:before{content:"\f057";} -.icon-ok-sign:before{content:"\f058";} -.icon-question-sign:before{content:"\f059";} -.icon-info-sign:before{content:"\f05a";} -.icon-screenshot:before{content:"\f05b";} -.icon-remove-circle:before{content:"\f05c";} -.icon-ok-circle:before{content:"\f05d";} -.icon-ban-circle:before{content:"\f05e";} -.icon-arrow-left:before{content:"\f060";} -.icon-arrow-right:before{content:"\f061";} -.icon-arrow-up:before{content:"\f062";} -.icon-arrow-down:before{content:"\f063";} -.icon-mail-forward:before,.icon-share-alt:before{content:"\f064";} -.icon-resize-full:before{content:"\f065";} -.icon-resize-small:before{content:"\f066";} -.icon-plus:before{content:"\f067";} -.icon-minus:before{content:"\f068";} -.icon-asterisk:before{content:"\f069";} -.icon-exclamation-sign:before{content:"\f06a";} -.icon-gift:before{content:"\f06b";} -.icon-leaf:before{content:"\f06c";} -.icon-fire:before{content:"\f06d";} -.icon-eye-open:before{content:"\f06e";} -.icon-eye-close:before{content:"\f070";} -.icon-warning-sign:before{content:"\f071";} -.icon-plane:before{content:"\f072";} -.icon-calendar:before{content:"\f073";} -.icon-random:before{content:"\f074";} -.icon-comment:before{content:"\f075";} -.icon-magnet:before{content:"\f076";} -.icon-chevron-up:before{content:"\f077";} -.icon-chevron-down:before{content:"\f078";} -.icon-retweet:before{content:"\f079";} -.icon-shopping-cart:before{content:"\f07a";} -.icon-folder-close:before{content:"\f07b";} -.icon-folder-open:before{content:"\f07c";} -.icon-resize-vertical:before{content:"\f07d";} -.icon-resize-horizontal:before{content:"\f07e";} -.icon-bar-chart:before{content:"\f080";} -.icon-twitter-sign:before{content:"\f081";} -.icon-facebook-sign:before{content:"\f082";} -.icon-camera-retro:before{content:"\f083";} -.icon-key:before{content:"\f084";} -.icon-gears:before,.icon-cogs:before{content:"\f085";} -.icon-comments:before{content:"\f086";} -.icon-thumbs-up-alt:before{content:"\f087";} -.icon-thumbs-down-alt:before{content:"\f088";} -.icon-star-half:before{content:"\f089";} -.icon-heart-empty:before{content:"\f08a";} -.icon-signout:before{content:"\f08b";} -.icon-linkedin-sign:before{content:"\f08c";} -.icon-pushpin:before{content:"\f08d";} -.icon-external-link:before{content:"\f08e";} -.icon-signin:before{content:"\f090";} -.icon-trophy:before{content:"\f091";} -.icon-github-sign:before{content:"\f092";} -.icon-upload-alt:before{content:"\f093";} -.icon-lemon:before{content:"\f094";} -.icon-phone:before{content:"\f095";} -.icon-unchecked:before,.icon-check-empty:before{content:"\f096";} -.icon-bookmark-empty:before{content:"\f097";} -.icon-phone-sign:before{content:"\f098";} -.icon-twitter:before{content:"\f099";} -.icon-facebook:before{content:"\f09a";} -.icon-github:before{content:"\f09b";} -.icon-unlock:before{content:"\f09c";} -.icon-credit-card:before{content:"\f09d";} -.icon-rss:before{content:"\f09e";} -.icon-hdd:before{content:"\f0a0";} -.icon-bullhorn:before{content:"\f0a1";} -.icon-bell:before{content:"\f0a2";} -.icon-certificate:before{content:"\f0a3";} -.icon-hand-right:before{content:"\f0a4";} -.icon-hand-left:before{content:"\f0a5";} -.icon-hand-up:before{content:"\f0a6";} -.icon-hand-down:before{content:"\f0a7";} -.icon-circle-arrow-left:before{content:"\f0a8";} -.icon-circle-arrow-right:before{content:"\f0a9";} -.icon-circle-arrow-up:before{content:"\f0aa";} -.icon-circle-arrow-down:before{content:"\f0ab";} -.icon-globe:before{content:"\f0ac";} -.icon-wrench:before{content:"\f0ad";} -.icon-tasks:before{content:"\f0ae";} -.icon-filter:before{content:"\f0b0";} -.icon-briefcase:before{content:"\f0b1";} -.icon-fullscreen:before{content:"\f0b2";} -.icon-group:before{content:"\f0c0";} -.icon-link:before{content:"\f0c1";} -.icon-cloud:before{content:"\f0c2";} -.icon-beaker:before{content:"\f0c3";} -.icon-cut:before{content:"\f0c4";} -.icon-copy:before{content:"\f0c5";} -.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";} -.icon-save:before{content:"\f0c7";} -.icon-sign-blank:before{content:"\f0c8";} -.icon-reorder:before{content:"\f0c9";} -.icon-list-ul:before{content:"\f0ca";} -.icon-list-ol:before{content:"\f0cb";} -.icon-strikethrough:before{content:"\f0cc";} -.icon-underline:before{content:"\f0cd";} -.icon-table:before{content:"\f0ce";} -.icon-magic:before{content:"\f0d0";} -.icon-truck:before{content:"\f0d1";} -.icon-pinterest:before{content:"\f0d2";} -.icon-pinterest-sign:before{content:"\f0d3";} -.icon-google-plus-sign:before{content:"\f0d4";} -.icon-google-plus:before{content:"\f0d5";} -.icon-money:before{content:"\f0d6";} -.icon-caret-down:before{content:"\f0d7";} -.icon-caret-up:before{content:"\f0d8";} -.icon-caret-left:before{content:"\f0d9";} -.icon-caret-right:before{content:"\f0da";} -.icon-columns:before{content:"\f0db";} -.icon-sort:before{content:"\f0dc";} -.icon-sort-down:before{content:"\f0dd";} -.icon-sort-up:before{content:"\f0de";} -.icon-envelope:before{content:"\f0e0";} -.icon-linkedin:before{content:"\f0e1";} -.icon-rotate-left:before,.icon-undo:before{content:"\f0e2";} -.icon-legal:before{content:"\f0e3";} -.icon-dashboard:before{content:"\f0e4";} -.icon-comment-alt:before{content:"\f0e5";} -.icon-comments-alt:before{content:"\f0e6";} -.icon-bolt:before{content:"\f0e7";} -.icon-sitemap:before{content:"\f0e8";} -.icon-umbrella:before{content:"\f0e9";} -.icon-paste:before{content:"\f0ea";} -.icon-lightbulb:before{content:"\f0eb";} -.icon-exchange:before{content:"\f0ec";} -.icon-cloud-download:before{content:"\f0ed";} -.icon-cloud-upload:before{content:"\f0ee";} -.icon-user-md:before{content:"\f0f0";} -.icon-stethoscope:before{content:"\f0f1";} -.icon-suitcase:before{content:"\f0f2";} -.icon-bell-alt:before{content:"\f0f3";} -.icon-coffee:before{content:"\f0f4";} -.icon-food:before{content:"\f0f5";} -.icon-file-text-alt:before{content:"\f0f6";} -.icon-building:before{content:"\f0f7";} -.icon-hospital:before{content:"\f0f8";} -.icon-ambulance:before{content:"\f0f9";} -.icon-medkit:before{content:"\f0fa";} -.icon-fighter-jet:before{content:"\f0fb";} -.icon-beer:before{content:"\f0fc";} -.icon-h-sign:before{content:"\f0fd";} -.icon-plus-sign-alt:before{content:"\f0fe";} -.icon-double-angle-left:before{content:"\f100";} -.icon-double-angle-right:before{content:"\f101";} -.icon-double-angle-up:before{content:"\f102";} -.icon-double-angle-down:before{content:"\f103";} -.icon-angle-left:before{content:"\f104";} -.icon-angle-right:before{content:"\f105";} -.icon-angle-up:before{content:"\f106";} -.icon-angle-down:before{content:"\f107";} -.icon-desktop:before{content:"\f108";} -.icon-laptop:before{content:"\f109";} -.icon-tablet:before{content:"\f10a";} -.icon-mobile-phone:before{content:"\f10b";} -.icon-circle-blank:before{content:"\f10c";} -.icon-quote-left:before{content:"\f10d";} -.icon-quote-right:before{content:"\f10e";} -.icon-spinner:before{content:"\f110";} -.icon-circle:before{content:"\f111";} -.icon-mail-reply:before,.icon-reply:before{content:"\f112";} -.icon-github-alt:before{content:"\f113";} -.icon-folder-close-alt:before{content:"\f114";} -.icon-folder-open-alt:before{content:"\f115";} -.icon-expand-alt:before{content:"\f116";} -.icon-collapse-alt:before{content:"\f117";} -.icon-smile:before{content:"\f118";} -.icon-frown:before{content:"\f119";} -.icon-meh:before{content:"\f11a";} -.icon-gamepad:before{content:"\f11b";} -.icon-keyboard:before{content:"\f11c";} -.icon-flag-alt:before{content:"\f11d";} -.icon-flag-checkered:before{content:"\f11e";} -.icon-terminal:before{content:"\f120";} -.icon-code:before{content:"\f121";} -.icon-reply-all:before{content:"\f122";} -.icon-mail-reply-all:before{content:"\f122";} -.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";} -.icon-location-arrow:before{content:"\f124";} -.icon-crop:before{content:"\f125";} -.icon-code-fork:before{content:"\f126";} -.icon-unlink:before{content:"\f127";} -.icon-question:before{content:"\f128";} -.icon-info:before{content:"\f129";} -.icon-exclamation:before{content:"\f12a";} -.icon-superscript:before{content:"\f12b";} -.icon-subscript:before{content:"\f12c";} -.icon-eraser:before{content:"\f12d";} -.icon-puzzle-piece:before{content:"\f12e";} -.icon-microphone:before{content:"\f130";} -.icon-microphone-off:before{content:"\f131";} -.icon-shield:before{content:"\f132";} -.icon-calendar-empty:before{content:"\f133";} -.icon-fire-extinguisher:before{content:"\f134";} -.icon-rocket:before{content:"\f135";} -.icon-maxcdn:before{content:"\f136";} -.icon-chevron-sign-left:before{content:"\f137";} -.icon-chevron-sign-right:before{content:"\f138";} -.icon-chevron-sign-up:before{content:"\f139";} -.icon-chevron-sign-down:before{content:"\f13a";} -.icon-html5:before{content:"\f13b";} -.icon-css3:before{content:"\f13c";} -.icon-anchor:before{content:"\f13d";} -.icon-unlock-alt:before{content:"\f13e";} -.icon-bullseye:before{content:"\f140";} -.icon-ellipsis-horizontal:before{content:"\f141";} -.icon-ellipsis-vertical:before{content:"\f142";} -.icon-rss-sign:before{content:"\f143";} -.icon-play-sign:before{content:"\f144";} -.icon-ticket:before{content:"\f145";} -.icon-minus-sign-alt:before{content:"\f146";} -.icon-check-minus:before{content:"\f147";} -.icon-level-up:before{content:"\f148";} -.icon-level-down:before{content:"\f149";} -.icon-check-sign:before{content:"\f14a";} -.icon-edit-sign:before{content:"\f14b";} -.icon-external-link-sign:before{content:"\f14c";} -.icon-share-sign:before{content:"\f14d";} -.icon-compass:before{content:"\f14e";} -.icon-collapse:before{content:"\f150";} -.icon-collapse-top:before{content:"\f151";} -.icon-expand:before{content:"\f152";} -.icon-euro:before,.icon-eur:before{content:"\f153";} -.icon-gbp:before{content:"\f154";} -.icon-dollar:before,.icon-usd:before{content:"\f155";} -.icon-rupee:before,.icon-inr:before{content:"\f156";} -.icon-yen:before,.icon-jpy:before{content:"\f157";} -.icon-renminbi:before,.icon-cny:before{content:"\f158";} -.icon-won:before,.icon-krw:before{content:"\f159";} -.icon-bitcoin:before,.icon-btc:before{content:"\f15a";} -.icon-file:before{content:"\f15b";} -.icon-file-text:before{content:"\f15c";} -.icon-sort-by-alphabet:before{content:"\f15d";} -.icon-sort-by-alphabet-alt:before{content:"\f15e";} -.icon-sort-by-attributes:before{content:"\f160";} -.icon-sort-by-attributes-alt:before{content:"\f161";} -.icon-sort-by-order:before{content:"\f162";} -.icon-sort-by-order-alt:before{content:"\f163";} -.icon-thumbs-up:before{content:"\f164";} -.icon-thumbs-down:before{content:"\f165";} -.icon-youtube-sign:before{content:"\f166";} -.icon-youtube:before{content:"\f167";} -.icon-xing:before{content:"\f168";} -.icon-xing-sign:before{content:"\f169";} -.icon-youtube-play:before{content:"\f16a";} -.icon-dropbox:before{content:"\f16b";} -.icon-stackexchange:before{content:"\f16c";} -.icon-instagram:before{content:"\f16d";} -.icon-flickr:before{content:"\f16e";} -.icon-adn:before{content:"\f170";} -.icon-bitbucket:before{content:"\f171";} -.icon-bitbucket-sign:before{content:"\f172";} -.icon-tumblr:before{content:"\f173";} -.icon-tumblr-sign:before{content:"\f174";} -.icon-long-arrow-down:before{content:"\f175";} -.icon-long-arrow-up:before{content:"\f176";} -.icon-long-arrow-left:before{content:"\f177";} -.icon-long-arrow-right:before{content:"\f178";} -.icon-apple:before{content:"\f179";} -.icon-windows:before{content:"\f17a";} -.icon-android:before{content:"\f17b";} -.icon-linux:before{content:"\f17c";} -.icon-dribbble:before{content:"\f17d";} -.icon-skype:before{content:"\f17e";} -.icon-foursquare:before{content:"\f180";} -.icon-trello:before{content:"\f181";} -.icon-female:before{content:"\f182";} -.icon-male:before{content:"\f183";} -.icon-gittip:before{content:"\f184";} -.icon-sun:before{content:"\f185";} -.icon-moon:before{content:"\f186";} -.icon-archive:before{content:"\f187";} -.icon-bug:before{content:"\f188";} -.icon-vk:before{content:"\f189";} -.icon-weibo:before{content:"\f18a";} -.icon-renren:before{content:"\f18b";} - -.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle;} -.nav [class^="icon-"],.nav [class*=" icon-"]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;}.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{vertical-align:-25%;} -.nav-pills [class^="icon-"].icon-large,.nav-tabs [class^="icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px;} -.btn [class^="icon-"].pull-left,.btn [class*=" icon-"].pull-left,.btn [class^="icon-"].pull-right,.btn [class*=" icon-"].pull-right{vertical-align:inherit;} -.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large{margin-top:-0.5em;} -a [class^="icon-"],a [class*=" icon-"]{cursor:pointer;} -.icon-glass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-music{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-search{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-film{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-large{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-in{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-out{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-power-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cog{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gear{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trash{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-home{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-time{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-road{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-repeat{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-refresh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-headphones{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-qrcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-barcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tags{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-book{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-print{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-font{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bold{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-italic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-height{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-width{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-center{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-justify{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facetime-video{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-picture{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pencil{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-map-marker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adjust{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tint{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-move{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pause{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eject{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-screenshot{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ban-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-small{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-asterisk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gift{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-leaf{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-warning-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plane{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-random{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magnet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-retweet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shopping-cart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bar-chart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera-retro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-key{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cogs{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gears{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signout{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pushpin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trophy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lemon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unchecked{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-credit-card{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hdd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullhorn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-certificate{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-globe{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-wrench{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tasks{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-filter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-briefcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fullscreen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-group{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beaker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cut{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-copy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paper-clip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paperclip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-save{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sign-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reorder{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ul{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ol{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-strikethrough{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-underline{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-table{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-truck{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-money{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-columns{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-undo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-legal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dashboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bolt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sitemap{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-umbrella{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paste{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lightbulb{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user-md{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stethoscope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-suitcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-coffee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-food{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-building{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hospital{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ambulance{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-medkit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fighter-jet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beer{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-h-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-desktop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-laptop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tablet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mobile-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-spinner{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-smile{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-frown{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-meh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gamepad{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-keyboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-checkered{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-terminal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-location-arrow{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-crop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code-fork{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlink{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-superscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-subscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eraser{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-puzzle-piece{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shield{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire-extinguisher{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rocket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-maxcdn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-html5{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-css3{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-anchor{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullseye{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ticket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-compass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-top{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eur{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-euro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gbp{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-usd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dollar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rupee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-jpy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-yen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cny{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renminbi{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-krw{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-won{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-btc{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitcoin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dropbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stackexchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-instagram{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flickr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-apple{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-windows{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-android{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linux{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dribbble{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-skype{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-foursquare{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trello{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-female{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-male{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gittip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sun{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-moon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-archive{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bug{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-vk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-weibo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renren{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} \ No newline at end of file diff --git a/goon/browserassets/html/browserOutput.html b/goon/browserassets/html/browserOutput.html deleted file mode 100644 index 74212fd815..0000000000 --- a/goon/browserassets/html/browserOutput.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - Chat - - - - - - - - -
    - -
    - Loading...

    - If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
    - If it still doesn't work, use the bug report button at the top right of the window. -
    -
    -
    - -
    - - - - \ No newline at end of file diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js deleted file mode 100644 index 0fb7386dd8..0000000000 --- a/goon/browserassets/js/browserOutput.js +++ /dev/null @@ -1,908 +0,0 @@ -/***************************************** -* -* FUNCTION AND VAR DECLARATIONS -* -******************************************/ - -//DEBUG STUFF -var escaper = encodeURIComponent || escape; -var decoder = decodeURIComponent || unescape; -window.onerror = function(msg, url, line, col, error) { - if (document.location.href.indexOf("proc=debug") <= 0) { - var extra = !col ? '' : ' | column: ' + col; - extra += !error ? '' : ' | error: ' + error; - extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent; - var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra; - window.location = '?_src_=chat&proc=debug¶m[error]='+escaper(debugLine); - } - return true; -}; - -//Globals -window.status = 'Output'; -var $messages, $subOptions, $contextMenu, $filterMessages; -var opts = { - //General - 'messageCount': 0, //A count...of messages... - 'messageLimit': 2053, //A limit...for the messages... - 'scrollSnapTolerance': 5, //If within x pixels of bottom - 'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup - 'popups': 0, //Amount of popups opened ever - 'wasd': false, //Is the user in wasd mode? - 'chatMode': 'default', //The mode the chat is in - 'priorChatHeight': 0, //Thing for height-resizing detection - 'restarting': false, //Is the round restarting? - - //Options menu - 'subOptionsLoop': null, //Contains the interval loop for closing the options menu - 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu - 'highlightTerms': [], - 'highlightLimit': 5, - 'highlightColor': '#FFFF00', //The color of the highlighted message - 'pingDisabled': false, //Has the user disabled the ping counter - - //Ping display - 'lastPang': 0, //Timestamp of the last response from the server. - 'pangLimit': 35000, - 'pingTime': 0, //Timestamp of when ping sent - 'pongTime': 0, //Timestamp of when ping received - 'noResponse': false, //Tracks the state of the previous ping request - 'noResponseCount': 0, //How many failed pings? - - //Clicks - 'mouseDownX': null, - 'mouseDownY': null, - 'preventFocus': false, //Prevents switching focus to the game window - - //Client Connection Data - 'clientDataLimit': 5, - 'clientData': [], - -}; - -function outerHTML(el) { - var wrap = document.createElement('div'); - wrap.appendChild(el.cloneNode(true)); - return wrap.innerHTML; -} - -//Polyfill for fucking date now because of course IE8 and below don't support it -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); - }; -} -//Polyfill for trim() (IE8 and below) -if (typeof String.prototype.trim !== 'function') { - String.prototype.trim = function () { - return this.replace(/^\s+|\s+$/g, ''); - }; -} - -//Shit fucking piece of crap that doesn't work god fuckin damn it -function linkify(text) { - var rex = /((?:'+$0+''; - } - else { - return $1 ? $0: ''+$0+''; - } - }); -} - -//Actually turns the highlight term match into appropriate html -function addHighlightMarkup(match) { - var extra = ''; - if (opts.highlightColor) { - extra += ' style="background-color: '+opts.highlightColor+'"'; - } - return ''+match+''; -} - -//Highlights words based on user settings -function highlightTerms(el) { - if (el.children.length > 0) { - for(var h = 0; h < el.children.length; h++){ - highlightTerms(el.children[h]); - } - } - - var hasTextNode = false; - for (var node = 0; node < el.childNodes.length; node++) - { - if (el.childNodes[node].nodeType === 3) - { - hasTextNode = true; - break; - } - } - - if (hasTextNode) { //If element actually has text - var newText = ''; - for (var c = 0; c < el.childNodes.length; c++) { //Each child element - if (el.childNodes[c].nodeType === 3) { //Is it text only? - var words = el.childNodes[c].data.split(' '); - for (var w = 0; w < words.length; w++) { //Each word in the text - var newWord = null; - for (var i = 0; i < opts.highlightTerms.length; i++) { //Each highlight term - if (opts.highlightTerms[i] && words[w].toLowerCase().indexOf(opts.highlightTerms[i].toLowerCase()) > -1) { //If a match is found - newWord = words[w].replace("<", "<").replace(new RegExp(opts.highlightTerms[i], 'gi'), addHighlightMarkup); - break; - } - console.log(newWord) - } - newText += newWord || words[w].replace("<", "<"); - newText += w >= words.length ? '' : ' '; - } - } else { //Every other type of element - newText += outerHTML(el.childNodes[c]); - } - } - el.innerHTML = newText; - } -} -//Send a message to the client -function output(message, flag) { - if (typeof message === 'undefined') { - return; - } - if (typeof flag === 'undefined') { - flag = ''; - } - - if (flag !== 'internal') - opts.lastPang = Date.now(); - - // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8. - // 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) - - //The behemoth of filter-code (for Admin message filters) - //Note: This is proooobably hella inefficient - var filteredOut = false; - if (opts.hasOwnProperty('showMessagesFilters') && !opts.showMessagesFilters['All'].show) { - //Get this filter type (defined by class on message) - var messageHtml = $.parseHTML(message), - messageClasses; - if (opts.hasOwnProperty('filterHideAll') && opts.filterHideAll) { - var internal = false; - messageClasses = (!!$(messageHtml).attr('class') ? $(messageHtml).attr('class').split(/\s+/) : false); - if (messageClasses) { - for (var i = 0; i < messageClasses.length; i++) { //Every class - if (messageClasses[i] == 'internal') { - internal = true; - break; - } - } - } - if (!internal) { - filteredOut = 'All'; - } - } else { - //If the element or it's child have any classes - if (!!$(messageHtml).attr('class') || !!$(messageHtml).children().attr('class')) { - messageClasses = $(messageHtml).attr('class').split(/\s+/); - if (!!$(messageHtml).children().attr('class')) { - messageClasses = messageClasses.concat($(messageHtml).children().attr('class').split(/\s+/)); - } - var tempCount = 0; - for (var i = 0; i < messageClasses.length; i++) { //Every class - var thisClass = messageClasses[i]; - $.each(opts.showMessagesFilters, function(key, val) { //Every filter - if (key !== 'All' && val.show === false && typeof val.match != 'undefined') { - for (var i = 0; i < val.match.length; i++) { - var matchClass = val.match[i]; - if (matchClass == thisClass) { - filteredOut = key; - break; - } - } - } - if (filteredOut) return false; - }); - if (filteredOut) break; - tempCount++; - } - } else { - if (!opts.showMessagesFilters['Misc'].show) { - filteredOut = 'Misc'; - } - } - } - } - - //Stuff we do along with appending a message - var atBottom = false; - if (!filteredOut) { - var bodyHeight = $('body').height(); - var messagesHeight = $messages.outerHeight(); - var scrollPos = $('body,html').scrollTop(); - - //Should we snap the output to the bottom? - if (bodyHeight + scrollPos >= messagesHeight - opts.scrollSnapTolerance) { - atBottom = true; - if ($('#newMessages').length) { - $('#newMessages').remove(); - } - //If not, put the new messages box in - } else { - if ($('#newMessages').length) { - var messages = $('#newMessages .number').text(); - messages = parseInt(messages); - messages++; - $('#newMessages .number').text(messages); - if (messages == 2) { - $('#newMessages .messageWord').append('s'); - } - } else { - $messages.after('1 new message '); - } - } - } - - //Url stuff - if (message.length && flag != 'preventLink') { - message = linkify(message); - } - - opts.messageCount++; - - //Pop the top message off if history limit reached - if (opts.messageCount >= opts.messageLimit) { - $messages.children('div.entry:first-child').remove(); - opts.messageCount--; //I guess the count should only ever equal the limit - } - - //Actually append the message - var entry = document.createElement('div'); - entry.className = 'entry'; - - if (filteredOut) { - entry.className += ' hidden'; - entry.setAttribute('data-filter', filteredOut); - } - - entry.innerHTML = message.trim(); - $messages[0].appendChild(entry); - - //Actually do the snap - if (!filteredOut && atBottom) { - $('body,html').scrollTop($messages.outerHeight()); - } - - //Stuff we can do after the message shows can go here, in the interests of responsiveness - if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms(entry); - } -} - -function internalOutput(message, flag) -{ - output(escaper(message), flag) -} - -//Runs a route within byond, client or server side. Consider this "ehjax" for byond. -function runByond(uri) { - window.location = uri; -} - -function setCookie(cname, cvalue, exdays) { - cvalue = escaper(cvalue); - var d = new Date(); - d.setTime(d.getTime() + (exdays*24*60*60*1000)); - var expires = 'expires='+d.toUTCString(); - document.cookie = cname + '=' + cvalue + '; ' + expires; -} - -function getCookie(cname) { - var name = cname + '='; - var ca = document.cookie.split(';'); - for(var i=0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0)==' ') c = c.substring(1); - if (c.indexOf(name) === 0) { - return decoder(c.substring(name.length,c.length)); - } - } - return ''; -} - -function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);} -function toHex(n) { - n = parseInt(n,10); - if (isNaN(n)) return "00"; - n = Math.max(0,Math.min(n,255)); - return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16); -} - -function changeMode(mode) { - switch (mode) { - case 'geocities': - //switch in stylesheet - opts.chatMode = mode; - break; - case 'console': - - opts.chatMode = mode; - break; - case 'default': - default: - //remove loaded stylesheet/s - opts.chatMode = 'default'; - } -} - -function handleClientData(ckey, ip, compid) { - //byond sends player info to here - var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid}; - if (opts.clientData && !$.isEmptyObject(opts.clientData)) { - runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]='+JSON.stringify({'connData': opts.clientData})); - - for (var i = 0; i < opts.clientData.length; i++) { - var saved = opts.clientData[i]; - if (currentData.ckey == saved.ckey && currentData.ip == saved.ip && currentData.compid == saved.compid) { - return; //Record already exists - } - } - - if (opts.clientData.length >= opts.clientDataLimit) { - opts.clientData.shift(); - } - } else { - runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]=none'); - } - - //Update the cookie with current details - opts.clientData.push(currentData); - setCookie('connData', JSON.stringify(opts.clientData), 365); -} - -//Server calls this on ehjax response -//Or, y'know, whenever really -function ehjaxCallback(data) { - opts.lastPang = Date.now(); - if (data == 'softPang') { - return; - } else if (data == 'pang') { - opts.pingCounter = 0; //reset - opts.pingTime = Date.now(); - runByond('?_src_=chat&proc=ping'); - - } else if (data == 'pong') { - if (opts.pingDisabled) {return;} - opts.pongTime = Date.now(); - var pingDuration = Math.ceil((opts.pongTime - opts.pingTime) / 2); - $('#pingMs').text(pingDuration+'ms'); - pingDuration = Math.min(pingDuration, 255); - var red = pingDuration; - var green = 255 - pingDuration; - var blue = 0; - var hex = rgbToHex(red, green, blue); - $('#pingDot').css('color', '#'+hex); - - } else if (data == 'roundrestart') { - opts.restarting = true; - internalOutput('
    The connection has been closed because the server is restarting. Please wait while you automatically reconnect.
    ', 'internal'); - } else if (data == 'stopaudio') { - $('.dectalk').remove(); - } else { - //Oh we're actually being sent data instead of an instruction - var dataJ; - try { - dataJ = $.parseJSON(data); - } catch (e) { - //But...incorrect :sadtrombone: - window.onerror('JSON: '+e+'. '+data, 'browserOutput.html', 327); - return; - } - data = dataJ; - - if (data.clientData) { - if (opts.restarting) { - opts.restarting = false; - $('.connectionClosed.restarting:not(.restored)').addClass('restored').text('The round restarted and you successfully reconnected!'); - } - if (!data.clientData.ckey && !data.clientData.ip && !data.clientData.compid) { - //TODO: Call shutdown perhaps - return; - } else { - handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid); - } - } else if (data.modeChange) { - changeMode(data.modeChange); - } else if (data.firebug) { - if (data.trigger) { - internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); - } else { - internalOutput('Loading firebug console...', 'internal'); - } - var firebugEl = document.createElement('script'); - firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; - document.body.appendChild(firebugEl); - } else if (data.dectalk) { - var message = ''; - if (data.decTalkTrigger) { - message = ' '+ - 'You hear a strange robotic voice...' + message; - } - internalOutput(message, 'preventLink'); - } - } -} - -function createPopup(contents, width) { - opts.popups++; - $('body').append(''); - - //Attach close popup event - var $popup = $('#popup'+opts.popups); - var height = $popup.outerHeight(); - $popup.css({'height': height+'px', 'margin': '-'+(height/2)+'px 0 0 -'+(width/2)+'px'}); - - $popup.on('click', '.close', function(e) { - e.preventDefault(); - $popup.remove(); - }); -} - -function toggleWasd(state) { - opts.wasd = (state == 'on' ? true : false); -} - -/***************************************** -* -* DOM READY -* -******************************************/ - -if (typeof $ === 'undefined') { - var div = document.getElementById('loading').childNodes[1]; - div += '

    ERROR: Jquery did not load.'; -} - -$(function() { - $messages = $('#messages'); - $subOptions = $('#subOptions'); - - //Hey look it's a controller loop! - setInterval(function() { - if (opts.lastPang + opts.pangLimit < Date.now() && !opts.restarting) { //Every pingLimit - if (!opts.noResponse) { //Only actually append a message if the previous ping didn't also fail (to prevent spam) - opts.noResponse = true; - opts.noResponseCount++; - internalOutput('
    You are either AFK, experiencing lag or the connection has closed.
    ', 'internal'); - } - } else if (opts.noResponse) { //Previous ping attempt failed ohno - $('.connectionClosed[data-count="'+opts.noResponseCount+'"]:not(.restored)').addClass('restored').text('Your connection has been restored (probably)!'); - opts.noResponse = false; - } - }, 2000); //2 seconds - - - /***************************************** - * - * LOAD SAVED CONFIG - * - ******************************************/ - var savedConfig = { - 'sfontSize': getCookie('fontsize'), - 'sfontType': getCookie('fonttype'), - 'spingDisabled': getCookie('pingdisabled'), - 'shighlightTerms': getCookie('highlightterms'), - 'shighlightColor': getCookie('highlightcolor'), - }; - - if (savedConfig.sfontSize) { - $messages.css('font-size', savedConfig.sfontSize); - internalOutput('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); - } - if (savedConfig.sfontType) { - $messages.css('font-family', savedConfig.sfontType); - internalOutput('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal'); - } - if (savedConfig.spingDisabled) { - if (savedConfig.spingDisabled == 'true') { - opts.pingDisabled = true; - $('#ping').hide(); - } - internalOutput('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); - } - if (savedConfig.shighlightTerms) { - var savedTerms = $.parseJSON(savedConfig.shighlightTerms); - var actualTerms = ''; - for (var i = 0; i < savedTerms.length; i++) { - if (savedTerms[i]) { - actualTerms += savedTerms[i] + ', '; - } - } - if (actualTerms) { - actualTerms = actualTerms.substring(0, actualTerms.length - 2); - internalOutput('Loaded highlight strings of: ' + actualTerms+'', 'internal'); - opts.highlightTerms = savedTerms; - } - } - if (savedConfig.shighlightColor) { - opts.highlightColor = savedConfig.shighlightColor; - internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); - } - - (function() { - var dataCookie = getCookie('connData'); - if (dataCookie) { - var dataJ; - try { - dataJ = $.parseJSON(dataCookie); - } catch (e) { - window.onerror('JSON '+e+'. '+dataCookie, 'browserOutput.html', 434); - return; - } - opts.clientData = dataJ; - } - })(); - - - /***************************************** - * - * BASE CHAT OUTPUT EVENTS - * - ******************************************/ - - $('body').on('click', 'a', function(e) { - e.preventDefault(); - }); - - $('body').on('mousedown', function(e) { - var $target = $(e.target); - - if ($contextMenu && opts.hasOwnProperty('contextMenuTarget') && opts.contextMenuTarget) { - hideContextMenu(); - return false; - } - - if ($target.is('a') || $target.parent('a').length || $target.is('input') || $target.is('textarea')) { - opts.preventFocus = true; - } else { - opts.preventFocus = false; - opts.mouseDownX = e.pageX; - opts.mouseDownY = e.pageY; - } - }); - - $messages.on('mousedown', function(e) { - if ($subOptions && $subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } - }); - - $('body').on('mouseup', function(e) { - if (!opts.preventFocus && - (e.pageX >= opts.mouseDownX - opts.clickTolerance && e.pageX <= opts.mouseDownX + opts.clickTolerance) && - (e.pageY >= opts.mouseDownY - opts.clickTolerance && e.pageY <= opts.mouseDownY + opts.clickTolerance) - ) { - opts.mouseDownX = null; - opts.mouseDownY = null; - runByond('byond://winset?mapwindow.map.focus=true'); - } - }); - - $messages.on('click', 'a', function(e) { - var href = $(this).attr('href'); - $(this).addClass('visited'); - if (href[0] == '?' || (href.length >= 8 && href.substring(0,8) == 'byond://')) { - runByond(href); - } else { - href = escaper(href); - runByond('?action=openLink&link='+href); - } - }); - - //Fuck everything about this event. Will look into alternatives. - $('body').on('keydown', function(e) { - if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') { - return; - } - - if (e.ctrlKey || e.altKey || e.shiftKey) { //Band-aid "fix" for allowing ctrl+c copy paste etc. Needs a proper fix. - return; - } - - e.preventDefault() - - var k = e.which; - var command; // Command to execute through winset. - - // Hardcoded because else there would be no feedback message. - if (k == 113) { // F2 - runByond('byond://winset?screenshot=auto'); - internalOutput('Screenshot taken', 'internal'); - } - - var c = ""; - switch (k) { - case 8: - c = 'BACK'; - case 9: - c = 'TAB'; - case 13: - c = 'ENTER'; - case 19: - c = 'PAUSE'; - case 27: - c = 'ESCAPE'; - case 33: // Page up - c = 'NORTHEAST'; - case 34: // Page down - c = 'SOUTHEAST'; - case 35: // End - c = 'SOUTHWEST'; - case 36: // Home - c = 'NORTHWEST'; - case 37: - c = 'WEST'; - case 38: - c = 'NORTH'; - case 39: - c = 'EAST'; - case 40: - c = 'SOUTH'; - case 45: - c = 'INSERT'; - case 46: - c = 'DELETE'; - case 93: // That weird thing to the right of alt gr. - c = 'APPS'; - - default: - c = String.fromCharCode(k); - } - -// if(opts.macros.hasOwnProperty(c.toUpperCase())) - // command = opts.macros[c]; - - if (command) { - runByond('byond://winset?mapwindow.map.focus=true;command='+command); - return false; - } - else if (c.length == 0) { - if (!e.shiftKey) { - c = c.toLowerCase(); - } - runByond('byond://winset?mapwindow.map.focus=true;mainwindow.input.text='+c); - return false; - } else { - runByond('byond://winset?mapwindow.map.focus=true'); - return false; - } - }); - - //Mildly hacky fix for scroll issues on mob change (interface gets resized sometimes, messing up snap-scroll) - $(window).on('resize', function(e) { - if ($(this).height() !== opts.priorChatHeight) { - $('body,html').scrollTop($messages.outerHeight()); - opts.priorChatHeight = $(this).height(); - } - }); - - //Audio sound prevention - $messages.on('click', '.stopAudio', function() { - var $audio = $(this).parent().children('audio'); - if ($audio) { - $audio.remove(); - } - }); - - - /***************************************** - * - * OPTIONS INTERFACE EVENTS - * - ******************************************/ - - $('body').on('click', '#newMessages', function(e) { - var messagesHeight = $messages.outerHeight(); - $('body,html').scrollTop(messagesHeight); - $('#newMessages').remove(); - runByond('byond://winset?mapwindow.map.focus=true'); - }); - - $('#toggleOptions').click(function(e) { - if ($subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } else { - $subOptions.slideDown('fast', function() { - var windowHeight = $(window).height(); - var toggleHeight = $('#toggleOptions').outerHeight(); - var priorSubHeight = $subOptions.outerHeight(); - var newSubHeight = windowHeight - toggleHeight; - $(this).height(newSubHeight); - if (priorSubHeight > (windowHeight - toggleHeight)) { - $(this).addClass('scroll'); - } - }); - opts.subOptionsLoop = setInterval(function() { - if (!opts.suppressOptionsClose && $('#subOptions').is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } - }, 5000); //Every 5 seconds - } - }); - - $('#subOptions, #toggleOptions').mouseenter(function() { - opts.suppressOptionsClose = true; - }); - - $('#subOptions, #toggleOptions').mouseleave(function() { - opts.suppressOptionsClose = false; - }); - - $('#decreaseFont').click(function(e) { - var fontSize = parseInt($messages.css('font-size')); - fontSize = fontSize - 1 + 'px'; - $messages.css({'font-size': fontSize}); - setCookie('fontsize', fontSize, 365); - internalOutput('Font size set to '+fontSize+'', 'internal'); - }); - - $('#increaseFont').click(function(e) { - var fontSize = parseInt($messages.css('font-size')); - fontSize = fontSize + 1 + 'px'; - $messages.css({'font-size': fontSize}); - setCookie('fontsize', fontSize, 365); - internalOutput('Font size set to '+fontSize+'', 'internal'); - }); - - $('#chooseFont').click(function(e) { - if ($('.popup .changeFont').is(':visible')) {return;} - var popupContent = '
    Change Font
    ' + - ''; - createPopup(popupContent, 200); - }); - - $('body').on('click', '#changeFont a', function(e) { - var font = $(this).attr('data-font'); - $messages.css('font-family', font); - setCookie('fonttype', font, 365); - }); - - $('#togglePing').click(function(e) { - if (opts.pingDisabled) { - $('#ping').slideDown('fast'); - opts.pingDisabled = false; - } else { - $('#ping').slideUp('fast'); - opts.pingDisabled = true; - } - setCookie('pingdisabled', (opts.pingDisabled ? 'true' : 'false'), 365); - }); - - $('#saveLog').click(function(e) { - var saved = ''; - - if (window.XMLHtpRequest) { - xmlHttp = new XMLHttpRequest(); - } else { - xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); - } - xmlHttp.open('GET', 'browserOutput.css', false); - xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xmlHttp.send(); - saved += ''; - - saved += $messages.html(); - saved = saved.replace(/&/g, '&'); - saved = saved.replace(/'; - } - var popupContent = '
    String Highlighting
    ' + - '
    ' + - '
    Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
    ' + - '
    ' + - termInputs + - '
    ' + - '
    ' + - '' + - '
    '; - createPopup(popupContent, 250); - }); - - $('body').on('keyup', '#highlightColor', function() { - var color = $('#highlightColor').val(); - color = color.trim(); - if (!color || color.charAt(0) != '#') return; - $('#highlightColor').css('background-color', color); - }); - - $('body').on('submit', '#highlightTermForm', function(e) { - e.preventDefault(); - - var count = 0; - while (count < opts.highlightLimit) { - var term = $('#highlightTermInput'+count).val(); - if (term) { - term = term.trim(); - if (term === '') { - opts.highlightTerms[count] = null; - } else { - opts.highlightTerms[count] = term.toLowerCase(); - } - } else { - opts.highlightTerms[count] = null; - } - count++; - } - - var color = $('#highlightColor').val(); - color = color.trim(); - if (color == '' || color.charAt(0) != '#') { - opts.highlightColor = '#FFFF00'; - } else { - opts.highlightColor = color; - } - var $popup = $('#highlightPopup').closest('.popup'); - $popup.remove(); - - setCookie('highlightterms', JSON.stringify(opts.highlightTerms), 365); - setCookie('highlightcolor', opts.highlightColor, 365); - }); - - $('#clearMessages').click(function() { - $messages.empty(); - opts.messageCount = 0; - }); - - - /***************************************** - * - * KICK EVERYTHING OFF - * - ******************************************/ - - runByond('?_src_=chat&proc=doneLoading'); - if ($('#loading').is(':visible')) { - $('#loading').remove(); - } - $('#userBar').show(); - opts.priorChatHeight = $(window).height(); -}); \ No newline at end of file diff --git a/goon/browserassets/js/json2.min.js b/goon/browserassets/js/json2.min.js deleted file mode 100644 index d867407f26..0000000000 --- a/goon/browserassets/js/json2.min.js +++ /dev/null @@ -1 +0,0 @@ -"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=0,rx_escapable.test(t)?'"'+t.replace(rx_escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,f=[],"[object Array]"===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||"null";return o=0===f.length?"[]":gap?"[\n"+gap+f.join(",\n"+gap)+"\n"+a+"]":"["+f.join(",")+"]",gap=a,o}if(rep&&"object"==typeof rep)for(u=rep.length,r=0;u>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));return o=0===f.length?"{}":gap?"{\n"+gap+f.join(",\n"+gap)+"\n"+a+"}":"{"+f.join(",")+"}",gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,r){var n;if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" ";else"string"==typeof r&&(indent=r);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(); \ No newline at end of file diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm deleted file mode 100644 index d928397728..0000000000 --- a/goon/code/datums/browserOutput.dm +++ /dev/null @@ -1,289 +0,0 @@ -/********************************* -For the main html chat area -*********************************/ - -//Precaching a bunch of shit -GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of icons for the browser output - -//On client, created on login -/datum/chatOutput - var/client/owner //client ref - var/loaded = FALSE // Has the client loaded the browser output area? - var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do - var/cookieSent = FALSE // Has the client sent a cookie for analysis - var/list/connectionHistory //Contains the connection history passed from chat cookie - var/broken = FALSE - -/datum/chatOutput/New(client/C) - owner = C - messageQueue = list() - connectionHistory = list() - // log_world("chatOutput: New()") - -/datum/chatOutput/proc/start() - //Check for existing chat - if(!owner) - return FALSE - - if(!winexists(owner, "browseroutput")) // Oh goddamnit. - alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.") - broken = TRUE - return FALSE - - if(winget(owner, "browseroutput", "is-disabled") == "false") //Already setup - doneLoading() - - else //Not setup - load() - - return TRUE - -/datum/chatOutput/proc/load() - set waitfor = FALSE - if(!owner) - return - - var/static/list/chatResources = list( - "code/modules/html_interface/js/jquery.min.js", - "goon/browserassets/js/json2.min.js", - "goon/browserassets/js/browserOutput.js", - "tgui/assets/fonts/fontawesome-webfont.eot", - "tgui/assets/fonts/fontawesome-webfont.svg", - "tgui/assets/fonts/fontawesome-webfont.ttf", - "tgui/assets/fonts/fontawesome-webfont.woff", - "goon/browserassets/css/font-awesome.css", - "goon/browserassets/css/browserOutput.css" - ) - - // to_chat(world.log, "chatOutput: load()") - for(var/attempts in 1 to 5) - for(var/asset in chatResources) - owner << browse_rsc(file(asset)) - - //log_world("Sending main chat window to client [owner.ckey]") - owner << browse(file("goon/browserassets/html/browserOutput.html"), "window=browseroutput") - sleep(14 + (chatResources.len * 7)) - if(!owner || loaded) - break - - if(owner && !loaded) - doneLoading() // try doing this manually - CRASH("[owner] failed to load chat. Attempting doneLoading() manually") - // log_world("chatOutput: [owner.ckey] load() completed") - -/datum/chatOutput/Topic(href, list/href_list) - if(usr.client != owner) - return TRUE - - // Build arguments. - // Arguments are in the form "param[paramname]=thing" - var/list/params = list() - for(var/key in href_list) - if(length(key) > 7 && findtext(key, "param")) // 7 is the amount of characters in the basic param key template. - var/param_name = copytext(key, 7, -1) - var/item = href_list[key] - - params[param_name] = item - - var/data // Data to be sent back to the chat. - switch(href_list["proc"]) - if("doneLoading") - data = doneLoading(arglist(params)) - - if("debug") - data = debug(arglist(params)) - - if("ping") - data = ping(arglist(params)) - - if("analyzeClientData") - data = analyzeClientData(arglist(params)) - - if(data) - ehjax_send(data = data) - -//Called on chat output done-loading by JS. -/datum/chatOutput/proc/doneLoading() - if(loaded) - return - - loaded = TRUE - winset(owner, "browseroutput", "is-disabled=false") - for(var/message in messageQueue) - to_chat(owner, message) - - messageQueue = null - sendClientData() - - pingLoop() - -/datum/chatOutput/proc/pingLoop() - set waitfor = FALSE - - while (owner) - ehjax_send(data = owner.is_afk(29) ? "softPang" : "pang") // SoftPang isn't handled anywhere but it'll always reset the opts.lastPang. - sleep(30) - -/datum/chatOutput/proc/ehjax_send(client/C = owner, window = "browseroutput", data) - if(islist(data)) - data = json_encode(data) - C << output("[data]", "[window]:ehjaxCallback") - -//Sends client connection details to the chat to handle and save -/datum/chatOutput/proc/sendClientData() - //Get dem deets - var/list/deets = list("clientData" = list()) - deets["clientData"]["ckey"] = owner.ckey - deets["clientData"]["ip"] = owner.address - deets["clientData"]["compid"] = owner.computer_id - var/data = json_encode(deets) - ehjax_send(data = data) - -//Called by client, sent data to investigate (cookie history so far) -/datum/chatOutput/proc/analyzeClientData(cookie = "") - if(!cookie) - return - - if(cookie != "none") - var/list/connData = json_decode(cookie) - if (connData && islist(connData) && connData.len > 0 && connData["connData"]) - connectionHistory = connData["connData"] //lol fuck - var/list/found = new() - for(var/i in connectionHistory.len to 1 step -1) - var/list/row = src.connectionHistory[i] - if (!row || row.len < 3 || (!row["ckey"] && !row["compid"] && !row["ip"])) //Passed malformed history object - return - if (world.IsBanned(row["ckey"], row["compid"], row["ip"])) - found = row - break - - //Uh oh this fucker has a history of playing on a banned account!! - if (found.len > 0) - //TODO: add a new evasion ban for the CURRENT client details, using the matched row details - message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") - log_admin("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") - - cookieSent = TRUE - -//Called by js client every 60 seconds -/datum/chatOutput/proc/ping() - return "pong" - -//Called by js client on js error -/datum/chatOutput/proc/debug(error) - log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]") - -#ifdef TESTING -/client/verb/debug_chat() - set hidden = TRUE - chatOutput.ehjax_send(data = list("firebug" = TRUE)) -#endif -//Global chat procs - -GLOBAL_LIST_EMPTY(bicon_cache) - -//Converts an icon to base64. Operates by putting the icon in the iconCache savefile, -// exporting it as text, and then parsing the base64 from that. -// (This relies on byond automatically storing icons in savefiles as base64) -/proc/icon2base64(icon/icon, iconKey = "misc") - if (!isicon(icon)) - return FALSE - GLOB.iconCache[iconKey] << icon - var/iconData = GLOB.iconCache.ExportText(iconKey) - var/list/partial = splittext(iconData, "{") - return replacetext(copytext(partial[2], 3, -5), "\n", "") - -/proc/bicon(obj) - if (!obj) - return - - if (isicon(obj)) - //Icons get pooled constantly, references are no good here. - /*if (!bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it. - bicon_cache["\ref[obj]"] = icon2base64(obj) - return ""*/ - return "" - - // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with. - var/atom/A = obj - var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]" - if (!GLOB.bicon_cache[key]) // Doesn't exist, make it. - var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1) - if (ishuman(obj)) // Shitty workaround for a BYOND issue. - var/icon/temp = I - I = icon() - I.Insert(temp, dir = SOUTH) - GLOB.bicon_cache[key] = icon2base64(I, key) - - return "" - -//Costlier version of bicon() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. -/proc/costly_bicon(obj) - if (!obj) - return - - if (isicon(obj)) - return bicon(obj) - - var/icon/I = getFlatIcon(obj) - return bicon(I) - -/proc/to_chat(target, message) - if(isnull(target)) - return - //Ok so I did my best but I accept that some calls to this will be for shit like sound and images - //It stands that we PROBABLY don't want to output those to the browser output so just handle them here - if (istype(message, /image) || istype(message, /sound) || istype(target, /savefile) || !(ismob(target) || islist(target) || istype(target, /client) || istype(target, /datum/log) || target == world)) - target << message - if (!istype(target, /atom)) // Really easy to mix these up, and not having to make sure things are mobs makes the code cleaner. - CRASH("DEBUG: Boutput called with invalid message") - return - - //Otherwise, we're good to throw it at the user - else if (istext(message)) - if (istext(target)) - return - - //Some macros remain in the string even after parsing and fuck up the eventual output - if (findtext(message, "\improper")) - message = replacetext(message, "\improper", "") - if (findtext(message, "\proper")) - message = replacetext(message, "\proper", "") - - //Grab us a client if possible - var/client/C = grab_client(target) - - if (C && C.chatOutput) - if(C.chatOutput.broken) // A player who hasn't updated his skin file. - to_chat(C, message) - return TRUE - if(!C.chatOutput.loaded && C.chatOutput.messageQueue && islist(C.chatOutput.messageQueue)) - //Client sucks at loading things, put their messages in a queue - C.chatOutput.messageQueue.Add(message) - return - - if(istype(target, /datum/log)) - var/datum/log/L = target - L.log += (message + "\n") - return - - message = replacetext(message, "\n", "
    ") - message = replacetext(message, "\t", "    ") - - // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. - target << output(url_encode(url_encode(message)), "browseroutput:output") - -/proc/grab_client(target) - if(istype(target, /client)) - return target - else if(istype(target, /mob)) - var/mob/M = target - if(M.client) - return M.client - else if(istype(target, /datum/mind)) - var/datum/mind/M = target - if(M.current && M.current.client) - return M.current.client - -/datum/log //exists purely to capture to_chat() output - var/log = "" \ No newline at end of file diff --git a/html/browser/roundend.css b/html/browser/roundend.css index 865b42999e..e69635e888 100644 --- a/html/browser/roundend.css +++ b/html/browser/roundend.css @@ -10,6 +10,10 @@ color: #ef2f3c; font-weight: bold; } +.bluetext { + color: #517fff; + font-weight: bold; +} .neutraltext { font-weight: bold; /* If you feel these should have some color feel free to change */ } diff --git a/html/changelogs/AutoChangeLog-pr-7544.yml b/html/changelogs/AutoChangeLog-pr-7544.yml new file mode 100644 index 0000000000..f70a0e0e30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7544.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - balance: "Reduced the default/baseline nanite pool amount from 100 nanites to 25 nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. The safety threshold was reduced from 50 nanites to 12 nanites." 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-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-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-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-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-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-8416.yml b/html/changelogs/AutoChangeLog-pr-8416.yml new file mode 100644 index 0000000000..34bac362be --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8416.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "adds the sec jetpack to sec hardsuit storge" 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-8479.yml b/html/changelogs/AutoChangeLog-pr-8479.yml new file mode 100644 index 0000000000..b6c8340527 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8479.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Buffed krav maga leg sweep stun and stamina damage. On the other hand, it's now unable to be used on already lying targets." 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-8497.yml b/html/changelogs/AutoChangeLog-pr-8497.yml new file mode 100644 index 0000000000..4c42899313 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8497.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds clockwork reflectors, a fragile anti-laser reflection shield object that can be constructed for 10 brass sheets. Upon firing on the object in the direction where it is shielded, it ricochets the bullet off of it relative to the shooting angle." + - tweak: "Renames some windows in the build menu for consistency." 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-8505.yml b/html/changelogs/AutoChangeLog-pr-8505.yml new file mode 100644 index 0000000000..57d6399680 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8505.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Clockwork Cult walls can no longer be deconstructed by RCDs when heated." 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-8561.yml b/html/changelogs/AutoChangeLog-pr-8561.yml new file mode 100644 index 0000000000..dca2bff2ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8561.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by JJRcop)" +delete-after: True +changes: + - rscadd: "Ports in more emojis, including : flushed :" 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-8565.yml b/html/changelogs/AutoChangeLog-pr-8565.yml new file mode 100644 index 0000000000..91faa4d8b6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8565.yml @@ -0,0 +1,4 @@ +author: "Skully)" +delete-after: True +changes: + - rscadd: "Nudity Permit, a completely invisible uniform that still has pockets and such, to loadout options. It is more or less a direct port from the RP server." 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/html/changelogs/AutoChangeLog-pr-8570.yml b/html/changelogs/AutoChangeLog-pr-8570.yml new file mode 100644 index 0000000000..787b486685 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8570.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "origami" diff --git a/html/changelogs/AutoChangeLog-pr-8578.yml b/html/changelogs/AutoChangeLog-pr-8578.yml new file mode 100644 index 0000000000..39ded33f2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8578.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - spellcheck: "Properly rewords the extinguisher's instructions on how to empty it on the floor since it was changed to be a screwdriver action instead of Alt Click a while ago." diff --git a/html/changelogs/AutoChangeLog-pr-8579.yml b/html/changelogs/AutoChangeLog-pr-8579.yml new file mode 100644 index 0000000000..56ecea119f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8579.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gang tower shield" + - tweak: "costs of boots" diff --git a/html/changelogs/AutoChangeLog-pr-8581.yml b/html/changelogs/AutoChangeLog-pr-8581.yml new file mode 100644 index 0000000000..90433ecb88 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8581.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Reskinnable PDAs. A related game preference." + - refactor: "Refactoring the pda, pda painter, obj reskinning and chameleon pda a bit to support this feature." + - imageadd: "more PDA sprites and ported reskins." diff --git a/html/changelogs/AutoChangeLog-pr-8584.yml b/html/changelogs/AutoChangeLog-pr-8584.yml new file mode 100644 index 0000000000..2621812d64 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8584.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "organ box" diff --git a/html/changelogs/AutoChangeLog-pr-8587.yml b/html/changelogs/AutoChangeLog-pr-8587.yml new file mode 100644 index 0000000000..4b7fdeb64c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8587.yml @@ -0,0 +1,4 @@ +author: "SkullyRoberts" +delete-after: True +changes: + - rscadd: "Penis autosurgeon as rare maint loot." diff --git a/html/changelogs/AutoChangeLog-pr-8591.yml b/html/changelogs/AutoChangeLog-pr-8591.yml new file mode 100644 index 0000000000..09eb449899 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8591.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by Vile Beggar)" +delete-after: True +changes: + - rscadd: "Warden now has an added drill hat in his locker. You can change the loudness setting of it by using a screwdriver on it. Use wirecutters on it for a surprise." diff --git a/html/changelogs/AutoChangeLog-pr-8599.yml b/html/changelogs/AutoChangeLog-pr-8599.yml new file mode 100644 index 0000000000..41134f4d5b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8599.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Pacifists can eat people for heal belly or noisy. Digestive modes are auto-swapped to noisy" diff --git a/html/changelogs/AutoChangeLog-pr-8602.yml b/html/changelogs/AutoChangeLog-pr-8602.yml new file mode 100644 index 0000000000..4974c1ae79 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8602.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added an underwear toggle button under 'Object' tab" + - tweak: "Genitals now layer under underwear. Hide these if they're too obnoxious." diff --git a/html/changelogs/AutoChangeLog-pr-8605.yml b/html/changelogs/AutoChangeLog-pr-8605.yml new file mode 100644 index 0000000000..c6a601f1ca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8605.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Medical breifcaseses" diff --git a/html/changelogs/AutoChangeLog-pr-8611.yml b/html/changelogs/AutoChangeLog-pr-8611.yml new file mode 100644 index 0000000000..8176d10a84 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8611.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added digitigrade socks of all known ones anyway." diff --git a/html/changelogs/AutoChangeLog-pr-8614.yml b/html/changelogs/AutoChangeLog-pr-8614.yml new file mode 100644 index 0000000000..e9473181fb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8614.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by SpaceManiac)" +delete-after: True +changes: + - bugfix: "Disassembling a chem dispenser for the first time will no longer always yield a fully-charged cell." diff --git a/html/changelogs/AutoChangeLog-pr-8618.yml b/html/changelogs/AutoChangeLog-pr-8618.yml new file mode 100644 index 0000000000..77ba2439a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8618.yml @@ -0,0 +1,7 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "New cargo crate for tech-slugs!" + - rscadd: "Ammo to each fitting crate" + - bugfix: "Cat-code" + - spellcheck: "fixed a few typos - Again my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8623.yml b/html/changelogs/AutoChangeLog-pr-8623.yml new file mode 100644 index 0000000000..63f51b18eb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8623.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "The RD can now suplex a immovable rod. Good fucking luck." diff --git a/html/changelogs/AutoChangeLog-pr-8624.yml b/html/changelogs/AutoChangeLog-pr-8624.yml new file mode 100644 index 0000000000..598ed9b457 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8624.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - bugfix: "Fixes high alert ERT suit sprites. You can see them now!" diff --git a/html/changelogs/AutoChangeLog-pr-8632.yml b/html/changelogs/AutoChangeLog-pr-8632.yml new file mode 100644 index 0000000000..b2f74869c2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8632.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "Traitor codewords are now highlighted for traitors." diff --git a/html/changelogs/AutoChangeLog-pr-8633.yml b/html/changelogs/AutoChangeLog-pr-8633.yml new file mode 100644 index 0000000000..3cbc9a78aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8633.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "You can now examine pumps filters and mixers to see if you can use CTRL and Alt click on them." diff --git a/html/changelogs/AutoChangeLog-pr-8634.yml b/html/changelogs/AutoChangeLog-pr-8634.yml new file mode 100644 index 0000000000..d351579640 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8634.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes power cells being unable to be rigged. Also prevents them from starting processing on init if they don't self recharge." + - bugfix: "Fixes many, little or otherwise, issues with the stunbaton status refactor." diff --git a/html/changelogs/AutoChangeLog-pr-8639.yml b/html/changelogs/AutoChangeLog-pr-8639.yml new file mode 100644 index 0000000000..f2f24d33ad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8639.yml @@ -0,0 +1,10 @@ +author: "Useroth" +delete-after: True +changes: + - tweak: "Makes the netting much less clunky. If there's only one target you can net while you press the +button, it will just net that target instead of bringing up a list of mobs." + - tweak: "Energy nets now revive and fully heal capturees (even dead ones, after calculating points). If someone's got a scan and wants to get cloned, they can always kill themselves still." + - tweak: "Capture points are added on capture, rather than round-end, so it no longer matters whether your captures kill themselves in the holding facility or not." + - balance: "Makes the nets a bit more sturdy. (previously it took mere two welder hits to break one)" + - balance: "Makes stungloves actually stun people (currently comparably with stunbatons, adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top of that, people in insulated gloves were completely unaffected." + - balance: "Reduced the stunglove electrocute_act value to 15 due to above. Could possibly be lowered further." diff --git a/html/changelogs/AutoChangeLog-pr-8640.yml b/html/changelogs/AutoChangeLog-pr-8640.yml new file mode 100644 index 0000000000..b06feb4613 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8640.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "baklava" diff --git a/html/changelogs/AutoChangeLog-pr-8643.yml b/html/changelogs/AutoChangeLog-pr-8643.yml new file mode 100644 index 0000000000..b172071e2e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8643.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "The sacrificial target icon will now display onto the cult objective ui alert once again." diff --git a/html/changelogs/AutoChangeLog-pr-8645.yml b/html/changelogs/AutoChangeLog-pr-8645.yml new file mode 100644 index 0000000000..c299dcbbb5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8645.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Stopping borgs from sprinting into negative cell charge." diff --git a/html/changelogs/AutoChangeLog-pr-8648.yml b/html/changelogs/AutoChangeLog-pr-8648.yml new file mode 100644 index 0000000000..8d0f9d20c8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8648.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "makes uplink kits more usefull for the risk" diff --git a/html/changelogs/AutoChangeLog-pr-8652.yml b/html/changelogs/AutoChangeLog-pr-8652.yml new file mode 100644 index 0000000000..b788c5785c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8652.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by Dennok)" +delete-after: True +changes: + - bugfix: "Now areas_in_z get areas spawned by templates and blueprints." diff --git a/html/changelogs/AutoChangeLog-pr-8658.yml b/html/changelogs/AutoChangeLog-pr-8658.yml new file mode 100644 index 0000000000..ad35118c3f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8658.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Moving some tablecrafting recipes to the appropriate categories: Kitty ears and lizard cloche hats to \"clothing\"; Hot dogs to \"Sandwichs\"; Cuban carb, fish and chips and fish fingers to \"Fish\"." + - bugfix: "Fixes the not-a-sandwich recipe being M.I.A." diff --git a/html/changelogs/AutoChangeLog-pr-8659.yml b/html/changelogs/AutoChangeLog-pr-8659.yml new file mode 100644 index 0000000000..6287f1307f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8659.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ninjanomnom)" +delete-after: True +changes: + - bugfix: "Orbiting is a little more aggressive about staying in orbit. The wisp as a result now correctly follows you over shuttle moves." diff --git a/html/changelogs/AutoChangeLog-pr-8663.yml b/html/changelogs/AutoChangeLog-pr-8663.yml new file mode 100644 index 0000000000..3f5aeacd3c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8663.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adding in peanuts, peanut butter, peanut butter toasts and sandwiches, and the PB&J sandwich. +The peanuts contain a little bit of extractable cooking oil (similarly to soy beans) and can be microwaved or dried in a drying rack to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut butter, required to make those sandwiches." diff --git a/html/changelogs/AutoChangeLog-pr-8665.yml b/html/changelogs/AutoChangeLog-pr-8665.yml new file mode 100644 index 0000000000..fc34f9ac3e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8665.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Buffed wizard and artificier's Magic Missile, wizard and xeno queen's Repulse and juggernaut's Gauntlet Echo." diff --git a/html/changelogs/AutoChangeLog-pr-8666.yml b/html/changelogs/AutoChangeLog-pr-8666.yml new file mode 100644 index 0000000000..df2e2e3af0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8666.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by YPOQ)" +delete-after: True +changes: + - bugfix: "Fixing roffle waffle, mushroom halluginogen and some invalid reagents." diff --git a/html/changelogs/AutoChangeLog-pr-8667.yml b/html/changelogs/AutoChangeLog-pr-8667.yml new file mode 100644 index 0000000000..1f80a2917d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8667.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Anturk)" +delete-after: True +changes: + - rscadd: "Recipe for fabled secret sauce can now be found in the deepest reaches of space." diff --git a/html/changelogs/AutoChangeLog-pr-8669.yml b/html/changelogs/AutoChangeLog-pr-8669.yml new file mode 100644 index 0000000000..20770e8cc2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8669.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Denton and Skoglol)" +delete-after: True +changes: + - tweak: "Reorganized the syndicate uplinks. Items are now mostly alphabetical, some misplaced items moved to more fitting categories. Bundles, random item and TC have been moved into a new category called \"Bundles and Telecrystals\". Gloves of the North Star and Box of Throwing Weapons have been moved to Conspicuous and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous Weapons. Moved all implants into the Implants category." + - tweak: "Added a new category to the uplink: Grenades and Explosives." diff --git a/html/changelogs/AutoChangeLog-pr-8671.yml b/html/changelogs/AutoChangeLog-pr-8671.yml new file mode 100644 index 0000000000..bb01481d5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8671.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by wesoda25)" +delete-after: True +changes: + - balance: "disembowelment no longer works on mobs that aren't dead or in critical condition" diff --git a/html/changelogs/AutoChangeLog-pr-8674.yml b/html/changelogs/AutoChangeLog-pr-8674.yml new file mode 100644 index 0000000000..3277946844 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8674.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "fixing cat code that dosnt work, my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8675.yml b/html/changelogs/AutoChangeLog-pr-8675.yml new file mode 100644 index 0000000000..170a44ca25 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8675.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Arcades stealing from noodles" diff --git a/html/changelogs/AutoChangeLog-pr-8676.yml b/html/changelogs/AutoChangeLog-pr-8676.yml new file mode 100644 index 0000000000..e82a965985 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8676.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "rapier" diff --git a/html/changelogs/AutoChangeLog-pr-8677.yml b/html/changelogs/AutoChangeLog-pr-8677.yml new file mode 100644 index 0000000000..181f6d2932 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8677.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "speedy quirk" diff --git a/html/changelogs/AutoChangeLog-pr-8681.yml b/html/changelogs/AutoChangeLog-pr-8681.yml new file mode 100644 index 0000000000..1cd5f04124 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8681.yml @@ -0,0 +1,6 @@ +author: "Ghommie (Original PRs by Tortellini Tony and BuffEngineering)" +delete-after: True +changes: + - bugfix: "E-cigs will continue to display their setting after being emagged." + - bugfix: "Vapes now come out of the mouth. +fix Fixes an E-cig initialize() runtime." diff --git a/html/changelogs/AutoChangeLog-pr-8687.yml b/html/changelogs/AutoChangeLog-pr-8687.yml new file mode 100644 index 0000000000..65347093ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8687.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by monster860)" +delete-after: True +changes: + - bugfix: "fixes advanced proccall" diff --git a/html/changelogs/AutoChangeLog-pr-8688.yml b/html/changelogs/AutoChangeLog-pr-8688.yml new file mode 100644 index 0000000000..b22c2c52fd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8688.yml @@ -0,0 +1,5 @@ +author: "Ghommie (Original PR by nemvar)" +delete-after: True +changes: + - rscadd: "Botanists can now get beeplushies (or cultivator and bucket) as an heirloom." + - bugfix: "Clowns and mimes will now properly pick either a can of paint or their brand as heirloom now." diff --git a/html/changelogs/AutoChangeLog-pr-8689.yml b/html/changelogs/AutoChangeLog-pr-8689.yml new file mode 100644 index 0000000000..bf44770c76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8689.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - rscadd: "Added a panda simplemob" diff --git a/html/changelogs/AutoChangeLog-pr-8690.yml b/html/changelogs/AutoChangeLog-pr-8690.yml new file mode 100644 index 0000000000..3ac76333a2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8690.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - bugfix: "fixes empathy exploit." diff --git a/html/changelogs/AutoChangeLog-pr-8691.yml b/html/changelogs/AutoChangeLog-pr-8691.yml new file mode 100644 index 0000000000..680904cc5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8691.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PRs by nemvar and Rowell)" +delete-after: True +changes: + - rscadd: "Added beekini bras and panties, thigh-high and knee-high bee socks." diff --git a/html/changelogs/AutoChangeLog-pr-8692.yml b/html/changelogs/AutoChangeLog-pr-8692.yml new file mode 100644 index 0000000000..f1d87676ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8692.yml @@ -0,0 +1,7 @@ +author: "Ghommie (original PRs by ShizCalev)" +delete-after: True +changes: + - bugfix: "Fixed a bug that allowed you to teleport an ID in your possession to a PDA anywhere ingame." + - bugfix: "Fixed an exploit allowing you to steal ID's/pens from PDA's not in your possession." + - bugfix: "Fixed an exploit allowing you unlimited control of a PDA's interface even if it wasn't near you/in your possession." + - bugfix: "Fixed Pride Mirror exploits." diff --git a/html/changelogs/AutoChangeLog-pr-8693.yml b/html/changelogs/AutoChangeLog-pr-8693.yml new file mode 100644 index 0000000000..1e5e3fda58 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8693.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Tlaltecuhtli)" +delete-after: True +changes: + - bugfix: "Other people's clothes burning no longer spam you" diff --git a/html/changelogs/AutoChangeLog-pr-8695.yml b/html/changelogs/AutoChangeLog-pr-8695.yml new file mode 100644 index 0000000000..671eaa519e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8695.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by grandpawalton and Mickyan)" +delete-after: True +changes: + - tweak: "the contents on the smartfridge icon now change depending on how many items it contains" + - bugfix: "opening the maintenance panel of smartfridges now correctly updates the icon" + - bugfix: "Screwing a disk compartmentalizer no longer makes it look like a smartfridge." diff --git a/html/changelogs/AutoChangeLog-pr-8698.yml b/html/changelogs/AutoChangeLog-pr-8698.yml new file mode 100644 index 0000000000..464f74427e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8698.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes flashlights being unable to be used for rudimentary eyes and mouth exams." diff --git a/html/changelogs/AutoChangeLog-pr-8708.yml b/html/changelogs/AutoChangeLog-pr-8708.yml new file mode 100644 index 0000000000..0929c2ee6c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8708.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - spellcheck: "Ironic" diff --git a/html/changelogs/AutoChangeLog-pr-8709.yml b/html/changelogs/AutoChangeLog-pr-8709.yml new file mode 100644 index 0000000000..4aa6fd9b1d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8709.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "A bunch of minor issues with xenobiology are no more!" diff --git a/html/changelogs/AutoChangeLog-pr-8711.yml b/html/changelogs/AutoChangeLog-pr-8711.yml new file mode 100644 index 0000000000..f836783659 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8711.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adds in a grey jumpsuit to the loadout choices, restricted to Assistants." diff --git a/html/changelogs/AutoChangeLog-pr-8715.yml b/html/changelogs/AutoChangeLog-pr-8715.yml new file mode 100644 index 0000000000..b99309cdd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8715.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic acid." + - tweak: "Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now have TRUE tox healing to heal TOXINLOVER as well." diff --git a/html/changelogs/AutoChangeLog-pr-8718.yml b/html/changelogs/AutoChangeLog-pr-8718.yml new file mode 100644 index 0000000000..102fbd4f23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8718.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "ability to quickly max sensors" diff --git a/html/changelogs/AutoChangeLog-pr-8720.yml b/html/changelogs/AutoChangeLog-pr-8720.yml new file mode 100644 index 0000000000..81684baeac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8720.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Credits to Kmc2000 for the original PR)" +delete-after: True +changes: + - rscadd: "Porting in MRE boxes from Yogstation. But be careful, eating possibly expired MREs found in maintenance comes with an unrealistically large (actually small) chance of food poisoning. Otherwise just bail out and order actually safe-to-eat MREs from cargo for 2000 credits." diff --git a/html/changelogs/AutoChangeLog-pr-8721.yml b/html/changelogs/AutoChangeLog-pr-8721.yml new file mode 100644 index 0000000000..4b616e9923 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8721.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by XDTM)" +delete-after: True +changes: + - bugfix: "Reagents now stop their passive effects (for example, stun immunity) if the liver stops working while they're active." diff --git a/html/changelogs/AutoChangeLog-pr-8722.yml b/html/changelogs/AutoChangeLog-pr-8722.yml new file mode 100644 index 0000000000..fe858768af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8722.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "I didn't code it right it in the first place" diff --git a/html/changelogs/AutoChangeLog-pr-8724.yml b/html/changelogs/AutoChangeLog-pr-8724.yml new file mode 100644 index 0000000000..5fc86dd9c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8724.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "new nodes" + - balance: "points and node gear" diff --git a/html/changelogs/AutoChangeLog-pr-8725.yml b/html/changelogs/AutoChangeLog-pr-8725.yml new file mode 100644 index 0000000000..d42840ef0a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8725.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "stuff n things" diff --git a/html/changelogs/AutoChangeLog-pr-8726.yml b/html/changelogs/AutoChangeLog-pr-8726.yml new file mode 100644 index 0000000000..49da4299ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8726.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Changed bible heal proc, halving the healed damage and increasing brain damage 5x in exchange for a much wider array of items to protect you from it." diff --git a/html/changelogs/AutoChangeLog-pr-8727.yml b/html/changelogs/AutoChangeLog-pr-8727.yml new file mode 100644 index 0000000000..b1ca5f0d51 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8727.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Jujumatic and PKPenguin321, respectively)" +delete-after: True +changes: + - rscadd: "Minesweeper Arcade machines. The higher the difficulty setting, the better the prizes will be." + - rscadd: "Also keep your eye out for another new (and rare) arcade game!" diff --git a/html/changelogs/AutoChangeLog-pr-8728.yml b/html/changelogs/AutoChangeLog-pr-8728.yml new file mode 100644 index 0000000000..2e860e737f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8728.yml @@ -0,0 +1,6 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Moved around some chems from emag list into upgrades." + - balance: "Added some fun chems to dispensers." + - bugfix: "Gave dispensers old tg functionality." diff --git a/html/changelogs/AutoChangeLog-pr-8729.yml b/html/changelogs/AutoChangeLog-pr-8729.yml new file mode 100644 index 0000000000..a72f624352 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8729.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by AffectedArc07)" +delete-after: True +changes: + - tweak: "Religion is now a globalvar instead of being a subsystem for some reason" diff --git a/html/changelogs/AutoChangeLog-pr-8730.yml b/html/changelogs/AutoChangeLog-pr-8730.yml new file mode 100644 index 0000000000..d0204f2830 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8730.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Tlaltecuhtli and nicbn)" +delete-after: True +changes: + - rscadd: "alt click to eject beakers from chem masters + chem dispensers + grinders + chem heaters" + - rscadd: "hit chem master + chem dispenser + chem heaters with a beaker and if its loaded with another it swaps em" + - rscadd: "All-In-One Blender UI uses a radial menu now. You can see the contents and reagents by examining." diff --git a/html/changelogs/AutoChangeLog-pr-8731.yml b/html/changelogs/AutoChangeLog-pr-8731.yml new file mode 100644 index 0000000000..0728c12124 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8731.yml @@ -0,0 +1,9 @@ +author: "Ghommie (original PRs by nicbn and coiax)" +delete-after: True +changes: + - rscadd: "Microwave UI uses a radial menu now. You can see the contents by examining." + - rscadd: "Microwaves have a single wire accessible when open, the activation wire. +When cut, the microwave will no longer function, when pulsed, the microwave +will turn on." + - rscadd: "Stabilized dark purple extracts now cook items in your hands, rather than dropping +the cooked item on the floor." diff --git a/html/changelogs/AutoChangeLog-pr-8732.yml b/html/changelogs/AutoChangeLog-pr-8732.yml new file mode 100644 index 0000000000..69a79b93ac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8732.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Nicjh)" +delete-after: True +changes: + - rscadd: "Abductor console's select disguise option now uses a radial" diff --git a/html/changelogs/AutoChangeLog-pr-8733.yml b/html/changelogs/AutoChangeLog-pr-8733.yml new file mode 100644 index 0000000000..593c06bd90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8733.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Swindly)" +delete-after: True +changes: + - rscadd: "Arm-mounted implants that contain more than one item use a radial menu instead of a list menu." diff --git a/html/changelogs/AutoChangeLog-pr-8734.yml b/html/changelogs/AutoChangeLog-pr-8734.yml new file mode 100644 index 0000000000..4f746c4cd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8734.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by coiax)" +delete-after: True +changes: + - code_imp: "Randomly coloured gloves and randomly coloured glowsticks now have +slightly different typepaths, but otherwise function the same." diff --git a/html/changelogs/AutoChangeLog-pr-8736.yml b/html/changelogs/AutoChangeLog-pr-8736.yml new file mode 100644 index 0000000000..68d64e2410 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8736.yml @@ -0,0 +1,6 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gear harness and a conflict merg" + - rscdel: "Nudity permits" + - bugfix: "nothing" diff --git a/html/changelogs/AutoChangeLog-pr-8737.yml b/html/changelogs/AutoChangeLog-pr-8737.yml new file mode 100644 index 0000000000..d8e868df33 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8737.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes CWC construct shells being visible as ghost role to latejoiners." diff --git a/html/changelogs/AutoChangeLog-pr-8738.yml b/html/changelogs/AutoChangeLog-pr-8738.yml new file mode 100644 index 0000000000..f0e48a77b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8738.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ShizCalev)" +delete-after: True +changes: + - bugfix: "Pineapple haters/lovers will get/no longer get pineapple pizzas respectively from infinite pizza boxes." diff --git a/html/changelogs/AutoChangeLog-pr-8739.yml b/html/changelogs/AutoChangeLog-pr-8739.yml new file mode 100644 index 0000000000..0c25a1a649 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8739.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Leather, cardboard, bronze & bone golems!" + - rscadd: "Bone hurting juice and interactions with plasmamen, skeletons & bone golems!" diff --git a/html/changelogs/AutoChangeLog-pr-8740.yml b/html/changelogs/AutoChangeLog-pr-8740.yml new file mode 100644 index 0000000000..1966f34331 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8740.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by Denton)" +delete-after: True +changes: + - tweak: "Nanotrasen has started shipping more types of bedsheets to its stations." + - rscadd: "Added in Runtime, Pirate and Gondola bedsheets. The second one can also be found in some pirate ships, while the last can be crafted from gondola hides." diff --git a/html/changelogs/AutoChangeLog-pr-8741.yml b/html/changelogs/AutoChangeLog-pr-8741.yml new file mode 100644 index 0000000000..be803933ae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8741.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by AffectedArc07 and Shazbot)" +delete-after: True +changes: + - imageadd: "Added 8 new sock styles" diff --git a/html/changelogs/AutoChangeLog-pr-8742.yml b/html/changelogs/AutoChangeLog-pr-8742.yml new file mode 100644 index 0000000000..03428fc8d1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8742.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Donner item" diff --git a/html/changelogs/AutoChangeLog-pr-8744.yml b/html/changelogs/AutoChangeLog-pr-8744.yml new file mode 100644 index 0000000000..2979a4a842 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8744.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "atmos helmet visual bug" diff --git a/html/changelogs/AutoChangeLog-pr-8745.yml b/html/changelogs/AutoChangeLog-pr-8745.yml new file mode 100644 index 0000000000..6feaa2eadd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8745.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Ported addition of new CAS cards." + - bugfix: "Ported a fix for CAS." diff --git a/html/changelogs/AutoChangeLog-pr-8747.yml b/html/changelogs/AutoChangeLog-pr-8747.yml new file mode 100644 index 0000000000..c8a4689c60 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8747.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Luna's Gauntlets" diff --git a/html/changelogs/AutoChangeLog-pr-8750.yml b/html/changelogs/AutoChangeLog-pr-8750.yml new file mode 100644 index 0000000000..a3ff5e8a91 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8750.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - bugfix: "Fixes brain damage/trauma healing nanites so they actually work while there are only traumas." diff --git a/html/changelogs/AutoChangeLog-pr-8752.yml b/html/changelogs/AutoChangeLog-pr-8752.yml new file mode 100644 index 0000000000..243b9695a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8752.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Added the ability to alter your genitalia as a slimeperson more than addition/removal." + - bugfix: "fixed genitalia removal proc in alter form." diff --git a/html/changelogs/AutoChangeLog-pr-8753.yml b/html/changelogs/AutoChangeLog-pr-8753.yml new file mode 100644 index 0000000000..04fd009e2f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8753.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Ported the inability for non-station AI to interact with station z-level." diff --git a/html/changelogs/AutoChangeLog-pr-8755.yml b/html/changelogs/AutoChangeLog-pr-8755.yml new file mode 100644 index 0000000000..a1c4742802 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8755.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - tweak: "tweaked the Genital character creation layout to look better" + - bugfix: "fixed having balls/womb when you don't have the linked organ at character creation" + - bugfix: "fixed being able to squeeze semen directly from your balls. Probably." diff --git a/html/changelogs/AutoChangeLog-pr-8756.yml b/html/changelogs/AutoChangeLog-pr-8756.yml new file mode 100644 index 0000000000..8d78c6d5e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8756.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "HoS mains can now peacefully sleep in their office." diff --git a/html/changelogs/AutoChangeLog-pr-8760.yml b/html/changelogs/AutoChangeLog-pr-8760.yml new file mode 100644 index 0000000000..78812c5c05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8760.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "rebalanced lingy dingy powery gamey" diff --git a/html/changelogs/AutoChangeLog-pr-8761.yml b/html/changelogs/AutoChangeLog-pr-8761.yml new file mode 100644 index 0000000000..4ee792c3a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8761.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "melee and block harm" + - bugfix: "sprites*" diff --git a/html/changelogs/AutoChangeLog-pr-8762.yml b/html/changelogs/AutoChangeLog-pr-8762.yml new file mode 100644 index 0000000000..e248589b1b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8762.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "new sprites for the flechette gun, its magazines and the toy ray gun" diff --git a/html/changelogs/AutoChangeLog-pr-8764.yml b/html/changelogs/AutoChangeLog-pr-8764.yml new file mode 100644 index 0000000000..ad5b82505a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8764.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "holster doing holster things" diff --git a/html/changelogs/AutoChangeLog-pr-8765.yml b/html/changelogs/AutoChangeLog-pr-8765.yml new file mode 100644 index 0000000000..2cac0773ad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8765.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Merges the end-of-shift and its shuttle autocall announcements into one." + - bugfix: "Prevents the end-of-shift shuttle from being recalled (even if to no avail)." diff --git a/html/changelogs/AutoChangeLog-pr-8766.yml b/html/changelogs/AutoChangeLog-pr-8766.yml new file mode 100644 index 0000000000..33c2a47a71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8766.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes being able to teleport papers to your location with TK." diff --git a/html/changelogs/AutoChangeLog-pr-8767.yml b/html/changelogs/AutoChangeLog-pr-8767.yml new file mode 100644 index 0000000000..ce01bf471b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8767.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed some monkey-code shenanigeans making items sometimes disappear from pickpocketing." diff --git a/html/changelogs/AutoChangeLog-pr-8768.yml b/html/changelogs/AutoChangeLog-pr-8768.yml new file mode 100644 index 0000000000..de8338b545 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8768.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "New sprites for the some pda cartridges." diff --git a/html/changelogs/AutoChangeLog-pr-8773.yml b/html/changelogs/AutoChangeLog-pr-8773.yml new file mode 100644 index 0000000000..6cc39f8184 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8773.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Podpeople now have customization options." diff --git a/html/changelogs/AutoChangeLog-pr-8775.yml b/html/changelogs/AutoChangeLog-pr-8775.yml new file mode 100644 index 0000000000..51e8a15b13 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8775.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "The crew monitor's entry for the Quartermaster will now appear bolded, while HoP's will be of the same color of the service/unknown/other jobs." diff --git a/html/changelogs/AutoChangeLog-pr-8776.yml b/html/changelogs/AutoChangeLog-pr-8776.yml new file mode 100644 index 0000000000..bd3d30677a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8776.yml @@ -0,0 +1,11 @@ +author: "Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli)" +delete-after: True +changes: + - bugfix: "Caks will no longer override the bonus reagents provided in a donut when frosting them." + - bugfix: "Caks can no longer create frosted frosted jelly donuts." + - bugfix: "Jelly donuts will no longer lose their vitamins when they're frosted." + - bugfix: "Fixed chaos donuts potentially doubling the amount of reagents added when microwaved with something else." + - bugfix: "Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted donuts have a chance at adding an extra sprinkle." + - code_imp: "Improved the code for ensuring that security members enjoy donuts and security-themed alcoholic drinks." + - balance: "neurotoxin doesnt insta stun but gives you limb paralysis overtime and heart attacks if it stays in for too long and it is also alcholic" + - balance: "beepsky smash now summons imaginary beepskys that deal stamina damage instead of outright stunning" diff --git a/html/changelogs/AutoChangeLog-pr-8778.yml b/html/changelogs/AutoChangeLog-pr-8778.yml new file mode 100644 index 0000000000..1fa8446e6a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8778.yml @@ -0,0 +1,16 @@ +author: "Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, Fire Chance, Ordonis, Krysonism and OnlineGirlfriend)" +delete-after: True +changes: + - tweak: "Reduced booze power of Mead, Red Mead, and Irish Cream." + - tweak: "Increased booze power of Grappa." + - rscadd: "Added a new premium drink to the soda machine called \"Grey Bull\" which gives temporary shock resistance" + - rscadd: "A new drink called Blank Paper was added to the bar menu, it was made by a mime and it represents a new start." + - rscadd: "Adds a variety of fine alcoholic beverages for discerning patrons of the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!" + - rscadd: "Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen." + - rscadd: "Packs of a novel artificial sweetener have been added to the kitchen vendor." + - rscadd: "Bottles of trappist beer and champagne are now available in the premium seection of the booze-o-mat." + - rscadd: "Juicing parsnips now yields parsnip juice." + - rscadd: "Maintenance peaches." + - bugfix: "Grape soda now cools you down like other sodas." + - tweak: "tweaked the Arnold Palmer recipe, it now uses lemonade." + - imageadd: "Added new drink, bottle, vomit and peach can sprites." diff --git a/html/changelogs/AutoChangeLog-pr-8779.yml b/html/changelogs/AutoChangeLog-pr-8779.yml new file mode 100644 index 0000000000..b5e90f7ecb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8779.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Roundstart carbon jetpacks now have full_speed FALSE." diff --git a/html/changelogs/AutoChangeLog-pr-8781.yml b/html/changelogs/AutoChangeLog-pr-8781.yml new file mode 100644 index 0000000000..12bd5ccdf0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8781.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Adds plasteel to medical and security techfabs." diff --git a/html/changelogs/AutoChangeLog-pr-8783.yml b/html/changelogs/AutoChangeLog-pr-8783.yml new file mode 100644 index 0000000000..5b283b9b21 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8783.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "emergency pods' storage will now properly work." diff --git a/html/changelogs/AutoChangeLog-pr-8784.yml b/html/changelogs/AutoChangeLog-pr-8784.yml new file mode 100644 index 0000000000..7d6d9d4739 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8784.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Donor item" diff --git a/html/changelogs/AutoChangeLog-pr-8785.yml b/html/changelogs/AutoChangeLog-pr-8785.yml new file mode 100644 index 0000000000..0dd9cb0df4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8785.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Joy, Happiness, Honk" diff --git a/html/changelogs/AutoChangeLog-pr-8790.yml b/html/changelogs/AutoChangeLog-pr-8790.yml new file mode 100644 index 0000000000..0c0e6cd116 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8790.yml @@ -0,0 +1,6 @@ +author: "Bhijn" +delete-after: True +changes: + - rscadd: "It's now possible to forcefully eject the occupants of a dogborg's sleeper by using a crowbar on them. This action is instant." + - tweak: "Resist values for dogborg sleepers have been adjusted. The baseline has been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds." + - tweak: "It now takes 10 full seconds to insert people into your sleeper. This should hopefully give people some more room to breathe and react to a dogborg attempting to sleeper someone either for no reason or in a way that violates law 2." diff --git a/html/changelogs/AutoChangeLog-pr-8793.yml b/html/changelogs/AutoChangeLog-pr-8793.yml new file mode 100644 index 0000000000..82a113c94d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8793.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "The PDA skin preference will now properly save up." + - tweak: "Changed the default PDA icon var to match the default PDA skin preference." diff --git a/html/changelogs/AutoChangeLog-pr-8794.yml b/html/changelogs/AutoChangeLog-pr-8794.yml new file mode 100644 index 0000000000..612a3e655b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8794.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixing the `(pointless) badassary` category appearing between the `dangerous and conspicious` and `stealthy and inconspicious` categories." + - bugfix: "Combat gloves plus now properly use the combat gloves sprite." diff --git a/html/changelogs/AutoChangeLog-pr-8796.yml b/html/changelogs/AutoChangeLog-pr-8796.yml new file mode 100644 index 0000000000..2ffdee9b37 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8796.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "small mix up in terms" diff --git a/html/changelogs/AutoChangeLog-pr-8797.yml b/html/changelogs/AutoChangeLog-pr-8797.yml new file mode 100644 index 0000000000..40c7afc570 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8797.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by @Tlaltecuhtli" +delete-after: True +changes: + - bugfix: "alt clicking the emitter now rotates it instead of only flipping" diff --git a/html/changelogs/AutoChangeLog-pr-8798.yml b/html/changelogs/AutoChangeLog-pr-8798.yml new file mode 100644 index 0000000000..367aadad80 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8798.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by Arkatos" +delete-after: True +changes: + - rscadd: "Action buttons can now be dragged onto each other to swap places" diff --git a/html/changelogs/AutoChangeLog-pr-8799.yml b/html/changelogs/AutoChangeLog-pr-8799.yml new file mode 100644 index 0000000000..73d3f590ba --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8799.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Promiscuous Organs crate, pills to lewd crate and testicles to maints" diff --git a/html/changelogs/AutoChangeLog-pr-8800.yml b/html/changelogs/AutoChangeLog-pr-8800.yml new file mode 100644 index 0000000000..7b397ec23e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8800.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by Skoglol" +delete-after: True +changes: + - rscadd: "Heaters/freezers now support ctrl clicking to turn on and alt clicking to min/max target temperature." diff --git a/html/changelogs/AutoChangeLog-pr-8801.yml b/html/changelogs/AutoChangeLog-pr-8801.yml new file mode 100644 index 0000000000..e1089f2f1d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8801.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by NewSta" +delete-after: True +changes: + - tweak: "updated the miasma canister sprites" diff --git a/html/changelogs/AutoChangeLog-pr-8802.yml b/html/changelogs/AutoChangeLog-pr-8802.yml new file mode 100644 index 0000000000..b97119c32d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8802.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja)" +delete-after: True +changes: + - rscadd: "Failsafe codes for uplinks are now available for purchase." + - rscadd: "Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as well as a couple different types of rockets for it. you can also suicide rocket jump with them!" + - spellcheck: "Improved Uplink item descriptions and formatting." diff --git a/html/changelogs/AutoChangeLog-pr-8805.yml b/html/changelogs/AutoChangeLog-pr-8805.yml new file mode 100644 index 0000000000..8abefd9ce2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8805.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "supply display are now properly on the wall" diff --git a/html/changelogs/AutoChangeLog-pr-8812.yml b/html/changelogs/AutoChangeLog-pr-8812.yml new file mode 100644 index 0000000000..0de67cfe59 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8812.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by XDTM" +delete-after: True +changes: + - rscadd: "Using the wrong surgery tool during surgery no longer attacks the patient, if on help or disarm intent." diff --git a/html/changelogs/AutoChangeLog-pr-8819.yml b/html/changelogs/AutoChangeLog-pr-8819.yml new file mode 100644 index 0000000000..0b750fccb6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8819.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Added public autolathes to all maps." diff --git a/html/changelogs/AutoChangeLog-pr-8820.yml b/html/changelogs/AutoChangeLog-pr-8820.yml new file mode 100644 index 0000000000..3e83e29cc3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8820.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by variableundefined)" +delete-after: True +changes: + - bugfix: "Cancel button to assault pod destination selector." diff --git a/html/changelogs/AutoChangeLog-pr-8821.yml b/html/changelogs/AutoChangeLog-pr-8821.yml new file mode 100644 index 0000000000..f45caba949 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8821.yml @@ -0,0 +1,7 @@ +author: "Ghommie (original PRs by ShizCalev)" +delete-after: True +changes: + - tweak: "Corgi collars can now be removed!" + - tweak: "Updated the corgi & parrot inventory panels to use the same formatting as other mobs" + - bugfix: "Fixed corgi inventory panels not closing properly." + - bugfix: "Fixed the parrot inventory panel not closing properly if you're not able to interact with it." diff --git a/html/changelogs/AutoChangeLog-pr-8823.yml b/html/changelogs/AutoChangeLog-pr-8823.yml new file mode 100644 index 0000000000..b334bfbd7e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8823.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by tralezab)" +delete-after: True +changes: + - bugfix: "Fixes an issue with spontaneous appendicitis picking incompatible mob biotypes." diff --git a/html/changelogs/AutoChangeLog-pr-8824.yml b/html/changelogs/AutoChangeLog-pr-8824.yml new file mode 100644 index 0000000000..6a12573112 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8824.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Mickyan)" +delete-after: True +changes: + - bugfix: "Fixed being unable to smother people using the damp rag" diff --git a/html/changelogs/AutoChangeLog-pr-8825.yml b/html/changelogs/AutoChangeLog-pr-8825.yml new file mode 100644 index 0000000000..a56be4e2ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8825.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PR by MrDoomBringer, AnturK and YPOQ)" +delete-after: True +changes: + - bugfix: "Explosions will no longer damage wizards in rod form, the supermatter monitoring radio and megafauna GPS." + - bugfix: "Supplypods no longer detonate their contents." + - bugfix: "Fixed silicon items (e.g. cyborg modules) being destroyed by explosion epicenters." diff --git a/html/changelogs/AutoChangeLog-pr-8826.yml b/html/changelogs/AutoChangeLog-pr-8826.yml new file mode 100644 index 0000000000..3f7520b84e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8826.yml @@ -0,0 +1,9 @@ +author: "Ghommie (original PR by Skoglol)" +delete-after: True +changes: + - code_imp: "New helper proc for alt-click turf listing, bypasses any interaction overrides." + - code_imp: "Ghosts and revenants now use the new proc." + - bugfix: "Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close laptops" + - bugfix: "Revenant can now alt-click turf to list contents." + - tweak: "Revenant now slightly less nosy, use shift click to examine." + - tweak: "Alt-clicking the same turf again no longer closes the turf listing tab." diff --git a/html/changelogs/AutoChangeLog-pr-8827.yml b/html/changelogs/AutoChangeLog-pr-8827.yml new file mode 100644 index 0000000000..e1aaadd698 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8827.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ninjanomnom)" +delete-after: True +changes: + - bugfix: "Gaps between sounds in some looping sound effects should no longer happen as much under heavy server lag." diff --git a/html/changelogs/AutoChangeLog-pr-8828.yml b/html/changelogs/AutoChangeLog-pr-8828.yml new file mode 100644 index 0000000000..4278a14ae1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8828.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Skoglol)" +delete-after: True +changes: + - bugfix: "Reduced ventcrawl lag greatly." diff --git a/html/changelogs/AutoChangeLog-pr-8834.yml b/html/changelogs/AutoChangeLog-pr-8834.yml new file mode 100644 index 0000000000..0b7a7b30c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8834.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes the space ninja's energy netting." diff --git a/html/changelogs/AutoChangeLog-pr-8835.yml b/html/changelogs/AutoChangeLog-pr-8835.yml new file mode 100644 index 0000000000..cf646b879b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8835.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - tweak: "consistency in hop and cap berets" diff --git a/html/changelogs/AutoChangeLog-pr-8841.yml b/html/changelogs/AutoChangeLog-pr-8841.yml new file mode 100644 index 0000000000..8bb73dac26 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8841.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adding one pAI to the wizard shuttle and ERT prep room" diff --git a/html/changelogs/AutoChangeLog-pr-8842.yml b/html/changelogs/AutoChangeLog-pr-8842.yml new file mode 100644 index 0000000000..8a8903b7e5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8842.yml @@ -0,0 +1,4 @@ +author: "UristMcAstronaut" +delete-after: True +changes: + - bugfix: "allows a pai to activate its holoform while in a pai connector without getting derped." diff --git a/html/changelogs/AutoChangeLog-pr-8843.yml b/html/changelogs/AutoChangeLog-pr-8843.yml new file mode 100644 index 0000000000..74a3cc07e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8843.yml @@ -0,0 +1,4 @@ +author: "Coolgat3" +delete-after: True +changes: + - imageadd: "added combat boots sprite" diff --git a/html/changelogs/AutoChangeLog-pr-8844.yml b/html/changelogs/AutoChangeLog-pr-8844.yml new file mode 100644 index 0000000000..05f0f2fb22 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8844.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes the rocket launcher being unreloadable." + - balance: "Buffed its accuracy a bit." + - tweak: "Replaced the grenade launcher emagged minesweeper loot with the rocket launcher like it was originally supposed to be." diff --git a/html/changelogs/AutoChangeLog-pr-8845.yml b/html/changelogs/AutoChangeLog-pr-8845.yml new file mode 100644 index 0000000000..4fe0319fad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8845.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "Tweaked the :b: emoji." diff --git a/html/changelogs/AutoChangeLog-pr-8846.yml b/html/changelogs/AutoChangeLog-pr-8846.yml new file mode 100644 index 0000000000..26b1dad6d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8846.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Rubber Toolboxes." diff --git a/html/changelogs/AutoChangeLog-pr-8847.yml b/html/changelogs/AutoChangeLog-pr-8847.yml new file mode 100644 index 0000000000..678b3d433b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8847.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Porting in two bar signs: Cyber Sylph's and Meow Mix." diff --git a/html/changelogs/AutoChangeLog-pr-8852.yml b/html/changelogs/AutoChangeLog-pr-8852.yml new file mode 100644 index 0000000000..4d49f26831 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8852.yml @@ -0,0 +1,4 @@ +author: "Tupinambis" +delete-after: True +changes: + - imagedel: "Removes a moth plush from the game." diff --git a/html/changelogs/AutoChangeLog-pr-8853.yml b/html/changelogs/AutoChangeLog-pr-8853.yml new file mode 100644 index 0000000000..1507e8620d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8853.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Naksu and coiax, loser)" +delete-after: True +changes: + - code_imp: "Cleaned up saycode" + - bugfix: "Taking mutadone while having the communication disorder brain trauma will no longer spam your chat with messages." + - rscadd: "IPCs now come with a subtype of robotic tongue without the omnilingual ability, instead of innately having robotic voice spans." diff --git a/html/changelogs/AutoChangeLog-pr-8854.yml b/html/changelogs/AutoChangeLog-pr-8854.yml new file mode 100644 index 0000000000..fc45d2087e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8854.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixing stamina damage melee weaponry being unusable by pacifists, and still damaging objects and triggering electrified grilles when thrown." diff --git a/html/changelogs/AutoChangeLog-pr-8857.yml b/html/changelogs/AutoChangeLog-pr-8857.yml new file mode 100644 index 0000000000..6e32fff883 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8857.yml @@ -0,0 +1,8 @@ +author: "Ghommie" +delete-after: True +changes: + - refactor: "refactored underwears to allow custom color preferences, instead of manually colored sprites." + - rscdel: "The aforementioned manually colored pieces. Some of your char preferences may have been resetted as result." + - rscadd: "More underwear choices, including: Bowling shirts, long johns, a tank top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the latter three by nemvar from /tg/station)." + - tweak: "random bodies will now have random underwear again." + - bugfix: "Dressers will now properly change undergarment again." diff --git a/html/changelogs/AutoChangeLog-pr-8858.yml b/html/changelogs/AutoChangeLog-pr-8858.yml new file mode 100644 index 0000000000..6fc057f88d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8858.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Made unholy water healtoxinlover" diff --git a/html/changelogs/AutoChangeLog-pr-8860.yml b/html/changelogs/AutoChangeLog-pr-8860.yml new file mode 100644 index 0000000000..95593b1dad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8860.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Zelus Oil, brass flasks" diff --git a/html/changelogs/AutoChangeLog-pr-8870.yml b/html/changelogs/AutoChangeLog-pr-8870.yml new file mode 100644 index 0000000000..08c9860a30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8870.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Toned down many species' female chest sprites to fit the smaller cups." + - bugfix: "Fixed some body parts sprites inconsistencies, such as the W/E female and male chest sprites being the same in some species, and jellypeople's legs being one tile off on W/E" diff --git a/html/changelogs/AutoChangeLog-pr-8872.yml b/html/changelogs/AutoChangeLog-pr-8872.yml new file mode 100644 index 0000000000..a79ec48298 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8872.yml @@ -0,0 +1,5 @@ +author: "deathride58" +delete-after: True +changes: + - balance: "Normal mops now only use 2 stamina to mop a tile, nerfed from their previous value of 5 stamina per tile mopped." + - balance: "Advanced mops now only use 1 stamina to mop turfs, from their former value of 2 stam." diff --git a/html/changelogs/AutoChangeLog-pr-8873.yml b/html/changelogs/AutoChangeLog-pr-8873.yml new file mode 100644 index 0000000000..af166d496a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8873.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by YPOQ)" +delete-after: True +changes: + - bugfix: "Fixes clockwork armor not actually having armor." diff --git a/html/changelogs/AutoChangeLog-pr-8874.yml b/html/changelogs/AutoChangeLog-pr-8874.yml new file mode 100644 index 0000000000..0d7b51a941 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8874.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax)" +delete-after: True +changes: + - rscadd: "You can now select what your pills will look like when making pills from the Chem Master" + - rscadd: "Red pills can make you think." diff --git a/html/changelogs/AutoChangeLog-pr-8877.yml b/html/changelogs/AutoChangeLog-pr-8877.yml new file mode 100644 index 0000000000..205ff8f2c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8877.yml @@ -0,0 +1,4 @@ +author: "BurgerLUA" +delete-after: True +changes: + - bugfix: "Fixed most reagents having a placeholder color." diff --git a/html/changelogs/AutoChangeLog-pr-8880.yml b/html/changelogs/AutoChangeLog-pr-8880.yml new file mode 100644 index 0000000000..e720f00ccb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8880.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "air alarms are green now instead of blue when the atmosphere is ideal" diff --git a/html/changelogs/AutoChangeLog-pr-8883.yml b/html/changelogs/AutoChangeLog-pr-8883.yml new file mode 100644 index 0000000000..715ce5dbfc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8883.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "Hexacrocin overdose no longer causes climaxes" diff --git a/html/changelogs/AutoChangeLog-pr-8884.yml b/html/changelogs/AutoChangeLog-pr-8884.yml new file mode 100644 index 0000000000..c63618a6d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8884.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by duckay)" +delete-after: True +changes: + - rscadd: "Added better names and descriptions for blueshirt officer gear." + - rscadd: "Added the above gear to the premium selection of the sectech" diff --git a/html/changelogs/AutoChangeLog-pr-8885.yml b/html/changelogs/AutoChangeLog-pr-8885.yml new file mode 100644 index 0000000000..1469ccf460 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8885.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by coiax)" +delete-after: True +changes: + - code_imp: "The Squeak subsystem has been renamed to Minor Mapping." diff --git a/html/changelogs/AutoChangeLog-pr-8887.yml b/html/changelogs/AutoChangeLog-pr-8887.yml new file mode 100644 index 0000000000..45826fe571 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8887.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "NT Newscasters have had repeated reports of gang activity and are now looking into it." + - rscadd: "NT Psykers keep mumbling about last words of someone who died. Somehow they even have a newsletter for this..." + - bugfix: "Gangster greeting messages are a batch message rather than 5 laggy to_chats" diff --git a/icons/UI_Icons/Pills/pill1.png b/icons/UI_Icons/Pills/pill1.png new file mode 100644 index 0000000000..3412ca9d0e Binary files /dev/null and b/icons/UI_Icons/Pills/pill1.png differ diff --git a/icons/UI_Icons/Pills/pill10.png b/icons/UI_Icons/Pills/pill10.png new file mode 100644 index 0000000000..06829b9b93 Binary files /dev/null and b/icons/UI_Icons/Pills/pill10.png differ diff --git a/icons/UI_Icons/Pills/pill11.png b/icons/UI_Icons/Pills/pill11.png new file mode 100644 index 0000000000..780d7abdfb Binary files /dev/null and b/icons/UI_Icons/Pills/pill11.png differ diff --git a/icons/UI_Icons/Pills/pill12.png b/icons/UI_Icons/Pills/pill12.png new file mode 100644 index 0000000000..587936f748 Binary files /dev/null and b/icons/UI_Icons/Pills/pill12.png differ diff --git a/icons/UI_Icons/Pills/pill13.png b/icons/UI_Icons/Pills/pill13.png new file mode 100644 index 0000000000..226cefdadb Binary files /dev/null and b/icons/UI_Icons/Pills/pill13.png differ diff --git a/icons/UI_Icons/Pills/pill14.png b/icons/UI_Icons/Pills/pill14.png new file mode 100644 index 0000000000..26c0c66ecb Binary files /dev/null and b/icons/UI_Icons/Pills/pill14.png differ diff --git a/icons/UI_Icons/Pills/pill15.png b/icons/UI_Icons/Pills/pill15.png new file mode 100644 index 0000000000..1e338ca26a Binary files /dev/null and b/icons/UI_Icons/Pills/pill15.png differ diff --git a/icons/UI_Icons/Pills/pill16.png b/icons/UI_Icons/Pills/pill16.png new file mode 100644 index 0000000000..e733281709 Binary files /dev/null and b/icons/UI_Icons/Pills/pill16.png differ diff --git a/icons/UI_Icons/Pills/pill17.png b/icons/UI_Icons/Pills/pill17.png new file mode 100644 index 0000000000..0f28a7c28a Binary files /dev/null and b/icons/UI_Icons/Pills/pill17.png differ diff --git a/icons/UI_Icons/Pills/pill18.png b/icons/UI_Icons/Pills/pill18.png new file mode 100644 index 0000000000..4658d7dfc4 Binary files /dev/null and b/icons/UI_Icons/Pills/pill18.png differ diff --git a/icons/UI_Icons/Pills/pill19.png b/icons/UI_Icons/Pills/pill19.png new file mode 100644 index 0000000000..cf74e83ba2 Binary files /dev/null and b/icons/UI_Icons/Pills/pill19.png differ diff --git a/icons/UI_Icons/Pills/pill2.png b/icons/UI_Icons/Pills/pill2.png new file mode 100644 index 0000000000..f996df8536 Binary files /dev/null and b/icons/UI_Icons/Pills/pill2.png differ diff --git a/icons/UI_Icons/Pills/pill20.png b/icons/UI_Icons/Pills/pill20.png new file mode 100644 index 0000000000..4e10a166e9 Binary files /dev/null and b/icons/UI_Icons/Pills/pill20.png differ diff --git a/icons/UI_Icons/Pills/pill21.png b/icons/UI_Icons/Pills/pill21.png new file mode 100644 index 0000000000..9b4450da27 Binary files /dev/null and b/icons/UI_Icons/Pills/pill21.png differ diff --git a/icons/UI_Icons/Pills/pill22.png b/icons/UI_Icons/Pills/pill22.png new file mode 100644 index 0000000000..0d9d5c3c55 Binary files /dev/null and b/icons/UI_Icons/Pills/pill22.png differ diff --git a/icons/UI_Icons/Pills/pill3.png b/icons/UI_Icons/Pills/pill3.png new file mode 100644 index 0000000000..365fa39e7d Binary files /dev/null and b/icons/UI_Icons/Pills/pill3.png differ diff --git a/icons/UI_Icons/Pills/pill4.png b/icons/UI_Icons/Pills/pill4.png new file mode 100644 index 0000000000..d7aa72da3b Binary files /dev/null and b/icons/UI_Icons/Pills/pill4.png differ diff --git a/icons/UI_Icons/Pills/pill5.png b/icons/UI_Icons/Pills/pill5.png new file mode 100644 index 0000000000..ed9a84427a Binary files /dev/null and b/icons/UI_Icons/Pills/pill5.png differ diff --git a/icons/UI_Icons/Pills/pill6.png b/icons/UI_Icons/Pills/pill6.png new file mode 100644 index 0000000000..675adab56d Binary files /dev/null and b/icons/UI_Icons/Pills/pill6.png differ diff --git a/icons/UI_Icons/Pills/pill7.png b/icons/UI_Icons/Pills/pill7.png new file mode 100644 index 0000000000..9961be2878 Binary files /dev/null and b/icons/UI_Icons/Pills/pill7.png differ diff --git a/icons/UI_Icons/Pills/pill8.png b/icons/UI_Icons/Pills/pill8.png new file mode 100644 index 0000000000..879a5bcd5b Binary files /dev/null and b/icons/UI_Icons/Pills/pill8.png differ diff --git a/icons/UI_Icons/Pills/pill9.png b/icons/UI_Icons/Pills/pill9.png new file mode 100644 index 0000000000..235cf5b280 Binary files /dev/null and b/icons/UI_Icons/Pills/pill9.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/eight.png b/icons/UI_Icons/minesweeper_tiles/eight.png new file mode 100644 index 0000000000..3a5c4179ef Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/eight.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/empty.png b/icons/UI_Icons/minesweeper_tiles/empty.png new file mode 100644 index 0000000000..8a4fb536bb Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/empty.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/five.png b/icons/UI_Icons/minesweeper_tiles/five.png new file mode 100644 index 0000000000..dacf837f9b Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/five.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/flag.png b/icons/UI_Icons/minesweeper_tiles/flag.png new file mode 100644 index 0000000000..e71d8685ed Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/flag.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/four.png b/icons/UI_Icons/minesweeper_tiles/four.png new file mode 100644 index 0000000000..17a2bdfeb4 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/four.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/hidden.png b/icons/UI_Icons/minesweeper_tiles/hidden.png new file mode 100644 index 0000000000..8d34a2a7f3 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/hidden.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/mine.png b/icons/UI_Icons/minesweeper_tiles/mine.png new file mode 100644 index 0000000000..e16c89c2a8 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/mine.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/minehit.png b/icons/UI_Icons/minesweeper_tiles/minehit.png new file mode 100644 index 0000000000..f0c9699d97 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/minehit.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/one.png b/icons/UI_Icons/minesweeper_tiles/one.png new file mode 100644 index 0000000000..a84e6010a3 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/one.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/seven.png b/icons/UI_Icons/minesweeper_tiles/seven.png new file mode 100644 index 0000000000..10d71c427e Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/seven.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/six.png b/icons/UI_Icons/minesweeper_tiles/six.png new file mode 100644 index 0000000000..fe2ba800f4 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/six.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/three.png b/icons/UI_Icons/minesweeper_tiles/three.png new file mode 100644 index 0000000000..1c128d88ee Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/three.png differ diff --git a/icons/UI_Icons/minesweeper_tiles/two.png b/icons/UI_Icons/minesweeper_tiles/two.png new file mode 100644 index 0000000000..ff74af5c82 Binary files /dev/null and b/icons/UI_Icons/minesweeper_tiles/two.png differ diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index dce76f58b5..6a1a35f326 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ 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/emoji.dmi b/icons/emoji.dmi index f0286dd33c..925b072a5f 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.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.dmi b/icons/mob/actions.dmi index 0ef4996b07..65b5733ffe 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.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/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi index dd8a6fb869..30927d3608 100644 Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.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 6099a3f037..e3c80708c3 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 1ae0b0a2b5..02fdc52b45 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi index 0c872625dd..d974d0ca6c 100644 Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi index c41cdf06d0..b69c6c88b1 100644 Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.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.dmi b/icons/mob/human_parts.dmi index 70aeba6a69..fc6fafb275 100644 Binary files a/icons/mob/human_parts.dmi and b/icons/mob/human_parts.dmi differ diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi index 50c143b9cb..7f10d992bc 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/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi index e9d0dd0d2b..3f29410f98 100644 Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi index dda17156fe..2c3f291e43 100644 Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/toolbox_lefthand.dmi b/icons/mob/inhands/equipment/toolbox_lefthand.dmi index b2fa42ce5e..801df7abb8 100644 Binary files a/icons/mob/inhands/equipment/toolbox_lefthand.dmi and b/icons/mob/inhands/equipment/toolbox_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/toolbox_righthand.dmi b/icons/mob/inhands/equipment/toolbox_righthand.dmi index ccb15982dd..f38ddfc9a4 100644 Binary files a/icons/mob/inhands/equipment/toolbox_righthand.dmi and b/icons/mob/inhands/equipment/toolbox_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/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index d6950f4e1e..d306e22892 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index 9655829113..3e0c3424d3 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index fbfa039451..5f0b665ff4 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index 3c126daba6..5eb270d23f 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index 45b0ab1f04..fe0146ccc4 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.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..42c32f134a 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 0b63685668..3174397b54 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 2ed1783941..3d281606de 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 24ede3c513..6282e555fa 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/atmos.dmi b/icons/obj/atmos.dmi index 9a51635b81..ee42e95dd2 100644 Binary files a/icons/obj/atmos.dmi and b/icons/obj/atmos.dmi differ diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index 50bfbace89..2c4d401088 100644 Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi index 73dcad452b..1cc99e09e9 100644 Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 56cfdf468b..1948bb605c 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/clothing/belts.dm b/icons/obj/clothing/belts.dm new file mode 100644 index 0000000000..34c716f5d8 Binary files /dev/null and b/icons/obj/clothing/belts.dm differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index dc5dde9cb6..34c716f5d8 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index a90efcdfea..7e0d03abd5 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/shoes.dmi b/icons/obj/clothing/shoes.dmi index db0634181b..8d7bd55426 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 8e0359e6b3..568adb69b3 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 84155bfe43..3e3a1cefcb 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 9a7d460e14..eb4f5813c8 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/dart.dmi b/icons/obj/dart.dmi new file mode 100644 index 0000000000..50ba4fc1ab Binary files /dev/null and b/icons/obj/dart.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/drinks.dmi b/icons/obj/drinks.dmi index a32d0234d6..7822cdb8c2 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/flora/pinetrees.dmi b/icons/obj/flora/pinetrees.dmi index a68e0388b0..3ee4a89f07 100644 Binary files a/icons/obj/flora/pinetrees.dmi and b/icons/obj/flora/pinetrees.dmi differ diff --git a/icons/obj/food/burgerbread.dmi b/icons/obj/food/burgerbread.dmi index c40dfaaa22..cd7fc1742b 100644 Binary files a/icons/obj/food/burgerbread.dmi and b/icons/obj/food/burgerbread.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index c348fb4f8f..f64dfd4740 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 9861a2e618..92b5203f5d 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/piecake.dmi b/icons/obj/food/piecake.dmi index 16bb9bf448..57dda21757 100644 Binary files a/icons/obj/food/piecake.dmi and b/icons/obj/food/piecake.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/projectile.dmi b/icons/obj/guns/projectile.dmi index e4a39903b3..7d44d35f55 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/hydroponics/growing_vegetables.dmi b/icons/obj/hydroponics/growing_vegetables.dmi index 9fc1520175..63cf069186 100644 Binary files a/icons/obj/hydroponics/growing_vegetables.dmi and b/icons/obj/hydroponics/growing_vegetables.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index 054aa47bbd..a1ab5b08e5 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi index 4c898aecd3..5a2088c332 100644 Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 543d57ff56..0d68f00c8b 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index fbb55434d1..140f6a4d9e 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/monitors.dmi b/icons/obj/monitors.dmi index 9880707010..e38760b84d 100644 Binary files a/icons/obj/monitors.dmi and b/icons/obj/monitors.dmi differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index 241bb46b98..7d184c6459 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/pda_alt.dmi b/icons/obj/pda_alt.dmi new file mode 100644 index 0000000000..4f03d2c574 Binary files /dev/null and b/icons/obj/pda_alt.dmi differ diff --git a/icons/obj/pda_modern.dmi b/icons/obj/pda_modern.dmi new file mode 100644 index 0000000000..26c3b9ce16 Binary files /dev/null and b/icons/obj/pda_modern.dmi differ diff --git a/icons/obj/pda_rugged.dmi b/icons/obj/pda_rugged.dmi new file mode 100644 index 0000000000..84c8ffd1f9 Binary files /dev/null and b/icons/obj/pda_rugged.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 7ca7b068b0..9048739e0c 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index d276655ae8..ad1d34836d 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index d6ffc12ae7..2a6ec3955a 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index f77735fc3e..80e681399a 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 8f6b844a23..cfb36bb3ae 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index 5e3757cedd..67079de3e2 100644 Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index e5d474f01d..553336115b 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/modular_citadel/code/controllers/subsystem/shuttle.dm b/modular_citadel/code/controllers/subsystem/shuttle.dm index bb4592f819..ce3f062bdd 100644 --- a/modular_citadel/code/controllers/subsystem/shuttle.dm +++ b/modular_citadel/code/controllers/subsystem/shuttle.dm @@ -1,6 +1,7 @@ -/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 3 hours has passed. - if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //3 hours - SSshuttle.emergency.request() - priority_announce("The shift has come to an end and the shuttle called.") +/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 2 hours have passed. + if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //2 hours + SSshuttle.emergency.request(silent = TRUE) + priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority") log_game("Round time limit reached. Shuttle has been auto-called.") message_admins("Round time limit reached. Shuttle called.") + emergencyNoRecall = TRUE 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/datums/uplink_items_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm deleted file mode 100644 index 16130de96d..0000000000 --- a/modular_citadel/code/datums/uplink_items_cit.dm +++ /dev/null @@ -1,177 +0,0 @@ -/*/datum/uplink_item/stealthy_tools/syndi_borer - name = "Syndicate Brain Slug" - desc = "A small cortical borer, modified to be completely loyal to the owner. \ - Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \ - to assist their host." - item = /obj/item/antag_spawner/syndi_borer - refundable = TRUE - cost = 10 - surplus = 20 //Let's not have this be too common - exclude_modes = list(/datum/game_mode/nuclear) */ - -/datum/uplink_item/stealthy_tools/holoparasite - name="Holoparasite Injector" - desc="An injector containing a swarm of holographic parasites. \ - They mimic the function of the guardians employed by the Space Wizard Federation, and their form can be selected upon application \ - NOTE: The precise nature of the symbiosis required by the parasites renders them incompatible with changelings" //updated to actually describe what they do and warn traitorchans not to buy it - item = /obj/item/storage/box/syndie_kit/holoparasite - refundable = TRUE - cant_discount = TRUE - cost = 15 - surplus = 20 //Nobody needs a ton of parasites - exclude_modes = list(/datum/game_mode/nuclear) - refund_path = /obj/item/guardiancreator/tech/choose/traitor - - -/obj/item/storage/box/syndie_kit/holoparasite - name = "box" - -/obj/item/storage/box/syndie_kit/holoparasite/PopulateContents() - new /obj/item/guardiancreator/tech/choose/traitor(src) - new /obj/item/paper/guides/antag/guardian(src) - -/datum/uplink_item/dangerous/antitank - name = "Anti Tank Pistol" - desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ - this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ - Uses sniper ammo. \ - Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." - item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate - cost = 14 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value. -/datum/uplink_item/dangerous/stealthpistol - name = "Stealth Pistol" - desc = "A compact, easily concealable bullpup pistol that fires 10mm auto rounds in 8 round magazines. \ - Has an integrated suppressor." - item = /obj/item/gun/ballistic/automatic/pistol/stealth - cost = 10 - surplus = 30 -*/ - -///Soporific 10mm mags/// - -/datum/uplink_item/ammo/pistolzzz - name = "10mm Soporific Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ - NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." - item = /obj/item/ammo_box/magazine/m10mm/soporific - cost = 2 - -///flechette memes/// - -/datum/uplink_item/dangerous/flechettegun - name = "Flechette Launcher" - desc = "A compact bullpup that fires micro-flechettes.\ - Flechettes have very poor performance idividually, but can be very deadly in numbers. \ - Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." - item = /obj/item/gun/ballistic/automatic/flechette - cost = 12 - surplus = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechetteap - name = "Armor Piercing Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." - item = /obj/item/ammo_box/magazine/flechette - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechettes - name = "Serrated Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ - These flechettes are highly likely to sever arteries, and even limbs." - item = /obj/item/ammo_box/magazine/flechette/s - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -///shredder/// - -/datum/uplink_item/nukeoffer/shredder - name = "Shredder bundle" - desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ - You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" - item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle - cost = 30 // normally 41 - -///Modular Pistols/// - -/datum/uplink_item/bundle/modular - name="Modular Pistol Kit" - desc="A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ - Includes a suit jacket that is padded with a robust liner." - item = /obj/item/storage/briefcase/modularbundle - cost = 12 - -//////Bundle stuff////// - -///bundle category/// - -/datum/uplink_item/bundle - category = "Bundles" - surplus = 0 - cant_discount = TRUE - -///place bundle storage items here I guess/// - -/obj/item/storage/briefcase/modularbundle - name = "briefcase" - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding." - icon_state = "briefcase" - flags_1 = CONDUCT_1 - force = 10 - hitsound = "swing_hit" - throw_speed = 2 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - resistance_flags = FLAMMABLE - max_integrity = 150 - -/obj/item/storage/briefcase/modularbundle/PopulateContents() - new /obj/item/gun/ballistic/automatic/pistol/modular(src) - new /obj/item/suppressor(src) - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/ammo_box/magazine/m10mm/soporific(src) - new /obj/item/ammo_box/c10mm/soporific(src) - new /obj/item/clothing/under/lawyer/blacksuit(src) - new /obj/item/clothing/accessory/waistcoat(src) - new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src) - -/obj/item/clothing/suit/toggle/lawyer/black/syndie - desc = "A snappy dress jacket. Suspiciously has no tags or branding." - armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10) - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle - desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/storage/belt/military(src) - new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) - -///End of Bundle stuff/// - - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/datum/uplink_item/dangerous/cxneb - name = "Dragon's Tooth Non-Eutactic Blade" - desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ - the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ - generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ - This particular model has a polychromic hardlight generator, allowing you to murder in style! \ - The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." - item = /obj/item/melee/transforming/energy/sword/cx/traitor - cost = 8 \ No newline at end of file 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..5ad740ed2e --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/dominator.dm @@ -0,0 +1,244 @@ +#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.news_report = GANG_VICTORY + 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..fa25701ac4 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang.dm @@ -0,0 +1,477 @@ +/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. + var/message = "You are now a member of the [name] Gang!" + message += "Help your bosses take over the station by claiming territory with spraycans. Simply spray on any unclaimed area of the station." + message += "You can also use recruitment pens to recruit more to your cause, If your boss provides you one." + message += "Their ultimate objective is to take over the station with a Dominator machine." + message += "You can identify your mates by their large, \[G\] icon." + to_chat(gangster, message) + 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..2e9ca4dcc0 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm @@ -0,0 +1,417 @@ +/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 = 20 + 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/gangsheild + name = "Tower Shield" + id = "metal" + cost = 45 //High block of melee and even higher for bullets + item_path = /obj/item/shield/riot/tower + +/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) 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 bdca91b0e6..12c29f7d98 100755 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -1,7 +1,3 @@ -/obj/machinery/vending/security - contraband = list(/obj/item/clothing/glasses/sunglasses = 2, /obj/item/storage/fancy/donut_box = 2, /obj/item/ssword_kit = 1) - premium = list(/obj/item/coin/antagtoken = 1, /obj/item/ssword_kit = 1) - /obj/machinery/vending/medical products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, @@ -27,11 +23,11 @@ /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5) - + /obj/machinery/vending/wardrobe/chap_wardrobe premium = list(/obj/item/toy/plush/plushvar = 1, /obj/item/toy/plush/narplush = 1) - + #define STANDARD_CHARGE 1 #define CONTRABAND_CHARGE 2 #define COIN_CHARGE 3 diff --git a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm deleted file mode 100644 index d26cf28778..0000000000 --- a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm +++ /dev/null @@ -1,4 +0,0 @@ -//Overrides TG's PDA sprites with Cit's PDA sprites. Remind me to turn this into a pref somewhere down the line. - -/obj/item/pda - icon = 'modular_citadel/icons/obj/pda.dmi' diff --git a/modular_citadel/code/game/objects/items/devices/flashlight.dm b/modular_citadel/code/game/objects/items/devices/flashlight.dm deleted file mode 100644 index 3a373c9277..0000000000 --- a/modular_citadel/code/game/objects/items/devices/flashlight.dm +++ /dev/null @@ -1,31 +0,0 @@ -/obj/item/flashlight - light_color = "#FFCC66" - flashlight_power = 0.8 - -/obj/item/flashlight/pen - light_color = "#FFDDCC" - flashlight_power = 0.3 - -/obj/item/flashlight/seclite - light_color = "#CDDDFF" - flashlight_power = 0.9 - -/obj/item/flashlight/lamp - light_color = "#FFDDBB" - flashlight_power = 0.8 - -/obj/item/flashlight/flare - light_color = "#FA421A" - flashlight_power = 0.8 - -/obj/item/flashlight/flare/torch - light_color = "#FAA44B" - flashlight_power = 0.8 - -/obj/item/flashlight/lantern - light_color = "#FFAA44" - flashlight_power = 0.75 - -/obj/item/flashlight/slime - light_color = "#FFEEAA" - flashlight_power = 0.6 diff --git a/modular_citadel/code/game/objects/items/holy_weapons.dm b/modular_citadel/code/game/objects/items/holy_weapons.dm index 204a27f3fa..3ecc6cc31b 100644 --- a/modular_citadel/code/game/objects/items/holy_weapons.dm +++ b/modular_citadel/code/game/objects/items/holy_weapons.dm @@ -11,8 +11,8 @@ /obj/item/nullrod/rosary/Initialize() .=..() - if(SSreligion.religion) - deity_name = SSreligion.deity + if(GLOB.religion) + deity_name = GLOB.deity /obj/item/nullrod/rosary/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!istype(M)) 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 e6ba224f8d..6e28a3115f 100644 --- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -119,8 +119,8 @@ /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]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool.") @@ -228,8 +228,8 @@ /obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/toy/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]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") @@ -367,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 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 deb3de589e..918b1dda5a 100644 --- a/modular_citadel/code/modules/admin/chat_commands.dm +++ b/modular_citadel/code/modules/admin/chat_commands.dm @@ -4,7 +4,7 @@ /datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","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/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","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")]" if(prob(10)) saltresult += "@here for your salt, all day every day" diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index 307cdff29f..27f7576e7f 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -14,6 +14,10 @@ var/saved_underwear = ""//saves their underwear so it can be toggled later var/saved_undershirt = "" + var/saved_socks = "" + var/hidden_underwear = FALSE + var/hidden_undershirt = FALSE + var/hidden_socks = FALSE /mob/living/carbon/human/New() ..() @@ -29,6 +33,33 @@ var/list/femcum_fluids = list("femcum") //Mob procs +/mob/living/carbon/human/proc/underwear_toggle() + set name = "Toggle undergarments" + set category = "Object" + if(ishuman(src)) + var/mob/living/carbon/human/humz = src + var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel") + if(confirm == "Top") + humz.hidden_undershirt = !humz.hidden_undershirt + + if(confirm == "Bottom") + humz.hidden_underwear = !humz.hidden_underwear + + if(confirm == "Socks") + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "All") + humz.hidden_undershirt = !humz.hidden_undershirt + humz.hidden_underwear = !humz.hidden_underwear + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "Cancel") + return + src.update_body() + + else + to_chat(src, "Humans only. How the fuck did you get this verb anyway.") + /mob/living/proc/handle_arousal() @@ -40,7 +71,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,14 +95,14 @@ /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() @@ -99,6 +130,8 @@ 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) @@ -112,54 +145,54 @@ 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" @@ -171,11 +204,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.") @@ -196,13 +229,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.") @@ -222,17 +248,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) @@ -260,16 +286,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) @@ -288,9 +314,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) @@ -298,9 +324,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) @@ -309,9 +335,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) @@ -335,14 +361,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 1239a515cd..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() . = ..() @@ -40,6 +39,10 @@ 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) @@ -54,13 +57,11 @@ 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_[lowertext(shape)]_[size]-s" + string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]-s" else color = "#[owner.dna.features["breasts_color"]]" - string = "breasts_[lowertext(shape)]_[size]" + 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() - - icon_state = sanitize_text(string) - 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 d13c2f6a97..63d6834409 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() . = ..() @@ -72,7 +73,7 @@ owner.exposed_genitals += src if("Hidden by clothes") through_clothes = FALSE - hidden = FALSE + hidden = TRUE if(src in owner.exposed_genitals) owner.exposed_genitals -= src if("Always hidden") @@ -133,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"]) @@ -165,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"] @@ -181,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"] @@ -204,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"] @@ -228,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"]]" @@ -280,7 +286,7 @@ 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() @@ -297,6 +303,8 @@ for(var/obj/item/organ/O in H.internal_organs) if(isgenital(O)) var/obj/item/organ/genital/G = O + if(G.hidden) + return //we're gunna just hijack this for updates. if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes genitals_to_add += H.getorganslot(G.slot) //Now we added all genitals that aren't internal and should be rendered @@ -311,6 +319,8 @@ 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) @@ -318,6 +328,7 @@ 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]_[aroused_state]_[layertext]" @@ -331,12 +342,15 @@ 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"]]" 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 e857c0d7ed..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 @@ -109,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 ac812e286d..b6cb8fa4b2 100644 --- a/modular_citadel/code/modules/arousal/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -5,14 +5,13 @@ icon = 'modular_citadel/icons/obj/genitals/penis.dmi' zone = "groin" slot = ORGAN_SLOT_PENIS - w_class = 3 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 @@ -52,15 +51,15 @@ 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() - icon_state = sanitize_text(string) - /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..1e6b4d62d4 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 = FALSE + 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,8 @@ linked_organ = (owner.getorganslot("penis")) if(linked_organ) linked_organ.linked_organ = src + size = linked_organ.size + else if(linked_organ) linked_organ.linked_organ = null @@ -49,6 +54,36 @@ /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() + switch(size) + if(0.1 to 1) + size_name = "average" + if(1.1 to 2) + size_name = "enlarged" + if(2.1 to INFINITY) + size_name = "engorged" + else + size_name = "nonexistant" + + if(!internal) + desc = "You see an [size_name] pair of testicles." + else + desc = "They don't have any testicles you can see." + + if(owner) + 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 b8ef7029b6..8c15aa5437 100644 --- a/modular_citadel/code/modules/arousal/organs/vagina.dm +++ b/modular_citadel/code/modules/arousal/organs/vagina.dm @@ -60,10 +60,9 @@ string = "vagina" if(ishuman(owner)) var/mob/living/carbon/human/H = owner + icon_state = sanitize_text(string) H.update_genitals() - icon_state = sanitize_text(string) - /obj/item/organ/genital/vagina/update_link() if(owner) linked_organ = (owner.getorganslot("womb")) 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..90172bbf43 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -373,4 +373,64 @@ 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") + +/datum/gear/kimono + name = "Kimono" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/kimono + ckeywhitelist = list("sfox63") + +/datum/gear/commjacket + name = "Dusty Commisar's Cloak" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/commjacket + ckeywhitelist = list("sadisticbatter") + +/datum/gear/mw2_russian_para + name = "Russian Paratrooper Jumper" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/mw2_russian_para + ckeywhitelist = list("investigator77") + +/datum/gear/longblackgloves + name = "Luna's Gauntlets" + category = SLOT_GLOVES + path = /obj/item/clothing/gloves/longblackgloves + ckeywhitelist = list("bigmanclancy") + +/datum/gear/trendy_fit + name = "Trendy Fit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/trendy_fit + ckeywhitelist = list("midgetdragon") + +/datum/gear/singery + name = "Yellow Performer Outfit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/singery + ckeywhitelist = list("maxlynchy") + +/datum/gear/csheet + name = "NT Bedsheet" + category = SLOT_NECK + path = /obj/item/bedsheet/captain + ckeywhitelist = list("tikibomb") diff --git a/modular_citadel/code/modules/client/loadout/_medical.dm b/modular_citadel/code/modules/client/loadout/_medical.dm index a0d0e3f2b2..eed1ad32a1 100644 --- a/modular_citadel/code/modules/client/loadout/_medical.dm +++ b/modular_citadel/code/modules/client/loadout/_medical.dm @@ -1,5 +1,32 @@ +/datum/gear/stethoscope + name = "Medical Briefcase" + category = SLOT_HANDS + path = /obj/item/storage/briefcase/medical + restricted_roles = list("Medical Doctor", "Chief Medical Officer") + /datum/gear/stethoscope name = "Stethoscope" category = SLOT_NECK path = /obj/item/clothing/neck/stethoscope restricted_roles = list("Medical Doctor", "Chief Medical Officer") + +/datum/gear/bluescrubs + name = "Blue Scrubs" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/rank/medical/blue + restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") + restricted_desc = "Medical" + +/datum/gear/greenscrubs + name = "Green Scrubs" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/rank/medical/green + restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") + restricted_desc = "Medical" + +/datum/gear/purplescrubs + name = "Purple Scrubs" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/rank/medical/purple + restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") + restricted_desc = "Medical" diff --git a/modular_citadel/code/modules/client/loadout/_service.dm b/modular_citadel/code/modules/client/loadout/_service.dm index 9b508bb93f..062e22f966 100644 --- a/modular_citadel/code/modules/client/loadout/_service.dm +++ b/modular_citadel/code/modules/client/loadout/_service.dm @@ -1,3 +1,9 @@ +/datum/gear/greytidestationwide + name = "Grey jumpsuit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/color/grey + restricted_roles = list("Assistant") + /datum/gear/plushvar name = "Ratvar Plushie" category = SLOT_IN_BACKPACK diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index bd26f44482..2d65f093bb 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -54,6 +54,11 @@ path = /obj/item/clothing/head/flakhelm cost = 2 +/datum/gear/bunnyears + name = "Bunny Ears" + category = SLOT_HEAD + path = /obj/item/clothing/head/rabbitears + //trek fancy Hats! /datum/gear/trekcap name = "Federation Officer's Cap (White)" diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 81e17e95d3..abdf8e3a24 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -73,6 +73,31 @@ 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/stripeddress + name = "Striped Dress" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/stripeddress + /datum/gear/kilt name = "Kilt" category = SLOT_W_UNIFORM @@ -283,3 +308,9 @@ 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") + +//Memes +/datum/gear/gear_harnesses + name = "Gear Harness" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/gear_harness \ No newline at end of file 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/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index b7f7aea0e8..0ce4fbdd78 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -417,7 +417,6 @@ icon_state = "flagcape" item_state = "flagcape" - /obj/item/clothing/shoes/lucky name = "Lucky Jackboots" icon = 'icons/obj/custom.dmi' @@ -454,3 +453,78 @@ 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 + +/obj/item/clothing/suit/kimono + name = "Blue Kimono" + desc = "A traditional kimono, this one is blue with purple flowers." + icon_state = "kimono" + item_state = "kimono" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/suit/commjacket + name = "Dusty Commisar's Cloak" + desc = "An Imperial Commisar's Coat, straight from the frontline of battle, filled with dirt, bulletholes, and dozens of little pockets. Alongside a curious golden eagle sitting on it's left breast, the marking '200th Venoland' is clearly visible on the inner workings of the coat. It certainly holds an imposing flair, however." + icon_state = "commjacket" + item_state = "commjacket" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/mw2_russian_para + name = "Russian Paratrooper Jumper" + desc = "A Russian made old paratrooper jumpsuit, has many pockets for easy storage of gear from a by gone era. As bulky as it looks, its shockingly light!" + icon_state = "mw2_russian_para" + item_state = "mw2_russian_para" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/gloves/longblackgloves + name = "Luna's Gauntlets" + desc = "These gloves seem to have a coating of slime fluid on them, you should possibly return them to their rightful owner." + icon_state = "longblackgloves" + item_state = "longblackgloves" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + +/obj/item/clothing/under/trendy_fit + name = "Trendy Fitting Clothing" + desc = "An outfit straight from the boredom of space, its the type of thing only someone trying to entertain themselves on the way to their next destination would wear." + icon_state = "trendy_fit" + item_state = "trendy_fit" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index a314baa852..aff1739ae4 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -183,6 +183,7 @@ key_third_person = "suddenly hits a dab" message = "suddenly hits a dab!" emote_type = EMOTE_AUDIBLE + restraint_check = TRUE 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 a4532d0820..bf811b777c 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 @@ -191,6 +191,32 @@ icon = 'modular_citadel/icons/mob/mam_ears.dmi' color_src = MATRIXED +/datum/sprite_accessory/ears/human/bigwolf + name = "Big Wolf" + icon_state = "bigwolf" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinner + name = "Big Wolf (ALT)" + icon_state = "bigwolfinner" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfdark + name = "Dark Big Wolf" + icon_state = "bigwolfdark" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinnerdark + name = "Dark Big Wolf (ALT)" + icon_state = "bigwolfinnerdark" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + /datum/sprite_accessory/ears/human/cow name = "Cow" icon_state = "cow" @@ -959,6 +985,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" @@ -1497,6 +1530,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" 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/ipc.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm index bbbe863ec2..25b8daf2cb 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -11,6 +11,7 @@ mutant_bodyparts = list("ipc_screen", "ipc_antenna") default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None") meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc + mutanttongue = /obj/item/organ/tongue/robot/ipc exotic_blood = "oil" @@ -27,9 +28,6 @@ screen.Remove(C) ..() -/datum/species/ipc/get_spans() - return SPAN_ROBOT - /datum/action/innate/monitor_change name = "Screen Change" check_flags = AB_CHECK_CONSCIOUS 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 b4eec5786a..fa6ded8065 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 @@ -69,7 +69,7 @@ /datum/action/innate/slime_change/proc/change_form() var/mob/living/carbon/human/H = owner - var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Cancel") + var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") if(select_alteration == "Hair Style") if(H.gender == MALE) var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list @@ -114,7 +114,7 @@ O.Remove(H) organ.forceMove(get_turf(H)) qdel(organ) - H.update_body() + H.update_genitals() else if (select_alteration == "Ears") var/list/snowflake_ears_list = list("Normal" = null) @@ -194,5 +194,65 @@ if(new_taur != "None") H.dna.features["mam_tail"] = "None" H.update_body() + + else if (select_alteration == "Penis") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list + if(new_shape) + H.dna.features["cock_shape"] = new_shape + H.update_genitals() + H.give_balls() + H.give_penis() + H.apply_overlay() + + + else if (select_alteration == "Vagina") + for(var/obj/item/organ/genital/vagina/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list + if(new_shape) + H.dna.features["vag_shape"] = new_shape + H.update_genitals() + H.give_womb() + H.give_vagina() + H.apply_overlay() + + else if (select_alteration == "Penis Length") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_length + new_length = input(owner, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Genital Alteration") as num|null + if(new_length) + H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) + H.update_genitals() + H.apply_overlay() + H.give_balls() + H.give_penis() + + else if (select_alteration == "Breast Size") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_size + new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in GLOB.breasts_size_list + if(new_size) + H.dna.features["breasts_size"] = new_size + H.update_genitals() + H.apply_overlay() + H.give_breasts() + + else if (select_alteration == "Breast Shape") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Breast Shape", "Genital Alteration") as null|anything in GLOB.breasts_shapes_list + if(new_shape) + H.dna.features["breasts_shape"] = new_shape + H.update_genitals() + H.apply_overlay() + H.give_breasts() + else return 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/silicon/robot/robot_movement.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm index 598690590c..c7a2447be6 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -4,20 +4,24 @@ /mob/living/silicon/robot/Move(NewLoc, direct) . = ..() if(. && sprinting && !(movement_type & FLYING) && canmove && !resting) - if(istype(cell)) - cell.charge -= 25 + if(!(cell?.use(25))) + togglesprint(TRUE) /mob/living/silicon/robot/movement_delay() . = ..() if(!resting && !sprinting) . += 1 -/mob/living/silicon/robot/proc/togglesprint() //Basically a copypaste of the proc from /mob/living/carbon/human - sprinting = !sprinting +/mob/living/silicon/robot/proc/togglesprint(shutdown = FALSE) //Basically a copypaste of the proc from /mob/living/carbon/human + if(!shutdown && (!cell || cell.charge < 25)) + return FALSE + sprinting = shutdown ? FALSE : !sprinting if(!resting && canmove) if(sprinting) playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE) else + if(shutdown) + playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE) playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE) if(hud_used && hud_used.static_inventory) for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory) 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 2bfd63a25d..78e18fdb5e 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 @@ -41,6 +41,10 @@ devourable = TRUE digestable = TRUE +/mob/living/simple_animal/kiwi + devourable = TRUE + digestable = TRUE + //STATION PETS /mob/living/simple_animal/pet devourable = TRUE @@ -65,7 +69,6 @@ /mob/living/simple_animal/sloth devourable = TRUE digestable = TRUE - feeding = TRUE /mob/living/simple_animal/parrot devourable = TRUE @@ -84,57 +87,48 @@ /mob/living/simple_animal/hostile/lizard devourable = TRUE digestable = TRUE + feeding = TRUE + vore_active = TRUE + isPredator = TRUE + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/alien - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/bear - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/poison/giant_spider - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE + isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/retaliate/poison/snake - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/gorilla - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/asteroid/goliath - devourable = TRUE - digestable = TRUE - feeding = TRUE + feeding = TRUE //for pet Goliaths I guess or something. vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/carp - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE 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_energy.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm index 8af0dc2013..8d08937f55 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm @@ -9,7 +9,7 @@ icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "mag-casing-live" projectile_type = /obj/item/projectile/bullet/magrifle - energy_cost = 300 + 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." @@ -17,7 +17,7 @@ icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "mag-casing-live" projectile_type = /obj/item/projectile/bullet/nlmagrifle - energy_cost = 300 + energy_cost = 200 /obj/item/ammo_casing/caseless/mag_e/amags desc = "A ferromagnetic slug intended to be launched out of a compatible weapon." @@ -25,7 +25,7 @@ icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "mag-casing-live" projectile_type = /obj/item/projectile/bullet/mags - energy_cost = 200 + energy_cost = 125 /obj/item/ammo_casing/caseless/mag_e/anlmags desc = "A specialized ferromagnetic slug designed with a less-than-lethal payload." @@ -33,7 +33,7 @@ icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "mag-casing-live" projectile_type = /obj/item/projectile/bullet/nlmags - energy_cost = 200 + energy_cost = 125 ///magazines/// @@ -53,14 +53,13 @@ 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 = 15 + max_ammo = 16 multiple_sprites = 2 /obj/item/ammo_box/magazine/mmag_e/small/lethal @@ -68,6 +67,7 @@ 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/// @@ -218,7 +218,6 @@ pin = null spawnwithmagazine = FALSE - ///magpistol/// /obj/item/gun/ballistic/automatic/pistol/mag_e @@ -278,7 +277,6 @@ if(!dead_cell) cell.give(cell.maxcharge) - /obj/item/gun/ballistic/automatic/pistol/mag_e/update_icon() ..() if(magazine) @@ -288,7 +286,6 @@ 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/reagents/chemistry/reagents/other_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm index 0f71a71add..00063c22d4 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -17,13 +17,13 @@ M.adjustStaminaLoss(-5*REM) . = ..() -/datum/reagent/syndicateadrenals/on_mob_add(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 0.5 to_chat(M, "You feel an intense surge of energy rushing through your veins.") -/datum/reagent/syndicateadrenals/on_mob_delete(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 2 diff --git a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm index a58a7fc825..4b7972d0a7 100755 --- a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm @@ -16,6 +16,7 @@ "purple hypovial" = "hypovial-p", "black hypovial" = "hypovial-t" ) + always_reskinnable = TRUE /obj/item/reagent_containers/glass/bottle/vial/Initialize() . = ..() @@ -29,17 +30,6 @@ /obj/item/reagent_containers/glass/bottle/vial/on_reagent_change() update_icon() -/obj/item/reagent_containers/glass/bottle/vial/reskin_obj(mob/M) //Makes the vials completely reskinnable, and renames them - overrides /obj/proc/reskin_obj - if(!LAZYLEN(unique_reskin)) - return - var/choice = input(M,"Do you wish to recolour your [src]?","Vial Recolour") as null|anything in unique_reskin - if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src)) - if(!unique_reskin[choice]) - return - icon_state = unique_reskin[choice] - name = choice - to_chat(M, "[src] is now skinned as '[choice].'") - /obj/item/reagent_containers/glass/bottle/vial/update_icon() cut_overlays() if(reagents.total_volume) diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm index 061f941043..ee8268128a 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 && !M.has_trait(TRAIT_CROCRIN_IMMUNE)) + 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 && !M.has_trait(TRAIT_CROCRIN_IMMUNE)) + 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,12 +151,10 @@ ..() /datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) - if(M && M.canbearoused && !M.has_trait(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 - to_chat(H, "Your libido is going haywire!") - H.mob_climax(forced_climax=TRUE) + if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE) && prob(33)) + if(prob(5) && M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) + if(prob(5)) //Less spam + to_chat(M, "Your libido is going haywire!") if(M.min_arousal < 50) M.min_arousal += 1 if(M.min_arousal < M.max_arousal) 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/research/techweb/all_nodes.dm b/modular_citadel/code/modules/research/techweb/all_nodes.dm index e561b106d8..c0ddaceaf7 100644 --- a/modular_citadel/code/modules/research/techweb/all_nodes.dm +++ b/modular_citadel/code/modules/research/techweb/all_nodes.dm @@ -19,7 +19,7 @@ display_name = "Games and Toys" description = "For the slackers on the station." prereq_ids = list("comptech") - design_ids = list("arcade_battle", "arcade_orion", "slotmachine", "autoylathe") + design_ids = list("arcade_battle", "arcade_orion", "arcade_minesweeper", "slotmachine", "autoylathe") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) export_price = 5000 diff --git a/modular_citadel/code/modules/uplink/uplink_items.dm b/modular_citadel/code/modules/uplink/uplink_items.dm deleted file mode 100644 index df076c3994..0000000000 --- a/modular_citadel/code/modules/uplink/uplink_items.dm +++ /dev/null @@ -1,18 +0,0 @@ -/* -// PUT ALL YOUR NEW UPLINK STUFF HERE, OVERRIDES GO IN HERE TOO -*/ - -/datum/uplink_item/device_tools/emagrecharge - name = "Electromagnet Charging Device" - desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." - item = /obj/item/emagrecharge - cost = 2 - -/datum/uplink_item/dangerous/revolver - item = /obj/item/gun/ballistic/revolver/syndie - -/datum/uplink_item/dangerous/phantomthief - name = "Syndicate Mask" - desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" - item = /obj/item/clothing/glasses/phantomthief/syndicate - cost = 2 diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm index 542241e9f2..6b6a3d30cc 100644 --- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm +++ b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm @@ -49,13 +49,16 @@ var/sound/pred_death = sound(get_sfx("death_pred")) var/turf/source = get_turf(owner) - ///////////////////////////// DM_HOLD ///////////////////////////// if(digest_mode == DM_HOLD) return SSBELLIES_PROCESSED //////////////////////////// DM_DIGEST //////////////////////////// else if(digest_mode == DM_DIGEST) + if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //obvious. + digest_mode = DM_NOISY + return + for (var/mob/living/M in contents) if(prob(25)) if((world.time - NORMIE_HEARCHECK) > last_hearcheck) @@ -210,6 +213,10 @@ //////////////////////////DM_DRAGON ///////////////////////////////////// //because dragons need snowflake guts if(digest_mode == DM_DRAGON) + if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //imagine var editing this when you're a pacifist. smh + digest_mode = DM_NOISY + return + for (var/mob/living/M in contents) if(prob(55)) //if you're hearing this, you're a vore ho anyway. if((world.time - NORMIE_HEARCHECK) > last_hearcheck) 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 deleted file mode 100644 index ed3286615b..0000000000 Binary files a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi and /dev/null differ diff --git a/modular_citadel/icons/mob/mam_ears.dmi b/modular_citadel/icons/mob/mam_ears.dmi index f2a788d900..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 ceecf12d2e..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_taur.dmi b/modular_citadel/icons/mob/mam_taur.dmi index 3d0d4a0e84..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 316d1d1af8..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 1ed73d2709..1e12d2bf1a 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 e1284679b3..e321f8ae47 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 c19fb01161..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 9513f82c9c..5ff291f400 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/clothing/trek_item_icon.dmi b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi index 86afe16b03..ed3286615b 100644 Binary files a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi and b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts.dmi b/modular_citadel/icons/obj/genitals/breasts.dmi index e864d09a70..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 b0dc1d7aef..c4b75b1172 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 5ea37a722d..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 2457759b73..434f171e22 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..33659cf13c 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 00891888a4..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 c22c12ded3..c4cf891eac 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..cc04fbcb14 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/pda.dmi b/modular_citadel/icons/obj/pda.dmi deleted file mode 100644 index 5404b908c6..0000000000 Binary files a/modular_citadel/icons/obj/pda.dmi and /dev/null differ diff --git a/sound/arcade/minesweeper_boardpress.ogg b/sound/arcade/minesweeper_boardpress.ogg new file mode 100644 index 0000000000..a928a7498d Binary files /dev/null and b/sound/arcade/minesweeper_boardpress.ogg differ diff --git a/sound/arcade/minesweeper_emag1.ogg b/sound/arcade/minesweeper_emag1.ogg new file mode 100644 index 0000000000..4601f8df89 Binary files /dev/null and b/sound/arcade/minesweeper_emag1.ogg differ diff --git a/sound/arcade/minesweeper_emag2.ogg b/sound/arcade/minesweeper_emag2.ogg new file mode 100644 index 0000000000..84cb5c2e25 Binary files /dev/null and b/sound/arcade/minesweeper_emag2.ogg differ diff --git a/sound/arcade/minesweeper_explosion1.ogg b/sound/arcade/minesweeper_explosion1.ogg new file mode 100644 index 0000000000..f8272722fd Binary files /dev/null and b/sound/arcade/minesweeper_explosion1.ogg differ diff --git a/sound/arcade/minesweeper_explosion2.ogg b/sound/arcade/minesweeper_explosion2.ogg new file mode 100644 index 0000000000..aabd43851d Binary files /dev/null and b/sound/arcade/minesweeper_explosion2.ogg differ diff --git a/sound/arcade/minesweeper_explosion3.ogg b/sound/arcade/minesweeper_explosion3.ogg new file mode 100644 index 0000000000..22aa309d9d Binary files /dev/null and b/sound/arcade/minesweeper_explosion3.ogg differ diff --git a/sound/arcade/minesweeper_menuselect.ogg b/sound/arcade/minesweeper_menuselect.ogg new file mode 100644 index 0000000000..b9e0b765dc Binary files /dev/null and b/sound/arcade/minesweeper_menuselect.ogg differ diff --git a/sound/arcade/minesweeper_startup.ogg b/sound/arcade/minesweeper_startup.ogg new file mode 100644 index 0000000000..c51d473d60 Binary files /dev/null and b/sound/arcade/minesweeper_startup.ogg differ diff --git a/sound/arcade/minesweeper_win.ogg b/sound/arcade/minesweeper_win.ogg new file mode 100644 index 0000000000..214f1925b0 Binary files /dev/null and b/sound/arcade/minesweeper_win.ogg differ diff --git a/sound/arcade/minesweeper_winfail.ogg b/sound/arcade/minesweeper_winfail.ogg new file mode 100644 index 0000000000..878f153063 Binary files /dev/null and b/sound/arcade/minesweeper_winfail.ogg 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/effects/gong.ogg b/sound/effects/gong.ogg new file mode 100644 index 0000000000..4d12f5d0d2 Binary files /dev/null and b/sound/effects/gong.ogg differ diff --git a/sound/magic/RATTLEMEBONES.ogg b/sound/magic/RATTLEMEBONES.ogg new file mode 100644 index 0000000000..d42cf51253 Binary files /dev/null and b/sound/magic/RATTLEMEBONES.ogg differ diff --git a/sound/magic/RATTLEMEBONES2.ogg b/sound/magic/RATTLEMEBONES2.ogg new file mode 100644 index 0000000000..7265a06aab Binary files /dev/null and b/sound/magic/RATTLEMEBONES2.ogg differ diff --git a/sound/vehicles/rocketlaunch.ogg b/sound/vehicles/rocketlaunch.ogg new file mode 100644 index 0000000000..d0ee9c7248 Binary files /dev/null and b/sound/vehicles/rocketlaunch.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/sound/weapons/whipgrab.ogg b/sound/weapons/whipgrab.ogg new file mode 100644 index 0000000000..3b17632056 Binary files /dev/null and b/sound/weapons/whipgrab.ogg differ diff --git a/strings/canadian_replacement.json b/strings/canadian_replacement.json new file mode 100644 index 0000000000..1430ae8793 --- /dev/null +++ b/strings/canadian_replacement.json @@ -0,0 +1,45 @@ +{ + + "canadian": { + "toilet": "washroom", + "bathroom": "washroom", + "restroom": "washroom", + "coffee": "doubledouble", + "backpack": "knapsack", + "rucksack": "knapsack", + "candybar": "chocolate bar", + "about": "aboot", + "friend": "buddy", + "pal": "buddy", + "donut": "doughnut", + "faucet": "tap", + "give": "give'r", + "bar": "boozecan", + "leave": "leave'r", + "scruffle": "kerfuffle", + "couch": "chesterfield", + "sofa": "chesterfield", + "alcohol": "mickey", + "shoes": "runners", + "cigarrete": "dart", + "cig": "dart", + "color": "colour", + "armor": "armour", + "armory": "armoury", + "defense": "defence", + "honor": "honour", + "labor": "labour", + "humor": "humour", + "humorous": "humourous", + "gray": "grey", + "labeled": "labelled", + "luster": "lustre", + "inch": "centimetre", + "yard": "metre", + "tumor": "tumour", + "mile": "kilometre", + "pound": "kilogram" + } + + +} diff --git a/strings/cas_black.txt b/strings/cas_black.txt index b63e33cdf2..734222d1fd 100644 --- a/strings/cas_black.txt +++ b/strings/cas_black.txt @@ -1,13 +1,13 @@ Today, Security killed ____. Security, the clown's breaking into ____. -The Chaplain is worshiping the Church of _____. +Our last Chaplain believed in nothing but _____. What angered the gods this time? Why didn't engineering set up the singularity? What does the traitor steal this time? Cargo: There's a galaxy-wide shortage of _______. I don't care what they called me back on the station, I'm not a traitor. I'm a man of _________. The Syndicate is offering crew members _________ to defect. -Cargo ordered a crate full of _____. +What is Nanotrasen's highest-priority bounty? What is the gray tide protesting this time? If the Space Gods didn't want _________ they wouldn't have given us __________. Why was the death squad sent in? @@ -30,11 +30,10 @@ What made the nuclear operatives fluke? Why did the Chief Engineer disable comms? Every spaceman receives an internals box and ________. What brought the space orgy to a grinding halt? -Scientists are no longer allowed to make _____. +Scientists are no longer allowed to make ______. What was the clown's best joke? The HoP is now hiring assistants for __________. What happens when you emag an emag? -Our gang doesn't wear uniforms. Our gang wears ___________. No matter how many lizards you have, _____ is never acceptable. No, the AI's second law is NOT to serve _____. First CentCom came for the ________. Now they're coming for the __________. @@ -109,5 +108,12 @@ The auxiliary base was disabled after landing in the middle of _______. Xenobiologists have found slimes to be exceptionally responsive to _______. Why did the captain give me a medal? The curator's new exhibit is devoted solely to _________. -There's no ______ on the new escape shuttle, but there is plenty of _________! -What made me sell my soul to the devil? \ No newline at end of file +What made me sell my soul to the devil? +The engineers are testing an experimental supermatter setup involving _________. +I'm __________ in the streets, __________ in the sheets. +What's my family heirloom? +The Lawyer was fired for messaging the entire station a picture of ___________. +On Lavaland, it is rumored that ashwalkers roam, worshipping _________. +How did the traitor die a glorious death? +Nanotrasen's new state-of-the-art emergency shuttle was repurposed from _________ and _________. +What caused my brain trauma? \ No newline at end of file diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 8cf224d1db..3e229862a2 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -2,6 +2,7 @@ Those motherfucking carp. Having sex in the maintenance tunnels. Space 'Nam. Space lesbians. +Space NEETs. Space Hitler. Space Asshole. Ragin' mages. @@ -57,7 +58,6 @@ Defusing a syndicate bomb with another bomb. Going braindead mid-murder. A petsplosion. Meat spikes. -Collecting the crew's brains. Lopping off the Captain's johnson and shooting it out a pneumatic cannon. The secret monkey technique. Putting the pAI's doorjack where it don't belong. @@ -84,7 +84,6 @@ Paranoia. Putting the boots to him, medium style. ERP-seeking meteors. Paperwork HoPs. -A sexy clown. Rampant vending machines. The prisoner transfer center. Nations. @@ -186,7 +185,6 @@ A big, black shadowling dick. Emagging. Dead lizard storage. Dermal armor. -Energy balls. Fisting somebody until they gib. Alternate uses for defibrillator paddles. Breaking spacetime with thousands of bluespace tomatoes. @@ -197,7 +195,7 @@ Plasmaman strippers. A Quartermaster who WON'T STOP ordering guns. Space lag. Polishing the captain's laser rifle. -That one asshole double agent. +That one asshole nuke op. A surprise visit from Nanotrasen's CEO. The bleeding, dismembered, beautiful corpse of the clown. A glass of ...what? @@ -220,20 +218,18 @@ Welderbombing. Validhunting. Nar'Sie making love to Lord Singulo. Fun. -Crashing the stock market. HONK! -Enough morphine to put the entire station down. +Enough morphine to make the entire station comatose. A defective comdom. Cleanbot. A beaker of dried space carp penis. An Ian storm. -voxtest2. Nuking it from orbit. My senpAI. Harmbatonning. A Nanotrasen D-Notice. TALKING MIMES. -The lusty xenomorph maid, +The lusty xenomorph maid. Using assistants as human shields. Sentient securitrons. Piloting the station into the nearest sun. @@ -247,11 +243,11 @@ Medbay stutterwhores. The scrubbers uncontrollably spewing cum. The lawyer's job. Emoting slowly drawing a gun, then slowly cocking the trigger, then slowly preparing to shoot... -NAR-SIE HAS RISEN. +NAR'SIE HAS RISEN. Pierrot's Throat. A clown bomb. Space bees? -The entire engineering team having unprotected group sex. +Driving the clown car full speed into the engine. IC in OOC. The best cookie. The wizard with his staff inserted into his anus. @@ -276,9 +272,8 @@ Draconic. Riding borgs, cowgirl style. The Voice of God. Overpowered stuns. -Unironically reading library smut. +Unironically enjoying library smut. Spiritual journeys with BZ. -Freon. Deep-fried body parts. Suit sensor unit gas chambers. Moonlighting. @@ -294,4 +289,14 @@ Mindswap. Potassium in the toilet bowls. Giving head to the heads. A lizard wearing cat ears. -DOOR STUCK!! +Precious clown gold. +Dabbing on a pile of corpses. +Tactical chairs. +The sweet, forbidden meat of the gondola. +Turning tricks for holocredits. +A captain that doesn't secure the disk. +A positive moodlet. +A sexy clown. +Razoring the wings off the moths. +Wiring the ethereals into the powernet. +Well-aged miasma. \ No newline at end of file diff --git a/strings/redpill.json b/strings/redpill.json new file mode 100644 index 0000000000..3f65db73e7 --- /dev/null +++ b/strings/redpill.json @@ -0,0 +1,43 @@ +{ + "redpill_questions": [ + "What happened to the ceiling?", + "Why is it called the emergency shuttle if it arrives every single shift?", + "Where does the Cook get all this meat from?", + "Space wind? How does that even make sense?", + "Why does Nanotrasen hire Clowns and Mimes for every single station?", + "Why is the station's air supply connected to the plasma tank?", + "Why are there fire alarms everywhere but no sprinklers?", + "Why is this a plasma research station if we know everything about plasma already?", + "Who hires all these unqualified, violent assistants?", + "How do the morgue trays know whether someone's soul is still in their body?", + "If two miners were in Lavaland and one of them killed the other with a pickaxe, wouldn't that be fucked up or what?", + "How do I know the names of all these people that I've never met before?", + "How do I know the name of someone just by hearing them talk?", + "How come a hole in the floor doesn't suck you out into space?", + "Why is space cold?", + "Why does space circle around on itself?", + "Nanotrasen just clones us every shift.", + "There's no biological difference between lizards and humans.", + "Why is there a floor, but no roof?", + "The universe always ends after we reach Centcomm.", + "Everyone is controlled by strings behind a glowing screen", + "Seperation is absolute.", + "It doesn't take much for people to murder their friends.", + "All the crew are just greytiders with different paint.", + "What the fuck is CO2?", + "2008 was 550 years ago.", + "This is all an endless looping nightmare of misery.", + "The ultimate god is really really stoned.", + "Space stations are no substitute for healthy social interaction.", + "The gods are always watching, and will wipe you from existence if you fuck up.", + "How do mirrors give people haircuts?", + "Why is this station so poorly designed?", + "How can an escape pod only take two people normally, but an infinite number of people if they're lying down?", + "Why do only lizards get their own native language?", + "Why do people just randomly murder all their friends some shifts?", + "If magic is real, why aren't we researching that?", + "How is everyone a complete expert in every threat in the universe?", + "If suit sensors are so important, why don't they always start maximized?", + "If we can wash clothes in a sink, why do we need washing machines?" + ] +} diff --git a/strings/traumas.json b/strings/traumas.json index f83a023491..45e31f2367 100644 --- a/strings/traumas.json +++ b/strings/traumas.json @@ -132,7 +132,9 @@ "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!!" + "@pick(semicolon) LIZZARRD SPEAKIGN IN EVIL BULL LANGUAGE SCI!!", + "@pick(semicolon)POST REBOOT MESSAGE LOLOL FUCK FUCK FUCK YOU", + "@pick(semicolon)so, i was trying to talk to someone on rp today, and then a mime walks up and pies them in the face along with some other prankster--i thought that mimes and clowns are supposed to be hired to entertain not to be a nuisance, and that if entertainment comes at someone elses expense then it's not supposed to be done. is that enough to like submit a player complaint or some shit or am i just being petty?" ], "mutations": [ @@ -295,4 +297,4 @@ "bluh daymon", "wizzerd" ] -} \ No newline at end of file +} diff --git a/tgstation.dme b/tgstation.dme index ec265f1aea..3e493d7135 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -130,6 +130,7 @@ #include "code\__HELPERS\qdel.dm" #include "code\__HELPERS\radiation.dm" #include "code\__HELPERS\radio.dm" +#include "code\__HELPERS\reagents.dm" #include "code\__HELPERS\roundend.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" @@ -199,6 +200,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" @@ -242,11 +244,11 @@ #include "code\controllers\subsystem\machines.dm" #include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\medals.dm" +#include "code\controllers\subsystem\minor_mapping.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" -#include "code\controllers\subsystem\orbit.dm" #include "code\controllers\subsystem\overlays.dm" #include "code\controllers\subsystem\pai.dm" #include "code\controllers\subsystem\parallax.dm" @@ -255,12 +257,10 @@ #include "code\controllers\subsystem\ping.dm" #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" -#include "code\controllers\subsystem\religion.dm" #include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" #include "code\controllers\subsystem\spacedrift.dm" -#include "code\controllers\subsystem\squeak.dm" #include "code\controllers\subsystem\stickyban.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\tgui.dm" @@ -336,6 +336,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\armor_plate.dm" +#include "code\datums\components\bouncy.dm" #include "code\datums\components\butchering.dm" #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" @@ -359,6 +360,7 @@ #include "code\datums\components\mood.dm" #include "code\datums\components\nanites.dm" #include "code\datums\components\ntnet_interface.dm" +#include "code\datums\components\orbiter.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\rad_insulation.dm" #include "code\datums\components\radioactive.dm" @@ -380,6 +382,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" @@ -442,8 +445,8 @@ #include "code\datums\helper_datums\icon_snapshot.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" +#include "code\datums\looping_sounds\_looping_sound.dm" #include "code\datums\looping_sounds\item_sounds.dm" -#include "code\datums\looping_sounds\looping_sound.dm" #include "code\datums\looping_sounds\machinery_sounds.dm" #include "code\datums\looping_sounds\weather.dm" #include "code\datums\martial\boxing.dm" @@ -492,6 +495,7 @@ #include "code\datums\wires\autolathe.dm" #include "code\datums\wires\emitter.dm" #include "code\datums\wires\explosive.dm" +#include "code\datums\wires\microwave.dm" #include "code\datums\wires\mulebot.dm" #include "code\datums\wires\particle_accelerator.dm" #include "code\datums\wires\r_n_d.dm" @@ -636,6 +640,10 @@ #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\telecrystalconsoles.dm" #include "code\game\machinery\computer\teleporter.dm" +#include "code\game\machinery\computer\arcade\battle.dm" +#include "code\game\machinery\computer\arcade\minesweeper.dm" +#include "code\game\machinery\computer\arcade\misc_arcade.dm" +#include "code\game\machinery\computer\arcade\orion_trail.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_electronics.dm" #include "code\game\machinery\doors\airlock_types.dm" @@ -834,12 +842,14 @@ #include "code\game\objects\items\devices\beacon.dm" #include "code\game\objects\items\devices\camera_bug.dm" #include "code\game\objects\items\devices\chameleonproj.dm" +#include "code\game\objects\items\devices\compressionkit.dm" #include "code\game\objects\items\devices\dogborg_sleeper.dm" #include "code\game\objects\items\devices\doorCharge.dm" #include "code\game\objects\items\devices\electroadaptive_pseudocircuit.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\forcefieldprojector.dm" #include "code\game\objects\items\devices\geiger_counter.dm" +#include "code\game\objects\items\devices\glue.dm" #include "code\game\objects\items\devices\gps.dm" #include "code\game\objects\items\devices\instruments.dm" #include "code\game\objects\items\devices\laserpointer.dm" @@ -1226,13 +1236,14 @@ #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_scripts.dm" #include "code\modules\antagonists\clockcult\clock_structures\_trap_object.dm" #include "code\modules\antagonists\clockcult\clock_structures\ark_of_the_clockwork_justicar.dm" -#include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm" #include "code\modules\antagonists\clockcult\clock_structures\clockwork_obelisk.dm" #include "code\modules\antagonists\clockcult\clock_structures\eminence_spire.dm" #include "code\modules\antagonists\clockcult\clock_structures\heralds_beacon.dm" #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\reflector.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" @@ -1495,6 +1506,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" @@ -1622,6 +1634,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" @@ -1650,6 +1663,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" @@ -1706,6 +1720,7 @@ #include "code\modules\hydroponics\grown\mushrooms.dm" #include "code\modules\hydroponics\grown\nettle.dm" #include "code\modules\hydroponics\grown\onion.dm" +#include "code\modules\hydroponics\grown\peanuts.dm" #include "code\modules\hydroponics\grown\pineapple.dm" #include "code\modules\hydroponics\grown\potato.dm" #include "code\modules\hydroponics\grown\pumpkin.dm" @@ -2078,6 +2093,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" @@ -2094,6 +2110,7 @@ #include "code\modules\mob\living\simple_animal\friendly\gondola.dm" #include "code\modules\mob\living\simple_animal\friendly\lizard.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" +#include "code\modules\mob\living\simple_animal\friendly\panda.dm" #include "code\modules\mob\living\simple_animal\friendly\penguin.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" #include "code\modules\mob\living\simple_animal\friendly\sloth.dm" @@ -2255,7 +2272,6 @@ #include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\relays.dm" #include "code\modules\NTNet\services\_service.dm" -#include "code\modules\orbit\orbit.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\filingcabinet.dm" @@ -2471,6 +2487,7 @@ #include "code\modules\reagents\chemistry\recipes\others.dm" #include "code\modules\reagents\chemistry\recipes\pyrotechnics.dm" #include "code\modules\reagents\chemistry\recipes\slime_extracts.dm" +#include "code\modules\reagents\chemistry\recipes\special.dm" #include "code\modules\reagents\chemistry\recipes\toxins.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" @@ -2501,15 +2518,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" @@ -2521,6 +2535,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" @@ -2646,6 +2678,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" @@ -2748,6 +2781,7 @@ #include "code\modules\vehicles\speedbike.dm" #include "code\modules\vehicles\vehicle_actions.dm" #include "code\modules\vehicles\vehicle_key.dm" +#include "code\modules\vehicles\wheelchair.dm" #include "code\modules\vehicles\cars\car.dm" #include "code\modules\vehicles\cars\clowncar.dm" #include "code\modules\vending\_vending.dm" @@ -2799,7 +2833,6 @@ #include "modular_citadel\code\controllers\configuration\entries\general.dm" #include "modular_citadel\code\controllers\subsystem\job.dm" #include "modular_citadel\code\controllers\subsystem\shuttle.dm" -#include "modular_citadel\code\datums\uplink_items_cit.dm" #include "modular_citadel\code\datums\components\material_container.dm" #include "modular_citadel\code\datums\components\phantomthief.dm" #include "modular_citadel\code\datums\components\souldeath.dm" @@ -2812,6 +2845,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" @@ -2843,8 +2887,6 @@ #include "modular_citadel\code\game\objects\items\vending_items.dm" #include "modular_citadel\code\game\objects\items\circuitboards\machine_circuitboards.dm" #include "modular_citadel\code\game\objects\items\devices\aicard.dm" -#include "modular_citadel\code\game\objects\items\devices\flashlight.dm" -#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" #include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" @@ -2991,7 +3033,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" @@ -3000,7 +3041,6 @@ #include "modular_citadel\code\modules\research\techweb\_techweb.dm" #include "modular_citadel\code\modules\research\techweb\all_nodes.dm" #include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm" -#include "modular_citadel\code\modules\uplink\uplink_items.dm" #include "modular_citadel\code\modules\vehicles\secway.dm" #include "modular_citadel\code\modules\vore\hook-defs_vr.dm" #include "modular_citadel\code\modules\vore\persistence.dm" diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 2eef691676..e073e5ffe2 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -9,13 +9,13 @@ name:"css",extend:function(t,e,n){if(n.css){var a=Up++,r=n.noCssTransform?n.css: return t.replace(/-([a-zA-Z])/g,function(t,e){return e.toUpperCase()})};Xi?(uf={},cf=co("div").style,pf=function(t){var e,n,a;if(t=mf(t),!uf[t])if(void 0!==cf[t])uf[t]=t;else for(a=t.charAt(0).toUpperCase()+t.substring(1),e=ro.length;e--;)if(n=ro[e],void 0!==cf[n+a]){uf[t]=n+a;break}return uf[t]}):pf=null;var gf,vf,bf=pf;Xi?(vf=window.getComputedStyle||Po.getComputedStyle,gf=function(t){var e,n,a,r,o;if(e=vf(this.node),"string"==typeof t)return o=e[bf(t)],"0px"===o&&(o=0),o;if(!i(t))throw Error("Transition$getStyle must be passed a string, or an array of strings representing CSS properties");for(n={},a=t.length;a--;)r=t[a],o=e[bf(r)],"0px"===o&&(o=0),n[r]=o;return n}):gf=null;var yf=gf,_f=function(t,e){var n;if("string"==typeof t)this.node.style[bf(t)]=e;else for(n in t)t.hasOwnProperty(n)&&(this.node.style[bf(n)]=t[n]);return this},xf=function(t){var e;this.duration=t.duration,this.step=t.step,this.complete=t.complete,"string"==typeof t.easing?(e=t.root.easing[t.easing],e||(g(Io(t.easing,"easing")),e=qa)):e="function"==typeof t.easing?t.easing:qa,this.easing=e,this.start=ns(),this.end=this.start+this.duration,this.running=!0,xs.add(this)};xf.prototype={tick:function(t){var e,n;return this.running?t>this.end?(this.step&&this.step(1),this.complete&&this.complete(1),!1):(e=t-this.start,n=this.easing(e/this.duration),this.step&&this.step(n),!0):!1},stop:function(){this.abort&&this.abort(),this.running=!1}};var wf,kf,Sf,Ef,Cf,Pf,Af,Of,Tf=xf,Rf=RegExp("^-(?:"+ro.join("|")+")-"),Mf=function(t){return t.replace(Rf,"")},Lf=RegExp("^(?:"+ro.join("|")+")([A-Z])"),jf=function(t){var e;return t?(Lf.test(t)&&(t="-"+t),e=t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})):""},Df={},Nf={};Xi?(kf=co("div").style,function(){void 0!==kf.transition?(Sf="transition",Ef="transitionend",Cf=!0):void 0!==kf.webkitTransition?(Sf="webkitTransition",Ef="webkitTransitionEnd",Cf=!0):Cf=!1}(),Sf&&(Pf=Sf+"Duration",Af=Sf+"Property",Of=Sf+"TimingFunction"),wf=function(t,e,n,a,r){setTimeout(function(){var i,o,s,p,u;p=function(){o&&s&&(t.root.fire(t.name+":end",t.node,t.isIntro),r())},i=(t.node.namespaceURI||"")+t.node.tagName,t.node.style[Af]=a.map(bf).map(jf).join(","),t.node.style[Of]=jf(n.easing||"linear"),t.node.style[Pf]=n.duration/1e3+"s",u=function(e){var n;n=a.indexOf(mf(Mf(e.propertyName))),-1!==n&&a.splice(n,1),a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},t.node.addEventListener(Ef,u,!1),setTimeout(function(){for(var r,c,l,d,f,h=a.length,g=[];h--;)d=a[h],r=i+d,Cf&&!Nf[r]&&(t.node.style[bf(d)]=e[d],Df[r]||(c=t.getStyle(d),Df[r]=t.getStyle(d)!=e[d],Nf[r]=!Df[r],Nf[r]&&(t.node.style[bf(d)]=c))),(!Cf||Nf[r])&&(void 0===c&&(c=t.getStyle(d)),l=a.indexOf(d),-1===l?m("Something very strange happened with transitions. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!",{node:t.node}):a.splice(l,1),f=/[^\d]*$/.exec(e[d])[0],g.push({name:bf(d),interpolator:qo(parseFloat(c),parseFloat(e[d])),suffix:f}));g.length?new Tf({root:t.root,duration:n.duration,easing:mf(n.easing||""),step:function(e){var n,a;for(a=g.length;a--;)n=g[a],t.node.style[n.name]=n.interpolator(e)+n.suffix},complete:function(){o=!0,p()}}):o=!0,a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},0)},n.delay||0)}):wf=null;var Ff,If,Bf,qf,Uf,Vf=wf;if("undefined"!=typeof document){if(Ff="hidden",Uf={},Ff in document)Bf="";else for(qf=ro.length;qf--;)If=ro[qf],Ff=If+"Hidden",Ff in document&&(Bf=If);void 0!==Bf?(document.addEventListener(Bf+"visibilitychange",Ua),Ua()):("onfocusout"in document?(document.addEventListener("focusout",Va),document.addEventListener("focusin",Ga)):(window.addEventListener("pagehide",Va),window.addEventListener("blur",Va),window.addEventListener("pageshow",Ga),window.addEventListener("focus",Ga)),Uf.hidden=!1)}var Gf,zf,Wf,Hf=Uf;Xi?(zf=window.getComputedStyle||Po.getComputedStyle,Gf=function(t,e,n){var a,r=this;if(4===arguments.length)throw Error("t.animateStyle() returns a promise - use .then() instead of passing a callback");if(Hf.hidden)return this.setStyle(t,e),Wf||(Wf=us.resolve());"string"==typeof t?(a={},a[t]=e):(a=t,n=e),n||(g('The "%s" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340',this.name),n=this);var i=new us(function(t){var e,i,o,s,p,u,c;if(!n.duration)return r.setStyle(a),void t();for(e=Object.keys(a),i=[],o=zf(r.node),p={},u=e.length;u--;)c=e[u],s=o[bf(c)],"0px"===s&&(s=0),s!=a[c]&&(i.push(c),r.node.style[bf(c)]=s);return i.length?void Vf(r,a,n,i,t):void t()});return i}):Gf=null;var Kf=Gf,Qf=function(t,e){return"number"==typeof t?t={duration:t}:"string"==typeof t?t="slow"===t?{duration:600}:"fast"===t?{duration:200}:{duration:400}:t||(t={}),r({},t,e)},Yf=za,$f=function(t,e,n){this.init(t,e,n)};$f.prototype={init:hf,start:Yf,getStyle:yf,setStyle:_f,animateStyle:Kf,processParams:Qf};var Jf,Xf,Zf=$f,th=Ha;Jf=function(){var t=this.node,e=this.fragment.toString(!1);if(window&&window.appearsToBeIELessEqual8&&(t.type="text/css"),t.styleSheet)t.styleSheet.cssText=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}},Xf=function(){this.node.type&&"text/javascript"!==this.node.type||m("Script tag was updated. This does not cause the code to be re-evaluated!",{ractive:this.root}),this.node.text=this.fragment.toString(!1)};var eh=function(){var t,e;return this.template.y?"":(t="<"+this.template.e,t+=this.attributes.map(Xa).join("")+this.conditionalAttributes.map(Xa).join(""),"option"===this.name&&$a(this)&&(t+=" selected"),"input"===this.name&&Ja(this)&&(t+=" checked"),t+=">","textarea"===this.name&&void 0!==this.getAttribute("value")?t+=Se(this.getAttribute("value")):void 0!==this.getAttribute("contenteditable")&&(t+=this.getAttribute("value")||""),this.fragment&&(e="script"!==this.name&&"style"!==this.name,t+=this.fragment.toString(e)),ic.test(this.template.e)||(t+=""),t)},nh=Za,ah=tr,rh=function(t){this.init(t)};rh.prototype={bubble:Tl,detach:Rl,find:Ml,findAll:Ll,findAllComponents:jl,findComponent:Dl,findNextNode:Nl,firstNode:Fl,getAttribute:Il,init:df,rebind:ff,render:th,toString:eh,unbind:nh,unrender:ah};var ih=rh,oh=/^\s*$/,sh=/^\s*/,ph=function(t){var e,n,a,r;return e=t.split("\n"),n=e[0],void 0!==n&&oh.test(n)&&e.shift(),a=D(e),void 0!==a&&oh.test(a)&&e.pop(),r=e.reduce(nr,null),r&&(t=e.map(function(t){return t.replace(r,"")}).join("\n")),t},uh=ar,ch=function(t,e){var n;return e?n=t.split("\n").map(function(t,n){return n?e+t:t}).join("\n"):t},lh='Could not find template for partial "%s"',dh=function(t){var e,n;e=this.parentFragment=t.parentFragment,this.root=e.root,this.type=Au,this.index=t.index,this.name=t.template.r,this.rendered=!1,this.fragment=this.fragmentToRender=this.fragmentToUnrender=null,Gc.init(this,t),this.keypath||((n=uh(this.root,this.name,e))?(_c.call(this),this.isNamed=!0,this.setTemplate(n)):g(lh,this.name))};dh.prototype={bubble:function(){this.parentFragment.bubble()},detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},getPartialName:function(){return this.isNamed&&this.name?this.name:void 0===this.value?this.name:this.value},getValue:function(){return this.fragment.getValue()},rebind:function(t,e){this.isNamed||Vc.call(this,t,e),this.fragment&&this.fragment.rebind(t,e)},render:function(){return this.docFrag=document.createDocumentFragment(),this.update(),this.rendered=!0,this.docFrag},resolve:Gc.resolve,setValue:function(t){var e;(void 0===t||t!==this.value)&&(void 0!==t&&(e=uh(this.root,""+t,this.parentFragment)),!e&&this.name&&(e=uh(this.root,this.name,this.parentFragment))&&(_c.call(this),this.isNamed=!0),e||g(lh,this.name,{ractive:this.root}),this.value=t,this.setTemplate(e||[]),this.bubble(),this.rendered&&bs.addView(this))},setTemplate:function(t){this.fragment&&(this.fragment.unbind(),this.rendered&&(this.fragmentToUnrender=this.fragment)),this.fragment=new rg({template:t,root:this.root,owner:this,pElement:this.parentFragment.pElement}),this.fragmentToRender=this.fragment},toString:function(t){var e,n,a,r;return e=this.fragment.toString(t),n=this.parentFragment.items[this.index-1],n&&n.type===ku?(a=n.text.split("\n").pop(),(r=/^\s+$/.exec(a))?ch(e,r[0]):e):e},unbind:function(){this.isNamed||_c.call(this),this.fragment&&this.fragment.unbind()},unrender:function(t){this.rendered&&(this.fragment&&this.fragment.unrender(t),this.rendered=!1)},update:function(){var t,e;this.fragmentToUnrender&&(this.fragmentToUnrender.unrender(!0),this.fragmentToUnrender=null),this.fragmentToRender&&(this.docFrag.appendChild(this.fragmentToRender.render()),this.fragmentToRender=null),this.rendered&&(t=this.parentFragment.getNode(),e=this.parentFragment.findNextNode(this),t.insertBefore(this.docFrag,e))}};var fh,hh,mh,gh=dh,vh=pr,bh=ur,yh=new is("detach"),_h=cr,xh=lr,wh=dr,kh=fr,Sh=hr,Eh=mr,Ch=function(t,e,n,a){var r=t.root,i=t.keypath;a?r.viewmodel.smartUpdate(i,e,a):r.viewmodel.mark(i)},Ph=[],Ah=["pop","push","reverse","shift","sort","splice","unshift"];Ah.forEach(function(t){var e=function(){for(var e=arguments.length,n=Array(e),a=0;e>a;a++)n[a]=arguments[a];var r,i,o,s;for(r=bp(this,t,n),i=Array.prototype[t].apply(this,arguments),bs.start(),this._ractive.setting=!0,s=this._ractive.wrappers.length;s--;)o=this._ractive.wrappers[s],bs.addRactive(o.root),Ch(o,this,t,r);return bs.end(),this._ractive.setting=!1,i};Eo(Ph,t,{value:e})}),fh={},fh.__proto__?(hh=function(t){t.__proto__=Ph},mh=function(t){t.__proto__=Array.prototype}):(hh=function(t){var e,n;for(e=Ah.length;e--;)n=Ah[e],Eo(t,n,{value:Ph[n],configurable:!0})},mh=function(t){var e;for(e=Ah.length;e--;)delete t[Ah[e]]}),hh.unpatch=mh;var Oh,Th,Rh,Mh=hh;Oh={filter:function(t){return i(t)&&(!t._ractive||!t._ractive.setting)},wrap:function(t,e,n){return new Th(t,e,n)}},Th=function(t,e,n){this.root=t,this.value=e,this.keypath=S(n),e._ractive||(Eo(e,"_ractive",{value:{wrappers:[],instances:[],setting:!1},configurable:!0}),Mh(e)),e._ractive.instances[t._guid]||(e._ractive.instances[t._guid]=0,e._ractive.instances.push(t)),e._ractive.instances[t._guid]+=1,e._ractive.wrappers.push(this)},Th.prototype={get:function(){return this.value},teardown:function(){var t,e,n,a,r;if(t=this.value,e=t._ractive,n=e.wrappers,a=e.instances,e.setting)return!1;if(r=n.indexOf(this),-1===r)throw Error(Rh);if(n.splice(r,1),n.length){if(a[this.root._guid]-=1,!a[this.root._guid]){if(r=a.indexOf(this.root),-1===r)throw Error(Rh);a.splice(r,1)}}else delete t._ractive,Mh.unpatch(this.value)}},Rh="Something went wrong in a rather interesting way";var Lh,jh,Dh=Oh,Nh=/^\s*[0-9]+\s*$/,Fh=function(t){return Nh.test(t)?[]:{}};try{Object.defineProperty({},"test",{value:0}),Lh={filter:function(t,e,n){var a,r;return e?(e=S(e),(a=n.viewmodel.wrapped[e.parent.str])&&!a.magic?!1:(r=n.viewmodel.get(e.parent),i(r)&&/^[0-9]+$/.test(e.lastKey)?!1:r&&("object"==typeof r||"function"==typeof r))):!1},wrap:function(t,e,n){return new jh(t,e,n)}},jh=function(t,e,n){var a,r,i;return n=S(n),this.magic=!0,this.ractive=t,this.keypath=n,this.value=e,this.prop=n.lastKey,a=n.parent,this.obj=a.isRoot?t.viewmodel.data:t.viewmodel.get(a),r=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),r&&r.set&&(i=r.set._ractiveWrappers)?void(-1===i.indexOf(this)&&i.push(this)):void gr(this,e,r)},jh.prototype={get:function(){return this.value},reset:function(t){return this.updating?void 0:(this.updating=!0,this.obj[this.prop]=t,bs.addRactive(this.ractive),this.ractive.viewmodel.mark(this.keypath,{keepExistingWrapper:!0}),this.updating=!1,!0)},set:function(t,e){this.updating||(this.obj[this.prop]||(this.updating=!0,this.obj[this.prop]=Fh(t),this.updating=!1),this.obj[this.prop][t]=e)},teardown:function(){var t,e,n,a,r;return this.updating?!1:(t=Object.getOwnPropertyDescriptor(this.obj,this.prop),e=t&&t.set,void(e&&(a=e._ractiveWrappers,r=a.indexOf(this),-1!==r&&a.splice(r,1),a.length||(n=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configurable:!0}),this.obj[this.prop]=n))))}}}catch(Ao){Lh=!1}var Ih,Bh,qh=Lh;qh&&(Ih={filter:function(t,e,n){return qh.filter(t,e,n)&&Dh.filter(t)},wrap:function(t,e,n){return new Bh(t,e,n)}},Bh=function(t,e,n){this.value=e,this.magic=!0,this.magicWrapper=qh.wrap(t,e,n),this.arrayWrapper=Dh.wrap(t,e,n)},Bh.prototype={get:function(){return this.value},teardown:function(){this.arrayWrapper.teardown(),this.magicWrapper.teardown()},reset:function(t){return this.magicWrapper.reset(t)}});var Uh=Ih,Vh=vr,Gh={},zh=_r,Wh=xr,Hh=Sr,Kh=Or,Qh=Tr,Yh=function(t,e){this.computation=t,this.viewmodel=t.viewmodel,this.ref=e,this.root=this.viewmodel.ractive,this.parentFragment=this.root.component&&this.root.component.parentFragment};Yh.prototype={resolve:function(t){this.computation.softDeps.push(t),this.computation.unresolvedDeps[t.str]=null,this.viewmodel.register(t,this.computation,"computed")}};var $h=Yh,Jh=function(t,e){this.key=t,this.getter=e.getter,this.setter=e.setter,this.hardDeps=e.deps||[],this.softDeps=[],this.unresolvedDeps={},this.depValues={},this._dirty=this._firstRun=!0};Jh.prototype={constructor:Jh,init:function(t){var e,n=this;this.viewmodel=t,this.bypass=!0,e=t.get(this.key),t.clearCache(this.key.str),this.bypass=!1,this.setter&&void 0!==e&&this.set(e),this.hardDeps&&this.hardDeps.forEach(function(e){return t.register(e,n,"computed")})},invalidate:function(){this._dirty=!0},get:function(){var t,e,n=this,a=!1;if(this.getting){var r="The "+this.key.str+" computation indirectly called itself. This probably indicates a bug in the computation. It is commonly caused by `array.sort(...)` - if that's the case, clone the array first with `array.slice().sort(...)`";return h(r),this.value}if(this.getting=!0,this._dirty){if(this._firstRun||!this.hardDeps.length&&!this.softDeps.length?a=!0:[this.hardDeps,this.softDeps].forEach(function(t){var e,r,i;if(!a)for(i=t.length;i--;)if(e=t[i],r=n.viewmodel.get(e),!s(r,n.depValues[e.str]))return n.depValues[e.str]=r,void(a=!0)}),a){this.viewmodel.capture();try{this.value=this.getter()}catch(i){m('Failed to compute "%s"',this.key.str),d(i.stack||i),this.value=void 0}t=this.viewmodel.release(),e=this.updateDependencies(t),e&&[this.hardDeps,this.softDeps].forEach(function(t){t.forEach(function(t){n.depValues[t.str]=n.viewmodel.get(t)})})}this._dirty=!1}return this.getting=this._firstRun=!1,this.value},set:function(t){if(this.setting)return void(this.value=t);if(!this.setter)throw Error("Computed properties without setters are read-only. (This may change in a future version of Ractive!)");this.setter(t)},updateDependencies:function(t){var e,n,a,r,i;for(n=this.softDeps,e=n.length;e--;)a=n[e],-1===t.indexOf(a)&&(r=!0,this.viewmodel.unregister(a,this,"computed"));for(e=t.length;e--;)a=t[e],-1!==n.indexOf(a)||this.hardDeps&&-1!==this.hardDeps.indexOf(a)||(r=!0,Rr(this.viewmodel,a)&&!this.unresolvedDeps[a.str]?(i=new $h(this,a.str),t.splice(e,1),this.unresolvedDeps[a.str]=i,bs.addUnresolved(i)):this.viewmodel.register(a,this,"computed"));return r&&(this.softDeps=t.slice()),r}};var Xh=Jh,Zh=Mr,tm={FAILED_LOOKUP:!0},em=Lr,nm={},am=Dr,rm=Nr,im=function(t,e){this.localKey=t,this.keypath=e.keypath,this.origin=e.origin,this.deps=[],this.unresolved=[],this.resolved=!1};im.prototype={forceResolution:function(){this.keypath=this.localKey,this.setup()},get:function(t,e){return this.resolved?this.origin.get(this.map(t),e):void 0},getValue:function(){return this.keypath?this.origin.get(this.keypath):void 0},initViewmodel:function(t){this.local=t,this.setup()},map:function(t){return void 0===typeof this.keypath?this.localKey:t.replace(this.localKey,this.keypath)},register:function(t,e,n){this.deps.push({keypath:t,dep:e,group:n}),this.resolved&&this.origin.register(this.map(t),e,n)},resolve:function(t){void 0!==this.keypath&&this.unbind(!0),this.keypath=t,this.setup()},set:function(t,e){this.resolved||this.forceResolution(),this.origin.set(this.map(t),e)},setup:function(){var t=this;void 0!==this.keypath&&(this.resolved=!0,this.deps.length&&(this.deps.forEach(function(e){var n=t.map(e.keypath);if(t.origin.register(n,e.dep,e.group),e.dep.setValue)e.dep.setValue(t.origin.get(n));else{if(!e.dep.invalidate)throw Error("An unexpected error occurred. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");e.dep.invalidate()}}),this.origin.mark(this.keypath)))},setValue:function(t){if(!this.keypath)throw Error("Mapping does not have keypath, cannot set value. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");this.origin.set(this.keypath,t)},unbind:function(t){var e=this;t||delete this.local.mappings[this.localKey],this.resolved&&(this.deps.forEach(function(t){e.origin.unregister(e.map(t.keypath),t.dep,t.group)}),this.tracker&&this.origin.unregister(this.keypath,this.tracker))},unregister:function(t,e,n){var a,r;if(this.resolved){for(a=this.deps,r=a.length;r--;)if(a[r].dep===e){a.splice(r,1);break}this.origin.unregister(this.map(t),e,n)}}};var om=Fr,sm=function(t,e){var n,a,r,i;return n={},a=0,r=t.map(function(t,r){var o,s,p;s=a,p=e.length;do{if(o=e.indexOf(t,s),-1===o)return i=!0,-1;s=o+1}while(n[o]&&p>s);return o===a&&(a+=1),o!==r&&(i=!0),n[o]=!0,o})},pm=Ir,um={},cm=Ur,lm=Gr,dm=zr,fm=Wr,hm=Kr,mm={implicit:!0},gm={noCascade:!0},vm=Yr,bm=$r,ym=function(t){var e,n,a=t.adapt,r=t.data,i=t.ractive,o=t.computed,s=t.mappings;this.ractive=i,this.adaptors=a,this.onchange=t.onchange,this.cache={},this.cacheMap=So(null),this.deps={computed:So(null),"default":So(null)},this.depsMap={computed:So(null),"default":So(null)},this.patternObservers=[],this.specials=So(null),this.wrapped=So(null),this.computations=So(null),this.captureGroups=[],this.unresolvedImplicitDependencies=[],this.changes=[],this.implicitChanges={},this.noCascade={},this.data=r,this.mappings=So(null);for(e in s)this.map(S(e),s[e]);if(r)for(e in r)(n=this.mappings[e])&&void 0===n.getValue()&&n.setValue(r[e]);for(e in o)s&&e in s&&l("Cannot map to a computed property ('%s')",e),this.compute(S(e),o[e]);this.ready=!0};ym.prototype={adapt:Vh,applyChanges:Hh,capture:Kh,clearCache:Qh,compute:Zh,get:em,init:am,map:rm,mark:om,merge:pm,register:cm,release:lm,reset:dm,set:fm,smartUpdate:hm,teardown:vm,unregister:bm};var _m=ym;Xr.prototype={constructor:Xr,begin:function(t){this.inProcess[t._guid]=!0},end:function(t){var e=t.parent;e&&this.inProcess[e._guid]?Zr(this.queue,e).push(t):ti(this,t),delete this.inProcess[t._guid]}};var xm=Xr,wm=ei,km=/\$\{([^\}]+)\}/g,Sm=new is("construct"),Em=new is("config"),Cm=new xm("init"),Pm=0,Am=["adaptors","components","decorators","easing","events","interpolators","partials","transitions"],Om=ii,Tm=ci;ci.prototype={bubble:function(){this.dirty||(this.dirty=!0,bs.addView(this))},update:function(){this.callback(this.fragment.getValue()),this.dirty=!1},rebind:function(t,e){this.fragment.rebind(t,e)},unbind:function(){this.fragment.unbind()}};var Rm=function(t,e,n,r,o){var s,p,u,c,l,d,f={},h={},g={},v=[];for(p=t.parentFragment,u=t.root,o=o||{},a(f,o),o.content=r||[],f[""]=o.content,e.defaults.el&&m("The <%s/> component has a default `el` property; it has been disregarded",t.name),c=p;c;){if(c.owner.type===Mu){l=c.owner.container;break}c=c.parent}return n&&Object.keys(n).forEach(function(e){var a,r,o=n[e];if("string"==typeof o)a=dc(o),h[e]=a?a.value:o;else if(0===o)h[e]=!0;else{if(!i(o))throw Error("erm wut");di(o)?(g[e]={origin:t.root.viewmodel,keypath:void 0},r=li(t,o[0],function(t){t.isSpecial?d?s.set(e,t.value):(h[e]=t.value,delete g[e]):d?s.viewmodel.mappings[e].resolve(t):g[e].keypath=t})):r=new Tm(t,o,function(t){d?s.set(e,t):h[e]=t}),v.push(r)}}),s=So(e.prototype),Om(s,{el:null,append:!0,data:h,partials:o,magic:u.magic||e.defaults.magic,modifyArrays:u.modifyArrays,adapt:u.adapt},{parent:u,component:t,container:l,mappings:g,inlinePartials:f,cssIds:p.cssIds}),d=!0,t.resolvers=v,s},Mm=fi,Lm=function(t){var e,n;for(e=t.root;e;)(n=e._liveComponentQueries["_"+t.name])&&n.push(t.instance),e=e.parent},jm=mi,Dm=gi,Nm=vi,Fm=bi,Im=yi,Bm=new is("teardown"),qm=xi,Um=function(t,e){this.init(t,e)};Um.prototype={detach:bh,find:_h,findAll:xh,findAllComponents:wh,findComponent:kh,findNextNode:Sh,firstNode:Eh,init:jm,rebind:Dm,render:Nm,toString:Fm,unbind:Im,unrender:qm};var Vm=Um,Gm=function(t){this.type=Ou,this.value=t.template.c};Gm.prototype={detach:vc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createComment(this.value)),this.node},toString:function(){return""},unrender:function(t){t&&this.node.parentNode.removeChild(this.node)}};var zm=Gm,Wm=function(t){var e,n;this.type=Mu,this.container=e=t.parentFragment.root,this.component=n=e.component,this.container=e,this.containerFragment=t.parentFragment,this.parentFragment=n.parentFragment;var a=this.name=t.template.n||"",r=e._inlinePartials[a];r||(m('Could not find template for partial "'+a+'"',{ractive:t.root}),r=[]),this.fragment=new rg({owner:this,root:e.parent,template:r,pElement:this.containerFragment.pElement}),i(n.yielders[a])?n.yielders[a].push(this):n.yielders[a]=[this],bs.scheduleTask(function(){if(n.yielders[a].length>1)throw Error("A component template can only have one {{yield"+(a?" "+a:"")+"}} declaration at a time")})};Wm.prototype={detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},findNextNode:function(){return this.containerFragment.findNextNode(this)},firstNode:function(){return this.fragment.firstNode()},getValue:function(t){return this.fragment.getValue(t)},render:function(){return this.fragment.render()},unbind:function(){this.fragment.unbind()},unrender:function(t){this.fragment.unrender(t),N(this.component.yielders[this.name],this)},rebind:function(t,e){this.fragment.rebind(t,e)},toString:function(){return""+this.fragment}};var Hm=Wm,Km=function(t){this.declaration=t.template.a};Km.prototype={init:ko,render:ko,unrender:ko,teardown:ko,toString:function(){return""}};var Qm=Km,Ym=wi,$m=Si,Jm=Ei,Xm=Ci,Zm=Oi,tg=Ri,eg=function(t){this.init(t)};eg.prototype={bubble:cu,detach:lu,find:du,findAll:fu,findAllComponents:hu,findComponent:mu,findNextNode:gu,firstNode:vu,getArgsList:hc,getNode:mc,getValue:gc,init:Ym,rebind:$m,registerIndexRef:function(t){var e=this.registeredIndexRefs;-1===e.indexOf(t)&&e.push(t)},render:Jm,toString:Xm,unbind:Zm,unregisterIndexRef:function(t){var e=this.registeredIndexRefs;e.splice(e.indexOf(t),1)},unrender:tg};var ng,ag,rg=eg,ig=Mi,og=["template","partials","components","decorators","events"],sg=new is("reset"),pg=function(t,e){function n(e,a,r){r&&r.partials[t]||e.forEach(function(e){e.type===Au&&e.getPartialName()===t&&a.push(e),e.fragment&&n(e.fragment.items,a,r),i(e.fragments)?n(e.fragments,a,r):i(e.items)?n(e.items,a,r):e.type===Ru&&e.instance&&n(e.instance.fragment.items,a,e.instance),e.type===Pu&&(i(e.attributes)&&n(e.attributes,a,r),i(e.conditionalAttributes)&&n(e.conditionalAttributes,a,r))})}var a,r=[];return n(this.fragment.items,r),this.partials[t]=e,a=bs.start(this,!0),r.forEach(function(e){e.value=void 0,e.setValue(t)}),bs.end(),a},ug=Li,cg=_p("reverse"),lg=ji,dg=_p("shift"),fg=_p("sort"),hg=_p("splice"),mg=Ni,gg=Fi,vg=new is("teardown"),bg=Bi,yg=qi,_g=Ui,xg=new is("unrender"),wg=_p("unshift"),kg=Vi,Sg=new is("update"),Eg=Gi,Cg={add:Zo,animate:Ss,detach:Cs,find:As,findAll:Fs,findAllComponents:Is,findComponent:Bs,findContainer:qs,findParent:Us,fire:Ws,get:Hs,insert:Qs,merge:$s,observe:lp,observeOnce:dp,off:mp,on:gp,once:vp,pop:xp,push:wp,render:Tp,reset:ig,resetPartial:pg,resetTemplate:ug,reverse:cg,set:lg,shift:dg,sort:fg,splice:hg,subtract:mg,teardown:gg,toggle:bg,toHTML:yg,toHtml:yg,unrender:_g,unshift:wg,update:kg,updateModel:Eg},Pg=function(t,e,n){return n||Wi(t,e)?function(){var n,a="_super"in this,r=this._super;return this._super=e,n=t.apply(this,arguments),a&&(this._super=r),n}:t},Ag=Hi,Og=$i,Tg=function(t){var e,n,a={};return t&&(e=t._ractive)?(a.ractive=e.root,a.keypath=e.keypath.str,a.index={},(n=Oc(e.proxy.parentFragment))&&(a.index=Oc.resolve(n)),a):a};ng=function(t){return this instanceof ng?void Om(this,t):new ng(t)},ag={DEBUG:{writable:!0,value:!0},DEBUG_PROMISES:{writable:!0,value:!0},extend:{value:Og},getNodeInfo:{value:Tg},parse:{value:Hp},Promise:{value:us},svg:{value:ao},magic:{value:eo},VERSION:{value:"0.7.3"},adaptors:{writable:!0,value:{}},components:{writable:!0,value:{}},decorators:{writable:!0,value:{}},easing:{writable:!0,value:po},events:{writable:!0,value:{}},interpolators:{writable:!0,value:Vo},partials:{writable:!0,value:{}},transitions:{writable:!0,value:{}}},Co(ng,ag),ng.prototype=a(Cg,so),ng.prototype.constructor=ng,ng.defaults=ng.prototype;var Rg="function";if(typeof Date.now!==Rg||typeof String.prototype.trim!==Rg||typeof Object.keys!==Rg||typeof Array.prototype.indexOf!==Rg||typeof Array.prototype.forEach!==Rg||typeof Array.prototype.map!==Rg||typeof Array.prototype.filter!==Rg||"undefined"!=typeof window&&typeof window.addEventListener!==Rg)throw Error("It looks like you're attempting to use Ractive.js in an older browser. You'll need to use one of the 'legacy builds' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.");var Mg=ng;return Mg})},{}],342:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.observe("value",function(e,n,a){var r=t.get(),i=r.min,o=r.max,s=Math.clamp(i,o,e);t.animate("percentage",Math.round((s-i)/(o-i)*100))})}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,305],t:7,e:"div",a:{"class":"bar"},f:[{p:[14,3,326],t:7,e:"div",a:{"class":["barFill ",{t:2,r:"state",p:[14,23,346]}],style:["width: ",{t:2,r:"percentage",p:[14,48,371]},"%"]}}," ",{p:[15,3,398],t:7,e:"span",a:{"class":"barText"},f:[{t:16,p:[15,25,420]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],343:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481);e.exports={computed:{clickable:function(){return!this.get("enabled")||this.get("state")&&"toggle"!=this.get("state")?!1:!0},enabled:function(){return this.get("config.status")===n.UI_INTERACTIVE?!0:!1},styles:function(){var t="";if(this.get("class")&&(t+=" "+this.get("class")),this.get("tooltip-side")&&(t=" tooltip-"+this.get("tooltip-side")),this.get("grid")&&(t+=" gridable"),this.get("enabled")){var e=this.get("state"),n=this.get("style");return e?"inactive "+e+" "+t:"active normal "+n+" "+t}return"inactive disabled "+t}},oninit:function(){var t=this;this.on("press",function(e){var n=t.get(),r=n.action,i=n.params;(0,a.act)(t.get("config.ref"),r,i),e.node.blur()})},data:{iconStackToHTML:function(t){var e="",n=t.split(",");if(n.length){e+='';for(var a=n,r=Array.isArray(a),i=0,a=r?a:a[Symbol.iterator]();;){var o;if(r){if(i>=a.length)break;o=a[i++]}else{if(i=a.next(),i.done)break;o=i.value}var s=o,p=/([\w\-]+)\s*(\dx)/g,u=p.exec(s),c=u[1],l=u[2];e+=''}}return e&&(e+=""),e}}}}(r),r.exports.template={v:3,t:[" ",{p:[70,1,2019],t:7,e:"span",a:{"class":["button ",{t:2,r:"styles",p:[70,21,2039]}],unselectable:"on","data-tooltip":[{t:2,r:"tooltip",p:[73,17,2124]}]},m:[{t:4,f:["tabindex='0'"],r:"clickable",p:[72,3,2075]}],v:{"mouseover-mousemove":"hover",mouseleave:"unhover","click-enter":{n:[{t:4,f:["press"],r:"clickable",p:[76,19,2217]}],d:[]}},f:[{t:4,f:[{p:[78,5,2265],t:7,e:"i",a:{"class":["fa fa-",{t:2,r:"icon",p:[78,21,2281]}]}}],n:50,r:"icon",p:[77,3,2247]}," ",{t:4,f:[{t:3,x:{r:["iconStackToHTML","icon_stack"],s:"_0(_1)"},p:[81,6,2335]}],n:50,r:"icon_stack",p:[80,3,2310]}," ",{t:16,p:[83,3,2383]}]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482}],344:[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":"display"},f:[{t:4,f:[{p:[3,5,44],t:7,e:"header",f:[{p:[4,7,60],t:7,e:"h3",f:[{t:2,r:"title",p:[4,11,64]}]}," ",{t:4,f:[{p:[6,9,110],t:7,e:"div",a:{"class":"buttonRight"},f:[{t:16,n:"button",p:[6,34,135]}]}],n:50,r:"button",p:[5,7,86]}]}],n:50,r:"title",p:[2,3,25]}," ",{p:[10,3,202],t:7,e:"article",f:[{t:16,p:[11,5,217]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],345:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.on("clear",function(){t.set("value",""),t.find("input").focus()})}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,170],t:7,e:"input",a:{type:"text",value:[{t:2,r:"value",p:[12,27,196]}],placeholder:[{t:2,r:"placeholder",p:[12,51,220]}]}}," ",{p:[13,1,240],t:7,e:"ui-button",a:{icon:"refresh"},v:{press:"clear"}}]},e.exports=a.extend(r.exports)},{341:341}],346:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";e.exports={data:{graph:t(338),xaccessor:function(t){return t.x},yaccessor:function(t){return t.y}},computed:{size:function(){var t=this.get("points");return t[0].length},scale:function(){var t=this.get("points");return Math.max.apply(Math,Array.map(t,function(t){return Math.max.apply(Math,Array.map(t,function(t){return t.y}))}))},xaxis:function(){var t=this.get("xinc"),e=this.get("size");return Array.from(Array(e).keys()).filter(function(e){return e&&e%t==0})},yaxis:function(){var t=this.get("yinc"),e=this.get("scale");return Array.from(Array(t).keys()).map(function(t){return Math.round(e*(++t/100)*10)})}},oninit:function(){var t=this;this.on({enter:function(t){this.set("selected",t.index.count)},exit:function(t){this.set("selected")}}),window.addEventListener("resize",function(e){t.set("width",t.el.clientWidth)})},onrender:function(){this.set("width",this.el.clientWidth)}}}(r),r.exports.template={v:3,t:[" ",{p:[47,1,1269],t:7,e:"svg",a:{"class":"linegraph",width:"100%",height:[{t:2,x:{r:["height"],s:"_0+10"},p:[47,45,1313]}]},f:[{p:[48,3,1334],t:7,e:"g",a:{transform:"translate(0, 5)"},f:[{t:4,f:[{t:4,f:[{p:[51,9,1504],t:7,e:"line",a:{x1:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,19,1514]}],x2:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,38,1533]}],y1:"0",y2:[{t:2,r:"height",p:[51,64,1559]}],stroke:"darkgray"}}," ",{t:4,f:[{p:[53,11,1635],t:7,e:"text",a:{x:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[53,20,1644]}],y:[{t:2,x:{r:["height"],s:"_0-5"},p:[53,38,1662]}],"text-anchor":"middle",fill:"white"},f:[{t:2,x:{r:["size",".","xfactor"],s:"(_0-_1)*_2"},p:[53,88,1712]}," ",{t:2,r:"xunit",p:[53,113,1737]}]}],n:50,x:{r:["@index"],s:"_0%2==0"},p:[52,9,1600]}],n:52,r:"xaxis",p:[50,7,1479]}," ",{t:4,f:[{p:[57,9,1820],t:7,e:"line",a:{x1:"0",x2:[{t:2,r:"width",p:[57,26,1837]}],y1:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,41,1852]}],y2:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,60,1871]}],stroke:"darkgray"}}," ",{p:[58,9,1915],t:7,e:"text",a:{x:"0",y:[{t:2,x:{r:["yscale","."],s:"_0(_1)-5"},p:[58,24,1930]}],"text-anchor":"begin",fill:"white"},f:[{t:2,x:{r:[".","yfactor"],s:"_0*_1"},p:[58,76,1982]}," ",{t:2,r:"yunit",p:[58,92,1998]}]}],n:52,r:"yaxis",p:[56,7,1795]}," ",{t:4,f:[{p:[61,9,2071],t:7,e:"path",a:{d:[{t:2,x:{r:["area.path"],s:"_0.print()"},p:[61,18,2080]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[61,47,2109]}],opacity:"0.1"}}],n:52,i:"curve",r:"curves",p:[60,7,2039]}," ",{t:4,f:[{p:[64,9,2200],t:7,e:"path",a:{d:[{t:2,x:{r:["line.path"],s:"_0.print()"},p:[64,18,2209]}],stroke:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[64,49,2240]}],fill:"none"}}],n:52, i:"curve",r:"curves",p:[63,7,2168]}," ",{t:4,f:[{t:4,f:[{p:[68,11,2375],t:7,e:"circle",a:{transform:["translate(",{t:2,r:".",p:[68,40,2404]},")"],r:[{t:2,x:{r:["selected","count"],s:"_0==_1?10:4"},p:[68,51,2415]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[68,89,2453]}]},v:{mouseenter:"enter",mouseleave:"exit"}}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[67,9,2329]}],n:52,i:"curve",r:"curves",p:[66,7,2297]}," ",{t:4,f:[{t:4,f:[{t:4,f:[{p:[74,13,2678],t:7,e:"text",a:{transform:["translate(",{t:2,r:".",p:[74,40,2705]},") ",{t:2,x:{r:["count","size"],s:'_0<=_1/2?"translate(15, 4)":"translate(-15, 4)"'},p:[74,47,2712]}],"text-anchor":[{t:2,x:{r:["count","size"],s:'_0<=_1/2?"start":"end"'},p:[74,126,2791]}],fill:"white"},f:[{t:2,x:{r:["count","item","yfactor"],s:"_1[_0].y*_2"},p:[75,15,2861]}," ",{t:2,r:"yunit",p:[75,43,2889]}," @ ",{t:2,x:{r:["size","count","item","xfactor"],s:"(_0-_2[_1].x)*_3"},p:[75,55,2901]}," ",{t:2,r:"xunit",p:[75,92,2938]}]}],n:50,x:{r:["selected","count"],s:"_0==_1"},p:[73,11,2638]}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[72,9,2592]}],n:52,i:"curve",r:"curves",p:[71,7,2560]}," ",{t:4,f:[{p:[81,9,3063],t:7,e:"g",a:{transform:["translate(",{t:2,x:{r:["width","curves.length","@index"],s:"(_0/(_1+1))*(_2+1)"},p:[81,33,3087]},", 10)"]},f:[{p:[82,11,3154],t:7,e:"circle",a:{r:"4",fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[82,31,3174]}]}}," ",{p:[83,11,3206],t:7,e:"text",a:{x:"8",y:"4",fill:"white"},f:[{t:2,rx:{r:"legend",m:[{t:30,n:"curve"}]},p:[83,42,3237]}]}]}],n:52,i:"curve",r:"curves",p:[80,7,3031]}],x:{r:["graph","points","xaccessor","yaccessor","width","height"],s:"_0({data:_1,xaccessor:_2,yaccessor:_3,width:_4,height:_5})"},p:[49,5,1371]}]}]}]},e.exports=a.extend(r.exports)},{338:338,341:341}],347:[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":"notice"},f:[{t:16,p:[2,3,24]}]}]},e.exports=a.extend(r.exports)},{341:341}],348:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={oninit:function(){var t=this,e=a.resize.bind(this),r=function(){return t.set({resize:!1,x:null,y:null})};this.observe("config.fancy",function(a,i,o){(0,n.winset)(t.get("config.window"),"can-resize",!a),a?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",r)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r))}),this.on("resize",function(){return t.toggle("resize")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[28,3,766],t:7,e:"div",a:{"class":"resize"},v:{mousedown:"resize"}}],n:50,r:"config.fancy",p:[27,1,742]}]},e.exports=a.extend(r.exports)},{341:341,481:481,483:483}],349:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"section",a:{"class":[{t:4,f:["candystripe"],r:"candystripe",p:[1,17,16]}]},f:[{t:4,f:[{p:[3,5,84],t:7,e:"span",a:{"class":"label",style:[{t:4,f:["color:",{t:2,r:"labelcolor",p:[3,53,132]}],r:"labelcolor",p:[3,32,111]}]},f:[{t:2,r:"label",p:[3,84,163]},":"]}],n:50,r:"label",p:[2,3,65]}," ",{t:4,f:[{t:16,p:[6,5,215]}],n:50,r:"nowrap",p:[5,3,195]},{t:4,n:51,f:[{p:[8,5,242],t:7,e:"div",a:{"class":"content",style:[{t:4,f:["float:right;"],r:"right",p:[8,33,270]}]},f:[{t:16,p:[9,7,312]}]}],r:"nowrap"}]}]},e.exports=a.extend(r.exports)},{341:341}],350:[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":"subdisplay"},f:[{t:4,f:[{p:[3,5,47],t:7,e:"header",f:[{p:[4,7,63],t:7,e:"h4",f:[{t:2,r:"title",p:[4,11,67]}]}," ",{t:4,f:[{t:16,n:"button",p:[5,21,103]}],n:50,r:"button",p:[5,7,89]}]}],n:50,r:"title",p:[2,3,28]}," ",{p:[8,3,156],t:7,e:"article",f:[{t:16,p:[9,5,171]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],351:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.set("active",this.findComponent("tab").get("name")),this.on("switch",function(e){t.set("active",e.node.textContent.trim())}),this.observe("active",function(e,n,a){for(var r=t.findAllComponents("tab"),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;p.set("shown",p.get("name")===e)}})}}}(r),r.exports.template={v:3,t:[" "," ",{p:[20,1,524],t:7,e:"header",f:[{t:4,f:[{p:[22,5,556],t:7,e:"ui-button",a:{pane:[{t:2,r:".",p:[22,22,573]}]},v:{press:"switch"},f:[{t:2,r:".",p:[22,47,598]}]}],n:52,r:"tabs",p:[21,3,536]}]}," ",{p:[25,1,641],t:7,e:"ui-display",f:[{t:8,r:"content",p:[26,3,657]}]}]},r.exports.components=r.exports.components||{};var i={tab:t(352)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,352:352}],352:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:16,p:[2,3,17]}],n:50,r:"shown",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],353:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481),r=t(483);e.exports={computed:{visualStatus:function(){switch(this.get("config.status")){case n.UI_INTERACTIVE:return"good";case n.UI_UPDATE:return"average";case n.UI_DISABLED:return"bad";default:return"bad"}}},oninit:function(){var t=this,e=r.drag.bind(this),n=function(e){return t.set({drag:!1,x:null,y:null})};this.observe("config.fancy",function(r,i,o){(0,a.winset)(t.get("config.window"),"titlebar",!r&&t.get("config.titlebar")),r?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",n)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n))}),this.on({drag:function(){this.toggle("drag")},close:function(){(0,a.winset)(this.get("config.window"),"is-visible",!1),window.location.href=(0,a.href)({command:"uiclose "+this.get("config.ref")},"winset")},minimize:function(){(0,a.winset)(this.get("config.window"),"is-minimized",!0)}})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[50,3,1440],t:7,e:"header",a:{"class":"titlebar"},v:{mousedown:"drag"},f:[{p:[51,5,1491],t:7,e:"i",a:{"class":["statusicon fa fa-eye fa-2x ",{t:2,r:"visualStatus",p:[51,42,1528]}]}}," ",{p:[52,5,1556],t:7,e:"span",a:{"class":"title"},f:[{t:16,p:[52,25,1576]}]}," ",{t:4,f:[{p:[54,7,1626],t:7,e:"i",a:{"class":"minimize fa fa-minus fa-2x"},v:{click:"minimize"}}," ",{p:[55,7,1696],t:7,e:"i",a:{"class":"close fa fa-close fa-2x"},v:{click:"close"}}],n:50,r:"config.fancy",p:[53,5,1598]}]}],n:50,r:"config.titlebar",p:[49,1,1413]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482,483:483}],354:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";var e=[11,10,9,8];t.exports={data:{userAgent:navigator.userAgent},computed:{ie:function(){if(document.documentMode)return document.documentMode;for(var t in e){var n=document.createElement("div");if(n.innerHTML="",n.getElementsByTagName("span").length)return t}}},oninit:function(){var t=this;this.on("debug",function(){return t.toggle("debug")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[27,3,662],t:7,e:"ui-notice",f:[{p:[28,5,679],t:7,e:"span",f:["You have an old (IE",{t:2,r:"ie",p:[28,30,704]},"), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed."]},{p:[28,137,811],t:7,e:"br"}," ",{p:[29,5,822],t:7,e:"span",f:["To upgrade, click 'Upgrade IE' to download IE11 from Microsoft."]},{p:[29,81,898],t:7,e:"br"}," ",{p:[30,5,909],t:7,e:"span",f:["If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft."]},{p:[30,122,1026],t:7,e:"br"}," ",{p:[31,5,1037],t:7,e:"span",f:["Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message)."]}," ",{p:[32,5,1155],t:7,e:"hr"}," ",{p:[33,5,1166],t:7,e:"ui-button",a:{icon:"close",action:"tgui:nofrills"},f:["No Frills"]}," ",{p:[34,5,1240],t:7,e:"ui-button",a:{icon:"internet-explorer",action:"tgui:link",params:'{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'},f:["Upgrade IE"]}," ",{p:[36,5,1416],t:7,e:"ui-button",a:{icon:"edge",action:"tgui:link",params:'{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'},f:["IE VMs"]}," ",{p:[38,5,1565],t:7,e:"ui-button",a:{icon:"info",action:"tgui:link",params:'{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'},f:["EOL Info"]}," ",{p:[40,5,1738],t:7,e:"ui-button",a:{icon:"bug"},v:{press:"debug"},f:["Debug Info"]}," ",{t:4,f:[{p:[42,7,1826],t:7,e:"hr"}," ",{p:[43,7,1839],t:7,e:"span",f:["Detected: IE",{t:2,r:"ie",p:[43,25,1857]}]},{p:[43,38,1870],t:7,e:"br"}," ",{p:[44,7,1883],t:7,e:"span",f:["User Agent: ",{t:2,r:"userAgent",p:[44,25,1901]}]}],n:50,r:"debug",p:[41,5,1805]}]}],n:50,x:{r:["config.fancy","ie"],s:"_0&&_1&&_1<11"},p:[26,1,621]}]},e.exports=a.extend(r.exports)},{341:341}],355:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},shockState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[22,1,348],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[23,2,384],t:7,e:"ui-section",a:{label:"Main"},f:[{p:[24,3,413],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.main"],s:"_0(_1)"},p:[24,16,426]}]},f:[{t:2,x:{r:["data.power.main"],s:'_0?"Online":"Offline"'},p:[24,49,459]}]}," ",{t:4,f:["[ ",{p:[26,6,567],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"},p:[25,3,512]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.main_timeleft",p:[29,7,674]}," seconds left ]"],n:50,x:{r:["data.power.main_timeleft"],s:"_0>0"},p:[28,4,630]}],x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"}}," ",{p:[32,3,744],t:7,e:"div",a:{style:"float:right"},f:[{p:[33,4,774],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-main",state:[{t:2,x:{r:["data.power.main"],s:'_0?null:"disabled"'},p:[33,63,833]}]},f:["Disrupt"]}]}]}," ",{p:[36,2,922],t:7,e:"ui-section",a:{label:"Backup"},f:[{p:[37,3,953],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.backup"],s:"_0(_1)"},p:[37,16,966]}]},f:[{t:2,x:{r:["data.power.backup"],s:'_0?"Online":"Offline"'},p:[37,51,1001]}]}," ",{t:4,f:["[ ",{p:[39,6,1115],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"},p:[38,3,1056]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.backup_timeleft",p:[42,7,1224]}," seconds left ]"],n:50,x:{r:["data.power.backup_timeleft"],s:"_0>0"},p:[41,4,1178]}],x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"}}," ",{p:[45,3,1296],t:7,e:"div",a:{style:"float:right"},f:[{p:[46,4,1326],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-backup",state:[{t:2,x:{r:["data.power.backup"],s:'_0?null:"disabled"'},p:[46,65,1387]}]},f:["Disrupt"]}]}]}," ",{p:[49,2,1478],t:7,e:"ui-section",a:{label:"Electrify"},f:[{p:[50,3,1512],t:7,e:"span",a:{"class":[{t:2,x:{r:["shockState","data.shock"],s:"_0(_1)"},p:[50,16,1525]}]},f:[{t:2,x:{r:["data.shock"],s:'_0==2?"Safe":"Electrified"'},p:[50,44,1553]}]}," ",{t:4,f:["[ ",{p:[52,6,1640],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.shock"],s:"!_0"},p:[51,3,1608]},{t:4,n:51,f:[{t:4,f:["[ ",{p:[55,7,1742],t:7,e:"span",a:{"class":"bad"},f:[{t:2,r:"data.shock_timeleft",p:[55,25,1760]}," seconds left"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0>0"},p:[54,4,1703]}," ",{t:4,f:["[ ",{p:[58,7,1863],t:7,e:"span",a:{"class":"bad"},f:["Permanent"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0==-1"},p:[57,4,1822]}],x:{r:["data.wires.shock"],s:"!_0"}}," ",{p:[61,3,1926],t:7,e:"div",a:{style:"float:right"},f:[{p:[62,4,1956],t:7,e:"ui-button",a:{icon:"wrench",action:"shock-restore",state:[{t:2,x:{r:["data.wires.shock","data.shock"],s:'_0&&_1==0?null:"disabled"'},p:[62,59,2011]}]},f:["Restore"]}," ",{p:[63,4,2094],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-temp",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[63,54,2144]}]},f:["Set (Temporary)"]}," ",{p:[64,4,2199],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-perm",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[64,53,2248]}]},f:["Set (Permanent)"]}]}]}]}," ",{p:[68,1,2341],t:7,e:"ui-display",a:{title:"Access & Door Control"},f:[{p:[69,2,2386],t:7,e:"ui-section",a:{label:"ID Scan"},f:[{t:4,f:["[ ",{p:[71,6,2455],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[70,3,2418]}," ",{p:[73,3,2516],t:7,e:"div",a:{style:"float:right"},f:[{p:[74,4,2546],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[74,22,2564]}],icon:"power-off",action:"idscan-on",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"selected":""'},p:[74,93,2635]}]},f:["Enabled"]}," ",{p:[75,4,2698],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[75,22,2716]}],icon:"close",action:"idscan-off",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"":"selected"'},p:[75,90,2784]}]},f:["Disabled"]}]}]}," ",{p:[78,2,2872],t:7,e:"ui-section",a:{label:"Emergency Access"},f:[{p:[79,3,2913],t:7,e:"div",a:{style:"float:right"},f:[{p:[80,4,2943],t:7,e:"ui-button",a:{icon:"power-off",action:"emergency-on",style:[{t:2,x:{r:["data.emergency"],s:'_0?"selected":""'},p:[80,61,3e3]}]},f:["Enabled"]}," ",{p:[81,4,3062],t:7,e:"ui-button",a:{icon:"close",action:"emergency-off",style:[{t:2,x:{r:["data.emergency"],s:'_0?"":"selected"'},p:[81,58,3116]}]},f:["Disabled"]}]}]}," ",{p:[84,2,3203],t:7,e:"br"}," ",{p:[85,2,3212],t:7,e:"ui-section",a:{label:"Door bolts"},f:[{t:4,f:["[ ",{p:[87,6,3279],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.bolts"],s:"!_0"},p:[86,3,3247]}," ",{p:[89,3,3340],t:7,e:"div",a:{style:"float:right"},f:[{p:[90,4,3370],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[90,22,3388]}],icon:"unlock",action:"bolt-raise",style:[{t:2,x:{r:["data.locked"],s:'_0?"":"selected"'},p:[90,85,3451]}]},f:["Raised"]}," ",{p:[91,4,3509],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[91,22,3527]}],icon:"lock",action:"bolt-drop",style:[{t:2,x:{r:["data.locked"],s:'_0?"selected":""'},p:[91,82,3587]}]},f:["Dropped"]}]}]}," ",{p:[94,2,3670],t:7,e:"ui-section",a:{label:"Door bolt lights"},f:[{t:4,f:["[ ",{p:[96,6,3744],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.lights"],s:"!_0"},p:[95,3,3711]}," ",{p:[98,3,3805],t:7,e:"div",a:{style:"float:right"},f:[{p:[99,4,3835],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[99,22,3853]}],icon:"power-off",action:"light-on",style:[{t:2,x:{r:["data.lights"],s:'_0?"selected":""'},p:[99,88,3919]}]},f:["Enabled"]}," ",{p:[100,4,3978],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[100,22,3996]}],icon:"close",action:"light-off",style:[{t:2,x:{r:["data.lights"],s:'_0?"":"selected"'},p:[100,85,4059]}]},f:["Disabled"]}]}]}," ",{p:[103,2,4143],t:7,e:"ui-section",a:{label:"Door force sensors"},f:[{t:4,f:["[ ",{p:[105,6,4217],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.safe"],s:"!_0"},p:[104,3,4186]}," ",{p:[107,3,4278],t:7,e:"div",a:{style:"float:right"},f:[{p:[108,4,4308],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[108,22,4326]}],icon:"power-off",action:"safe-on",style:[{t:2,x:{r:["data.safe"],s:'_0?"selected":""'},p:[108,85,4389]}]},f:["Enabled"]}," ",{p:[109,4,4446],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[109,22,4464]}],icon:"close",action:"safe-off",style:[{t:2,x:{r:["data.safe"],s:'_0?"":"selected"'},p:[109,82,4524]}]},f:["Disabled"]}]}]}," ",{p:[112,2,4606],t:7,e:"ui-section",a:{label:"Door timing safety"},f:[{t:4,f:["[ ",{p:[114,6,4682],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.timing"],s:"!_0"},p:[113,3,4649]}," ",{p:[116,3,4743],t:7,e:"div",a:{style:"float:right"},f:[{p:[117,4,4773],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[117,22,4791]}],icon:"power-off",action:"speed-on",style:[{t:2,x:{r:["data.speed"],s:'_0?"selected":""'},p:[117,88,4857]}]},f:["Enabled"]}," ",{p:[118,4,4915],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[118,22,4933]}],icon:"close",action:"speed-off",style:[{t:2,x:{r:["data.speed"],s:'_0?"":"selected"'},p:[118,85,4996]}]},f:["Disabled"]}]}]}," ",{p:[121,2,5079],t:7,e:"br"}," ",{p:[122,2,5088],t:7,e:"ui-section",a:{label:"Door control"},f:[{t:4,f:["[ ",{p:[124,6,5166],t:7,e:"span",a:{"class":"bad"},f:["Door is ",{t:2,x:{r:["data.locked","data.welded"],s:'(_0?"bolted":"")+(_0&&_1?" and ":"")+(_1?"welded":"")'},p:[124,32,5192]}]}," ]"],n:50,x:{r:["data.locked","data.welded"],s:"_0||_1"},p:[123,3,5125]}," ",{p:[126,3,5327],t:7,e:"div",a:{style:"float:right"},f:[{p:[127,4,5357],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(_2&&"disabled")'},p:[127,22,5375]}],icon:"sign-out",action:"open-close"},f:["Open door"]}," ",{p:[128,4,5502],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(!_2&&"disabled")'},p:[128,22,5520]}],icon:"sign-in",action:"open-close"},f:["Close door"]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],356:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,267],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,312],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[10,7,355],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,372]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,423]}]}]}],n:50,r:"data.siliconUser",p:[8,3,282]},{t:4,n:51,f:[{p:[13,5,514],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,540]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,625],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,719],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,762],t:7,e:"ui-section",f:[{p:[21,11,786],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,803]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,873]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,937]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1045],t:7,e:"ui-section",f:[{p:[25,11,1069],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1086]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1154]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1236]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1322],t:7,e:"br"}," ",{p:[29,9,1337],t:7,e:"ui-section",f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1494],t:7,e:"ui-section",f:[{p:[33,11,1518],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1657],t:7,e:"ui-section",f:[{p:[36,11,1681],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1810],t:7,e:"ui-section",f:[{p:[39,11,1834],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,680]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,2032],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2089],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2146],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2204],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,636]}]},r.exports.components=r.exports.components||{};var i={vents:t(362),modes:t(358),thresholds:t(361),status:t(360),scrubbers:t(359)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,358:358,359:359,360:360,361:361,362:362}],357:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{341:341}],358:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,115],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,168],t:7,e:"ui-section",f:[{p:[9,7,188],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,205]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,267]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,361]},"}"]},f:[{t:2,r:"name",p:[11,51,372]}]}]}],n:52,r:"data.modes",p:[7,3,142]}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],359:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," ",{p:{button:[{p:[6,5,185],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[9,5,242],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[9,27,264]}]},f:[{p:[10,7,287],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,323],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[11,26,340]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[11,68,382]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[12,46,459]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[12,66,479]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[12,80,493]}]}]}," ",{p:[14,7,558],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[15,9,593],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[15,26,610]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[15,71,655]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[16,50,738]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[16,70,758]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[16,88,776]}]}]}," ",{p:[18,7,858],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[19,9,894],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[19,26,911]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[19,70,955]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,1036]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[20,68,1056]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[20,84,1072]}]}]}," ",{p:[22,7,1148],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[23,9,1186],t:7,e:"filters"}]}]}],n:52,r:"data.scrubbers",p:[8,3,212]},{t:4,n:51,f:[{p:[27,5,1257],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457),back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357,457:457}],360:[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:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,110],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,129]}]},f:[{p:[5,6,146],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,159]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,237]},{t:2,r:"unit",p:[6,29,261]}]}]}],n:52,r:"adata.environment_data",p:[3,5,70]}," ",{p:[10,5,322],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,363],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,376]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,475]}]}]}," ",{p:[15,5,619],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,659],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,672]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,744]}]}]}],n:50,r:"data.environment_data",p:[2,3,35]},{t:4,n:51,f:[{p:[21,5,876],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,912],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1040],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1076],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,1014]}]}]},e.exports=a.extend(r.exports)},{341:341}],361:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" th, td {\r\n padding-right: 16px;\r\n text-align: left;\r\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,116],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,143],t:7,e:"table",f:[{p:[8,5,156],t:7,e:"thead",f:[{p:[8,12,163],t:7,e:"tr",f:[{p:[9,7,175],t:7,e:"th"}," ",{p:[10,7,192],t:7,e:"th",f:[{p:[10,11,196],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,238],t:7,e:"th",f:[{p:[11,11,242],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,288],t:7,e:"th",f:[{p:[12,11,292],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,338],t:7,e:"th",f:[{p:[13,11,342],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,401],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,441],t:7,e:"tr",f:[{p:[17,9,455],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,459]}]}," ",{t:4,f:[{p:[18,27,502],t:7,e:"td",f:[{p:[19,11,518],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,565]},'", "var": "',{t:2,r:"val",p:[19,76,583]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,594]}]}]}],n:52,r:"settings",p:[18,9,484]}]}],n:52,r:"data.thresholds",p:[16,7,416]}]}," ",{p:[23,3,697],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],362:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,113],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,166],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,188]}]},f:[{p:[9,7,211],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,264]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,306]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,383]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,403]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,417]}]}]}," ",{p:[13,7,482],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,517],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,523]}]}]}," ",{p:[16,7,616],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,665],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,698]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,779]},'", "val": ',{t:2,r:"checks",p:[18,68,799]},"}"]},f:["Internal"]}," ",{p:[19,9,842],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,876]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,957]},'", "val": ',{t:2,r:"checks",p:[20,68,977]},"}"]},f:["External"]}]}," ",{t:4,f:[{p:[23,9,1064],t:7,e:"ui-section",a:{label:"Internal Target Pressure"},f:[{p:[24,11,1121],t:7,e:"ui-button",a:{icon:"pencil",action:"set_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,33,1210]},'"}']},f:[{t:2,x:{r:["internal"],s:"Math.fixed(_0)"},p:[25,47,1224]}]}," ",{p:[26,11,1272],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["intdefault"],s:'_0?"disabled":null'},p:[26,44,1305]}],action:"reset_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,33,1407]},'"}']},f:["Reset"]}]}],n:50,r:"incheck",p:[22,7,1039]}," ",{t:4,f:[{p:[31,11,1511],t:7,e:"ui-section",a:{label:"External Target Pressure"},f:[{p:[32,13,1570],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,35,1661]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[33,49,1675]}]}," ",{p:[34,13,1725],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[34,46,1758]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[35,35,1862]},'"}']},f:["Reset"]}]}],n:50,r:"excheck",p:[30,7,1484]}]}],n:52,r:"data.vents",p:[7,3,140]},{t:4,n:51,f:[{p:[40,5,1973],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],363:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" table {\r\n width: 100%;\r\n border-spacing: 2px;\r\n }\r\n th {\r\n text-align: left;\r\n }\r\n td {\r\n vertical-align: top;\r\n }\r\n td .button {\r\n margin-top: 4px\r\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",f:[{p:[3,5,34],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,51]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,111]}," Required"]}," ",{p:[4,5,172],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,251],t:7,e:"hr"}," ",{p:[7,3,260],t:7,e:"table",f:[{p:[8,3,271],t:7,e:"thead",f:[{p:[9,4,283],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,315],t:7,e:"th",f:[{p:[10,9,319],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,348]}]}]}],n:52,r:"data.regions",p:[9,8,287]}]}]}," ",{p:[13,3,403],t:7,e:"tbody",f:[{p:[14,4,415],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,447],t:7,e:"td",f:[{t:4,f:[{p:[16,11,481],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,498]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,546]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,621]},'"}']},f:[{t:2,r:"name",p:[17,56,631]}]}," ",{p:[18,9,661],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,451]}]}],n:52,r:"data.regions",p:[14,8,419]}]}]}]}," ",{p:[23,2,731],t:7,e:"hr"}," ",{p:[24,2,739],t:7,e:"span",a:{"class":"highlight bold"},f:["Unrestricted Access:"]}," ",{p:[25,2,798],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"check-square-o":"square-o"'},p:[25,19,815]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"selected":null'},p:[25,88,884]}],action:"direc_set",params:'{"unres_direction": "1"}'},f:["North"]}," ",{p:[26,2,1007],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"check-square-o":"square-o"'},p:[26,19,1024]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"selected":null'},p:[26,88,1093]}],action:"direc_set",params:'{"unres_direction": "4"}'},f:["East"]}," ",{p:[27,2,1215],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&2?"check-square-o":"square-o"'},p:[27,19,1232]}],style:[{t:2,x:{r:["data.unres_direction"], s:'_0&2?"selected":null'},p:[27,88,1301]}],action:"direc_set",params:'{"unres_direction": "2"}'},f:["South"]}," ",{p:[28,2,1424],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"check-square-o":"square-o"'},p:[28,19,1441]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"selected":null'},p:[28,88,1510]}],action:"direc_set",params:'{"unres_direction": "8"}'},f:["West"]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],364:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1206],t:7,e:"ui-notice",f:[{p:[47,3,1221],t:7,e:"b",f:[{p:[47,6,1224],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1255],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1327],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1355]}," seconds... ",{p:[50,3,1387],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1451],t:7,e:"br"},{p:[50,71,1455],t:7,e:"br"},{p:[50,75,1459],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1182]},{t:4,n:51,f:[{p:[53,2,1491],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1535],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1576],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1593]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1644]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1507]},{t:4,n:51,f:[{p:[59,3,1732],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1758]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1846],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1884],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1967],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1980]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,2019]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1921]},{t:4,n:51,f:[{p:[67,5,2079],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2096]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2149]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2212]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2293],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2345]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2381]}]}]}," ",{p:[74,4,2490],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2567],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2600]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2633]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2659]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2525]},{t:4,n:51,f:[{p:[78,5,2724],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2830],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2913],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2926]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2964]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2868]},{t:4,n:51,f:[{p:[86,4,3026],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,3043]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3093]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3156]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3236],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3249]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3286]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2790]}]}," ",{p:[94,2,3445],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3517],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3536]}],nowrap:0},f:[{p:[97,5,3560],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.powerChannels",m:[{t:30,n:"@index"},"powerLoad"]},p:[97,26,3581]}]}," ",{p:[98,5,3634],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3655],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3668]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3702]}]}]}," ",{p:[99,5,3751],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3773],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3779]}]},"]"]}," ",{p:[100,5,3849],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3942],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3975]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,4057]}]},f:["Auto"]}," ",{p:[104,6,4102],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4137]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4204]}]},f:["On"]}," ",{p:[106,6,4245],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4276]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4343]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3895]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3485]}," ",{p:[112,4,4439],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4474],t:7,e:"span",a:{"class":"bold"},f:[{t:2,r:"adata.totalLoad",p:[113,22,4493]}]}]}]}," ",{t:4,f:[{p:[117,4,4585],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4626],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4727],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4744]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4765]}],action:[{t:2,r:"malfAction",p:[120,97,4819]}]},f:[{t:2,r:"malfButton",p:[120,113,4835]}]}],n:50,r:"data.malfStatus",p:[119,3,4698]}]}],n:50,r:"data.siliconUser",p:[116,2,4556]}," ",{p:[124,2,4903],t:7,e:"ui-notice",f:[{p:[125,4,4919],t:7,e:"ui-section",a:{label:"Emergency Light Fallback"},f:[{t:4,f:[{p:[127,8,5020],t:7,e:"span",f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[127,14,5026]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,6,4971]},{t:4,n:51,f:[{p:[129,8,5106],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"emergency_lighting"},f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[129,66,5164]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[133,2,5275],t:7,e:"ui-notice",f:[{p:[134,4,5291],t:7,e:"ui-section",a:{label:"Night Shift Lighting"},f:[{t:4,f:[{p:[136,8,5388],t:7,e:"span",f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[136,14,5394]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[135,6,5339]},{t:4,n:51,f:[{p:[138,8,5475],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"toggle_nightshift"},f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[138,65,5532]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[142,2,5644],t:7,e:"ui-notice",f:[{p:[143,4,5660],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[145,5,5741],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[145,11,5747]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[144,3,5695]},{t:4,n:51,f:[{p:[147,5,5819],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[147,22,5836]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[147,79,5893]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{341:341}],365:[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:"Alarms"},f:[{p:[2,3,31],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,72],t:7,e:"li",f:[{p:[4,11,76],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,148]},'"}']},f:[{t:2,r:".",p:[4,92,157]}]}]}],n:52,r:"data.priority",p:[3,5,41]},{t:4,n:51,f:[{p:[6,7,201],t:7,e:"li",f:[{p:[6,11,205],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,303],t:7,e:"li",f:[{p:[9,11,307],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,380]},'"}']},f:[{t:2,r:".",p:[9,93,389]}]}]}],n:52,r:"data.minor",p:[8,5,275]},{t:4,n:51,f:[{p:[11,7,433],t:7,e:"li",f:[{p:[11,11,437],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],366:[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:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,102],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,124]}]},f:[{p:[4,7,167],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,200],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,206]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,302],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,346],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,352]}," K"]}]}],n:50,r:"temperature",p:[7,7,273]}," ",{t:4,f:[{p:[13,9,462],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,481]}]},f:[{p:[14,5,495],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,501]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,434]}]}],n:52,r:"adata.sensors",p:[2,3,73]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,704],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[25,5,792],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,835],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,852]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,903]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,968]}]}]}," ",{p:[29,5,1044],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1083],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1089]}," L/s"]}]}," ",{p:[32,5,1156],t:7,e:"ui-section",a:{label:"Output Regulator"},f:[{p:[33,7,1201],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1218]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1270]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1337]}]}]}," ",{p:[36,5,1412],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1456],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1499]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,618]}]},e.exports=a.extend(r.exports)},{341:341}],367:[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,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,518],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,524]}," kPa"]}]}," ",{p:[11,3,586],t:7,e:"ui-section",a:{label:"Filter"},f:[{t:4,f:[{p:[13,7,654],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[13,25,672]}],action:"filter",params:['{"mode": ',{t:2,r:"id",p:[14,42,748]},"}"]},f:[{t:2,r:"name",p:[14,51,757]}]}],n:52,r:"data.filter_types",p:[12,5,619]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],368:[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,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,522],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,528]}," kPa"]}]}," ",{p:[11,3,594],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,627],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,666]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,783],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,817]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,935],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,968]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1087],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1125]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1243],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1249]},"%"]}]}," ",{p:[22,3,1319],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1352],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1391]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1508],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1542]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1660],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1693]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1812],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1850]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1968],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1974]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],369:[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,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{t:4,f:[{p:[7,5,250],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,292],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,381],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,411]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,525],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,531]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,223]},{t:4,n:51,f:[{p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{341:341}],370:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,72],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"data.borg.name",p:[1,20,19]}],button:0},f:[" ",{p:[5,2,149],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[6,4,181],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"check-square-o":"square-o"'},p:[6,21,198]}],style:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"selected":null'},p:[6,83,260]}],action:"toggle_emagged"},f:["Emagged"]}," ",{p:[7,4,351],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"check-square-o":"square-o"'},p:[7,21,368]}],style:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"selected":null'},p:[7,84,431]}],action:"toggle_lockdown"},f:["Locked down"]}," ",{p:[8,4,528],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"check-square-o":"square-o"'},p:[8,21,545]}],style:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"selected":null'},p:[8,90,614]}],action:"toggle_scrambledcodes"},f:["Scrambled codes"]}]}," ",{p:[10,2,741],t:7,e:"ui-section",a:{label:"Charge"},f:[{t:4,f:[{p:[12,4,803],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.cell.maxcharge",p:[12,25,824]}],value:[{t:2,r:"data.cell.charge",p:[12,57,856]}]},f:[{t:2,x:{r:["data.cell.charge"],s:"Math.round(_0)"},p:[12,79,878]}," / ",{t:2,x:{r:["data.cell.maxcharge"],s:"Math.round(_0)"},p:[12,114,913]}]}],n:50,x:{r:["data.cell.missing"],s:"!_0"},p:[11,3,772]},{t:4,n:51,f:[{p:[14,4,974],t:7,e:"span",a:{"class":"warning"},f:["Cell missing"]},{p:[14,45,1015],t:7,e:"br"}],x:{r:["data.cell.missing"],s:"!_0"}}," ",{p:[16,3,1035],t:7,e:"ui-button",a:{icon:"pencil",action:"set_charge"},f:["Set"]},{p:[16,63,1095],t:7,e:"ui-button",a:{icon:"eject",action:"change_cell"},f:["Change"]},{p:[16,126,1158],t:7,e:"ui-button",a:{icon:"trash","class":"bad",action:"remove_cell"},f:["Remove"]}]}," ",{p:[18,2,1252],t:7,e:"ui-section",a:{label:"Radio channels"},f:[{t:4,f:[{p:[20,4,1319],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[20,21,1336]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[20,75,1390]}],action:"toggle_radio",params:['{"channel": "',{t:2,r:"name",p:[20,154,1469]},'"}']},f:[{t:2,r:"name",p:[20,166,1481]}]}],n:52,r:"data.channels",p:[19,3,1291]}]}," ",{p:[23,2,1533],t:7,e:"ui-section",a:{label:"Module"},f:[{t:4,f:[{p:[25,4,1591],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"check-square-o":"square-o"'},p:[25,21,1608]}],style:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"selected":null'},p:[25,97,1684]}],action:"setmodule",params:['{"module": "',{t:2,r:"type",p:[25,193,1780]},'"}']},f:[{t:2,r:"name",p:[25,205,1792]}]}],n:52,r:"data.modules",p:[24,3,1564]}]}," ",{p:[28,2,1844],t:7,e:"ui-section",a:{label:"Upgrades"},f:[{t:4,f:[{p:[30,4,1905],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[30,21,1922]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[30,75,1976]}],action:"toggle_upgrade",params:['{"upgrade": "',{t:2,r:"type",p:[30,155,2056]},'"}']},f:[{t:2,r:"name",p:[30,167,2068]}]}],n:52,r:"data.upgrades",p:[29,3,1877]}]}," ",{p:[33,2,2120],t:7,e:"ui-section",a:{label:"Master AI"},f:[{t:4,f:[{p:[35,4,2177],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["connected"],s:'_0?"check-square-o":"square-o"'},p:[35,21,2194]}],style:[{t:2,x:{r:["connected"],s:'_0?"selected":null'},p:[35,75,2248]}],action:"slavetoai",params:['{"slavetoai": "',{t:2,r:"ref",p:[35,152,2325]},'"}']},f:[{t:2,r:"name",p:[35,163,2336]}]}],n:52,r:"data.ais",p:[34,3,2154]}]}]}," ",{p:{button:[{p:[41,3,2460],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"check-square-o":"square-o"'},p:[41,20,2477]}],style:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"selected":null'},p:[41,84,2541]}],action:"toggle_lawupdate"},f:["Lawsync"]}]},t:7,e:"ui-display",a:{title:"Laws",button:0},f:[" ",{t:4,f:[{p:[44,3,2672],t:7,e:"p",f:[{t:2,r:".",p:[44,6,2675]}]}],n:52,r:"data.laws",p:[43,2,2649]}]}]},e.exports=a.extend(r.exports)},{341:341}],371:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],372:[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:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{341:341}],373:[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.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{341:341}],374:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove", -params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"desc",p:[85,31,2720]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[85,90,2779]},'"}']},f:[{t:2,r:"cost",p:[85,100,2789]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{341:341}],375:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,174],t:7,e:"ui-notice",f:[{t:4,f:[{p:[14,5,220],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[15,7,263],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[15,24,280]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[15,75,331]}]}]}],n:50,r:"data.siliconUser",p:[13,3,189]},{t:4,n:51,f:[{p:[18,5,422],t:7,e:"span",f:["Swipe a QM-Level ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[18,39,456]}," this interface."]}],r:"data.siliconUser"}]}," ",{t:4,f:[{p:[23,3,568],t:7,e:"ui-display",a:{title:"Express Cargo Console"},f:[{p:[25,5,618],t:7,e:"ui-section",a:{label:"Landing Location"},f:[{p:[26,7,663],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.usingBeacon"],s:'_0?null:"selected"'},p:[26,25,681]}],action:"LZCargo"},f:["Cargo Bay"]}," ",{p:[27,7,770],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.hasBeacon","data.usingBeacon"],s:'_0?_1?"selected":null:"disabled"'},p:[27,25,788]}],action:"LZBeacon"},f:[{t:2,r:"data.beaconzone",p:[27,116,879]}," (",{t:2,r:"data.beaconName",p:[27,137,900]},")"]}," ",{p:[28,7,940],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBuyBeacon"],s:'_0?null:"disabled"'},p:[28,25,958]}],action:"printBeacon"},f:[{t:2,r:"data.printMsg",p:[28,90,1023]}]}]}," ",{p:[31,5,1079],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[32,7,1115],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[32,13,1121]}]}]}," ",{p:[35,5,1183],t:7,e:"ui-section",a:{label:"Notice"},f:[{p:[36,7,1218],t:7,e:"span",f:[{t:2,r:"data.message",p:[36,13,1224]}]}]}]}," ",{p:[39,3,1287],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[39,18,1302]}]},f:[{t:4,f:[{p:[41,7,1349],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[41,18,1360]}]},f:[{t:4,f:[{p:[43,11,1407],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[43,30,1426]}],candystripe:0,right:0},f:[{p:[44,13,1468],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBeacon"],s:'_0?null:"disabled"'},p:[44,31,1486]}],tooltip:[{t:2,r:"desc",p:[44,80,1535]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[44,139,1594]},'"}']},f:[{t:2,r:"cost",p:[44,149,1604]}," Credits ",{t:2,r:"data.beaconError",p:[44,166,1621]}]}]}],n:52,r:"packs",p:[42,9,1380]}]}],n:52,r:"data.supplies",p:[40,5,1318]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[22,1,543]}]},e.exports=a.extend(r.exports)},{341:341}],376:[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:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities available."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{341:341}],377:[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,5,17],t:7,e:"span",f:["To use this, simply spawn the atoms you want in one of the four Centcom Supplypod Bays. Items in the bay will then be launched inside your supplypod, one turf-full at a time! You can optionally use the following buttons to configure how the supplypod acts."]}]}," ",{p:[5,1,304],t:7,e:"ui-display",a:{title:"Centcom Pod Customization (to be used against helen weinstein)"},f:[{p:[6,4,392],t:7,e:"ui-section",a:{label:"Which supplypod bay will you use?"},f:[{p:[7,9,458],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==1?"selected":null'},p:[7,27,476]}],action:"bay1"},f:["Bay #1"]}," ",{p:[8,9,557],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==2?"selected":null'},p:[8,27,575]}],action:"bay2"},f:["Bay #2"]}," ",{p:[9,9,656],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==3?"selected":null'},p:[9,27,674]}],action:"bay3"},f:["Bay #3"]}," ",{p:[10,9,755],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==4?"selected":null'},p:[10,27,773]}],action:"bay4"},f:["Bay #4"]}]}," ",{p:[13,5,871],t:7,e:"ui-section",a:{label:"Useful teleport tools!"},f:[{p:[14,9,926],t:7,e:"ui-button",a:{action:"teleportCentcom"},f:["Teleport to Centcom's Supplypod Loading Bay"]}," ",{p:[15,9,1027],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.oldArea"],s:'_0?null:"disabled"'},p:[15,27,1045]}],action:"teleportBack"},f:["Teleport Back to ",{t:2,x:{r:["data.oldArea"],s:'_0?_0:"where you were"'},p:[15,103,1121]}]}]}," ",{p:[18,5,1210],t:7,e:"ui-section",a:{label:"Keep stuff after launching?"},f:[{p:[19,9,1268],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchClone"],s:'_0?"selected":null'},p:[19,27,1286]}],action:"launchClone","tooltip-side":"left",tooltip:"Choosing this will create a duplicate of the item to be launched in Centcom, allowing you to send one type of item multiple times. Either way, the atoms are forceMoved into the supplypod after it lands (but before it opens)."},f:["Clone and Launch"]}]}," ",{p:[23,5,1668],t:7,e:"ui-section",a:{label:"Launch all at once?"},f:[{p:[24,9,1718],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==1?"selected":null'},p:[24,27,1736]}],action:"launchOrdered","tooltip-side":"left",tooltip:'Instead of launching everything in the bay at once, this will "scan" things (one turf-full at a time) in order, left to right and top to bottom. Refreshing will reset the "scanner" to the top-leftmost position.'},f:["Ordered"]}," ",{p:[26,9,2086],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==2?"selected":null'},p:[26,27,2104]}],action:"launchRandom","tooltip-side":"left",tooltip:"Instead of launching everything in the bay at once, this will launch one random turf of items at a time."},f:["Random"]}]}," ",{p:[30,5,2362],t:7,e:"ui-section",a:{label:"Add an explosion?"},f:[{p:[31,9,2410],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==1?"selected":null'},p:[31,27,2428]}],action:"explosionCustom","tooltip-side":"left",tooltip:"This will cause an explosion of whatever size you like (including flame range) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Custom Size"]}," ",{p:[33,9,2740],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==2?"selected":null'},p:[33,27,2758]}],action:"explosionBus","tooltip-side":"left",tooltip:"This will cause a maxcap explosion (dependent on server config) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Adminbus"]}]}," ",{p:[37,5,3066],t:7,e:"ui-section",a:{label:"Extra damage?","(default":"None)"},f:[{p:[38,9,3127],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==1?"selected":null'},p:[38,27,3145]}],action:"damageCustom","tooltip-side":"left",tooltip:"Anyone caught under the pod when it lands will be dealt this amount of brute damage. Sucks to be them!"},f:["Custom Damage"]}," ",{p:[40,9,3392],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==2?"selected":null'},p:[40,27,3410]}],action:"damageGib","tooltip-side":"left",tooltip:"This will attempt to gib any mob caught under the pod when it lands, as well as dealing a nice 5000 brute damage. Ya know, just to be sure!"},f:["Gib"]}]}," ",{p:[44,5,3698],t:7,e:"ui-section",a:{label:"Extra effects?"},f:[{p:[45,9,3743],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStun"],s:'_0?"selected":null'},p:[45,27,3761]}],action:"effectStun","tooltip-side":"left",tooltip:"Anyone who is on the turf when the supplypod is launched will be stunned until the supplypod lands. They cant get away that easy!"},f:["Stun"]}," ",{p:[47,9,4017],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectLimb"],s:'_0?"selected":null'},p:[47,27,4035]}],action:"effectLimb","tooltip-side":"left",tooltip:"This will cause anyone caught under the pod to lose a limb, excluding their head."},f:["Delimb"]}," ",{p:[49,9,4245],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBluespace"],s:'_0?"selected":null'},p:[49,27,4263]}],action:"effectBluespace","tooltip-side":"left",tooltip:"Gives the supplypod an advanced Bluespace Recyling Device. After opening, the supplypod will be warped directly to the surface of a nearby NT-designated trash planet (/r/ss13)."},f:["Bluespace"]}," ",{p:[51,9,4581],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStealth"],s:'_0?"selected":null'},p:[51,27,4599]}],action:"effectStealth","tooltip-side":"left",tooltip:'This hides the red target icon from appearing when you launch the supplypod. Combos well with the "Invisible" style. Sneak attack, go!'},f:["Stealth"]}," ",{p:[53,9,4869],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectQuiet"],s:'_0?"selected":null'},p:[53,27,4887]}],action:"effectQuiet","tooltip-side":"left",tooltip:"This will keep the supplypod from making any sounds, except for those specifically set by admins in the Sound section."},f:["Quiet Landing"]}," ",{p:[55,9,5143],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectReverse"],s:'_0?"selected":null'},p:[55,27,5161]}],action:"effectReverse","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, after landing, the supplypod will close (similar to a normal closet closing), and then launch back to the right centcom bay to drop off any new contents."},f:["Reverse Mode"]}," ",{p:[57,9,5498],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectMissile"],s:'_0?"selected":null'},p:[57,27,5516]}],action:"effectMissile","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, it will immediatley delete after landing (Similar visually to setting openDelay & departDelay to 0, but this looks nicer). Useful if you just wanna fuck some shit up. Combos well with the Missile style."},f:["Missile Mode"]}," ",{p:[59,9,5902],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectCircle"],s:'_0?"selected":null'},p:[59,27,5920]}],action:"effectCircle","tooltip-side":"left",tooltip:"This will make the supplypod come in from any angle. Im not sure why this feature exists, but here it is."},f:["Any Descent Angle"]}," ",{p:[61,9,6169],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBurst"],s:'_0?"selected":null'},p:[61,27,6187]}],action:"effectBurst","tooltip-side":"left",tooltip:"This will make each click launch 5 supplypods inaccuratly around the target turf (a 3x3 area). Combos well with the Missle Mode if you dont want shit lying everywhere after."},f:["Machine Gun Mode"]}," ",{p:[63,9,6501],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectTarget"],s:'_0?"selected":null'},p:[63,27,6519]}],action:"effectTarget","tooltip-side":"left",tooltip:"This will make the supplypod target a specific atom, instead of the mouses position. Smiting does this automatically!"},f:["Specific Target"]}," ",{p:[65,9,6778],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectName"],s:'_0?"selected":null'},p:[65,27,6796]}],action:"effectName","tooltip-side":"left",tooltip:"Allows you to add a custom name and description."},f:["Custom Name/Desc"]}]}," ",{p:[69,5,7e3],t:7,e:"ui-section",a:{label:"Sound?"},f:[{p:[70,9,7037],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingSound"],s:'_0?"selected":null'},p:[70,27,7055]}],action:"landingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod lands."},f:["Custom Landing Sound"]}," ",{p:[72,10,7245],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingSound"],s:'_0?"selected":null'},p:[72,28,7263]}],action:"openingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod opens."},f:["Custom Opening Sound"]}," ",{p:[74,9,7452],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.leavingSound"],s:'_0?"selected":null'},p:[74,27,7470]}],action:"leavingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod departs (whether that be delection in the case of a bluespace pod, or leaving for centcom for a reversing pod)."},f:["Custom Leaving Sound"]}," ",{p:[76,9,7764],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.soundVolume"],s:'_0?"selected":null'},p:[76,27,7782]}],action:"soundVolume","tooltip-side":"left",tooltip:"Choose the volume for the sound to play at. Default values are between 1 and 100, but hey, do whatever. Im a tooltip, not a cop."},f:["Admin Sound Volume"]}]}," ",{p:[80,5,8070],t:7,e:"ui-section",a:{label:"Delay timers?"},f:[{p:[81,9,8114],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingDelay"],s:'_0!=5?"selected":null'},p:[81,27,8132]}],action:"landingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to hit the station. By default this value is 0.5 seconds."},f:["Custom Landing Time"]}," ",{p:[83,10,8394],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingDelay"],s:'_0!=30?"selected":null'},p:[83,28,8412]}],action:"openingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to open after landing. Useful for giving whatevers inside the pod a nice dramatic entrance! By default this value is 3 seconds."},f:["Custom Opening Time"]}," ",{p:[85,9,8744],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.departureDelay"],s:'_0!=30?"selected":null'},p:[85,27,8762]}],action:"departureDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to leave after landing. By default this value is 3 seconds."},f:["Custom Leaving Time"]}]}," ",{p:[89,5,9047],t:7,e:"ui-section",a:{label:"Style?"},f:[{p:[90,9,9084],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==1?"selected":null'},p:[90,27,9102]}],action:"styleStandard","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to your standard Nanotrasen black and orange. Same color scheme as the normal station-used supplypods."},f:["Standard"]}," ",{p:[92,9,9405],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==2?"selected":null'},p:[92,27,9423]}],action:"styleBluespace","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to the same as the stations upgraded blue-and-white Bluespace Supplypods."},f:["Advanced"]}," ",{p:[94,9,9698],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==4?"selected":null'},p:[94,27,9716]}],action:"styleSyndie","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and blood-red. Great for sending meme-ops in style!"},f:["Syndicate"]}," ",{p:[96,9,9987],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==5?"selected":null'},p:[96,27,10005]}],action:"styleBlue","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and dark blue. Great for sending deathsquads in style!"},f:["Deathsquad"]}," ",{p:[98,10,10279],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==6?"selected":null'},p:[98,28,10297]}],action:"styleCult","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a blood and rune covered cult pod!"},f:["Cult Pod"]}," ",{p:[100,9,10524],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==7?"selected":null'},p:[100,27,10542]}],action:"styleMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large missile. Combos well with a missile mode, so the missile doesnt stick around after landing."},f:["Missile"]}," ",{p:[102,9,10836],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==8?"selected":null'},p:[102,27,10854]}],action:"styleSMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large blood-red missile. Combos well with missile mode, so the missile doesnt stick around after landing."},f:["Syndicate Missile"]}," ",{p:[104,9,11167],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==9?"selected":null'},p:[104,27,11185]}],action:"styleBox","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large, dark-green military supply crate."},f:["Supply Crate"]}," ",{p:[106,9,11423],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==10?"selected":null'},p:[106,27,11441]}],action:"styleHONK","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a colorful, clown inspired look."},f:["HONK"]}," ",{p:[108,9,11670],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==11?"selected":null'},p:[108,27,11688]}],action:"styleFruit","tooltip-side":"left",tooltip:"for when an orange is angry"},f:["Fruit~"]}," ",{p:[110,9,11851],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==12?"selected":null'},p:[110,27,11869]}],action:"styleInvisible","tooltip-side":"left",tooltip:'Makes the supplypod invisible! Useful for when you want to use this feature with a gateway or something. Combos well with the "Stealth" and "Quiet Landing" effects.'},f:["Invisible"]}," ",{p:[112,9,12175],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==13?"selected":null'},p:[112,27,12193]}],action:"styleGondola","tooltip-side":"left",tooltip:"this gondola can control when he wants to deliver his supplies if he has a smart enough mind, so offer up his body to ghosts for maximum enjoyment. (Make sure to turn off bluespace and set a arbitrarily high open-time if you do!)"},f:["Gondola (alive)"]}]}]}," ",{p:[117,1,12597],t:7,e:"ui-display",f:[{p:[118,5,12615],t:7,e:"ui-section",a:{label:[{t:2,r:"data.numObjects",p:[118,26,12636]}," turfs with launchable atoms found in Bay #",{t:2,r:"data.bay",p:[118,88,12698]}]},f:[{p:[119,9,12722],t:7,e:"ui-button",a:{action:"refresh","tooltip-side":"right",tooltip:"Manually refreshes the possible things to launch in the pod bay."},f:["Refresh Pod Bay"]}]}," ",{p:[123,5,12909],t:7,e:"ui-section",f:[{p:[124,9,12931],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.giveLauncher"],s:'_0?"selected":null'},p:[124,27,12949]}],action:"giveLauncher","tooltip-side":"right",tooltip:"THE CODEX ASTARTES CALLS THIS MANEUVER: STEEL RAIN!!"},f:["Enter Launch Mode"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],378:[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:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:[6,1,206],t:7,e:"ui-display",a:{title:"Saved Recipes",button:0},f:[{p:[7,3,251],t:7,e:"ui-section",f:[{p:[8,5,269],t:7,e:"ui-button",a:{icon:"plus",action:"add_recipe"},f:["Add Recipe"]}," ",{p:[9,2,337],t:7,e:"ui-button",a:{icon:"minus",action:"clear_recipes"},f:["Clear Recipes"]}," ",{t:4,f:[{p:[11,7,445],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense_recipe",params:['{"recipe": "',{t:2,r:"contents",p:[11,80,518]},'"}']},f:[{t:2,r:"recipe_name",p:[11,96,534]}]}],n:52,r:"data.recipes",p:[10,5,415]}]}]}," ",{p:{button:[{t:4,f:[{p:[18,7,719],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[18,37,749]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[18,114,826]},"}"]},f:[{t:2,r:".",p:[18,122,834]}]}],n:52,r:"data.beakerTransferAmounts",p:[17,5,675]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[21,3,886],t:7,e:"ui-section",f:[{t:4,f:[{p:[23,7,936],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[23,74,1003]},'"}']},f:[{t:2,r:"title",p:[23,84,1013]}]}],n:52,r:"data.chemicals",p:[22,5,904]}]}]}," ",{p:{button:[{t:4,f:[{p:[30,7,1190],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[30,66,1249]},"}"]},f:[{t:2,r:".",p:[30,74,1257]}]}],n:52,r:"data.beakerTransferAmounts",p:[29,5,1146]}," ",{p:[32,5,1295],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[32,36,1326]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[34,3,1423],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[36,7,1493],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[36,13,1499]},"/",{t:2,r:"data.beakerMaxVolume",p:[36,55,1541]}," Units"]}," ",{p:[37,7,1586],t:7,e:"br"}," ",{t:4,f:[{p:[39,9,1639],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[39,52,1682]}," units of ",{t:2,r:"name",p:[39,87,1717]}]},{p:[39,102,1732],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[38,7,1599]},{t:4,n:51,f:[{p:[41,9,1763],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[35,5,1458]},{t:4,n:51,f:[{p:[44,7,1839],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],379:[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:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,7,831],t:7,e:"br"}," ",{t:4,f:[{p:[21,9,885],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[21,52,928]}," units of ",{t:2,r:"name",p:[21,87,963]}]},{p:[21,102,978],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[20,7,845]},{t:4,n:51,f:[{p:[23,9,1009],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[26,7,1085],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],380:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,32],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,87]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,143]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,199]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"No beaker"'},p:[7,5,268]}]}," ",{p:[10,3,340],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,426],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,445]}," units of ",{t:2,r:"name",p:[13,60,480]}],nowrap:0},f:[{p:[14,7,505],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,555],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,608]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,653],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,706]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,751],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,804]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,851],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,904]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,954],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1007]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1058],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[20,52,1102]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,390]},{t:4,n:51,f:[{p:[24,5,1184],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,357]},{t:4,n:51,f:[{p:[27,5,1255],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1343],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1374],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1412]}]},f:["Destroy"]}," ",{p:[34,3,1470],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1508]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1577],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1629],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1648]}," units of ",{t:2,r:"name",p:[37,59,1683]}],nowrap:0},f:[{p:[38,6,1707],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1756],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1811]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1855],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1910]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1954],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2009]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2055],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2110]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2159],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2214]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2264],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[44,51,2308]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1594]}]}]}," ",{t:4,f:[{p:[52,3,2444],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2534],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[54,39,2568]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[54,88,2617]}]}," ",{p:[55,5,2698],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[55,27,2720]},"/",{t:2,r:"data.pillBotMaxContent",p:[55,51,2744]}]}],n:50,r:"data.isPillBottleLoaded",p:[53,4,2497]},{t:4,n:51,f:[{p:[57,5,2796],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[60,4,2860],t:7,e:"br"}," ",{p:[61,4,2870],t:7,e:"br"}," ",{p:[62,4,2880],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[62,63,2939]}]},f:["Create Pill (max 50µ)"]}," ",{p:[63,4,3023],t:7,e:"br"}," ",{p:[64,4,3033],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[64,63,3092]}]},f:["Create Multiple Pills"]}," ",{p:[65,4,3176],t:7,e:"br"}," ",{p:[66,4,3186],t:7,e:"br"}," ",{p:[67,4,3196],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,64,3256]}]},f:["Create Patch (max 40µ)"]}," ",{p:[68,4,3341],t:7,e:"br"}," ",{p:[69,4,3351],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[69,64,3411]}]},f:["Create Multiple Patches"]}," ",{p:[70,4,3497],t:7,e:"br"}," ",{p:[71,4,3507],t:7,e:"br"}," ",{p:[72,4,3517],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,65,3578]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[73,4,3664],t:7,e:"br"}," ",{p:[74,4,3674],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[74,65,3735]}]},f:["Dispense Buffer to Bottles"]}," ",{p:[75,4,3824],t:7,e:"br"}," ",{p:[76,4,3834],t:7,e:"br"}," ",{p:[77,4,3844],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[77,63,3903]}]},f:["Create Hypo Vial (max 30µ)"]}," ",{p:[78,4,3992],t:7,e:"br"}," ",{p:[79,4,4002],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[79,63,4061]}]},f:["Dispense Buffer to Hypo vials"]}," ",{p:[80,4,4154],t:7,e:"br"}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2421]},{t:4,n:51,f:[{p:[85,3,4197],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[86,4,4252], -t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[86,63,4311]}]},f:["Create Pack (max 10µ)"]}," ",{p:[87,4,4395],t:7,e:"br"}," ",{p:[88,4,4405],t:7,e:"br"}," ",{p:[89,4,4415],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[89,65,4476]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,1,0]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[93,2,4624],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[93,20,4642]}]},f:[{p:[94,3,4673],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[95,3,4721],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[95,46,4764]}]}," ",{p:[96,3,4807],t:7,e:"br"}," ",{p:[97,3,4816],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[98,3,4858],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[98,23,4878]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[98,69,4924]}]},f:[{t:2,r:"data.analyzeVars.color",p:[98,97,4952]}]}," ",{p:[99,3,4989],t:7,e:"br"}," ",{p:[100,3,4998],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[101,3,5040],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[101,25,5062]}]}," ",{p:[102,3,5099],t:7,e:"br"}," ",{p:[103,3,5108],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[104,3,5164],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[104,25,5186]},"µ/minute"]}," ",{p:[105,3,5234],t:7,e:"br"}," ",{p:[106,3,5243],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[107,3,5298],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[107,25,5320]}]}," ",{p:[108,3,5357],t:7,e:"br"}," ",{p:[109,3,5366],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[110,3,5422],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[110,25,5444]}]}," ",{p:[111,3,5482],t:7,e:"br"}," ",{p:[112,3,5491],t:7,e:"br"}," ",{p:[113,3,5500],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{341:341}],381:[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:"Recipient Contents"},f:[{p:[2,2,42],t:7,e:"ui-section",f:[{p:[3,3,58],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[3,34,89]}],action:"ejectBeaker"},f:["Eject"]}," ",{p:[4,3,176],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[4,35,208]}],action:"input"},f:["Input"]}," ",{p:[5,3,289],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,35,321]}],action:"amount"},f:[{t:2,r:"data.amount",p:[5,96,382]},"U"]}," ",{p:[6,3,414],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"disabled":null'},p:[6,33,444]}],action:"makecup"},f:["Create Beaker"]}]}]}," ",{p:[9,1,564],t:7,e:"ui-display",a:{title:"Recipient"},f:[{p:[10,2,597],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[12,4,662],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[12,10,668]},"/",{t:2,r:"data.beakerMaxVolume",p:[12,52,710]}," Units"]}," ",{t:4,f:[{p:[14,5,788],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[14,48,831]}," units of ",{t:2,r:"name",p:[14,83,866]}]},{p:[14,98,881],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[13,4,752]},{t:4,n:51,f:[{p:[16,5,905],t:7,e:"span",a:{"class":"bad"},f:["Recipient Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,3,630]},{t:4,n:51,f:[{p:[19,4,976],t:7,e:"span",a:{"class":"average"},f:["No Recipient"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],382:[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,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}]}," ",{t:4,f:[{p:[5,3,149],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[6,3,165]}," ",{t:4,f:[{p:[8,4,231],t:7,e:"br"},{p:[8,8,235],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[8,63,290]},'"}']},f:[{t:3,r:"name",p:[8,75,302]}," - ",{t:3,r:"desc",p:[8,88,315]}]}],n:52,r:"data.recollection_categories",p:[7,3,188]}," ",{t:3,r:"data.rec_section",p:[10,3,354]}," ",{t:3,r:"data.rec_binds",p:[11,3,380]}]}],n:50,r:"data.recollection",p:[4,1,120]},{t:4,n:51,f:[{p:[14,2,431],t:7,e:"ui-display",a:{title:"Power",button:0},f:[{p:[15,4,469],t:7,e:"ui-section",f:[{t:3,r:"data.power",p:[16,6,488]}]}]}," ",{p:[19,2,541],t:7,e:"ui-display",f:[{p:[20,3,557],t:7,e:"ui-section",f:[{p:[21,4,574],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[21,22,592]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[22,4,715],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[22,22,733]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[23,4,857],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[23,22,875]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[24,4,1014],t:7,e:"br"},{t:3,r:"data.tier_info",p:[24,8,1018]}]}," ",{p:[26,3,1059],t:7,e:"ui-section",f:[{t:3,r:"data.scripturecolors",p:[27,4,1076]}]},{p:[28,16,1119],t:7,e:"hr"}," ",{p:[29,3,1127],t:7,e:"ui-section",f:[{t:4,f:[{p:[31,4,1172],t:7,e:"div",f:[{p:[31,9,1177],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[31,29,1197]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[31,99,1267]},'"}']},f:["Recite ",{t:3,r:"required",p:[31,118,1286]}]}," ",{t:4,f:[{t:4,f:[{p:[34,6,1362],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[34,53,1409]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[34,72,1428]}]}],n:50,r:"bound",p:[33,5,1342]},{t:4,n:51,f:[{p:[36,6,1472],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[36,53,1519]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[32,6,1319]}," ",{t:3,r:"name",p:[39,6,1586]}," ",{t:3,r:"descname",p:[39,17,1597]}," ",{t:3,r:"invokers",p:[39,32,1612]}]}],n:52,r:"data.scripture",p:[30,3,1143]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{341:341}],383:[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:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve"},f:["ve"]}," ",{p:[26,3,1920],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1939]}],action:"odr"},f:["odr"]}," ",{p:[27,3,2021],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2040]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2124],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2143]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2223],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2242]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2326],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2345]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2427],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2446]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2532],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2551]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2635],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2654]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2738],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2757]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2839],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2858]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2942],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2961]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3045],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3064]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3146],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3165]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3268],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3299],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3318]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3409],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3428]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3529],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3548]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3645],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3664]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3786],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3805]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3909],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3941],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],384:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{341:341}],385:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"text_buffer",p:[32,37,942]}]}," ",{p:[34,2,976],t:7,e:"ui-section",f:[{p:[34,14,988],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],386:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{isHead:function(t){return t%10==0},dept_class:function(t){return 0==t?"dept-cap":t>=10&&20>t?"dept-sec":t>=20&&30>t?"dept-med":t>=30&&40>t?"dept-sci":t>=40&&50>t?"dept-eng":t>=50&&60>t?"dept-cargo":t>=200&&230>t?"dept-cent":"dept-other"},health_state:function(t,e,n,a){var r=t+e+n+a;return 0>=r?"health-5":25>=r?"health-4":50>=r?"health-3":75>=r?"health-2":"health-0"}}}}(r),r.exports.css=" .health {\r\n width: 16px;\r\n height: 16px;\r\n background-color: #FFF;\r\n border: 1px solid #434343;\r\n position: relative;\r\n top: 2px;\r\n display: inline-block;\r\n }\r\n .health-5 { background-color: #17d568; }\r\n .health-4 { background-color: #2ecc71; }\r\n .health-3 { background-color: #e67e22; }\r\n .health-2 { background-color: #ed5100; }\r\n .health-1 { background-color: #e74c3c; }\r\n .health-0 { background-color: #ed2814; }\r\n\r\n .dept-cap {color : #C06616;}\r\n .dept-sec {color : #E74C3C;}\r\n .dept-med {color : #3498DB;}\r\n .dept-sci {color : #9B59B6;}\r\n .dept-eng {color : #F1C40F;}\r\n .dept-cargo {color : #F39C12;}\r\n .dept-cent {color : #00C100;}\r\n .dept-other {color: #C38312;}\r\n\r\n .oxy { color : #3498db; }\r\n .toxin { color : #2ecc71; }\r\n .burn { color : #e67e22; }\r\n .brute { color : #e74c3c; }\r\n\r\n table.crew{\r\n border-collapse: collapse;\r\n }\r\n\r\n table.crew td {\r\n padding : 0px 10px;\r\n }",r.exports.template={v:3,t:[" ",{p:[27,1,1030],t:7,e:"ui-display",f:[{p:[28,2,1045],t:7,e:"ui-section",f:[{p:[29,3,1061],t:7,e:"table",a:{"class":"crew"},f:[{p:[30,3,1085],t:7,e:"thead",f:[{p:[31,3,1096],t:7,e:"tr",f:[{p:[32,4,1105],t:7,e:"th",f:["Name"]}," ",{p:[33,4,1123],t:7,e:"th",f:["Status"]}," ",{p:[34,4,1143],t:7,e:"th",f:["Vitals"]}," ",{p:[35,4,1163],t:7,e:"th",f:["Position"]}," ",{t:4,f:[{p:[37,5,1216],t:7,e:"th",f:["Tracking"]}],n:50,r:"data.link_allowed",p:[36,4,1185]}]}]}," ",{p:[41,3,1270],t:7,e:"tbody",f:[{t:4,f:[{p:[43,4,1308],t:7,e:"tr",f:[{p:[44,5,1318],t:7,e:"td",f:[{p:[45,6,1329],t:7,e:"span",a:{"class":[{t:2,x:{r:["isHead","ijob"],s:'_0(_1)?"bold ":""'},p:[45,19,1342]},{t:2,x:{r:["dept_class","ijob"],s:"_0(_1)"},p:[45,49,1372]}]},f:[{t:2,r:"name",p:[46,7,1402]}," (",{t:2,r:"assignment",p:[46,17,1412]},") ",{p:[47,6,1434],t:7,e:"span",f:[]}]}]}," ",{p:[49,5,1457],t:7,e:"td",f:[{t:4,f:[{p:[51,7,1498],t:7,e:"span",a:{"class":["health ",{t:2,x:{r:["health_state","oxydam","toxdam","burndam","brutedam"],s:"_0(_1,_2,_3,_4)"},p:[51,27,1518]}]}}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[50,6,1468]},{t:4,n:51,f:[{t:4,f:[{p:[54,8,1626],t:7,e:"span",a:{"class":"health health-5"}}],n:50,r:"life_status",p:[53,7,1598]},{t:4,n:51,f:[{p:[56,8,1688],t:7,e:"span",a:{"class":"health health-0"}}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[60,5,1771],t:7,e:"td",f:[{t:4,f:[{p:[62,7,1812],t:7,e:"span",f:["( ",{p:[64,8,1836],t:7,e:"span",a:{"class":"oxy"},f:[{t:2,r:"oxydam",p:[64,26,1854]}]}," / ",{p:[66,8,1890],t:7,e:"span",a:{"class":"toxin"},f:[{t:2,r:"toxdam",p:[66,28,1910]}]}," / ",{p:[68,8,1946],t:7,e:"span",a:{"class":"burn"},f:[{t:2,r:"burndam",p:[68,27,1965]}]}," / ",{p:[70,8,2002],t:7,e:"span",a:{"class":"brute"},f:[{t:2,r:"brutedam",p:[70,28,2022]}]}," )"]}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[61,6,1782]},{t:4,n:51,f:[{t:4,f:[{p:[75,8,2116],t:7,e:"span",f:["Alive"]}],n:50,r:"life_status",p:[74,7,2088]},{t:4,n:51,f:[{p:[77,8,2159],t:7,e:"span",f:["Dead"]}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[81,5,2222],t:7,e:"td",f:[{t:4,f:[{p:[83,6,2260],t:7,e:"span",f:[{t:2,r:"area",p:[83,12,2266]}]}],n:50,x:{r:["pos_x"],s:"_0!=null"},p:[82,5,2232]},{t:4,n:51,f:[{p:[85,6,2302],t:7,e:"span",f:["N/A"]}],x:{r:["pos_x"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[89,6,2381],t:7,e:"td",f:[{p:[90,7,2393],t:7,e:"ui-button",a:{action:"select_person",state:[{t:2,x:{r:["can_track"],s:'_0?null:"disabled"'},p:[90,48,2434]}],params:['{"name":"',{t:2,r:"name",p:[90,100,2486]},'"}']},f:["Track"]}]}],n:50,r:"data.link_allowed",p:[88,5,2348]}]}],n:52,r:"data.sensors",p:[42,3,1281]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],387:[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,189],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,223],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,236]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,265]}]}]}," ",{p:[9,4,317],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,356],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,369]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,406]}," K"]}]}," ",{p:[12,5,472],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,507],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,520]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,554]}],value:[{t:2,r:"data.occupant.health",p:[13,90,590]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,632]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,684]}]}]}," ",{t:4,f:[{p:[17,7,908],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,927]}]},f:[{p:[18,9,948],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,969]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,1005]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1042]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,742]}],n:50,r:"data.hasOccupant",p:[5,3,159]}]}," ",{p:[23,1,1138],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1167],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1199],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1216]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1276]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1332]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1391]}]}]}," ",{p:[30,3,1459],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1495],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1508]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1536]}," K"]}]}," ",{p:[33,2,1588],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1619],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1636]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1687]}]}," ",{p:[35,5,1740],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1757]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1821]}]}]}]}," ",{p:{button:[{p:[40,5,1967],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1998]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2101],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2211],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2254]}," units of ",{t:2,r:"name",p:[45,72,2274]}]},{p:[45,87,2289],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2171]},{t:4,n:51,f:[{p:[47,9,2320],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2136]},{t:4,n:51,f:[{p:[50,7,2396],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],388:[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",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"' -},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],389:[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:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{341:341}],390:[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,183],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,225],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,231]}]}]}],n:50,r:"data.items",p:[5,3,159]}," ",{t:4,f:[{p:[11,5,310],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,344],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,357]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,386]}]}]}," ",{p:[14,5,439],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,474],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,487]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,521]}],value:[{t:2,r:"data.occupant.health",p:[15,90,557]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,599]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,651]}]}]}," ",{t:4,f:[{p:[19,7,888],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,907]}]},f:[{p:[20,9,928],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,949]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,985]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1022]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,722]}," ",{p:[23,5,1109],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1145],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1158]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1204]}]}]}," ",{p:[26,5,1287],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1323],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1336]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1382]}]}]}," ",{p:[29,5,1466],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1553],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1596]}," units of ",{t:2,r:"name",p:[31,89,1631]}]},{p:[31,104,1646],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1508]},{t:4,n:51,f:[{p:[33,11,1681],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,283]}]}," ",{p:[38,1,1777],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1812],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1872],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1903]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1976]},'"}']},f:[{t:2,r:"name",p:[41,121,1986]}]},{p:[41,141,2006],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1845]}]}," ",{p:[44,2,2046],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2079],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2166],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2204],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],391:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{341:341}],392:[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,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{341:341}],393:[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,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131]}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{341:341}],394:[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 requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{341:341}],395:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,20],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,163],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,232],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,256]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,339]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,449],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,484],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,520],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,559],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,620],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,680],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,719],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,808],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,845],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,876]}]}," ",{p:[31,7,910],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,941]}]}," ",{p:[34,7,977],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,1008],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1084],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1136],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,773]}]}],n:50,r:"data.show_materials",p:[13,3,417]}]}," ",{p:[45,2,1274],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1334],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1345]}]}],r:"data.categories",p:[46,3,1309]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{341:341}],396:[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,3,16],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,49],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,111]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,166]}]}]}," ",{p:[9,3,235],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,292],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,314]},{p:[11,30,319],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,269]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],397:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{341:341}],398:[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:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{341:341}],399:[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:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],400:[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:"center",f:[{p:[2,10,23],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[2,40,53]}]}]}]}," ",{p:[4,1,135],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[6,3,194],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[6,22,213]}]},f:[{p:[7,4,228],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[7,56,280]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[7,72,296]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[5,2,171]}]}]},e.exports=a.extend(r.exports)},{341:341}],401:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{341:341}],402:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],403:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{341:341}],404:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{341:341}],405:[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:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"ID"},f:[{p:[10,3,215],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[10,33,245]}]}]}," ",{t:4,f:[{p:[13,3,339],t:7,e:"ui-section",a:{label:"Points collected"},f:[{p:[14,4,381],t:7,e:"span",f:[{t:2,r:"data.points",p:[14,10,387]}]}]}," ",{p:[16,3,430],t:7,e:"ui-section",a:{label:"Goal"},f:[{p:[17,4,460],t:7,e:"span",f:[{t:2,r:"data.goal",p:[17,10,466]}]}]}," ",{p:[19,3,507],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[20,4,549],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[20,10,555]}]}," ",{p:[21,4,592],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[21,43,631]}]},f:["Claim points"]}]}],n:50,r:"data.id",p:[12,2,320]}]}," ",{p:[25,1,745],t:7,e:"ui-display",f:[{p:[26,2,760],t:7,e:"center",f:[{p:[27,3,772],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[27,42,811]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],406:[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:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{341:341}],407:[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:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section", -a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{341:341}],408:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{341:341}],409:[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:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{341:341}],410:[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:"Nanite Chamber Console"},f:[{p:[2,1,45],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,2,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,63,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,3,200],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[6,36,233]}]}," ",{p:[7,3,268],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[7,35,300]}]}," ",{p:[8,3,335],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[8,41,373]}]}," ",{t:4,f:[{p:[10,4,477],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[10,41,514]}]}],n:50,r:"data.disk.activation_delay",p:[9,3,438]}," ",{t:4,f:[{p:[13,4,600],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[13,30,626]}]}," ",{p:[14,4,663],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[14,36,695]}]}],n:50,r:"data.disk.timer",p:[12,3,572]}," ",{t:4,f:[{p:[17,4,785],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[17,40,821]}]}],n:50,r:"data.disk.activation_code",p:[16,3,747]}," ",{t:4,f:[{p:[20,4,918],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[20,42,956]}]}],n:50,r:"data.disk.deactivation_code",p:[19,3,878]}," ",{t:4,f:[{p:[23,4,1047],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[23,34,1077]}]}],n:50,r:"data.disk.kill_code",p:[22,3,1015]}," ",{t:4,f:[{p:[26,4,1163],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[26,37,1196]}]}],n:50,r:"data.disk.trigger_code",p:[25,3,1128]}," ",{t:4,f:[{t:4,f:[{p:[30,6,1332],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[30,25,1351]}]},f:[{t:2,r:"value",p:[30,35,1361]}]}],n:52,r:"data.disk.extra_settings",p:[29,4,1291]}],n:50,r:"data.disk.has_extra_settings",p:[28,3,1250]}],n:50,r:"data.has_program",p:[5,2,172]},{t:4,n:51,f:[{p:[34,3,1423],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,1,80]},{t:4,n:51,f:[{p:[37,2,1489],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[40,1,1550],t:7,e:"br"}," ",{t:4,f:[{p:[42,2,1582],t:7,e:"ui-notice",f:[{t:2,r:"data.status_msg",p:[42,13,1593]}]}],n:50,r:"data.status_msg",p:[41,1,1556]},{t:4,n:51,f:[{p:[44,2,1637],t:7,e:"ui-display",a:{title:"Chamber"},f:[{p:[45,2,1668],t:7,e:"ui-section",f:[{p:[45,14,1680],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock-open":"lock"'},p:[45,30,1696]}],action:"toggle_lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[45,90,1756]}," Chamber"]},{p:[45,146,1812],t:7,e:"br"}]}," ",{p:[46,2,1832],t:7,e:"ui-section",f:[{p:[46,14,1844],t:7,e:"b",f:["Occupant:"]}," ",{t:2,r:"data.occupant_name",p:[46,31,1861]}]}," ",{t:4,f:[{p:[48,4,1929],t:7,e:"ui-section",f:[{p:[48,16,1941],t:7,e:"ui-notice",f:["No nanites detected."]}]}," ",{p:[49,4,2002],t:7,e:"ui-section",f:[{p:[49,16,2014],t:7,e:"ui-button",a:{icon:"syringe",action:"nanite_injection"},f:["Implant Nanites"]}]}],n:50,x:{r:["data.has_nanites"],s:"!_0"},p:[47,2,1899]},{t:4,n:51,f:[{p:[51,3,2121],t:7,e:"ui-display",a:{title:"Nanites"},f:[{t:4,f:[{p:[53,5,2181],t:7,e:"ui-button",a:{icon:"download",action:"add_program"},f:["Install Program From Disk"]},{p:[53,90,2266],t:7,e:"br"}," ",{p:[54,5,2276],t:7,e:"br"}],n:50,r:"data.has_disk",p:[52,4,2154]}," ",{p:[56,4,2297],t:7,e:"ui-section",f:[{p:[57,5,2315],t:7,e:"ui-section",a:{label:"Nanite Volume"},f:[{t:2,r:"data.nanite_volume",p:[57,39,2349]}]}," ",{p:[58,5,2390],t:7,e:"ui-section",a:{label:"Growth Rate"},f:[{t:2,r:"data.regen_rate",p:[58,37,2422]}]}," ",{p:[59,5,2460],t:7,e:"ui-section",a:{label:"Safety Threshold"},f:[{t:2,r:"data.safety_threshold",p:[59,42,2497]}," ",{p:[59,68,2523],t:7,e:"ui-button",a:{icon:"pencil",action:"set_safety"},f:["Set"]}]}," ",{p:[60,5,2603],t:7,e:"ui-section",a:{label:"Cloud ID"},f:[{t:2,x:{r:["data.cloud_id"],s:'_0?_0:"No Cloud"'},p:[60,34,2632]}," ",{p:[60,82,2680],t:7,e:"ui-button",a:{icon:"pencil",action:"set_cloud"},f:["Set"]}]}]}," ",{p:[62,4,2776],t:7,e:"ui-display",a:{title:"Programs"},f:[{t:4,f:[{p:[64,6,2845],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[64,25,2864]}],button:0},f:[{p:[65,6,2888],t:7,e:"ui-button",a:{icon:"minus",action:"remove_program",params:['{"program_id": "',{t:2,r:"id",p:[65,78,2960]},'"}']},f:["Uninstall"]}," ",{p:[66,6,2998],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[66,38,3030]}]}," ",{t:4,f:[{p:[68,7,3094],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[68,45,3132]}]}," ",{p:[69,7,3191],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[69,44,3228]},"/s"]}," ",{t:4,f:[{p:[71,8,3291],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[71,41,3324]}]}," ",{p:[72,8,3362],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[72,45,3399]}," seconds"]}],n:50,r:"can_trigger",p:[70,7,3263]}," ",{t:4,f:[{t:4,f:[{p:[76,9,3534],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,46,3571]}]}],n:50,r:"activation_delay",p:[75,8,3500]}," ",{t:4,f:[{p:[79,9,3652],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,35,3678]}]}," ",{p:[80,9,3710],t:7,e:"ui-section",a:{label:"Timer Type"},f:[{t:2,r:"timer_type",p:[80,40,3741]}]}],n:50,r:"timer",p:[78,8,3629]}," ",{t:4,f:[{t:4,f:[{p:[84,11,3865],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,30,3884]}]},f:[{t:2,r:"value",p:[84,40,3894]}]}],n:52,r:"extra_settings",p:[83,9,3829]}],n:50,r:"has_extra_settings",p:[82,8,3793]}," ",{t:4,f:[{t:4,f:[{p:[89,10,4032],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[89,46,4068]}]}],n:50,r:"activation_code",p:[88,9,3998]}," ",{t:4,f:[{p:[92,10,4163],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[92,48,4201]}]}],n:50,r:"deactivation_code",p:[91,9,4127]}," ",{t:4,f:[{p:[95,10,4290],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[95,40,4320]}]}],n:50,r:"kill_code",p:[94,9,4262]}," ",{t:4,f:[{p:[98,10,4404],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[98,43,4437]}]}],n:50,r:"trigger_code",p:[97,9,4373]}],n:50,x:{r:["data.scan_level"],s:"_0>=4"},p:[87,8,3960]}],n:50,x:{r:["data.scan_level"],s:"_0>=3"},p:[74,7,3463]}],n:50,x:{r:["data.scan_level"],s:"_0>=2"},p:[67,6,3058]}]}],n:52,r:"data.mob_programs",p:[63,5,2811]}]}]}],x:{r:["data.has_nanites"],s:"!_0"}}]}],r:"data.status_msg"}]}]},e.exports=a.extend(r.exports)},{341:341}],411:[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:"Nanite Cloud Console"},f:[{p:[2,1,43],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,3,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,64,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,4,202],t:7,e:"ui-section",f:[{p:[7,5,220],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[7,38,253]}]}," ",{p:[8,5,290],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[8,37,322]}]}," ",{p:[9,5,359],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[9,43,397]}]}," ",{t:4,f:[{p:[11,6,505],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[11,43,542]}]}],n:50,r:"data.disk.activation_delay",p:[10,5,464]}," ",{t:4,f:[{p:[14,6,634],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[14,32,660]}]}," ",{p:[15,6,699],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[15,38,731]}]}],n:50,r:"data.disk.timer",p:[13,5,604]}," ",{t:4,f:[{p:[18,6,827],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[18,42,863]}]}],n:50,r:"data.disk.activation_code",p:[17,5,787]}," ",{t:4,f:[{p:[21,6,966],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[21,44,1004]}]}],n:50,r:"data.disk.deactivation_code",p:[20,5,924]}," ",{t:4,f:[{p:[24,6,1101],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[24,36,1131]}]}],n:50,r:"data.disk.kill_code",p:[23,5,1067]}," ",{t:4,f:[{p:[27,6,1223],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[27,39,1256]}]}],n:50,r:"data.disk.trigger_code",p:[26,5,1186]}," ",{t:4,f:[{t:4,f:[{p:[31,8,1400],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[31,27,1419]}]},f:[{t:2,r:"value",p:[31,37,1429]}]}],n:52,r:"data.disk.extra_settings",p:[30,6,1357]}],n:50,r:"data.disk.has_extra_settings",p:[29,5,1314]}]}],n:50,r:"data.has_program",p:[5,3,173]},{t:4,n:51,f:[{p:[36,4,1515],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,2,79]},{t:4,n:51,f:[{p:[39,3,1584],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[42,1,1646],t:7,e:"ui-display",a:{title:"Cloud Storage"},f:[{t:4,f:[{p:[44,3,1713],t:7,e:"ui-button",a:{icon:"plus-circle",action:"create_backup"},f:["Create New Backup"]}," ",{p:[45,3,1799],t:7,e:"ui-display",a:{title:"Active Backups"},f:[{t:4,f:[{p:[47,5,1873],t:7,e:"ui-button",a:{action:"set_view",params:['{"view": "',{t:2,r:"cloud_id",p:[47,52,1920]},'"}']},f:["Backup #",{t:2,r:"cloud_id",p:[47,76,1944]}]}],n:52,r:"data.cloud_backups",p:[46,4,1839]}]}],n:50,x:{r:["data.current_view"],s:"!_0"},p:[43,2,1683]},{t:4,n:51,f:[{p:[51,3,2014],t:7,e:"ui-button",a:{icon:"undo",action:"set_view",params:'{"view": "0"}'},f:["Return"]}," ",{t:4,f:[{p:[53,4,2131],t:7,e:"ui-notice",f:["ERROR: Backup not found."]}],n:50,x:{r:["data.cloud_backup"],s:"!_0"},p:[52,3,2100]},{t:4,n:51,f:[{p:[55,4,2195],t:7,e:"ui-display",a:{title:["Backup #",{t:2,r:"data.current_view",p:[55,31,2222]}]},f:[{t:4,f:[{p:[57,6,2282],t:7,e:"ui-button",a:{icon:"upload",action:"upload_program",style:"selected"},f:["Upload Program From Disk"]},{p:[57,108,2384],t:7,e:"br"}],n:50,r:"data.has_program",p:[56,5,2251]}," ",{t:4,f:[{p:[60,6,2443],t:7,e:"hr"}," ",{p:[61,6,2454],t:7,e:"ui-section",f:[{p:[62,7,2474],t:7,e:"h3",f:[{t:2,r:"name",p:[62,11,2478]}]}," ",{p:[63,7,2499],t:7,e:"div",a:{style:"float:right"},f:[{p:[64,8,2533],t:7,e:"ui-button",a:{icon:"minus-circle",action:"remove_program",style:"danger",params:['{"program_id": "',{t:2,r:"id",p:[64,102,2627]},'"}']},f:["Uninstall"]}]}]}," ",{p:[67,6,2699],t:7,e:"ui-section",f:[{p:[68,7,2719],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[68,39,2751]}]}," ",{p:[69,7,2780],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[69,45,2818]}]}," ",{p:[70,7,2877],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[70,44,2914]},"/s"]}," ",{t:4,f:[{p:[72,8,2977],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[72,41,3010]},"/s"]}," ",{p:[73,8,3050],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[73,45,3087]},"/s"]}],n:50,r:"can_trigger",p:[71,7,2949]}," ",{t:4,f:[{p:[76,8,3178],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,45,3215]}]}],n:50,r:"activation_delay",p:[75,7,3145]}," ",{t:4,f:[{p:[79,8,3293],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,34,3319]}]}," ",{p:[80,8,3350],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"timer_type",p:[80,40,3382]}]}],n:50,r:"timer",p:[78,7,3271]}," ",{t:4,f:[{p:[83,8,3464],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[83,44,3500]}]}],n:50,r:"activation_code",p:[82,7,3432]}," ",{t:4,f:[{p:[86,8,3589],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[86,46,3627]}]}],n:50,r:"deactivation_code",p:[85,7,3555]}," ",{t:4,f:[{p:[89,8,3710],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[89,38,3740]}]}],n:50,r:"kill_code",p:[88,7,3684]}," ",{t:4,f:[{p:[92,8,3818],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[92,41,3851]}]}],n:50,r:"trigger_code",p:[91,7,3789]}," ",{t:4,f:[{t:4,f:[{p:[96,10,3973],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[96,29,3992]}]},f:[{t:2,r:"value",p:[96,39,4002]}]}],n:52,r:"extra_settings",p:[95,8,3938]}],n:50,r:"has_extra_settings",p:[94,7,3903]}]}],n:52,r:"data.cloud_programs",p:[59,5,2407]}]}],x:{r:["data.cloud_backup"],s:"!_0"}}],x:{r:["data.current_view"],s:"!_0"}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],412:[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:"Nanite Program Hub"},f:[{t:4,f:[{p:[3,2,65],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{p:[4,3,102],t:7,e:"ui-section",f:[{p:[5,4,119],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{p:[6,4,185],t:7,e:"ui-button",a:{icon:"minus-circle",action:"clear"},f:["Delete Program"]}]}," ",{t:4,f:[{p:[9,4,307],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[9,37,340]}]}," ",{p:[10,4,376],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[10,36,408]}]}],n:50,r:"data.has_program",p:[8,3,278]},{t:4,n:51,f:[{p:[12,4,456],t:7,e:"ui-notice",f:["No program installed."]}],r:"data.has_program"}]}],n:50,r:"data.has_disk",p:[2,1,41]},{t:4,n:51,f:[{p:[16,2,540],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"},{p:[18,1,586],t:7,e:"br"}," ",{p:[19,1,592],t:7,e:"ui-display",a:{title:"Programs"},f:[{p:[20,2,624],t:7,e:"ui-section",f:[{p:[21,3,640],t:7,e:"ui-button",a:{icon:"undo",action:"set_category",params:'{"category": "Main"}'},f:["Return"]}," ",{p:[22,3,737],t:7,e:"ui-button",a:{icon:"align-justify ",action:"toggle_details"},f:[{t:2,x:{r:["data.detail_view"],s:'_0?"Compact View":"Detailed View"'},p:[22,60,794]}]}]}," ",{t:4,f:[{p:[25,3,916],t:7,e:"ui-display",f:[{t:4,f:[{p:[27,5,964],t:7,e:"ui-section",f:[{p:[27,17,976],t:7,e:"ui-button",a:{action:"set_category",params:['{"category": "',{t:2,r:"name",p:[27,72,1031]},'"}']},f:[{t:2,r:"name",p:[27,84,1043]}]}]}],n:52,r:"data.categories",p:[26,4,933]}]}],n:50,x:{r:["data.category"],s:'_0=="Main"'},p:[24,2,881]},{t:4,n:51,f:[{p:[31,3,1122],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[31,22,1141]}]},f:[{t:4,f:[{t:4,f:[{p:[34,6,1229],t:7,e:"ui-display",f:[{p:[35,7,1249],t:7,e:"ui-section",f:[{p:[35,19,1261],t:7,e:"b",f:[{t:2,r:"name",p:[35,22,1264]}]}]}," ",{p:[36,7,1297],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[36,19,1309]}]}," ",{p:[37,7,1338],t:7,e:"ui-section",f:[{p:[38,8,1359],t:7,e:"ui-button",a:{icon:"download",action:"download",params:['{"program_id": "',{t:2,r:"id",p:[38,77,1428]},'"}'],state:[{t:2,x:{r:["data.has_disk"],s:'_0?null:"disabled"'},p:[38,94,1445]}]},f:["Download"]}]}]}],n:50,r:"data.detail_view",p:[33,5,1198]},{t:4,n:51,f:[{p:[44,6,1585],t:7,e:"ui-section",f:[{p:[44,18,1597],t:7,e:"ui-button",a:{action:"download",params:['{"program_id": "',{t:2,r:"id",p:[44,71,1650]},'"}']},f:[{t:2,r:"name",p:[44,81,1660]}]}]}],r:"data.detail_view"}],n:52,r:"data.program_list",p:[32,4,1165]}]}],x:{r:["data.category"],s:'_0=="Main"'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],413:[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:"Nanite Programming"},f:[{t:4,f:[{p:[3,3,67],t:7,e:"ui-notice",f:["Insert a nanite program disk."]}],n:50,x:{r:["data.has_disk"],s:"!_0"},p:[2,1,41]},{t:4,n:51,f:[{p:[5,3,133],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{t:4,f:[{p:[7,5,229],t:7,e:"ui-notice",f:["No program detected."]}],n:50,x:{r:["data.has_program"],s:"!_0"},p:[6,3,198]},{t:4,n:51,f:[{p:[9,5,290],t:7,e:"ui-section",f:[{p:[10,7,310],t:7,e:"ui-display",a:{title:[{t:2,r:"data.name",p:[10,26,329]}]},f:[{t:2,r:"data.desc",p:[11,9,354]}]}]}," ",{p:[14,5,413],t:7,e:"ui-section",f:[{p:[15,7,433],t:7,e:"ui-section",a:{label:"Program Info"},f:["Nanites Consumed: ",{t:2,r:"data.use_rate",p:[16,26,493]},{p:[16,43,510],t:7,e:"br"}," ",{t:4,f:["Trigger Cost: ",{t:2,r:"data.trigger_cost",p:[18,25,574]},"u",{p:[18,47,596],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[17,9,524]}]}," ",{p:[22,7,648],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[23,9,685],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.activated"],s:'_0?"toggle-on":"toggle-off"'},p:[24,17,713]}],action:"toggle_active"},f:[{t:2,x:{r:["data.activated"],s:'_0?"Active":"Inactive"'},p:[26,11,809]}]}]}," ",{p:[30,7,905],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[31,9,944],t:7,e:"ui-button",a:{icon:"pencil",action:"set_activation_delay"}}," Activation Delay: ",{t:2,r:"data.activation_delay",p:[31,95,1030]}," ",{p:[31,121,1056],t:7,e:"br"}," ",{p:[32,9,1070],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer"}}," Timer: ",{t:2,r:"data.timer",p:[32,73,1134]}," ",{p:[32,88,1149],t:7,e:"br"}," ",{p:[33,9,1163],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer_type"}}," Timer Type: ",{t:2,r:"data.timer_type",p:[33,83,1237]}," ",{p:[33,103,1257],t:7,e:"br"}]}," ",{p:[36,7,1292],t:7,e:"ui-section",a:{label:"Codes"},f:[{p:[37,9,1328],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "activation"}'}}," Activation Code: ",{t:2,r:"data.activation_code",p:[37,121,1440]}," ",{p:[37,146,1465],t:7,e:"br"}," ",{p:[38,9,1479],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "deactivation"}'}}," Deactivation Code: ",{t:2,r:"data.deactivation_code",p:[38,125,1595]}," ",{p:[38,152,1622],t:7,e:"br"}," ",{p:[39,9,1636],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "kill"}'}}," Kill Code: ",{t:2,r:"data.kill_code",p:[39,109,1736]}," ",{p:[39,128,1755],t:7,e:"br"}," ",{t:4,f:[{p:[41,11,1805],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "trigger"}'}}," Trigger Code: ",{t:2,r:"data.trigger_code",p:[41,117,1911]}," ",{p:[41,139,1933],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[40,9,1769]}]}," ",{t:4,f:[{p:[46,9,2026],t:7,e:"ui-section",a:{label:"Special"},f:[{t:4,f:[{p:[48,13,2109],t:7,e:"ui-button",a:{icon:"pencil",action:"set_extra_setting",params:['{"target_setting": "',{t:2,r:"name",p:[48,93,2189]},'"}']}}," ",{t:2,r:"name",p:[48,118,2214]},": ",{t:2,r:"value",p:[48,128,2224]}," ",{p:[48,138,2234],t:7,e:"br"}],n:52,r:"data.extra_settings",p:[47,11,2066]}]}],n:50,r:"data.has_extra_settings",p:[45,7,1985]}]}],x:{r:["data.has_program"],s:"!_0"}}],x:{r:["data.has_disk"],s:"!_0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],414:[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:"Nanite Control"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-notice",f:["The interface is locked."]}],n:50,r:"data.locked",p:[2,1,37]},{t:4,n:51,f:[{p:[5,3,121],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock Interface"]}," ",{p:[6,3,188],t:7,e:"ui-button",a:{icon:"save",action:"save"},f:["Save Current Setting"]}," ",{p:[7,3,261],t:7,e:"ui-section",a:{label:"Signal Code"},f:[{p:[8,5,299],t:7,e:"span",f:[{t:2,r:"data.code",p:[8,11,305]}]}," ",{p:[9,4,330],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code"},f:["Set"]}]}," ",{t:4,f:[{p:[12,5,443],t:7,e:"ui-section",a:{label:"Relay Code"},f:[{p:[13,7,482],t:7,e:"span",f:[{t:2,r:"data.relay_code",p:[13,13,488]}]}," ",{p:[14,5,520],t:7,e:"ui-button",a:{icon:"pencil",action:"set_relay_code"},f:["Set"]}]}],n:50,x:{r:["data.mode"],s:'_0=="Relay"'},p:[11,3,409]}," ",{p:[17,3,618],t:7,e:"ui-section",a:{label:"Signal Mode"},f:[{p:[18,5,656],t:7,e:"span",f:[{t:2,r:"data.mode",p:[18,11,662]}]}," ",{p:[19,5,688],t:7,e:"br"}," ",{p:[20,4,697],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Off"}'},f:["Off"]}," ",{p:[21,5,775],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Local"}'},f:["Local"]}," ",{p:[22,5,857],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Targeted"}'},f:["Targeted"]}," ",{p:[23,5,945],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Area"}'},f:["Area"]}," ",{p:[24,5,1025],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Relay"}'},f:["Relay"]}]}],r:"data.locked"}]}," ",{p:[28,1,1144],t:7,e:"ui-display",a:{title:"Saved Settings"},f:[{t:4,f:[{p:[30,3,1215],t:7,e:"ui-button",a:{icon:"load",action:"load",params:['{"save_id": "',{t:2,r:"id",p:[30,61,1273]},'"}']},f:[{t:2,r:"name",p:[30,71,1283]}]}," ",{t:4,f:[{p:[32,4,1332],t:7,e:"ui-button",a:{icon:"remove",action:"remove_save",params:['{"save_id": "',{t:2,r:"id",p:[32,71,1399]},'"}']},f:["Remove"]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[31,3,1307]}," ",{p:[34,3,1442],t:7,e:"br"}],n:52,r:"data.saved_settings",p:[29,2,1182]}]}]},e.exports=a.extend(r.exports)},{341:341}],415:[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:"Ghost roles"},f:[{p:[2,2,35],t:7,e:"ui-section",a:{label:"Ignored roles"},f:[{t:4,f:[{p:[4,4,99],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[4,21,116]}],style:[{t:2,x:{r:["enabled"],s:'_0?"danger":null'},p:[4,73,168]}],action:"toggle_ignore",params:['{"key": "',{t:2,r:"key",p:[4,144,239]},'"}']},f:[{t:2,r:"desc",p:[4,155,250]}]}],n:52,r:"data.ignore",p:[3,3,73]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],416:[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:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{341:341}],417:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],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}],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]}," ",{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=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],384:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{341:341}],385:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"text_buffer",p:[32,37,942]}]}," ",{p:[34,2,976],t:7,e:"ui-section",f:[{p:[34,14,988],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],386:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{isHead:function(t){return t%10==0},dept_class:function(t){return 0==t?"dept-cap":t>=10&&20>t?"dept-sec":t>=20&&30>t?"dept-med":t>=30&&40>t?"dept-sci":t>=40&&50>t?"dept-eng":t>=50&&60>t?"dept-cargo":t>=200&&230>t?"dept-cent":"dept-other"},health_state:function(t,e,n,a){var r=t+e+n+a;return 0>=r?"health-5":25>=r?"health-4":50>=r?"health-3":75>=r?"health-2":"health-0"}}}}(r),r.exports.css=" .health {\r\n width: 16px;\r\n height: 16px;\r\n background-color: #FFF;\r\n border: 1px solid #434343;\r\n position: relative;\r\n top: 2px;\r\n display: inline-block;\r\n }\r\n .health-5 { background-color: #17d568; }\r\n .health-4 { background-color: #2ecc71; }\r\n .health-3 { background-color: #e67e22; }\r\n .health-2 { background-color: #ed5100; }\r\n .health-1 { background-color: #e74c3c; }\r\n .health-0 { background-color: #ed2814; }\r\n\r\n .dept-cap {color : #C06616;}\r\n .dept-sec {color : #E74C3C;}\r\n .dept-med {color : #3498DB;}\r\n .dept-sci {color : #9B59B6;}\r\n .dept-eng {color : #F1C40F;}\r\n .dept-cargo {color : #F39C12;}\r\n .dept-cent {color : #00C100;}\r\n .dept-other {color: #C38312;}\r\n\r\n .oxy { color : #3498db; }\r\n .toxin { color : #2ecc71; }\r\n .burn { color : #e67e22; }\r\n .brute { color : #e74c3c; }\r\n\r\n table.crew{\r\n border-collapse: collapse;\r\n }\r\n\r\n table.crew td {\r\n padding : 0px 10px;\r\n }",r.exports.template={v:3,t:[" ",{p:[27,1,1030],t:7,e:"ui-display",f:[{p:[28,2,1045],t:7,e:"ui-section",f:[{p:[29,3,1061],t:7,e:"table",a:{"class":"crew"},f:[{p:[30,3,1085],t:7,e:"thead",f:[{p:[31,3,1096],t:7,e:"tr",f:[{p:[32,4,1105],t:7,e:"th",f:["Name"]}," ",{p:[33,4,1123],t:7,e:"th",f:["Status"]}," ",{p:[34,4,1143],t:7,e:"th",f:["Vitals"]}," ",{p:[35,4,1163],t:7,e:"th",f:["Position"]}," ",{t:4,f:[{p:[37,5,1216],t:7,e:"th",f:["Tracking"]}],n:50,r:"data.link_allowed",p:[36,4,1185]}]}]}," ",{p:[41,3,1270],t:7,e:"tbody",f:[{t:4,f:[{p:[43,4,1308],t:7,e:"tr",f:[{p:[44,5,1318],t:7,e:"td",f:[{p:[45,6,1329],t:7,e:"span",a:{"class":[{t:2,x:{r:["isHead","ijob"],s:'_0(_1)?"bold ":""'},p:[45,19,1342]},{t:2,x:{r:["dept_class","ijob"],s:"_0(_1)"},p:[45,49,1372]}]},f:[{t:2,r:"name",p:[46,7,1402]}," (",{t:2,r:"assignment",p:[46,17,1412]},") ",{p:[47,6,1434],t:7,e:"span",f:[]}]}]}," ",{p:[49,5,1457],t:7,e:"td",f:[{t:4,f:[{p:[51,7,1498],t:7,e:"span",a:{"class":["health ",{t:2,x:{r:["health_state","oxydam","toxdam","burndam","brutedam"],s:"_0(_1,_2,_3,_4)"},p:[51,27,1518]}]}}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[50,6,1468]},{t:4,n:51,f:[{t:4,f:[{p:[54,8,1626],t:7,e:"span",a:{"class":"health health-5"}}],n:50,r:"life_status",p:[53,7,1598]},{t:4,n:51,f:[{p:[56,8,1688],t:7,e:"span",a:{"class":"health health-0"}}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[60,5,1771],t:7,e:"td",f:[{t:4,f:[{p:[62,7,1812],t:7,e:"span",f:["( ",{p:[64,8,1836],t:7,e:"span",a:{"class":"oxy"},f:[{t:2,r:"oxydam",p:[64,26,1854]}]}," / ",{p:[66,8,1890],t:7,e:"span",a:{"class":"toxin"},f:[{t:2,r:"toxdam",p:[66,28,1910]}]}," / ",{p:[68,8,1946],t:7,e:"span",a:{"class":"burn"},f:[{t:2,r:"burndam",p:[68,27,1965]}]}," / ",{p:[70,8,2002],t:7,e:"span",a:{"class":"brute"},f:[{t:2,r:"brutedam",p:[70,28,2022]}]}," )"]}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[61,6,1782]},{t:4,n:51,f:[{t:4,f:[{p:[75,8,2116],t:7,e:"span",f:["Alive"]}],n:50,r:"life_status",p:[74,7,2088]},{t:4,n:51,f:[{p:[77,8,2159],t:7,e:"span",f:["Dead"]}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[81,5,2222],t:7,e:"td",f:[{t:4,f:[{p:[83,6,2260],t:7,e:"span",f:[{t:2,r:"area",p:[83,12,2266]}]}],n:50,x:{r:["pos_x"],s:"_0!=null"},p:[82,5,2232]},{t:4,n:51,f:[{p:[85,6,2302],t:7,e:"span",f:["N/A"]}],x:{r:["pos_x"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[89,6,2381],t:7,e:"td",f:[{p:[90,7,2393],t:7,e:"ui-button",a:{action:"select_person",state:[{t:2,x:{r:["can_track"],s:'_0?null:"disabled"'},p:[90,48,2434]}],params:['{"name":"',{t:2,r:"name",p:[90,100,2486]},'"}']},f:["Track"]}]}],n:50,r:"data.link_allowed",p:[88,5,2348]}]}],n:52,r:"data.sensors",p:[42,3,1281]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],387:[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,189],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,223],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,236]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,265]}]}]}," ",{p:[9,4,317],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,356],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,369]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,406]}," K"]}]}," ",{p:[12,5,472],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,507],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,520]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,554]}],value:[{t:2,r:"data.occupant.health",p:[13,90,590]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,632]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,684]}]}]}," ",{t:4,f:[{p:[17,7,908],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,927]}]},f:[{p:[18,9,948],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,969]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,1005]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1042]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,742]}],n:50,r:"data.hasOccupant",p:[5,3,159]}]}," ",{p:[23,1,1138],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1167],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1199],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1216]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1276]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1332]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1391]}]}]}," ",{p:[30,3,1459],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1495],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1508]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1536]}," K"]}]}," ",{p:[33,2,1588],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1619],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1636]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1687]}]}," ",{p:[35,5,1740],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1757]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1821]}]}]}]}," ",{p:{button:[{p:[40,5,1967],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1998]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2101],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2211],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2254]}," units of ",{t:2,r:"name",p:[45,72,2274]}]},{p:[45,87,2289],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2171]},{t:4,n:51,f:[{p:[47,9,2320],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2136]},{t:4,n:51,f:[{p:[50,7,2396],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],388:[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",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{ +p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],389:[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:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{341:341}],390:[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,183],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,225],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,231]}]}]}],n:50,r:"data.items",p:[5,3,159]}," ",{t:4,f:[{p:[11,5,310],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,344],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,357]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,386]}]}]}," ",{p:[14,5,439],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,474],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,487]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,521]}],value:[{t:2,r:"data.occupant.health",p:[15,90,557]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,599]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,651]}]}]}," ",{t:4,f:[{p:[19,7,888],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,907]}]},f:[{p:[20,9,928],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,949]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,985]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1022]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,722]}," ",{p:[23,5,1109],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1145],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1158]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1204]}]}]}," ",{p:[26,5,1287],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1323],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1336]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1382]}]}]}," ",{p:[29,5,1466],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1553],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1596]}," units of ",{t:2,r:"name",p:[31,89,1631]}]},{p:[31,104,1646],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1508]},{t:4,n:51,f:[{p:[33,11,1681],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,283]}]}," ",{p:[38,1,1777],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1812],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1872],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1903]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1976]},'"}']},f:[{t:2,r:"name",p:[41,121,1986]}]},{p:[41,141,2006],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1845]}]}," ",{p:[44,2,2046],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2079],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2166],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2204],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],391:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{341:341}],392:[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,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{341:341}],393:[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,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131]}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{341:341}],394:[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 requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{341:341}],395:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,20],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,163],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,232],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,256]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,339]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,449],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,484],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,520],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,559],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,620],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,680],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,719],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,808],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,845],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,876]}]}," ",{p:[31,7,910],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,941]}]}," ",{p:[34,7,977],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,1008],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1084],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1136],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,773]}]}],n:50,r:"data.show_materials",p:[13,3,417]}]}," ",{p:[45,2,1274],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1334],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1345]}]}],r:"data.categories",p:[46,3,1309]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{341:341}],396:[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,3,16],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,49],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,111]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,166]}]}]}," ",{p:[9,3,235],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,292],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,314]},{p:[11,30,319],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,269]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],397:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{341:341}],398:[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:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{341:341}],399:[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:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],400:[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:"center",f:[{p:[2,10,23],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[2,40,53]}]}]}]}," ",{p:[4,1,135],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[6,3,194],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[6,22,213]}]},f:[{p:[7,4,228],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[7,56,280]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[7,72,296]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[5,2,171]}]}]},e.exports=a.extend(r.exports)},{341:341}],401:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{341:341}],402:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],403:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{341:341}],404:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{341:341}],405:[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:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"ID"},f:[{p:[10,3,215],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[10,33,245]}]}]}," ",{t:4,f:[{p:[13,3,339],t:7,e:"ui-section",a:{label:"Points collected"},f:[{p:[14,4,381],t:7,e:"span",f:[{t:2,r:"data.points",p:[14,10,387]}]}]}," ",{p:[16,3,430],t:7,e:"ui-section",a:{label:"Goal"},f:[{p:[17,4,460],t:7,e:"span",f:[{t:2,r:"data.goal",p:[17,10,466]}]}]}," ",{p:[19,3,507],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[20,4,549],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[20,10,555]}]}," ",{p:[21,4,592],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[21,43,631]}]},f:["Claim points"]}]}],n:50,r:"data.id",p:[12,2,320]}]}," ",{p:[25,1,745],t:7,e:"ui-display",f:[{p:[26,2,760],t:7,e:"center",f:[{p:[27,3,772],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[27,42,811]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],406:[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:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{341:341}],407:[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:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.", +"tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{341:341}],408:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{341:341}],409:[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:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{341:341}],410:[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:"Nanite Chamber Console"},f:[{p:[2,1,45],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,2,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,63,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,3,200],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[6,36,233]}]}," ",{p:[7,3,268],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[7,35,300]}]}," ",{p:[8,3,335],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[8,41,373]}]}," ",{t:4,f:[{p:[10,4,477],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[10,41,514]}]}],n:50,r:"data.disk.activation_delay",p:[9,3,438]}," ",{t:4,f:[{p:[13,4,600],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[13,30,626]}]}," ",{p:[14,4,663],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[14,36,695]}]}],n:50,r:"data.disk.timer",p:[12,3,572]}," ",{t:4,f:[{p:[17,4,785],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[17,40,821]}]}],n:50,r:"data.disk.activation_code",p:[16,3,747]}," ",{t:4,f:[{p:[20,4,918],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[20,42,956]}]}],n:50,r:"data.disk.deactivation_code",p:[19,3,878]}," ",{t:4,f:[{p:[23,4,1047],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[23,34,1077]}]}],n:50,r:"data.disk.kill_code",p:[22,3,1015]}," ",{t:4,f:[{p:[26,4,1163],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[26,37,1196]}]}],n:50,r:"data.disk.trigger_code",p:[25,3,1128]}," ",{t:4,f:[{t:4,f:[{p:[30,6,1332],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[30,25,1351]}]},f:[{t:2,r:"value",p:[30,35,1361]}]}],n:52,r:"data.disk.extra_settings",p:[29,4,1291]}],n:50,r:"data.disk.has_extra_settings",p:[28,3,1250]}],n:50,r:"data.has_program",p:[5,2,172]},{t:4,n:51,f:[{p:[34,3,1423],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,1,80]},{t:4,n:51,f:[{p:[37,2,1489],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[40,1,1550],t:7,e:"br"}," ",{t:4,f:[{p:[42,2,1582],t:7,e:"ui-notice",f:[{t:2,r:"data.status_msg",p:[42,13,1593]}]}],n:50,r:"data.status_msg",p:[41,1,1556]},{t:4,n:51,f:[{p:[44,2,1637],t:7,e:"ui-display",a:{title:"Chamber"},f:[{p:[45,2,1668],t:7,e:"ui-section",f:[{p:[45,14,1680],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock-open":"lock"'},p:[45,30,1696]}],action:"toggle_lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[45,90,1756]}," Chamber"]},{p:[45,146,1812],t:7,e:"br"}]}," ",{p:[46,2,1832],t:7,e:"ui-section",f:[{p:[46,14,1844],t:7,e:"b",f:["Occupant:"]}," ",{t:2,r:"data.occupant_name",p:[46,31,1861]}]}," ",{t:4,f:[{p:[48,4,1929],t:7,e:"ui-section",f:[{p:[48,16,1941],t:7,e:"ui-notice",f:["No nanites detected."]}]}," ",{p:[49,4,2002],t:7,e:"ui-section",f:[{p:[49,16,2014],t:7,e:"ui-button",a:{icon:"syringe",action:"nanite_injection"},f:["Implant Nanites"]}]}],n:50,x:{r:["data.has_nanites"],s:"!_0"},p:[47,2,1899]},{t:4,n:51,f:[{p:[51,3,2121],t:7,e:"ui-display",a:{title:"Nanites"},f:[{t:4,f:[{p:[53,5,2181],t:7,e:"ui-button",a:{icon:"download",action:"add_program"},f:["Install Program From Disk"]},{p:[53,90,2266],t:7,e:"br"}," ",{p:[54,5,2276],t:7,e:"br"}],n:50,r:"data.has_disk",p:[52,4,2154]}," ",{p:[56,4,2297],t:7,e:"ui-section",f:[{p:[57,5,2315],t:7,e:"ui-section",a:{label:"Nanite Volume"},f:[{t:2,r:"data.nanite_volume",p:[57,39,2349]}]}," ",{p:[58,5,2390],t:7,e:"ui-section",a:{label:"Growth Rate"},f:[{t:2,r:"data.regen_rate",p:[58,37,2422]}]}," ",{p:[59,5,2460],t:7,e:"ui-section",a:{label:"Safety Threshold"},f:[{t:2,r:"data.safety_threshold",p:[59,42,2497]}," ",{p:[59,68,2523],t:7,e:"ui-button",a:{icon:"pencil",action:"set_safety"},f:["Set"]}]}," ",{p:[60,5,2603],t:7,e:"ui-section",a:{label:"Cloud ID"},f:[{t:2,x:{r:["data.cloud_id"],s:'_0?_0:"No Cloud"'},p:[60,34,2632]}," ",{p:[60,82,2680],t:7,e:"ui-button",a:{icon:"pencil",action:"set_cloud"},f:["Set"]}]}]}," ",{p:[62,4,2776],t:7,e:"ui-display",a:{title:"Programs"},f:[{t:4,f:[{p:[64,6,2845],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[64,25,2864]}],button:0},f:[{p:[65,6,2888],t:7,e:"ui-button",a:{icon:"minus",action:"remove_program",params:['{"program_id": "',{t:2,r:"id",p:[65,78,2960]},'"}']},f:["Uninstall"]}," ",{p:[66,6,2998],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[66,38,3030]}]}," ",{t:4,f:[{p:[68,7,3094],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[68,45,3132]}]}," ",{p:[69,7,3191],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[69,44,3228]},"/s"]}," ",{t:4,f:[{p:[71,8,3291],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[71,41,3324]}]}," ",{p:[72,8,3362],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[72,45,3399]}," seconds"]}],n:50,r:"can_trigger",p:[70,7,3263]}," ",{t:4,f:[{t:4,f:[{p:[76,9,3534],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,46,3571]}]}],n:50,r:"activation_delay",p:[75,8,3500]}," ",{t:4,f:[{p:[79,9,3652],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,35,3678]}]}," ",{p:[80,9,3710],t:7,e:"ui-section",a:{label:"Timer Type"},f:[{t:2,r:"timer_type",p:[80,40,3741]}]}],n:50,r:"timer",p:[78,8,3629]}," ",{t:4,f:[{t:4,f:[{p:[84,11,3865],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,30,3884]}]},f:[{t:2,r:"value",p:[84,40,3894]}]}],n:52,r:"extra_settings",p:[83,9,3829]}],n:50,r:"has_extra_settings",p:[82,8,3793]}," ",{t:4,f:[{t:4,f:[{p:[89,10,4032],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[89,46,4068]}]}],n:50,r:"activation_code",p:[88,9,3998]}," ",{t:4,f:[{p:[92,10,4163],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[92,48,4201]}]}],n:50,r:"deactivation_code",p:[91,9,4127]}," ",{t:4,f:[{p:[95,10,4290],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[95,40,4320]}]}],n:50,r:"kill_code",p:[94,9,4262]}," ",{t:4,f:[{p:[98,10,4404],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[98,43,4437]}]}],n:50,r:"trigger_code",p:[97,9,4373]}],n:50,x:{r:["data.scan_level"],s:"_0>=4"},p:[87,8,3960]}],n:50,x:{r:["data.scan_level"],s:"_0>=3"},p:[74,7,3463]}],n:50,x:{r:["data.scan_level"],s:"_0>=2"},p:[67,6,3058]}]}],n:52,r:"data.mob_programs",p:[63,5,2811]}]}]}],x:{r:["data.has_nanites"],s:"!_0"}}]}],r:"data.status_msg"}]}]},e.exports=a.extend(r.exports)},{341:341}],411:[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:"Nanite Cloud Console"},f:[{p:[2,1,43],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,3,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,64,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,4,202],t:7,e:"ui-section",f:[{p:[7,5,220],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[7,38,253]}]}," ",{p:[8,5,290],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[8,37,322]}]}," ",{p:[9,5,359],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[9,43,397]}]}," ",{t:4,f:[{p:[11,6,505],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[11,43,542]}]}],n:50,r:"data.disk.activation_delay",p:[10,5,464]}," ",{t:4,f:[{p:[14,6,634],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[14,32,660]}]}," ",{p:[15,6,699],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[15,38,731]}]}],n:50,r:"data.disk.timer",p:[13,5,604]}," ",{t:4,f:[{p:[18,6,827],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[18,42,863]}]}],n:50,r:"data.disk.activation_code",p:[17,5,787]}," ",{t:4,f:[{p:[21,6,966],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[21,44,1004]}]}],n:50,r:"data.disk.deactivation_code",p:[20,5,924]}," ",{t:4,f:[{p:[24,6,1101],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[24,36,1131]}]}],n:50,r:"data.disk.kill_code",p:[23,5,1067]}," ",{t:4,f:[{p:[27,6,1223],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[27,39,1256]}]}],n:50,r:"data.disk.trigger_code",p:[26,5,1186]}," ",{t:4,f:[{t:4,f:[{p:[31,8,1400],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[31,27,1419]}]},f:[{t:2,r:"value",p:[31,37,1429]}]}],n:52,r:"data.disk.extra_settings",p:[30,6,1357]}],n:50,r:"data.disk.has_extra_settings",p:[29,5,1314]}]}],n:50,r:"data.has_program",p:[5,3,173]},{t:4,n:51,f:[{p:[36,4,1515],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,2,79]},{t:4,n:51,f:[{p:[39,3,1584],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[42,1,1646],t:7,e:"ui-display",a:{title:"Cloud Storage"},f:[{t:4,f:[{p:[44,3,1713],t:7,e:"ui-button",a:{icon:"plus-circle",action:"create_backup"},f:["Create New Backup"]}," ",{p:[45,3,1799],t:7,e:"ui-display",a:{title:"Active Backups"},f:[{t:4,f:[{p:[47,5,1873],t:7,e:"ui-button",a:{action:"set_view",params:['{"view": "',{t:2,r:"cloud_id",p:[47,52,1920]},'"}']},f:["Backup #",{t:2,r:"cloud_id",p:[47,76,1944]}]}],n:52,r:"data.cloud_backups",p:[46,4,1839]}]}],n:50,x:{r:["data.current_view"],s:"!_0"},p:[43,2,1683]},{t:4,n:51,f:[{p:[51,3,2014],t:7,e:"ui-button",a:{icon:"undo",action:"set_view",params:'{"view": "0"}'},f:["Return"]}," ",{t:4,f:[{p:[53,4,2131],t:7,e:"ui-notice",f:["ERROR: Backup not found."]}],n:50,x:{r:["data.cloud_backup"],s:"!_0"},p:[52,3,2100]},{t:4,n:51,f:[{p:[55,4,2195],t:7,e:"ui-display",a:{title:["Backup #",{t:2,r:"data.current_view",p:[55,31,2222]}]},f:[{t:4,f:[{p:[57,6,2282],t:7,e:"ui-button",a:{icon:"upload",action:"upload_program",style:"selected"},f:["Upload Program From Disk"]},{p:[57,108,2384],t:7,e:"br"}],n:50,r:"data.has_program",p:[56,5,2251]}," ",{t:4,f:[{p:[60,6,2443],t:7,e:"hr"}," ",{p:[61,6,2454],t:7,e:"ui-section",f:[{p:[62,7,2474],t:7,e:"h3",f:[{t:2,r:"name",p:[62,11,2478]}]}," ",{p:[63,7,2499],t:7,e:"div",a:{style:"float:right"},f:[{p:[64,8,2533],t:7,e:"ui-button",a:{icon:"minus-circle",action:"remove_program",style:"danger",params:['{"program_id": "',{t:2,r:"id",p:[64,102,2627]},'"}']},f:["Uninstall"]}]}]}," ",{p:[67,6,2699],t:7,e:"ui-section",f:[{p:[68,7,2719],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[68,39,2751]}]}," ",{p:[69,7,2780],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[69,45,2818]}]}," ",{p:[70,7,2877],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[70,44,2914]},"/s"]}," ",{t:4,f:[{p:[72,8,2977],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[72,41,3010]},"/s"]}," ",{p:[73,8,3050],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[73,45,3087]},"/s"]}],n:50,r:"can_trigger",p:[71,7,2949]}," ",{t:4,f:[{p:[76,8,3178],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,45,3215]}]}],n:50,r:"activation_delay",p:[75,7,3145]}," ",{t:4,f:[{p:[79,8,3293],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,34,3319]}]}," ",{p:[80,8,3350],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"timer_type",p:[80,40,3382]}]}],n:50,r:"timer",p:[78,7,3271]}," ",{t:4,f:[{p:[83,8,3464],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[83,44,3500]}]}],n:50,r:"activation_code",p:[82,7,3432]}," ",{t:4,f:[{p:[86,8,3589],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[86,46,3627]}]}],n:50,r:"deactivation_code",p:[85,7,3555]}," ",{t:4,f:[{p:[89,8,3710],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[89,38,3740]}]}],n:50,r:"kill_code",p:[88,7,3684]}," ",{t:4,f:[{p:[92,8,3818],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[92,41,3851]}]}],n:50,r:"trigger_code",p:[91,7,3789]}," ",{t:4,f:[{t:4,f:[{p:[96,10,3973],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[96,29,3992]}]},f:[{t:2,r:"value",p:[96,39,4002]}]}],n:52,r:"extra_settings",p:[95,8,3938]}],n:50,r:"has_extra_settings",p:[94,7,3903]}]}],n:52,r:"data.cloud_programs",p:[59,5,2407]}]}],x:{r:["data.cloud_backup"],s:"!_0"}}],x:{r:["data.current_view"],s:"!_0"}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],412:[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:"Nanite Program Hub"},f:[{t:4,f:[{p:[3,2,65],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{p:[4,3,102],t:7,e:"ui-section",f:[{p:[5,4,119],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{p:[6,4,185],t:7,e:"ui-button",a:{icon:"minus-circle",action:"clear"},f:["Delete Program"]}]}," ",{t:4,f:[{p:[9,4,307],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[9,37,340]}]}," ",{p:[10,4,376],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[10,36,408]}]}],n:50,r:"data.has_program",p:[8,3,278]},{t:4,n:51,f:[{p:[12,4,456],t:7,e:"ui-notice",f:["No program installed."]}],r:"data.has_program"}]}],n:50,r:"data.has_disk",p:[2,1,41]},{t:4,n:51,f:[{p:[16,2,540],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"},{p:[18,1,586],t:7,e:"br"}," ",{p:[19,1,592],t:7,e:"ui-display",a:{title:"Programs"},f:[{p:[20,2,624],t:7,e:"ui-section",f:[{p:[21,3,640],t:7,e:"ui-button",a:{icon:"undo",action:"set_category",params:'{"category": "Main"}'},f:["Return"]}," ",{p:[22,3,737],t:7,e:"ui-button",a:{icon:"align-justify ",action:"toggle_details"},f:[{t:2,x:{r:["data.detail_view"],s:'_0?"Compact View":"Detailed View"'},p:[22,60,794]}]}]}," ",{t:4,f:[{p:[25,3,916],t:7,e:"ui-display",f:[{t:4,f:[{p:[27,5,964],t:7,e:"ui-section",f:[{p:[27,17,976],t:7,e:"ui-button",a:{action:"set_category",params:['{"category": "',{t:2,r:"name",p:[27,72,1031]},'"}']},f:[{t:2,r:"name",p:[27,84,1043]}]}]}],n:52,r:"data.categories",p:[26,4,933]}]}],n:50,x:{r:["data.category"],s:'_0=="Main"'},p:[24,2,881]},{t:4,n:51,f:[{p:[31,3,1122],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[31,22,1141]}]},f:[{t:4,f:[{t:4,f:[{p:[34,6,1229],t:7,e:"ui-display",f:[{p:[35,7,1249],t:7,e:"ui-section",f:[{p:[35,19,1261],t:7,e:"b",f:[{t:2,r:"name",p:[35,22,1264]}]}]}," ",{p:[36,7,1297],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[36,19,1309]}]}," ",{p:[37,7,1338],t:7,e:"ui-section",f:[{p:[38,8,1359],t:7,e:"ui-button",a:{icon:"download",action:"download",params:['{"program_id": "',{t:2,r:"id",p:[38,77,1428]},'"}'],state:[{t:2,x:{r:["data.has_disk"],s:'_0?null:"disabled"'},p:[38,94,1445]}]},f:["Download"]}]}]}],n:50,r:"data.detail_view",p:[33,5,1198]},{t:4,n:51,f:[{p:[44,6,1585],t:7,e:"ui-section",f:[{p:[44,18,1597],t:7,e:"ui-button",a:{action:"download",params:['{"program_id": "',{t:2,r:"id",p:[44,71,1650]},'"}']},f:[{t:2,r:"name",p:[44,81,1660]}]}]}],r:"data.detail_view"}],n:52,r:"data.program_list",p:[32,4,1165]}]}],x:{r:["data.category"],s:'_0=="Main"'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],413:[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:"Nanite Programming"},f:[{t:4,f:[{p:[3,3,67],t:7,e:"ui-notice",f:["Insert a nanite program disk."]}],n:50,x:{r:["data.has_disk"],s:"!_0"},p:[2,1,41]},{t:4,n:51,f:[{p:[5,3,133],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{t:4,f:[{p:[7,5,229],t:7,e:"ui-notice",f:["No program detected."]}],n:50,x:{r:["data.has_program"],s:"!_0"},p:[6,3,198]},{t:4,n:51,f:[{p:[9,5,290],t:7,e:"ui-section",f:[{p:[10,7,310],t:7,e:"ui-display",a:{title:[{t:2,r:"data.name",p:[10,26,329]}]},f:[{t:2,r:"data.desc",p:[11,9,354]}]}]}," ",{p:[14,5,413],t:7,e:"ui-section",f:[{p:[15,7,433],t:7,e:"ui-section",a:{label:"Program Info"},f:["Nanites Consumed: ",{t:2,r:"data.use_rate",p:[16,26,493]},{p:[16,43,510],t:7,e:"br"}," ",{t:4,f:["Trigger Cost: ",{t:2,r:"data.trigger_cost",p:[18,25,574]},"u",{p:[18,47,596],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[17,9,524]}]}," ",{p:[22,7,648],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[23,9,685],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.activated"],s:'_0?"toggle-on":"toggle-off"'},p:[24,17,713]}],action:"toggle_active"},f:[{t:2,x:{r:["data.activated"],s:'_0?"Active":"Inactive"'},p:[26,11,809]}]}]}," ",{p:[30,7,905],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[31,9,944],t:7,e:"ui-button",a:{icon:"pencil",action:"set_activation_delay"}}," Activation Delay: ",{t:2,r:"data.activation_delay",p:[31,95,1030]}," ",{p:[31,121,1056],t:7,e:"br"}," ",{p:[32,9,1070],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer"}}," Timer: ",{t:2,r:"data.timer",p:[32,73,1134]}," ",{p:[32,88,1149],t:7,e:"br"}," ",{p:[33,9,1163],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer_type"}}," Timer Type: ",{t:2,r:"data.timer_type",p:[33,83,1237]}," ",{p:[33,103,1257],t:7,e:"br"}]}," ",{p:[36,7,1292],t:7,e:"ui-section",a:{label:"Codes"},f:[{p:[37,9,1328],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "activation"}'}}," Activation Code: ",{t:2,r:"data.activation_code",p:[37,121,1440]}," ",{p:[37,146,1465],t:7,e:"br"}," ",{p:[38,9,1479],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "deactivation"}'}}," Deactivation Code: ",{t:2,r:"data.deactivation_code",p:[38,125,1595]}," ",{p:[38,152,1622],t:7,e:"br"}," ",{p:[39,9,1636],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "kill"}'}}," Kill Code: ",{t:2,r:"data.kill_code",p:[39,109,1736]}," ",{p:[39,128,1755],t:7,e:"br"}," ",{t:4,f:[{p:[41,11,1805],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "trigger"}'}}," Trigger Code: ",{t:2,r:"data.trigger_code",p:[41,117,1911]}," ",{p:[41,139,1933],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[40,9,1769]}]}," ",{t:4,f:[{p:[46,9,2026],t:7,e:"ui-section",a:{label:"Special"},f:[{t:4,f:[{p:[48,13,2109],t:7,e:"ui-button",a:{icon:"pencil",action:"set_extra_setting",params:['{"target_setting": "',{t:2,r:"name",p:[48,93,2189]},'"}']}}," ",{t:2,r:"name",p:[48,118,2214]},": ",{t:2,r:"value",p:[48,128,2224]}," ",{p:[48,138,2234],t:7,e:"br"}],n:52,r:"data.extra_settings",p:[47,11,2066]}]}],n:50,r:"data.has_extra_settings",p:[45,7,1985]}]}],x:{r:["data.has_program"],s:"!_0"}}],x:{r:["data.has_disk"],s:"!_0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],414:[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:"Nanite Control"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-notice",f:["The interface is locked."]}],n:50,r:"data.locked",p:[2,1,37]},{t:4,n:51,f:[{p:[5,3,121],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock Interface"]}," ",{p:[6,3,188],t:7,e:"ui-button",a:{icon:"save",action:"save"},f:["Save Current Setting"]}," ",{p:[7,3,261],t:7,e:"ui-section",a:{label:"Signal Code"},f:[{p:[8,5,299],t:7,e:"span",f:[{t:2,r:"data.code",p:[8,11,305]}]}," ",{p:[9,4,330],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code"},f:["Set"]}]}," ",{t:4,f:[{p:[12,5,443],t:7,e:"ui-section",a:{label:"Relay Code"},f:[{p:[13,7,482],t:7,e:"span",f:[{t:2,r:"data.relay_code",p:[13,13,488]}]}," ",{p:[14,5,520],t:7,e:"ui-button",a:{icon:"pencil",action:"set_relay_code"},f:["Set"]}]}],n:50,x:{r:["data.mode"],s:'_0=="Relay"'},p:[11,3,409]}," ",{p:[17,3,618],t:7,e:"ui-section",a:{label:"Signal Mode"},f:[{p:[18,5,656],t:7,e:"span",f:[{t:2,r:"data.mode",p:[18,11,662]}]}," ",{p:[19,5,688],t:7,e:"br"}," ",{p:[20,4,697],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Off"}'},f:["Off"]}," ",{p:[21,5,775],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Local"}'},f:["Local"]}," ",{p:[22,5,857],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Targeted"}'},f:["Targeted"]}," ",{p:[23,5,945],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Area"}'},f:["Area"]}," ",{p:[24,5,1025],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Relay"}'},f:["Relay"]}]}],r:"data.locked"}]}," ",{p:[28,1,1144],t:7,e:"ui-display",a:{title:"Saved Settings"},f:[{t:4,f:[{p:[30,3,1215],t:7,e:"ui-button",a:{icon:"load",action:"load",params:['{"save_id": "',{t:2,r:"id",p:[30,61,1273]},'"}']},f:[{t:2,r:"name",p:[30,71,1283]}]}," ",{t:4,f:[{p:[32,4,1332],t:7,e:"ui-button",a:{icon:"remove",action:"remove_save",params:['{"save_id": "',{t:2,r:"id",p:[32,71,1399]},'"}']},f:["Remove"]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[31,3,1307]}," ",{p:[34,3,1442],t:7,e:"br"}],n:52,r:"data.saved_settings",p:[29,2,1182]}]}]},e.exports=a.extend(r.exports)},{341:341}],415:[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:"Ghost roles"},f:[{p:[2,2,35],t:7,e:"ui-section",a:{label:"Ignored roles"},f:[{t:4,f:[{p:[4,4,99],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[4,21,116]}],style:[{t:2,x:{r:["enabled"],s:'_0?"danger":null'},p:[4,73,168]}],action:"toggle_ignore",params:['{"key": "',{t:2,r:"key",p:[4,144,239]},'"}']},f:[{t:2,r:"desc",p:[4,155,250]}]}],n:52,r:"data.ignore",p:[3,3,73]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],416:[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:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{341:341}],417:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations" +},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],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}],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]}," ",{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 + {{#each data.pillStyles}} + {{{htmltag}}} + {{/each}} +
    {{#if data.isPillBottleLoaded}} {{data.isPillBottleLoaded ? "Eject" : "No Pill bottle loaded"}} {{data.pillBotContent}}/{{data.pillBotMaxContent}} {{else}} No Pillbottle {{/if}} - -
    +
    Create Pill (max 50µ)
    diff --git a/tgui/tgui.html b/tgui/tgui.html index fcab1b21eb..2f604b4cd5 100644 --- a/tgui/tgui.html +++ b/tgui/tgui.html @@ -16,7 +16,8 @@ }; - + + diff --git a/tools/ss13_genchangelog.py b/tools/ss13_genchangelog.py index 5c77063e96..e97bef7684 100644 --- a/tools/ss13_genchangelog.py +++ b/tools/ss13_genchangelog.py @@ -74,9 +74,9 @@ failed_cache_read = True if os.path.isfile(changelog_cache): try: with open(changelog_cache,encoding='utf-8') as f: - (_, all_changelog_entries) = yaml.load_all(f) + (_, all_changelog_entries) = yaml.load_all(f, Loader=yaml.SafeLoader) failed_cache_read = False - + # Convert old timestamps to newer format. new_entries = {} for _date in all_changelog_entries.keys(): @@ -92,10 +92,10 @@ if os.path.isfile(changelog_cache): except Exception as e: print("Failed to read cache:") print(e, file=sys.stderr) - -if args.dryRun: + +if args.dryRun: changelog_cache = os.path.join(args.ymlDir, '.dry_changelog.yml') - + if failed_cache_read and os.path.isfile(args.targetFile): from bs4 import BeautifulSoup from bs4.element import NavigableString @@ -111,7 +111,7 @@ if failed_cache_read and os.path.isfile(args.targetFile): if author.endswith('updated:'): author = author[:-8] author = author.strip() - + # Find
      ulT = authorT.next_sibling while(ulT.name != 'ul'): @@ -124,14 +124,14 @@ if failed_cache_read and os.path.isfile(args.targetFile): newdat = {changeT['class'][0] + '': val + ''} if newdat not in changes: changes += [newdat] - + if len(changes) > 0: entry[author] = changes if date in all_changelog_entries: all_changelog_entries[date].update(entry) else: all_changelog_entries[date] = entry - + del_after = [] print('Reading changelogs...') for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")): @@ -142,7 +142,7 @@ for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")): print(' Reading {}...'.format(fileName)) cl = {} with open(fileName, 'r',encoding='utf-8') as f: - cl = yaml.load(f) + cl = yaml.load(f, Loader=yaml.SafeLoader) f.close() if today not in all_changelog_entries: all_changelog_entries[today] = {} @@ -156,23 +156,23 @@ for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")): print(' {0}: Invalid prefix {1}'.format(fileName, change_type), file=sys.stderr) author_entries += [change] new += 1 - all_changelog_entries[today][cl['author']] = author_entries + all_changelog_entries[today][cl['author']] = author_entries if new > 0: print(' Added {0} new changelog entries.'.format(new)) - + if cl.get('delete-after', False): if os.path.isfile(fileName): if args.dryRun: print(' Would delete {0} (delete-after set)...'.format(fileName)) else: del_after += [fileName] - + if args.dryRun: continue - + cl['changes'] = [] with open(fileName, 'w', encoding='utf-8') as f: - yaml.dump(cl, f, default_flow_style=False) - + yaml.dump(cl, f, default_flow_style=False) + targetDir = os.path.dirname(args.targetFile) with open(args.targetFile.replace('.htm', '.dry.htm') if args.dryRun else args.targetFile, 'w', encoding='utf-8') as changelog: @@ -195,18 +195,18 @@ with open(args.targetFile.replace('.htm', '.dry.htm') if args.dryRun else args.t for (css_class, change) in (dictToTuples(e)[0] for e in all_changelog_entries[_date][author]): if change in changes_added: continue write_entry = True - changes_added += [change] + changes_added += [change] author_htm += '\t\t\t\t
    • {change}
    • \n'.format(css_class=css_class, change=change.strip()) author_htm += '\t\t\t
    \n' if len(changes_added) > 0: entry_htm += author_htm if write_entry: changelog.write(entry_htm) - + with open(os.path.join(targetDir, 'templates', 'footer.html'), 'r', encoding='utf-8') as h: for line in h: changelog.write(line) - + with open(changelog_cache, 'w') as f: cache_head = 'DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.' diff --git a/tools/travis/build_dependencies.sh b/tools/travis/build_dependencies.sh index 9e594733ea..2c24bdbaaf 100755 --- a/tools/travis/build_dependencies.sh +++ b/tools/travis/build_dependencies.sh @@ -41,19 +41,10 @@ if [ $BUILD_TOOLS = false ] && [ $BUILD_TESTING = false ]; then echo "Setting up MariaDB." rm -rf "$HOME/MariaDB" mkdir -p "$HOME/MariaDB" - wget http://mirrors.kernel.org/ubuntu/pool/universe/m/mariadb-client-lgpl/libmariadb2_2.0.0-1_i386.deb - dpkg -x libmariadb2_2.0.0-1_i386.deb /tmp/extract - rm libmariadb2_2.0.0-1_i386.deb - mv /tmp/extract/usr/lib/i386-linux-gnu/libmariadb.so.2 $HOME/MariaDB/ - ln -s $HOME/MariaDB/libmariadb.so.2 $HOME/MariaDB/libmariadb.so - rm -rf /tmp/extract - - wget http://mirrors.kernel.org/ubuntu/pool/universe/m/mariadb-connector-c/libmariadb-dev_2.3.3-1_i386.deb - dpkg -x libmariadb-dev_2.3.3-1_i386.deb /tmp/extract - rm libmariadb-dev_2.3.3-1_i386.deb - mv /tmp/extract/usr/include $HOME/MariaDB/ - #fuck what is this even? - mv $HOME/MariaDB/include/mariadb $HOME/MariaDB/include/mysql + mkdir -p "$HOME/MariaDB/include" + cp /usr/lib/i386-linux-gnu/libmariadb.so.2 $HOME/MariaDB/ + ln -s $HOME/MariaDB/libmariadb.so.2 $HOME/MariaDB/libmariadb.so + cp -r /usr/include/mariadb $HOME/MariaDB/include/ fi cd artifacts diff --git a/tools/travis/install_build_tools.sh b/tools/travis/install_build_tools.sh index 9dd73f854c..0ea2a605ab 100755 --- a/tools/travis/install_build_tools.sh +++ b/tools/travis/install_build_tools.sh @@ -4,9 +4,8 @@ set -e source dependencies.sh if [ "$BUILD_TOOLS" = true ]; then - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $NODE_VERSION - pip3 install --user PyYaml -q - pip3 install --user beautifulsoup4 -q + source ~/.nvm/nvm.sh + nvm install $NODE_VERSION + pip3 install --user PyYaml + pip3 install --user beautifulsoup4 fi; - -
    " dat += "

    Clothing & Equipment

    " dat += "Underwear:[underwear]" + if(UNDIE_COLORABLE(GLOB.underwear_list[underwear])) + dat += "Underwear Color:[undie_color]" dat += "Undershirt:[undershirt]" + if(UNDIE_COLORABLE(GLOB.undershirt_list[undershirt])) + dat += "Undershirt Color:[shirt_color]" dat += "Socks:[socks]" + if(UNDIE_COLORABLE(GLOB.socks_list[socks])) + dat += "Socks Color:[socks_color]" dat += "Backpack:[backbag]" dat += "Uplink Location:[uplink_spawn_loc]" dat += "