diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3a19bc34edf..66d1598d898 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,28 +1,26 @@ -# This list auto requests reviews from the specified maintainer when a PR that modifies the file in question is opened -# This list is alphabetized by User -> Filename KEEP IT THAT WAY -# In the event that multiple org members are to be informed of changes to the same file or dir, add them to the end under Multiple Owners -# This is ONLY for taking ownership of server-critical code which must be written in a very specific way for the server to operate at all. +# This list auto requests reviews from the specified org members +# when a PR that modifies the file in question is opened +# This list is alphabetized by User -> Filename and separated into sections for Maintainers/Contributors KEEP IT THAT WAY +# In the event that people are to be informed of changes +# to the same file or dir, add them to the end of under Multiple Owners -### AffectedArc07 -# Actual Code -/code/controllers/subsystem/mapping.dm @AffectedArc07 -/code/controllers/subsystem/ticker.dm @AffectedArc07 -/tgui/ @AffectedArc07 -# CI + Tooling -/.github/workflows/ @AffectedArc07 -/code/modules/unit_tests/ @AffectedArc07 -/tools/ci/ @AffectedArc07 +# MAINTAINERS -# Executables that need to be security-cleared -dreamchecker.exe @AffectedArc07 -rust_g.dll @AffectedArc07 +### azizonkg +# CI + Tooling +/.github/workflows/ @Bizzonium +/code/modules/unit_tests/ @Bizzonium +/tools/ci/ @Bizzonium +_build_dependencies.sh @Bizzonium +# Server Stuff +/SQL/ @Bizzonium +/config/ @Bizzonium +# Executables that need to be security-cleared +dreamchecker.exe @Bizzonium +rust_g.dll @Bizzonium -### Fox-McCloud -/code/ATMOSPHERICS/ @Fox-McCloud -/code/controllers/subsystem/air.dm @Fox-McCloud -/code/controllers/subsystem/garbage.dm @Fox-McCloud -/code/modules/reagents/chemistry/holder.dm @Fox-McCloud -/code/modules/reagents/chemistry/reagents.dm @Fox-McCloud +# MULTIPLE OWNERS +/_maps/ @ss220-space/map-reviewers diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 82452dac133..6b7f1882c85 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -56,22 +56,28 @@ actual development. * While we have no issue helping contributors (and especially new contributors) bring reasonably sized contributions up to standards via the pull request review process, larger contributions are expected to pass a higher bar of completeness and code quality *before* you open a pull request. Maintainers may close such pull requests that are deemed to be substantially flawed. You should take some time to discuss with maintainers or other contributors on how to improve the changes. -#### Using Changelog - * Tags used in changelog include add/rscadd, del/rscdel, fix/fixes, typo/spellcheck. - * Without specifying a name it will default to using your GitHub name. - Some examples -``` -:cl: -add: The ability to change the color of wires -del: Deleted depreciated wire merging now handled in parent -fix: Moving wires now follows the user input instead of moving the stack -/:cl: -``` +#### Использование Changelog +Перед вашим заголовком PR, требуется поставить корректный тэг, чтобы в игре Changelog его правильно отображал. + +Пример: ``` -:cl: N3X15 -typo: Fixes some misspelled words under Using Changelog -/:cl: +bugfix: clothing removes itself trying to adjust it. +add: new lavaland elite mob ``` +Список тегов для PRa: +* **add:** если Вы добавили новую фичу +* **admin:** если меняете что-то важно связанное с администрацией.(Кнопки, управления, панели, щитспавн) +* **balance:** если производите балансировку в игре.(Изменение цифры урона, баффы или нерфы предмета/моба) +* **bugfix:** если Вы исправили некий баг +* **code_imp:** если имплементируете новое для билда, не меняя при этом ничего в самой игре. +* **config:** если меняете перестановку конфигов или меняете работу SQL. (По этому поводу обращаться стоит с хосту) +* **imageadd:** если просто поменяли спрайты, без затрагивания кода +* **soundadd:** если просто добавили новые звуки, без затрагивания кода +* **spellcheck:** если исправляете грамматику в коде. +* **tweak:** если Вы сделали незначительную правку (например изменили одно число на другое) +* **refactor:** если Вы полностью переписали старый код, улучшив его, НО не изменив функционал +* **qol:** если Ваше изменение не влияет на баланс, а только улучшает взаимодействие между игрой и игроком +* **wip:** если Ваш PR в драфте и планируется длительная разработка (можно не ставить) ## Specifications @@ -377,12 +383,14 @@ This prevents nesting levels from getting deeper then they need to be. #define MACRO_ONE (1<<0) #define MACRO_TWO (1<<1) #define MACRO_THREE (1<<2) + #define MACRO_ALL (~0) ``` Is preferable to ``` #define MACRO_ONE 1 #define MACRO_TWO 2 #define MACRO_THREE 4 + #defin MACRO_ALL 7 // or 16777215 as more accurate ``` This make the code more readable and less prone to error diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 15768fdcf23..9b12f1b949c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -43,13 +43,23 @@ on: default: true jobs: + check: + name: Check User Permission + runs-on: ubuntu-latest + steps: + - uses: skjnldsv/check-actor-permission@v3 + with: + require: 'admin' + CI: + needs: [check] uses: ./.github/workflows/ci.yml # use the callable tests job to run tests if: ${{ inputs.ci_required }} update-isp-lists: name: Update ISP Lists runs-on: ubuntu-latest + needs: [check] steps: - name: Update ISP Lists @@ -64,6 +74,7 @@ jobs: set-matrix: name: Set Deployment Matrix runs-on: ubuntu-latest + needs: [check] outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: @@ -101,7 +112,7 @@ jobs: fail-fast: false matrix: ${{fromJson(needs.set-matrix.outputs.matrix)}} environment: ${{ matrix.environment }} - needs: [update-isp-lists, CI, set-matrix] + needs: [check, update-isp-lists, CI, set-matrix] if: always() && !cancelled() && !failure() steps: diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index e537cd3b5ae..e883090be14 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -67,6 +67,7 @@ CREATE TABLE `characters` ( `med_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `sec_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `gen_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `exploit_record` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, `disabilities` mediumint(8) NOT NULL, `player_alt_titles` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `organ_data` longtext COLLATE utf8mb4_unicode_ci NOT NULL, @@ -288,6 +289,7 @@ CREATE TABLE `player` ( `discord_name` varchar(32) NULL DEFAULT NULL, `keybindings` longtext COLLATE 'utf8mb4_unicode_ci' DEFAULT NULL, `viewrange` VARCHAR(5) NOT NULL DEFAULT '17x15' COLLATE 'utf8mb4_general_ci', + `ghost_darkness_level` tinyint(1) UNSIGNED NOT NULL DEFAULT '255', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`), KEY `lastseen` (`lastseen`), diff --git a/SQL/updates/31-32.sql b/SQL/updates/31-32.sql new file mode 100644 index 00000000000..90e2d119a9b --- /dev/null +++ b/SQL/updates/31-32.sql @@ -0,0 +1,5 @@ +# Add exploit records +ALTER TABLE `characters` + ADD COLUMN `exploit_record` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER `gen_record`; +# Adds support for persistent ghost darkness +ALTER TABLE `player` ADD COLUMN `ghost_darkness_level` tinyint(1) UNSIGNED NOT NULL DEFAULT '255' diff --git a/SQL/updates/32-33.sql b/SQL/updates/32-33.sql new file mode 100644 index 00000000000..b6760ba037d --- /dev/null +++ b/SQL/updates/32-33.sql @@ -0,0 +1,2 @@ +# Adds tracking of who flagged which book. +ALTER TABLE `library` ADD COLUMN `flaggedby` VARCHAR(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT ' ' AFTER `flagged`; \ No newline at end of file diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index 2f5b36fb9ba..9cdfa9f06da 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -14,9 +14,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /mob/living/simple_animal/mouse/gray, /turf/simulated/floor/plating, /area/maintenance/fore) @@ -47,7 +44,7 @@ icon_state = "1-2" }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "aah" = ( @@ -141,9 +138,6 @@ dir = 1; on = 1 }, -/obj/machinery/ai_status_display{ - pixel_y = 32 - }, /obj/structure/cable{ icon_state = "2-4" }, @@ -586,7 +580,6 @@ icon_state = "4-8" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/structure/cable{ @@ -1007,7 +1000,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/toxins/lab) "aiL" = ( @@ -1139,6 +1133,23 @@ icon_state = "neutral" }, /area/engine/mechanic_workshop/expedition) +"ajY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 8; + tag = "icon-pipe-j2" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/turf/simulated/floor/plasteel{ + icon_state = "purplefull" + }, +/area/medical/research/nhallway) "ake" = ( /obj/machinery/light{ dir = 4 @@ -1544,12 +1555,10 @@ /turf/simulated/floor/plating, /area/security/permabrig) "aob" = ( -/obj/machinery/recharge_station, -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "aoc" = ( /obj/machinery/portable_atmospherics/canister/toxins, /obj/effect/decal/warning_stripes/yellow/hollow, @@ -2775,6 +2784,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "axa" = ( @@ -2982,8 +2992,9 @@ /turf/simulated/floor/plasteel, /area/hallway/secondary/entry/westarrival) "ays" = ( +/obj/effect/spawner/window/reinforced, /obj/structure/disposalpipe/segment, -/turf/simulated/wall, +/turf/simulated/floor/plating, /area/quartermaster/sorting) "ayv" = ( /obj/machinery/navbeacon{ @@ -3210,6 +3221,13 @@ }, /turf/simulated/floor/plating, /area/maintenance/asmaint4) +"aAy" = ( +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "neutralfull" + }, +/area/bridge/checkpoint/south) "aAB" = ( /obj/structure/chair/comfy/red{ dir = 4 @@ -3849,13 +3867,13 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aEh" = ( -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/toolbox/mechanical, +/obj/machinery/vending/coffee, +/obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ - icon_state = "white" + dir = 10; + icon_state = "whitepurple" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "aEi" = ( /obj/structure/table/reinforced, /obj/item/storage/firstaid/regular, @@ -3918,7 +3936,7 @@ tag = "icon-pipe-j1 (EAST)" }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "aEp" = ( @@ -4441,7 +4459,6 @@ /turf/simulated/wall, /area/bridge/checkpoint/north) "aIm" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -4680,6 +4697,9 @@ pixel_x = 7; pixel_y = -7 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "aJF" = ( @@ -5496,6 +5516,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -5591,6 +5615,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "aOT" = ( @@ -6061,9 +6086,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fore) "aSh" = ( @@ -6833,8 +6855,7 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/crew_quarters/fitness) "aWY" = ( @@ -7296,6 +7317,10 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/fore) "aZp" = ( @@ -7334,6 +7359,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "aZz" = ( @@ -7346,6 +7374,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/fore) "aZA" = ( @@ -7580,6 +7612,13 @@ "bbl" = ( /turf/simulated/floor/plating, /area/maintenance/fore) +"bbm" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/grille, +/turf/simulated/floor/plating, +/area/maintenance/asmaint2) "bbw" = ( /obj/effect/decal/warning_stripes/south, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -7605,15 +7644,6 @@ icon_state = "darkblue" }, /area/crew_quarters/theatre) -"bbJ" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "bbN" = ( /obj/machinery/light{ dir = 4 @@ -7736,7 +7766,7 @@ }, /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "bck" = ( @@ -8499,9 +8529,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -8532,9 +8559,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "bluecorner" @@ -8780,6 +8804,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -9646,9 +9671,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -9750,6 +9773,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/fore) "boJ" = ( @@ -9834,6 +9861,9 @@ /obj/structure/barricade/wooden{ layer = 3.5 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "bph" = ( @@ -9850,6 +9880,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "bpm" = ( @@ -9868,6 +9901,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "bpo" = ( @@ -9913,6 +9949,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/fore) "bpK" = ( @@ -9924,22 +9964,9 @@ /area/atmos) "bpR" = ( /obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/door/airlock/maintenance{ - name = "Break Room Maintenance"; - req_access = list(47) - }, -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/plasteel{ - icon_state = "white" + icon_state = "0-2" }, +/turf/simulated/floor/plating, /area/maintenance/asmaint2) "bpU" = ( /obj/machinery/door/airlock/maintenance{ @@ -10105,14 +10132,15 @@ /turf/simulated/floor/plasteel, /area/engine/mechanic_workshop) "brk" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, /obj/structure/reagent_dispensers/fueltank/chem{ pixel_x = 32; pixel_y = 32 }, +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + name = "Mechanic"; + sortType = 30 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "yellow" @@ -10183,13 +10211,14 @@ /turf/simulated/floor/plating, /area/quartermaster/storage) "brG" = ( -/obj/machinery/door/airlock/engineering/glass{ - name = "Mechanic Workshop"; - req_access = list(70) +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plasteel, -/area/engine/mechanic_workshop) +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "darkyellow" + }, +/area/engine/mechanic_workshop/hangar) "brI" = ( /obj/structure/cable{ icon_state = "4-8" @@ -10220,6 +10249,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -10236,6 +10268,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -10765,6 +10800,10 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 1 }, @@ -11862,6 +11901,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "byN" = ( @@ -12690,6 +12730,9 @@ }, /obj/item/c_tube, /obj/effect/decal/cleanable/blood, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "bBK" = ( @@ -13190,8 +13233,14 @@ icon_state = "yellowcorner" }, /area/storage/primary) +"bDP" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/medical/research/nhallway) "bDR" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/multi_tile/glass{ name = "Bridge West Hallway"; @@ -13302,6 +13351,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "bEh" = ( @@ -13517,10 +13567,10 @@ }, /area/storage/tech) "bFi" = ( -/obj/item/twohanded/required/kirbyplants, /obj/item/radio/intercom{ pixel_y = -28 }, +/obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "yellow" @@ -13672,6 +13722,7 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "bFH" = ( @@ -14061,6 +14112,13 @@ icon_state = "freezerfloor" }, /area/crew_quarters/kitchen) +"bHE" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/medical/research/nhallway) "bHH" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ @@ -14679,6 +14737,22 @@ icon_state = "darkblue" }, /area/turret_protected/aisat) +"bLQ" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/grille, +/turf/simulated/floor/plating, +/area/maintenance/asmaint2) "bLT" = ( /obj/structure/cable{ icon_state = "0-4" @@ -15078,7 +15152,8 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research) "bNJ" = ( @@ -16094,14 +16169,11 @@ }, /area/janitor) "bRO" = ( -/obj/structure/transit_tube{ - icon_state = "N-SE"; - tag = "icon-N-SE" - }, /obj/structure/window/reinforced{ dir = 4 }, /obj/structure/window/reinforced, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "darkblue" @@ -17531,14 +17603,13 @@ /turf/simulated/wall, /area/library/game_zone) "bYl" = ( -/obj/structure/transit_tube{ - icon_state = "E-SW-NW"; - tag = "icon-E-SW-NW" - }, /obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/transit_tube/junction{ + dir = 8 + }, /turf/space, /area/space) "bYn" = ( @@ -17782,9 +17853,6 @@ /turf/space, /area/solar/auxstarboard) "bZN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -17809,9 +17877,6 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fore) "bZV" = ( @@ -18349,6 +18414,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "darkyellow" }, @@ -18478,10 +18544,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "greencorner" @@ -18547,9 +18609,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "hydrofloor" }, @@ -18746,7 +18805,6 @@ }, /area/hallway/primary/fore) "cdP" = ( -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkbluecorners" @@ -18844,10 +18902,11 @@ /obj/structure/cable{ icon_state = "2-8" }, -/obj/structure/disposalpipe/junction{ +/obj/structure/disposalpipe/sortjunction{ dir = 8; - icon_state = "pipe-j2"; - tag = "icon-pipe-j1 (WEST)" + icon_state = "pipe-j2s"; + name = "Magistrate's Office"; + sortType = 28 }, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" @@ -19145,9 +19204,7 @@ /area/atmos) "cfD" = ( /obj/effect/spawner/random_spawners/blood_maybe, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable{ @@ -19199,6 +19256,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -19325,6 +19385,16 @@ /obj/machinery/portable_atmospherics/pump, /turf/simulated/floor/plasteel, /area/engine/controlroom) +"cgJ" = ( +/obj/machinery/vending/clothing/departament/science, +/obj/structure/sign/poster/random{ + pixel_y = 32 + }, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "cgK" = ( /obj/structure/table/reinforced, /obj/machinery/reagentgrinder{ @@ -19401,6 +19471,7 @@ icon_state = "2-8" }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -19531,7 +19602,7 @@ network = list("SS13","MiniSat") }, /turf/space, -/area/space) +/area/turret_protected/ai) "chX" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance, @@ -19772,14 +19843,6 @@ icon_state = "darkred" }, /area/security/warden) -"cjl" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "W-NE"; - tag = "icon-W-NE" - }, -/turf/space, -/area/space) "cjn" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -19838,6 +19901,16 @@ }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) +"cjD" = ( +/obj/machinery/light_switch{ + pixel_x = -22; + pixel_y = -22 + }, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" + }, +/area/medical/research/restroom) "cjF" = ( /obj/structure/table/reinforced, /obj/item/stock_parts/matter_bin, @@ -19999,6 +20072,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "ckp" = ( @@ -20123,7 +20197,8 @@ /obj/item/reagent_containers/dropper, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/toxins/lab) "clj" = ( @@ -20503,7 +20578,6 @@ /area/storage/secure) "cmP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "green" @@ -20859,14 +20933,13 @@ /turf/simulated/floor/plasteel, /area/atmos) "coB" = ( -/obj/structure/transit_tube{ - icon_state = "E-NW"; - tag = "icon-E-NW" - }, /obj/structure/window/reinforced{ dir = 4 }, /obj/structure/lattice/catwalk, +/obj/structure/transit_tube/curved{ + dir = 4 + }, /turf/space, /area/space) "coE" = ( @@ -21062,6 +21135,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutralcorner" @@ -21404,6 +21480,15 @@ icon_state = "neutralfull" }, /area/atmos) +"cry" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plating, +/area/maintenance/engineering) "crA" = ( /obj/structure/railing{ dir = 1 @@ -21434,8 +21519,7 @@ /obj/effect/decal/cleanable/dust, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/maintenance/banya) "crF" = ( @@ -22509,6 +22593,9 @@ }, /area/hallway/primary/central/sw) "cwP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 0; icon_state = "green" @@ -22820,6 +22907,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "cyg" = ( @@ -23809,9 +23897,7 @@ /area/engine/engineering) "cCt" = ( /obj/machinery/door/airlock/maintenance, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable{ @@ -24337,6 +24423,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutralcorner" @@ -24468,7 +24555,7 @@ icon_state = "2-4" }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "cEE" = ( @@ -24525,6 +24612,7 @@ icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -24541,6 +24629,7 @@ icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -24680,7 +24769,7 @@ dir = 4 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "cFE" = ( @@ -24790,7 +24879,7 @@ pixel_y = -25 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "cFW" = ( @@ -25044,6 +25133,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "green" @@ -25099,7 +25191,8 @@ /obj/structure/chair, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "cHz" = ( @@ -26141,6 +26234,10 @@ faction = list("plants","neutral","hostile"); name = "Витамин" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "blue" @@ -26371,9 +26468,13 @@ /turf/simulated/floor/plating, /area/maintenance/banya) "cNt" = ( -/obj/structure/table/reinforced, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/item/twohanded/required/kirbyplants, +/turf/simulated/floor/plasteel{ + dir = 9; + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTHWEST)" + }, +/area/medical/research/restroom) "cNw" = ( /obj/structure/table/wood, /obj/item/ammo_box/shotgun/beanbag, @@ -26809,12 +26910,13 @@ /turf/space, /area/space) "cOY" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 }, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "cPa" = ( /obj/effect/decal/warning_stripes/yellow/hollow, /obj/structure/cable{ @@ -26824,11 +26926,15 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "cPd" = ( -/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/comfy/purp{ + dir = 4 + }, +/obj/effect/decal/warning_stripes/northwest, +/obj/effect/landmark/start/scientist, /turf/simulated/floor/plasteel{ - icon_state = "white" + icon_state = "whitepurplefull" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "cPe" = ( /obj/structure/table/reinforced, /obj/item/folder/white, @@ -27087,6 +27193,10 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/engine/engineering) "cQb" = ( @@ -27274,10 +27384,14 @@ }, /area/crew_quarters/serviceyard) "cQS" = ( -/obj/structure/barricade/wooden, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/chair/comfy/purp{ + dir = 8 + }, +/obj/effect/decal/warning_stripes/northeast, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplefull" + }, +/area/medical/research/restroom) "cQU" = ( /obj/effect/turf_decal/box, /obj/machinery/light{ @@ -27286,16 +27400,14 @@ /turf/simulated/floor/plasteel, /area/quartermaster/sorting) "cQV" = ( -/obj/structure/safe, -/obj/item/stack/ore/bluespace_crystal, -/obj/item/stack/ore/bluespace_crystal, -/obj/item/stack/ore/bluespace_crystal, -/obj/item/stack/ore/bluespace_crystal, -/obj/item/stack/ore/bluespace_crystal, -/obj/item/grown/bananapeel/bluespace, -/obj/item/slime_extract/bluespace, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "cQW" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk, @@ -27622,17 +27734,27 @@ }, /area/hallway/primary/fore) "cSc" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "cSd" = ( -/obj/effect/decal/cleanable/dirt, +/obj/structure/table/glass, +/obj/item/reagent_containers/food/drinks/chocolate, +/obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ - icon_state = "purplefull" + icon_state = "whitepurplefull" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "cSe" = ( /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel{ @@ -27823,7 +27945,7 @@ /obj/machinery/disposal, /obj/structure/disposalpipe/trunk, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "cTl" = ( @@ -28237,6 +28359,20 @@ "cUS" = ( /turf/simulated/wall/r_wall, /area/toxins/sm_test_chamber) +"cUT" = ( +/obj/machinery/power/apc{ + dir = 8; + name = "west bump"; + pixel_x = -26 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "cUU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -28322,13 +28458,15 @@ icon_state = "orangecorner" }, /area/hallway/primary/aft) -"cVf" = ( -/turf/simulated/wall/rust, -/area/teleporter/abandoned) "cVg" = ( -/obj/structure/computerframe, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" + }, +/area/medical/research/restroom) "cVh" = ( /obj/machinery/atmospherics/pipe/simple/visible{ desc = "Труба служит для подачу горючей смеси в турбину для её работы"; @@ -28541,7 +28679,8 @@ /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "cWa" = ( @@ -28935,9 +29074,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/item/radio/intercom{ pixel_x = 30; pixel_y = 24 @@ -29167,7 +29303,8 @@ /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/toxins/lab) "cYJ" = ( @@ -29589,7 +29726,6 @@ /turf/simulated/floor/plating, /area/maintenance/engineering) "dan" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -29602,6 +29738,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -29660,7 +29800,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/toxins/lab) "daF" = ( @@ -30310,6 +30451,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -30365,6 +30509,17 @@ icon_state = "whiteblue" }, /area/medical/paramedic) +"ddM" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/coffee, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "ddO" = ( /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, @@ -30437,7 +30592,6 @@ /turf/simulated/floor/transparent/glass/reinforced, /area/maintenance/trading) "des" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -30656,9 +30810,6 @@ icon_state = "redcorner" }, /area/security/prison/cell_block/A) -"dfe" = ( -/turf/simulated/wall, -/area/medical/research/restroom) "dff" = ( /obj/effect/decal/warning_stripes/southeast, /obj/structure/cable{ @@ -30945,7 +31096,8 @@ "dgk" = ( /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/nhallway) "dgo" = ( @@ -31035,9 +31187,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/spawner/random_barrier, /turf/simulated/floor/plating, /area/maintenance/fore) @@ -32677,8 +32826,10 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/structure/disposalpipe/junction{ - dir = 8 +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + name = "Detective"; + sortType = 27 }, /turf/simulated/floor/plasteel{ dir = 1 @@ -32785,7 +32936,9 @@ pixel_y = -29 }, /obj/effect/decal/cleanable/dirt, -/obj/item/twohanded/required/kirbyplants, +/obj/structure/transit_tube/cap{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -32900,7 +33053,7 @@ name = "Toilet" }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "doi" = ( @@ -32977,7 +33130,7 @@ pixel_y = 32 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "doy" = ( @@ -33036,7 +33189,7 @@ dir = 10 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "doP" = ( @@ -33089,9 +33242,6 @@ dir = 8; name = "Genetics Desk" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -33557,18 +33707,21 @@ /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/nhallway) "drv" = ( /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) "drC" = ( /obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -33578,16 +33731,6 @@ icon_state = "whitebluecorner" }, /area/medical/genetics) -"drF" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurplecorner" - }, -/area/medical/genetics) "drH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -33801,13 +33944,6 @@ icon_state = "darkblue" }, /area/construction/hallway) -"dsx" = ( -/obj/item/twohanded/required/kirbyplants, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "dsz" = ( /obj/machinery/papershredder, /obj/machinery/newscaster{ @@ -33819,12 +33955,14 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) "dsG" = ( /obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -34344,22 +34482,19 @@ }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "dvd" = ( /obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" + icon_state = "1-8" }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 }, /turf/simulated/floor/plasteel{ icon_state = "purplefull" @@ -34406,7 +34541,8 @@ /obj/item/robotanalyzer, /turf/simulated/floor/plasteel{ dir = 5; - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whiteblue (NORTHEAST)" }, /area/assembly/robotics) "dvk" = ( @@ -34488,9 +34624,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -35163,18 +35296,13 @@ /turf/simulated/floor/plasteel, /area/toxins/storage) "dyC" = ( -/obj/machinery/camera{ - c_tag = "Research South Hallway"; - dir = 4; - network = list("Research","SS13"); - pixel_y = -22 - }, -/obj/structure/extinguisher_cabinet{ - pixel_x = -28 +/obj/structure/sign/poster/official/help_others{ + pixel_x = -32 }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "dyD" = ( @@ -35405,15 +35533,18 @@ }, /area/hallway/primary/fore) "dzH" = ( -/obj/structure/sign/poster/official/nanotrasen_logo{ - pixel_x = -32 +/obj/machinery/power/apc{ + dir = 8; + name = "west bump"; + pixel_x = -26 }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 +/obj/structure/cable{ + icon_state = "0-4" }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "dzI" = ( @@ -35422,7 +35553,8 @@ }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "dzJ" = ( @@ -35443,6 +35575,7 @@ "dzQ" = ( /obj/effect/decal/warning_stripes/yellow/partial, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -35649,7 +35782,8 @@ /obj/item/wrench, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/toxins/lab) "dAX" = ( @@ -36105,13 +36239,11 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ - icon_state = "neutralfull" + icon_state = "dark" }, -/area/hallway/primary/central/nw) +/area/engine/mechanic_workshop/hangar) "dCK" = ( /obj/structure/table/reinforced, /obj/item/reagent_containers/food/condiment/peppermill{ @@ -36130,18 +36262,14 @@ }, /area/crew_quarters/kitchen) "dCL" = ( -/obj/structure/sign/poster/random{ +/obj/structure/closet/radiation, +/obj/structure/sign/poster/official/nanotrasen_logo{ pixel_x = 32 }, -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/vending/clothing/departament/science, /turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitepurple" + icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "dCM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/effect/decal/cleanable/dirt, @@ -36367,6 +36495,7 @@ name = "west bump"; pixel_x = -26 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "red" @@ -36429,33 +36558,17 @@ /turf/simulated/floor/plasteel, /area/engine/engineering) "dDQ" = ( -/obj/effect/decal/warning_stripes/northwest, -/obj/structure/chair/comfy/purp{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8; - initialize_directions = 11 - }, +/obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ - icon_state = "whitepurplefull" + icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "dDR" = ( /obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/turf/simulated/floor/plasteel{ - icon_state = "white" + icon_state = "2-8" }, -/area/medical/research/restroom) +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "dDU" = ( /obj/effect/turf_decal/siding/wood{ dir = 10 @@ -36524,17 +36637,6 @@ icon_state = "blue" }, /area/atmos) -"dEi" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plating, -/area/maintenance/engineering) "dEk" = ( /obj/structure/cable{ icon_state = "0-8" @@ -36711,28 +36813,23 @@ }, /area/crew_quarters/bar) "dFn" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/unary/vent_scrubber{ - dir = 1; - name = "standard air scrubber"; - on = 1; - scrub_N2O = 1; - scrub_Toxins = 1 +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/machinery/power/apc{ + cell_type = 0; + name = "south bump"; + pixel_y = -26 }, /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "dFp" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -37044,13 +37141,6 @@ icon_state = "brown" }, /area/quartermaster/storage) -"dGO" = ( -/obj/item/twohanded/required/kirbyplants, -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "dGP" = ( /obj/item/radio/intercom{ pixel_y = -28 @@ -37203,9 +37293,7 @@ /obj/structure/chair/office/dark{ dir = 8 }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "dHl" = ( @@ -37324,9 +37412,17 @@ /turf/simulated/floor/plating, /area/turret_protected/ai) "dHD" = ( -/obj/structure/closet/emcloset, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/table, +/obj/machinery/kitchen_machine/microwave{ + pixel_x = -1; + pixel_y = 7 + }, +/turf/simulated/floor/plasteel{ + dir = 5; + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHWEST)" + }, +/area/medical/research/restroom) "dHH" = ( /obj/machinery/computer/arcade/battle, /obj/effect/decal/warning_stripes/red/hollow, @@ -37526,6 +37622,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -37538,7 +37635,6 @@ scrub_Toxins = 1 }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/securearmory) @@ -37634,6 +37730,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dIE" = ( @@ -37643,6 +37742,13 @@ }, /turf/simulated/floor/engine, /area/maintenance/turbine) +"dIG" = ( +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" + }, +/area/medical/research) "dIH" = ( /obj/structure/cable{ icon_state = "4-8" @@ -37679,10 +37785,13 @@ /turf/simulated/floor/plating, /area/security/checkpoint/south) "dIL" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitepurple" @@ -38094,10 +38203,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /obj/effect/landmark/event/lightsout, /turf/simulated/floor/plasteel, /area/hydroponics) @@ -38666,6 +38771,7 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -38844,6 +38950,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1 }, @@ -38924,16 +39031,13 @@ }, /area/medical/virology/lab) "dNZ" = ( -/obj/structure/table, -/obj/item/storage/box/donkpockets, -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitepurple" +/obj/structure/table/reinforced, +/obj/item/gps, +/obj/structure/sign/poster/official/ian{ + pixel_x = -32 }, -/area/medical/research/restroom) +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "dOa" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ @@ -39142,7 +39246,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "blue" @@ -40141,9 +40244,7 @@ pixel_x = 24; pixel_y = -22 }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/library) "dSM" = ( @@ -40801,7 +40902,7 @@ pixel_y = -32 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "dVy" = ( @@ -40929,6 +41030,9 @@ dir = 4 }, /obj/structure/girder, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "dVY" = ( @@ -41968,6 +42072,9 @@ maxcharge = 15000 }, /obj/item/clothing/glasses/welding, +/obj/item/radio/intercom{ + pixel_y = 24 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -42104,7 +42211,6 @@ /area/bridge/vip) "dZN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "blue" @@ -42590,6 +42696,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -42836,17 +42945,6 @@ icon_state = "darkblue" }, /area/medical/surgery/north) -"ehA" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/newscaster{ - pixel_y = -28 - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "ehB" = ( /obj/structure/cable{ icon_state = "4-8" @@ -43126,6 +43224,15 @@ icon_state = "purplefull" }, /area/medical/research/nhallway) +"eke" = ( +/obj/item/radio/intercom{ + pixel_x = 28 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "ekj" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment, @@ -44104,21 +44211,13 @@ /turf/simulated/floor/wood/fancy/light, /area/crew_quarters/courtroom) "exh" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/research{ - name = "Research Break Room"; +/obj/machinery/door/airlock/maintenance{ req_access = list(47) }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "exl" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -44529,6 +44628,9 @@ /obj/item/radio/intercom{ pixel_y = 24 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -44546,16 +44648,10 @@ dir = 4; pixel_x = 28 }, -/obj/machinery/atmospherics/unary/vent_scrubber{ - dir = 8; - name = "standard air scrubber"; - on = 1; - scrub_N2O = 1; - scrub_Toxins = 1 - }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "eCU" = ( @@ -44832,7 +44928,6 @@ dir = 4 }, /obj/item/stock_parts/manipulator, -/obj/effect/decal/cleanable/blood/oil/streak, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "eGn" = ( @@ -45149,6 +45244,20 @@ }, /turf/simulated/floor/plasteel, /area/crew_quarters/locker/locker_toilet) +"eJE" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Break Room Maintenance"; + req_access = list(47) + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/maintenance/engineering) "eJH" = ( /obj/effect/decal/warning_stripes/yellow/hollow, /obj/item/clothing/glasses/meson{ @@ -45272,8 +45381,8 @@ pixel_y = 3 }, /obj/item/melee/chainofcommand{ - pixel_y = 5; - pixel_x = 5 + pixel_x = 5; + pixel_y = 5 }, /turf/simulated/floor/carpet/royalblue, /area/crew_quarters/captain/bedroom) @@ -45473,13 +45582,19 @@ }, /area/medical/cmostore) "eMO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "4-8" }, -/turf/simulated/floor/plasteel, -/area/bridge/vip) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/bridge) "eMU" = ( /obj/machinery/atmospherics/unary/portables_connector, /obj/machinery/portable_atmospherics/scrubber, @@ -46435,7 +46550,6 @@ /turf/simulated/floor/plating, /area/security/checkpoint/south) "eXY" = ( -/obj/structure/disposalpipe/segment, /obj/effect/landmark/event/lightsout, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -46446,6 +46560,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -46477,6 +46595,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -47204,6 +47325,7 @@ dir = 4 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -47270,12 +47392,6 @@ icon_state = "neutralcorner" }, /area/crew_quarters/fitness) -"fib" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/wall/r_wall, -/area/security/interrogation) "fif" = ( /obj/structure/dresser, /obj/item/radio/intercom{ @@ -47525,18 +47641,6 @@ icon_state = "dark" }, /area/security/permabrig) -"fkL" = ( -/obj/effect/decal/warning_stripes/southwest, -/obj/structure/chair/comfy/purp{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurplefull" - }, -/area/medical/research/restroom) "fkP" = ( /obj/structure/window/reinforced{ dir = 4 @@ -47808,7 +47912,6 @@ icon_state = "4-8" }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/interrogation) @@ -48335,18 +48438,11 @@ }, /area/chapel/main) "fvB" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/barricade/wooden, -/obj/effect/decal/warning_stripes/north, -/obj/structure/cable{ - icon_state = "4-8" - }, +/obj/machinery/atmospherics/unary/vent_scrubber, /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "fvC" = ( /obj/machinery/portable_atmospherics/canister/air, /obj/effect/decal/warning_stripes/yellow/hollow, @@ -48508,6 +48604,9 @@ name = "Награда за первое нарушение в новом бриге"; pixel_y = 32 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -49037,6 +49136,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, +/obj/structure/disposalpipe/junction{ + dir = 4; + icon_state = "pipe-y" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutral" @@ -49077,7 +49180,7 @@ network = list("SS13","MiniSat") }, /turf/space, -/area/space) +/area/turret_protected/ai) "fFv" = ( /obj/structure/cable{ icon_state = "0-2" @@ -49309,7 +49412,7 @@ network = list("SS13","MiniSat") }, /turf/space, -/area/space) +/area/turret_protected/ai) "fId" = ( /obj/machinery/door/firedoor, /obj/machinery/door/poddoor{ @@ -49366,9 +49469,23 @@ /turf/simulated/floor/wood, /area/security/hos) "fIC" = ( -/obj/effect/decal/cleanable/blood/oil/streak, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "neutralfull" + }, +/area/hallway/primary/central/south) "fIE" = ( /obj/machinery/vending/cart, /obj/structure/window/reinforced{ @@ -49417,9 +49534,11 @@ }, /area/crew_quarters/theatre) "fJp" = ( -/obj/machinery/teleport/hub, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/turf/simulated/floor/plasteel{ + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" + }, +/area/medical/research/restroom) "fJE" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/vending/wallmed{ @@ -49704,6 +49823,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "fNH" = ( @@ -49953,7 +50073,8 @@ pixel_y = -32 }, /turf/simulated/floor/plasteel{ - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whitehall (WEST)" }, /area/assembly/robotics) "fQW" = ( @@ -49975,9 +50096,7 @@ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "redfull" }, @@ -50557,13 +50676,9 @@ /obj/structure/disposalpipe/trunk{ dir = 2 }, -/obj/item/radio/intercom{ - pixel_y = 24 - }, /obj/machinery/door_control{ id = "SecPilotPriv"; name = "Pilot Privacy Shutters Control"; - pixel_x = 16; pixel_y = 24; req_access = list(71) }, @@ -50641,7 +50756,8 @@ }, /obj/machinery/light, /turf/simulated/floor/plasteel{ - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/assembly/robotics) "fXD" = ( @@ -50669,7 +50785,7 @@ network = list("SS13","MiniSat") }, /turf/space, -/area/space) +/area/turret_protected/ai) "fXQ" = ( /obj/effect/spawner/window/reinforced, /obj/machinery/door/poddoor{ @@ -50714,6 +50830,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "fYu" = ( @@ -50734,9 +50851,13 @@ }, /area/atmos) "fYC" = ( -/mob/living/simple_animal/mouse/gray, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/table/glass, +/obj/effect/decal/warning_stripes/south, +/obj/item/storage/fancy/donut_box, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplefull" + }, +/area/medical/research/restroom) "fYM" = ( /obj/structure/cable{ icon_state = "2-8" @@ -50786,6 +50907,7 @@ /obj/effect/decal/warning_stripes/yellow/partial, /obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -51196,6 +51318,7 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -51247,6 +51370,7 @@ /area/quartermaster/qm) "gfO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "green" @@ -51356,6 +51480,9 @@ /obj/machinery/light{ dir = 1 }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, /turf/simulated/floor/plasteel{ icon_state = "cmo" }, @@ -51415,8 +51542,7 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/research) "gio" = ( @@ -51451,13 +51577,15 @@ }, /area/turret_protected/aisat) "gjD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/west, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitepurplecorner" + icon_state = "white" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "gjM" = ( /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, @@ -51479,16 +51607,10 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/toxins/lab) -"gkk" = ( -/obj/structure/transit_tube{ - icon_state = "D-NW"; - tag = "icon-D-NW" - }, -/turf/space, -/area/space) "gko" = ( /obj/effect/decal/warning_stripes/south, /obj/structure/cable{ @@ -51548,13 +51670,10 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8; - initialize_directions = 11 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable{ + icon_state = "2-8" }, /turf/simulated/floor/plasteel{ icon_state = "purplefull" @@ -51702,9 +51821,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -52032,11 +52149,9 @@ }, /area/medical/virology) "gpS" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "gpT" = ( /obj/structure/closet/crate/medical, /obj/effect/spawner/lootdrop/maintenance/tripple, @@ -52118,6 +52233,7 @@ tag = "icon-pipe-j1 (EAST)" }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/sw) @@ -52393,6 +52509,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore) "gvy" = ( @@ -52785,14 +52904,18 @@ }, /area/crew_quarters/theatre) "gAF" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/effect/decal/cleanable/dirt, +/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 }, /turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitepurplecorner" + dir = 6; + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHEAST)" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "gAS" = ( /obj/machinery/door/airlock/command{ id_tag = "captainofficedoor"; @@ -53115,13 +53238,16 @@ }, /area/medical/reception) "gDZ" = ( -/obj/structure/disposalpipe/junction{ - dir = 1 +/obj/structure/cable{ + icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ - icon_state = "purplecorner" + icon_state = "white" }, -/area/hallway/primary/aft) +/area/medical/medbay) "gEq" = ( /obj/structure/table, /obj/item/storage/toolbox/mechanical, @@ -53322,7 +53448,6 @@ }, /area/security/securehallway) "gGp" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -53332,6 +53457,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/junction{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "neutralcorner" }, @@ -53440,9 +53568,7 @@ "gHq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/library) "gHz" = ( @@ -53557,6 +53683,7 @@ /obj/effect/turf_decal/siding/brown{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/light, /area/bridge/meeting_room) "gIq" = ( @@ -53735,8 +53862,7 @@ "gKd" = ( /obj/structure/table, /obj/item/storage/toolbox/emergency/old, -/turf/simulated/floor/plasteel{ - dir = 10; +/turf/simulated/floor/plasteel/airless{ icon_state = "darkredfull" }, /area/space) @@ -54025,14 +54151,6 @@ icon_state = "wood-broken6" }, /area/maintenance/kitchen) -"gMU" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "gMZ" = ( /obj/structure/cable{ icon_state = "1-4" @@ -54511,6 +54629,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -55348,9 +55470,18 @@ }, /area/medical/virology/lab) "hbL" = ( -/obj/effect/decal/warning_stripes/west, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "hbO" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/window/reinforced{ @@ -55557,6 +55688,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "blue" @@ -55645,12 +55777,15 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/door/firedoor, +/obj/effect/decal/warning_stripes/yellow, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, -/area/hallway/primary/central/north) +/area/hallway/primary/central/nw) "hfM" = ( /turf/simulated/floor/wood, /area/security/hos) @@ -55701,20 +55836,16 @@ /turf/simulated/floor/plating, /area/maintenance/detectives_office) "hgH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/apc{ - cell_type = 0; - dir = 1; - name = "north bump"; - pixel_y = 26 - }, -/obj/structure/cable{ - icon_state = "0-2" +/obj/structure/table, +/obj/item/storage/box/donkpockets, +/obj/structure/sign/poster/random{ + pixel_y = 32 }, /turf/simulated/floor/plasteel{ - icon_state = "white" + dir = 1; + icon_state = "whitepurple" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "hgM" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ @@ -56322,9 +56453,14 @@ /obj/machinery/firealarm{ pixel_y = 26 }, +/obj/machinery/light{ + dir = 1; + on = 1 + }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "hoU" = ( @@ -56340,7 +56476,6 @@ }, /obj/effect/landmark/start/warden, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/warden) @@ -57094,7 +57229,7 @@ dir = 1 }, /obj/machinery/light_switch{ - pixel_x = -26; + pixel_x = -24; pixel_y = -4 }, /turf/simulated/floor/plasteel{ @@ -57123,9 +57258,6 @@ /turf/simulated/floor/plasteel, /area/atmos) "hyT" = ( -/obj/structure/disposalpipe/junction{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -57135,6 +57267,12 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/sortjunction{ + dir = 1; + name = "Morgue"; + sortType = 25; + tag = "icon-pipe-j1s (EAST)" + }, /turf/simulated/floor/plasteel{ icon_state = "neutralcorner" }, @@ -57163,7 +57301,6 @@ }, /obj/machinery/computer/card, /turf/simulated/floor/plasteel{ - dir = 6; icon_state = "bluefull" }, /area/bridge/checkpoint/south) @@ -57702,7 +57839,8 @@ /obj/effect/landmark/start/roboticist, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/assembly/robotics) "hGs" = ( @@ -57948,6 +58086,7 @@ "hJX" = ( /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -58118,13 +58257,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/engineering) -"hLJ" = ( -/obj/machinery/vending/cigarette/free, -/obj/effect/decal/warning_stripes/southeast, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/medical/research/restroom) "hLK" = ( /obj/structure/chair/sofa/left{ dir = 4 @@ -59131,15 +59263,6 @@ /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "hYi" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "purplefull" }, @@ -59195,6 +59318,10 @@ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -59445,9 +59572,9 @@ /area/chapel/office) "icl" = ( /obj/effect/landmark/tiles/burnturf, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkred" +/turf/simulated/floor/plasteel/airless{ + icon_state = "darkred"; + dir = 9 }, /area/space) "icp" = ( @@ -59605,12 +59732,16 @@ }, /area/turret_protected/ai) "ifq" = ( -/obj/item/radio/intercom{ - pixel_y = 24 +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "ifw" = ( @@ -60248,11 +60379,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/junction{ - dir = 2; - icon_state = "pipe-j2"; - tag = "icon-pipe-j2" - }, /obj/structure/cable{ icon_state = "2-4" }, @@ -60262,6 +60388,12 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/sortjunction{ + dir = 2; + icon_state = "pipe-j2s"; + name = "Botany"; + sortType = 21 + }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "imJ" = ( @@ -60526,10 +60658,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/junction{ - dir = 8; - icon_state = "pipe-j2"; - tag = "icon-pipe-j1 (WEST)" +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel, /area/hydroponics) @@ -60875,11 +61006,8 @@ /turf/simulated/wall/r_wall/coated, /area/maintenance/incinerator) "itZ" = ( +/obj/structure/transit_tube/diagonal/crossing, /obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "D-NE"; - tag = "icon-D-NE" - }, /turf/space, /area/space) "iuh" = ( @@ -61026,6 +61154,7 @@ scrub_Toxins = 1 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -61246,8 +61375,7 @@ /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/reception) "ixu" = ( @@ -61277,9 +61405,6 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 0; icon_state = "green" @@ -61300,9 +61425,21 @@ }, /area/security/brig) "izb" = ( -/obj/effect/decal/warning_stripes/south, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/hologram/holopad, +/obj/effect/decal/warning_stripes/yellow/hollow, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "izf" = ( /obj/structure/table/wood/fancy/royalblack, /obj/machinery/computer/secure_data/laptop{ @@ -61414,6 +61551,21 @@ icon_state = "green" }, /area/hallway/secondary/exit) +"iAW" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8; + initialize_directions = 11 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/shallway) "iBj" = ( /obj/structure/chair/wood{ dir = 4 @@ -62851,9 +63003,7 @@ /area/hydroponics) "iTF" = ( /obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "NE-SW" - }, +/obj/structure/transit_tube/crossing/horizontal, /turf/space, /area/space) "iTM" = ( @@ -63025,12 +63175,13 @@ }, /area/atmos/control) "iVN" = ( -/obj/machinery/vending/coffee, -/obj/effect/decal/warning_stripes/south, +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/toolbox/mechanical, /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "iWe" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -63088,6 +63239,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/asmaint) "iWM" = ( @@ -63575,10 +63727,19 @@ /turf/simulated/floor/plating, /area/crew_quarters/trading) "jcR" = ( -/obj/machinery/light/small, -/obj/effect/decal/warning_stripes/south, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "jcU" = ( /obj/effect/spawner/window/reinforced, /obj/machinery/door/poddoor{ @@ -63849,10 +64010,6 @@ /turf/simulated/floor/engine, /area/medical/chemistry) "jgk" = ( -/obj/item/radio/intercom{ - pixel_x = 28; - pixel_y = -2 - }, /obj/machinery/light{ dir = 4 }, @@ -64256,21 +64413,11 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "red" }, /area/security/processing) -"jlL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office/light{ - dir = 4; - pixel_y = 3 - }, -/obj/effect/decal/warning_stripes/southeast, -/turf/simulated/floor/plasteel{ - icon_state = "purplefull" - }, -/area/teleporter/abandoned) "jlW" = ( /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/mouse/brown, @@ -64293,7 +64440,8 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/crew_quarters/hor) "jmx" = ( @@ -64316,7 +64464,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/hologram/holopad, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -64502,7 +64649,8 @@ }, /turf/simulated/floor/plasteel{ dir = 9; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTHWEST)" }, /area/medical/research) "joX" = ( @@ -64582,7 +64730,8 @@ /obj/item/stock_parts/cell/high, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "jqd" = ( @@ -65204,10 +65353,6 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/fitness) "jwN" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, @@ -65426,9 +65571,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "green" @@ -65500,10 +65642,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "blue" @@ -65522,16 +65660,16 @@ }, /area/quartermaster/storage) "jzw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/filingcabinet/chestdrawer, -/obj/machinery/alarm{ - pixel_y = 22 +/obj/structure/cable{ + icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ - dir = 5; + dir = 1; icon_state = "whitepurple" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "jAa" = ( /obj/machinery/light/small{ dir = 4 @@ -65601,6 +65739,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -65652,6 +65791,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/door/firedoor, /obj/effect/decal/warning_stripes/yellow, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "jBm" = ( @@ -66213,6 +66353,9 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "jIv" = ( @@ -66323,7 +66466,6 @@ icon_state = "1-2" }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/warden) @@ -66594,12 +66736,11 @@ /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "jMs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/radiation, /turf/simulated/floor/plasteel{ - icon_state = "white" + dir = 4; + icon_state = "whitepurple" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "jMx" = ( /obj/machinery/light{ dir = 1; @@ -66747,7 +66888,7 @@ /area/bridge/vip) "jPC" = ( /obj/effect/landmark/tiles/burnturf, -/turf/simulated/floor/plasteel{ +/turf/simulated/floor/plasteel/airless{ icon_state = "darkred" }, /area/space) @@ -66900,7 +67041,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/toxins/lab) "jRL" = ( @@ -67273,14 +67415,6 @@ icon_state = "darkblue" }, /area/bridge) -"jWl" = ( -/obj/machinery/door/firedoor, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "ramptop"; - tag = "icon-stage_stairs" - }, -/area/medical/reception) "jWn" = ( /obj/structure/plasticflaps, /obj/effect/decal/warning_stripes/yellow, @@ -67365,6 +67499,10 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "redcorner" }, @@ -67456,13 +67594,12 @@ }, /area/security/lobby) "jXW" = ( -/obj/structure/transit_tube{ - icon_state = "D-SW"; - tag = "icon-D-SW" - }, /obj/structure/window/reinforced{ dir = 8 }, +/obj/structure/transit_tube/curved/flipped{ + dir = 8 + }, /turf/space, /area/space) "jYe" = ( @@ -67778,20 +67915,12 @@ }, /area/security/interrogation) "kdl" = ( -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2"; - tag = "icon-pipe-j2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurple" +/obj/machinery/door/airlock/maintenance{ + name = "Telescience" }, -/area/medical/research/restroom) +/obj/structure/barricade/wooden, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "kdM" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -68306,6 +68435,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "kkK" = ( @@ -68348,6 +68481,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -68528,11 +68662,6 @@ }, /area/toxins/xenobiology) "kmU" = ( -/obj/structure/transit_tube/station{ - dir = 8; - tag = "icon-closed (EAST)" - }, -/obj/structure/transit_tube_pod, /obj/structure/window/reinforced{ dir = 4 }, @@ -68548,11 +68677,6 @@ icon_state = "darkblue" }, /area/construction/hallway) -"kna" = ( -/turf/simulated/floor/greengrid{ - temperature = 80 - }, -/area/toxins/xenobiology) "knb" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -69324,7 +69448,8 @@ /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/nhallway) "kxT" = ( @@ -70068,6 +70193,20 @@ /obj/structure/lattice, /turf/simulated/wall/rust, /area/space) +"kGZ" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "kHa" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/maintenance/double, @@ -70475,16 +70614,11 @@ }, /area/quartermaster/miningdock) "kMz" = ( -/obj/machinery/hologram/holopad, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/light/small, /turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitepurplecorner" + icon_state = "purplefull" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "kMC" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/item/clothing/head/kitty, @@ -70778,16 +70912,11 @@ /turf/simulated/floor/plating, /area/crew_quarters/bar) "kQU" = ( -/obj/machinery/alarm{ - dir = 8; - pixel_x = 24 - }, -/obj/item/twohanded/required/kirbyplants, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/pen, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "kQV" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ @@ -70842,6 +70971,7 @@ /obj/effect/turf_decal/siding/brown/corner{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/light, /area/bridge/meeting_room) "kRE" = ( @@ -70999,7 +71129,8 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment{ - dir = 4 + dir = 8; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel, /area/hallway/secondary/exit) @@ -71042,7 +71173,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "kVH" = ( @@ -71100,17 +71232,6 @@ icon_state = "dark" }, /area/atmos) -"kWh" = ( -/obj/structure/transit_tube{ - icon_state = "D-NE"; - tag = "icon-D-NE" - }, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/lattice, -/turf/space, -/area/space) "kWn" = ( /obj/item/grown/bananapeel{ layer = 1.9 @@ -71160,11 +71281,8 @@ /turf/simulated/floor/plating, /area/maintenance/starboard) "kXY" = ( -/obj/structure/transit_tube{ - icon_state = "D-NW"; - tag = "icon-D-NW" - }, -/obj/structure/window/reinforced{ +/obj/structure/lattice, +/obj/structure/transit_tube/curved{ dir = 8 }, /turf/space, @@ -71356,11 +71474,21 @@ }, /area/toxins/test_chamber) "lap" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, /obj/structure/disposalpipe/segment{ dir = 4 }, -/turf/simulated/floor/plasteel, -/area/hallway/secondary/exit) +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "neutralfull" + }, +/area/hallway/primary/central/south) "lay" = ( /obj/structure/holosign/barrier/engineering, /obj/effect/landmark/tiles/damageturf, @@ -71606,7 +71734,8 @@ /obj/machinery/door_control{ id = "Clown"; name = "Clowns Privacy Shutters Control"; - pixel_x = 26 + pixel_x = 25; + pixel_y = -10 }, /turf/simulated/floor/plasteel{ icon_state = "bar" @@ -72292,7 +72421,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/assembly/robotics) "lmx" = ( @@ -72506,6 +72636,7 @@ /obj/effect/turf_decal/siding/brown{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/light, /area/bridge/meeting_room) "loT" = ( @@ -72943,7 +73074,6 @@ }, /area/medical/medbay2) "luu" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -73221,6 +73351,16 @@ icon_state = "caution" }, /area/engine/break_room) +"lxY" = ( +/obj/effect/spawner/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/simulated/floor/plating, +/area/medical/research/nhallway) "lxZ" = ( /obj/structure/cable{ icon_state = "0-4" @@ -73375,9 +73515,7 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/hor) "lzm" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable{ @@ -73456,6 +73594,7 @@ icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -73507,12 +73646,6 @@ icon_state = "cmo" }, /area/medical/ward) -"lAU" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/wall/r_wall, -/area/security/holding_cell) "lAV" = ( /obj/structure/table/reinforced, /obj/item/folder/yellow, @@ -73527,17 +73660,6 @@ icon_state = "darkred" }, /area/security/processing) -"lBh" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/medical/research/shallway) "lBo" = ( /obj/machinery/light_switch{ on = 0; @@ -73566,6 +73688,10 @@ pixel_x = -24; req_access = list(63) }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "red" @@ -73878,10 +74004,17 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/fitness) "lGD" = ( -/obj/structure/table/reinforced, -/obj/item/gps, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/sign/poster/official/nanotrasen_logo{ + pixel_x = -32 + }, +/obj/structure/table, +/obj/item/paper_bin, +/obj/item/pen, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "lGF" = ( /obj/machinery/door/airlock/medical{ name = "Virology Bedroom"; @@ -73908,8 +74041,7 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/research) "lGO" = ( @@ -74215,7 +74347,6 @@ /turf/simulated/floor/plating, /area/maintenance/disposal) "lJZ" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -74259,9 +74390,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "neutralcorner" }, @@ -74295,9 +74423,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -74600,10 +74725,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -74833,8 +74954,7 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/reception) "lRk" = ( @@ -75853,7 +75973,6 @@ }, /obj/effect/landmark/start/warden, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/warden) @@ -76135,6 +76254,16 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/toxins/xenobiology) +"mhI" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplecorner" + }, +/area/medical/genetics) "mhK" = ( /obj/structure/cable{ icon_state = "4-8" @@ -76661,7 +76790,8 @@ }, /turf/simulated/floor/plasteel{ dir = 9; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTHWEST)" }, /area/toxins/lab) "mnk" = ( @@ -77324,16 +77454,16 @@ }, /area/atmos) "muS" = ( -/obj/structure/transit_tube{ - icon_state = "S-NE"; - tag = "icon-S-NE" - }, /obj/structure/window/reinforced{ dir = 4 }, /obj/structure/window/reinforced{ dir = 1 }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "darkblue" @@ -77412,12 +77542,13 @@ }, /area/aisat/maintenance) "mwg" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" +/obj/structure/disposalpipe/junction{ + dir = 1 }, -/turf/simulated/wall/r_wall, -/area/security/processing) +/turf/simulated/floor/plasteel{ + icon_state = "purplecorner" + }, +/area/hallway/primary/aft) "mwh" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -77459,6 +77590,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutralcorner" @@ -77716,19 +77851,6 @@ icon_state = "red" }, /area/security/main) -"mzX" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/machinery/atmospherics/unary/portables_connector{ - dir = 4 - }, -/obj/machinery/portable_atmospherics/canister/air, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/construction/hallway) "mzZ" = ( /obj/structure/sign/science{ icon_state = "doors" @@ -77742,15 +77864,6 @@ icon_state = "whitepurple" }, /area/toxins/misc_lab) -"mAd" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/barricade/wooden, -/obj/effect/decal/warning_stripes/northeast, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) "mAl" = ( /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ @@ -77851,7 +77964,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/toxins/lab) "mAS" = ( @@ -78342,7 +78456,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "mEG" = ( @@ -78469,10 +78584,6 @@ }, /area/medical/medbay2) "mGs" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable{ icon_state = "1-2" @@ -78480,6 +78591,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -78918,7 +79030,7 @@ "mLJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/junction, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/transparent/glass/reinforced, /area/hallway/secondary/exit) "mLS" = ( @@ -79149,6 +79261,7 @@ dir = 4 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/sw) @@ -79445,18 +79558,13 @@ }, /area/security/customs) "mSh" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/apc{ - cell_type = 5000; - dir = 4; - name = "east bump"; - pixel_x = 26 +/obj/structure/sign/science{ + pixel_x = 32 }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "mSn" = ( @@ -79493,14 +79601,13 @@ }, /area/chapel/main) "mSG" = ( -/obj/structure/transit_tube{ - icon_state = "W-SE"; - tag = "icon-W-SE" - }, /obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/transit_tube/curved{ + dir = 8 + }, /turf/space, /area/space) "mSR" = ( @@ -79691,7 +79798,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, -/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/junction, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutral" @@ -79934,6 +80041,7 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -80007,6 +80115,10 @@ /obj/structure/cable{ icon_state = "2-8" }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "mZk" = ( @@ -80015,6 +80127,7 @@ dir = 4 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -80098,7 +80211,8 @@ /obj/item/stack/cable_coil, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/toxins/lab) "naf" = ( @@ -80112,6 +80226,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -80276,10 +80391,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2"; - tag = "icon-pipe-j2" +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ icon_state = "purplefull" @@ -80324,10 +80438,11 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/structure/disposalpipe/segment{ - dir = 4 + dir = 1; + icon_state = "pipe-c" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/plating, /area/maintenance/fore) "ncu" = ( @@ -80591,16 +80706,10 @@ scrub_N2O = 1; scrub_Toxins = 1 }, -/obj/machinery/light{ - dir = 1; - on = 1 - }, -/obj/structure/sign/poster/official/random{ - pixel_y = 32 - }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "nfX" = ( @@ -80683,9 +80792,6 @@ }, /area/crew_quarters/fitness) "nhF" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -81026,6 +81132,9 @@ name = "Hydroponics"; req_access = list(35) }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -81163,9 +81272,6 @@ }, /area/medical/research/shallway) "nmy" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 28 - }, /obj/machinery/papershredder, /turf/simulated/floor/plasteel{ icon_state = "cmo" @@ -81411,8 +81517,10 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/disposalpipe/junction{ - dir = 8 +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + name = "IAA Office"; + sortType = 29 }, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" @@ -81423,7 +81531,8 @@ /obj/machinery/door_control{ id = "Mime"; name = "Mimes Privacy Shutters Control"; - pixel_x = -27 + pixel_x = -25; + pixel_y = -10 }, /turf/simulated/floor/plasteel{ dir = 4; @@ -81487,7 +81596,7 @@ pixel_y = -32 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "nqH" = ( @@ -81564,6 +81673,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "nrr" = ( @@ -81601,12 +81711,13 @@ }, /area/hallway/primary/central/north) "nrB" = ( -/obj/structure/sign/nosmoking_2{ - pixel_y = 32 +/obj/item/radio/intercom{ + pixel_y = 24 }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "nrD" = ( @@ -81624,6 +81735,16 @@ /obj/structure/cable, /turf/simulated/floor/plating, /area/security/prisonershuttle) +"nrG" = ( +/obj/structure/table/glass, +/obj/item/scalpel{ + pixel_y = 8 + }, +/obj/effect/decal/warning_stripes/north, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplefull" + }, +/area/medical/research/restroom) "nrJ" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ @@ -81650,8 +81771,7 @@ /obj/structure/delta_statue/nw, /turf/simulated/floor/plasteel{ dir = 5; - icon_state = "vault"; - tag = "icon-vault (NORTHEAST)" + icon_state = "vault" }, /area/bridge/vip) "nsi" = ( @@ -81738,7 +81858,8 @@ /obj/structure/cable, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research) "nsH" = ( @@ -82000,6 +82121,10 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -82559,13 +82684,15 @@ }, /area/security/prison/cell_block/A) "nDf" = ( -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/glass{ - amount = 10 +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 8 }, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/turf/simulated/floor/plasteel{ + dir = 6; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "nDj" = ( /obj/structure/closet/emcloset, /obj/item/radio/intercom{ @@ -82742,6 +82869,7 @@ /obj/effect/decal/warning_stripes/south, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/maintenance/asmaint2) "nFA" = ( @@ -82827,6 +82955,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "nGj" = ( @@ -83056,7 +83187,6 @@ }, /area/hydroponics) "nIG" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -83069,6 +83199,10 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "darkblue" @@ -83213,7 +83347,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "nKc" = ( @@ -83372,8 +83507,7 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/research) "nMs" = ( @@ -83454,6 +83588,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -83619,9 +83756,15 @@ /turf/simulated/floor/plasteel, /area/gateway) "nPX" = ( -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/chair/comfy/purp{ + dir = 8 + }, +/obj/effect/decal/warning_stripes/southeast, +/obj/effect/landmark/start/scientist, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplefull" + }, +/area/medical/research/restroom) "nPZ" = ( /obj/machinery/newscaster{ pixel_x = 28; @@ -83906,7 +84049,7 @@ name = "Toilet" }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "nSz" = ( @@ -84064,7 +84207,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "blue" @@ -84252,8 +84394,7 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/virology/lab) "nXm" = ( @@ -84307,6 +84448,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "red" @@ -84810,7 +84954,8 @@ }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/toxins/lab) "ofn" = ( @@ -85113,7 +85258,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/toxins/lab) "ohF" = ( @@ -85531,6 +85677,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -85711,6 +85858,7 @@ opacity = 0 }, /obj/effect/spawner/window/reinforced, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/security/holding_cell) "opF" = ( @@ -86343,7 +86491,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "oxF" = ( @@ -86541,8 +86690,20 @@ /turf/simulated/floor/carpet, /area/library) "ozs" = ( -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/machinery/camera{ + c_tag = "Research Break Room"; + network = list("Research","SS13") + }, +/obj/structure/closet/secure_closet/scientist, +/obj/machinery/light{ + dir = 1; + on = 1 + }, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "ozQ" = ( /obj/structure/cable{ icon_state = "2-8" @@ -87020,13 +87181,12 @@ }, /area/medical/surgery/south) "oFp" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/simulated/floor/plasteel{ - icon_state = "white" +/obj/structure/chair/office/light{ + dir = 4; + pixel_y = 3 }, -/area/medical/research/restroom) +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "oFs" = ( /turf/simulated/floor/plating, /area/engine/engineering) @@ -87136,6 +87296,19 @@ /obj/structure/sign/vacuum, /turf/simulated/wall/r_wall, /area/engine/engineering) +"oHb" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" + }, +/area/medical/research/shallway) "oHg" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -87273,6 +87446,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "oIy" = ( @@ -87359,7 +87535,8 @@ /obj/item/stock_parts/cell/high, /turf/simulated/floor/plasteel{ dir = 9; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTHWEST)" }, /area/toxins/lab) "oJN" = ( @@ -87438,7 +87615,8 @@ /obj/effect/landmark/start/civilian, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "oKs" = ( @@ -87833,6 +88011,9 @@ /turf/simulated/floor/plating/airless, /area/space) "oPr" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 0; icon_state = "blue" @@ -88168,9 +88349,7 @@ /obj/effect/landmark/event/lightsout, /obj/machinery/hologram/holopad, /obj/effect/decal/warning_stripes/yellow/hollow, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "oTl" = ( @@ -88184,6 +88363,9 @@ icon_state = "4-8" }, /obj/structure/grille, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "oTu" = ( @@ -88349,7 +88531,8 @@ /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "oVs" = ( @@ -88566,21 +88749,10 @@ }, /area/toxins/lab) "oXs" = ( -/obj/structure/closet/secure_closet/scientist, -/obj/machinery/power/apc{ - cell_type = 5000; - dir = 4; - name = "east bump"; - pixel_x = 26 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/emcloset, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "oXx" = ( /obj/structure/cable{ icon_state = "1-2" @@ -88992,7 +89164,8 @@ /obj/machinery/portable_atmospherics/canister/nitrogen, /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ - icon_state = "redfull" + icon_state = "redfull"; + tag = "icon-redfull (NORTHWEST)" }, /area/toxins/storage) "pdi" = ( @@ -89387,10 +89560,11 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/disposalpipe/junction{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -89797,6 +89971,18 @@ }, /turf/simulated/floor/plating, /area/maintenance/asmaint4) +"pmZ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "vault" + }, +/area/engine/mechanic_workshop/hangar) "pnb" = ( /obj/effect/spawner/window/reinforced, /obj/machinery/door/poddoor/shutters{ @@ -89813,28 +89999,9 @@ /turf/simulated/floor/plating, /area/magistrateoffice) "pnv" = ( -/obj/structure/sign/science{ - pixel_y = 32 - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/obj/machinery/camera{ - c_tag = "Research Break Room"; - network = list("Research","SS13") - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/machinery/teleport/hub, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "pnx" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -90551,9 +90718,6 @@ }, /area/maintenance/kitchen) "puA" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 9 - }, /obj/machinery/access_button{ command = "cycle_interior"; frequency = 1379; @@ -90562,6 +90726,9 @@ pixel_x = 25; pixel_y = 25 }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 5 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "darkblue" @@ -90780,6 +90947,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -91010,10 +91178,6 @@ /turf/simulated/floor/plasteel, /area/security/checkpoint/south) "pAy" = ( -/obj/machinery/light{ - dir = 1; - on = 1 - }, /obj/structure/disposalpipe/segment{ dir = 4; icon_state = "pipe-c" @@ -91056,7 +91220,9 @@ /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /obj/structure/disposalpipe/junction{ - dir = 8 + dir = 2; + icon_state = "pipe-j2"; + tag = "icon-pipe-j2" }, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" @@ -91095,8 +91261,7 @@ /obj/structure/window/reinforced, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "ramptop"; - tag = "icon-stage_stairs" + icon_state = "ramptop" }, /area/crew_quarters/fitness) "pBl" = ( @@ -91108,6 +91273,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -91152,6 +91318,9 @@ /obj/machinery/newscaster{ pixel_y = 32 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -91341,11 +91510,6 @@ /turf/simulated/floor/carpet/arcade, /area/crew_quarters/fitness) "pCX" = ( -/obj/structure/closet/secure_closet/guncabinet{ - anchored = 1; - name = "Magazines for SP-91-RC"; - req_access = list(1) - }, /obj/item/gun/energy/gun/advtaser{ pixel_x = -3; pixel_y = 3 @@ -91360,6 +91524,11 @@ name = "Station Intercom (General)"; pixel_y = -29 }, +/obj/structure/closet/secure_closet/guncabinet{ + anchored = 1; + name = "Tasers"; + req_access = list(1) + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "red" @@ -91454,7 +91623,8 @@ /obj/structure/closet/walllocker/emerglocker/north, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "pEe" = ( @@ -91623,6 +91793,10 @@ pixel_y = 32 }, /obj/effect/turf_decal/siding/brown/corner, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood/fancy/light, /area/bridge/meeting_room) "pFI" = ( @@ -91828,9 +92002,10 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint3) "pHL" = ( -/obj/machinery/photocopier, +/obj/machinery/vending/cigarette, /turf/simulated/floor/plasteel{ - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/nhallway) "pHP" = ( @@ -92534,7 +92709,8 @@ }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research) "pOg" = ( @@ -92751,7 +92927,6 @@ icon_state = "1-2" }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/warden) @@ -93057,9 +93232,6 @@ "pVL" = ( /obj/machinery/disposal, /obj/effect/decal/warning_stripes/red, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, /obj/structure/sign/deathsposal{ pixel_y = 32 }, @@ -93067,6 +93239,9 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "redfull" }, @@ -93433,6 +93608,9 @@ pixel_x = -24; pixel_y = -22 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -93663,6 +93841,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -94126,7 +94305,8 @@ /obj/item/stamp/rd, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/crew_quarters/hor) "qhn" = ( @@ -94320,6 +94500,15 @@ }, /turf/simulated/floor/plasteel, /area/engine/gravitygenerator) +"qjq" = ( +/obj/machinery/newscaster{ + pixel_x = 28 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "qjr" = ( /obj/effect/decal/warning_stripes/yellow/hollow, /obj/machinery/atmospherics/unary/vent_pump/high_volume{ @@ -94479,6 +94668,18 @@ }, /turf/simulated/floor/plating, /area/crew_quarters/courtroom) +"qlc" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "vault" + }, +/area/engine/mechanic_workshop/hangar) "qlu" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -94806,6 +95007,7 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -94956,6 +95158,7 @@ /area/quartermaster/storage) "qqe" = ( /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -95149,9 +95352,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/visible, /turf/simulated/floor/plating, /area/maintenance/fore) @@ -95517,7 +95717,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment{ - dir = 2; + dir = 8; icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ @@ -95566,13 +95766,17 @@ }, /area/engine/aienter) "qwa" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office/light{ +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, -/obj/effect/decal/warning_stripes/northwest, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "qwb" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, @@ -95583,6 +95787,9 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "qws" = ( @@ -96206,9 +96413,6 @@ /obj/structure/cable{ icon_state = "1-4" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, /area/security/holding_cell) @@ -96763,7 +96967,7 @@ pixel_y = 32 }, /turf/simulated/floor/plasteel{ - icon_state = "hydrofloor" + icon_state = "neutralfull" }, /area/crew_quarters/serviceyard) "qKI" = ( @@ -96857,6 +97061,9 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "qLc" = ( @@ -96955,6 +97162,9 @@ id_tag = "BridgeLockdown"; name = "Bridge Lockdown" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -97063,11 +97273,14 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/medical/genetics) "qNX" = ( -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/effect/decal/warning_stripes/north, /obj/effect/spawner/random_spawners/blood_maybe, /turf/simulated/floor/plasteel{ @@ -97078,6 +97291,7 @@ /obj/item/robot_parts/robot_suit, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -97176,6 +97390,28 @@ icon_state = "dark" }, /area/maintenance/library) +"qPg" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Research Break Room"; + req_access = list(47) + }, +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/nhallway) "qPr" = ( /obj/machinery/door/airlock/security/glass{ id = "execution"; @@ -97539,6 +97775,7 @@ /obj/machinery/hologram/holopad, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -97630,15 +97867,6 @@ icon_state = "neutralfull" }, /area/hallway/primary/aft) -"qVm" = ( -/obj/structure/transit_tube{ - icon_state = "D-SE"; - tag = "icon-D-SE" - }, -/obj/structure/window/reinforced, -/obj/structure/lattice, -/turf/space, -/area/space) "qVp" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ @@ -97747,9 +97975,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/crew_quarters/theatre) -"qWU" = ( -/turf/simulated/wall/r_wall, -/area/teleporter/abandoned) "qXd" = ( /obj/machinery/vending/security, /obj/machinery/newscaster/security_unit{ @@ -97783,10 +98008,13 @@ }, /area/maintenance/tourist) "qXv" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "2-8" }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitepurple" @@ -98263,6 +98491,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "rcD" = ( @@ -98364,6 +98593,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "rdT" = ( @@ -98618,19 +98848,13 @@ /turf/simulated/floor/wood, /area/library) "rgD" = ( -/obj/structure/sign/poster/official/nanotrasen_logo{ - pixel_x = -32 - }, -/obj/structure/table, -/obj/machinery/kitchen_machine/microwave{ - pixel_x = -1; - pixel_y = 7 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitepurple" +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/glass{ + amount = 10 }, -/area/medical/research/restroom) +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "rgF" = ( /obj/effect/decal/warning_stripes/west, /obj/structure/table/reinforced, @@ -98887,7 +99111,6 @@ /turf/simulated/floor/plating, /area/maintenance/maintcentral) "rki" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -99277,7 +99500,8 @@ }, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "roC" = ( @@ -99303,7 +99527,8 @@ }, /turf/simulated/floor/plasteel{ dir = 9; - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whiteblue (NORTHWEST)" }, /area/assembly/robotics) "roX" = ( @@ -99488,8 +99713,8 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplefull" @@ -99671,6 +99896,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "rtn" = ( @@ -99691,6 +99919,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "red" @@ -99783,15 +100012,15 @@ /turf/simulated/floor/plating, /area/security/checkpoint/south) "ruT" = ( -/obj/effect/decal/warning_stripes/south, -/obj/machinery/vending/snack, -/obj/structure/sign/poster/contraband/smoke{ +/obj/structure/computerframe, +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/poster/random{ pixel_y = 32 }, /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "rvb" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -100154,12 +100383,22 @@ /turf/simulated/floor/wood, /area/crew_quarters/cabin3) "rzA" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, /obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" + dir = 4 }, -/turf/simulated/wall/r_wall, -/area/security/interrogation) +/turf/simulated/floor/plasteel{ + dir = 1 + }, +/area/security/processing) "rzM" = ( /obj/machinery/atmospherics/unary/portables_connector, /obj/machinery/portable_atmospherics/canister/air, @@ -100342,7 +100581,8 @@ dir = 4 }, /turf/simulated/floor/plasteel{ - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/nhallway) "rCs" = ( @@ -100458,11 +100698,13 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/hor) "rDm" = ( -/obj/structure/transit_tube, /obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/transit_tube/junction{ + dir = 4 + }, /turf/space, /area/space) "rDp" = ( @@ -100962,12 +101204,13 @@ /turf/simulated/floor/plasteel, /area/gateway) "rJr" = ( -/obj/machinery/vending/cigarette, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/photocopier, /turf/simulated/floor/plasteel{ - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/nhallway) "rJG" = ( @@ -101065,7 +101308,8 @@ "rKQ" = ( /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research/shallway) "rKZ" = ( @@ -101074,7 +101318,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -101275,9 +101518,7 @@ req_access = list(37) }, /obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/library) "rMu" = ( @@ -101331,7 +101572,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ @@ -101696,13 +101936,12 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, /obj/structure/cable{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, @@ -101783,7 +102022,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/toxins/lab) "rTW" = ( @@ -101954,10 +102194,6 @@ /turf/simulated/floor/plasteel, /area/storage/tech) "rVF" = ( -/obj/structure/disposalpipe/junction{ - dir = 8; - tag = "icon-pipe-j1 (EAST)" - }, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=A39"; location = "A38" @@ -101970,6 +102206,10 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/hallway/secondary/entry/lounge) "rVP" = ( @@ -102291,8 +102531,7 @@ /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "rampbottom"; - tag = "icon-stage_stairs" + icon_state = "rampbottom" }, /area/medical/research) "sbb" = ( @@ -102839,7 +103078,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "2-4" }, @@ -103066,10 +103304,6 @@ dir = 8; initialize_directions = 11 }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" }, @@ -103157,9 +103391,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -103601,6 +103832,17 @@ icon_state = "red" }, /area/security/range) +"sqA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + icon_state = "neutralfull" + }, +/area/hallway/primary/central/nw) "sqB" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ @@ -103618,7 +103860,8 @@ }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, /area/medical/research) "sqO" = ( @@ -103830,6 +104073,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "stf" = ( @@ -103860,8 +104104,8 @@ /obj/structure/disposalpipe/sortjunction{ dir = 1; icon_state = "pipe-j2s"; - name = "HoP Office"; - sortType = 15 + name = "NTR Office"; + sortType = 26 }, /turf/simulated/floor/plasteel{ icon_state = "neutralfull" @@ -104053,6 +104297,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "neutral" @@ -104483,7 +104730,12 @@ scrub_N2O = 1; scrub_Toxins = 1 }, -/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/sortjunction{ + dir = 1; + name = "Genetics"; + sortType = 23; + tag = "icon-pipe-j1s (EAST)" + }, /turf/simulated/floor/plasteel{ icon_state = "purplecorner" }, @@ -104518,6 +104770,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "sAI" = ( @@ -104530,6 +104785,9 @@ dir = 6; network = list("SS13","MiniSat") }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "darkblue" @@ -104549,6 +104807,9 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint3) "sAN" = ( +/obj/item/radio/intercom{ + pixel_y = -28 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitegreencorner" @@ -104762,7 +105023,6 @@ dir = 9 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "green" @@ -105046,9 +105306,9 @@ }, /area/turret_protected/aisat_interior) "sHT" = ( -/obj/structure/transit_tube{ - icon_state = "D-SW"; - tag = "icon-D-SW" +/obj/structure/lattice, +/obj/structure/transit_tube/curved/flipped{ + dir = 8 }, /turf/space, /area/space) @@ -105571,18 +105831,11 @@ }, /area/chapel/main) "sPe" = ( -/obj/structure/transit_tube{ - icon_state = "D-NE"; - tag = "icon-D-NE" - }, -/obj/structure/transit_tube{ - icon_state = "D-SE"; - tag = "icon-D-SE" - }, /obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/transit_tube/crossing/horizontal, /turf/space, /area/space) "sPr" = ( @@ -105640,10 +105893,27 @@ }, /area/bridge) "sPY" = ( -/obj/machinery/hologram/holopad, -/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command/glass{ + name = "Bridge"; + req_access = list(19) + }, +/obj/machinery/door/poddoor/preopen{ + id_tag = "BridgeLockdown"; + name = "Bridge Lockdown" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/plasteel{ - icon_state = "dark" + dir = 8; + icon_state = "vault" }, /area/bridge) "sQd" = ( @@ -105654,8 +105924,7 @@ "sQt" = ( /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitegreen"; - tag = "icon-whitegreen (WEST)" + icon_state = "whitegreen" }, /area/medical/medbay) "sQx" = ( @@ -105723,7 +105992,8 @@ /obj/structure/chair, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "sRk" = ( @@ -105804,13 +106074,12 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research) "sRH" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutralcorner" @@ -105883,6 +106152,7 @@ dir = 6 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/bridge/checkpoint/south) @@ -106087,6 +106357,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -106116,9 +106387,6 @@ }, /turf/simulated/floor/plating, /area/engine/controlroom) -"sVN" = ( -/turf/simulated/wall, -/area/teleporter/abandoned) "sVU" = ( /turf/simulated/wall, /area/security/range) @@ -106176,6 +106444,7 @@ /obj/item/clothing/suit/jacket/leather/overcoat, /obj/item/reagent_containers/food/drinks/bottle/whiskey, /obj/item/clothing/head/fedora, +/obj/item/ammo_box/magazine/internal/cylinder/improvised/steel, /turf/simulated/floor/plating, /area/maintenance/detectives_office) "sWX" = ( @@ -106644,13 +106913,12 @@ }, /area/library/game_zone) "tdf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurplecorner" +/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/office/light{ + dir = 8 }, -/area/medical/research/restroom) +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "tdh" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -106907,10 +107175,11 @@ }, /area/crew_quarters/theatre) "tfy" = ( -/obj/machinery/vending/snack, +/obj/machinery/vending/sustenance, /turf/simulated/floor/plasteel{ dir = 6; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHEAST)" }, /area/medical/research/nhallway) "tfB" = ( @@ -107020,25 +107289,6 @@ icon_state = "purplefull" }, /area/toxins/sm_test_chamber) -"tgP" = ( -/obj/item/radio/intercom{ - dir = 1; - pixel_y = 28 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) "tgT" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -107151,9 +107401,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -107278,12 +107526,13 @@ }, /area/hallway/primary/fore) "tjq" = ( -/obj/structure/computerframe, -/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/snack, +/obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plasteel{ - icon_state = "white" + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "tjr" = ( /obj/machinery/constructable_frame/machine_frame, /obj/machinery/light/small, @@ -107330,12 +107579,10 @@ "tkf" = ( /obj/item/hand_labeler, /obj/item/reagent_containers/spray/cleaner, -/obj/machinery/light_switch{ - dir = 8; - name = "east bump"; - pixel_x = 25 - }, /obj/structure/table/glass, +/obj/machinery/newscaster{ + pixel_x = 32 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "whitepurple" @@ -107406,6 +107653,7 @@ /obj/machinery/hologram/holopad, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/medical/research/nhallway) @@ -107723,13 +107971,8 @@ /turf/simulated/floor/wood/fancy/light, /area/crew_quarters/heads/hop) "tou" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" - }, +/obj/structure/transit_tube/diagonal/topleft, +/obj/structure/lattice, /turf/space, /area/space) "toB" = ( @@ -107956,12 +108199,6 @@ icon_state = "neutralcorner" }, /area/crew_quarters/locker) -"trI" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitepurplecorner" - }, -/area/medical/research/restroom) "tsq" = ( /obj/machinery/alarm{ dir = 4; @@ -108146,15 +108383,17 @@ /turf/simulated/floor/plasteel, /area/medical/research/nhallway) "tuQ" = ( -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" +/obj/structure/window/reinforced, +/obj/structure/transit_tube/station{ + dir = 1 }, -/obj/structure/lattice/catwalk, -/obj/structure/cable{ - icon_state = "4-8" +/obj/structure/transit_tube_pod{ + dir = 8 }, -/turf/space, -/area/space) +/turf/simulated/floor/plasteel{ + icon_state = "darkblue" + }, +/area/construction/hallway) "tuS" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light_switch{ @@ -108347,12 +108586,12 @@ /area/maintenance/consarea_virology) "twQ" = ( /obj/docking_port/stationary{ - name = "Station Church dock"; dir = 2; - id = "graveyard_church"; dwidth = 2; - width = 10; - height = 7 + height = 7; + id = "graveyard_church"; + name = "Station Church dock"; + width = 10 }, /turf/space{ icon_state = "black" @@ -109245,8 +109484,8 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, /turf/simulated/floor/plasteel{ icon_state = "white" @@ -109418,9 +109657,12 @@ }, /area/security/securehallway) "tID" = ( -/obj/structure/transit_tube{ - icon_state = "D-NE"; - tag = "icon-D-NE" +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/transit_tube/curved/flipped{ + dir = 4 }, /turf/space, /area/space) @@ -109590,13 +109832,10 @@ }, /area/security/processing) "tKj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/north, -/obj/structure/cable{ - icon_state = "0-4" +/turf/simulated/floor/plasteel{ + icon_state = "white" }, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/area/medical/research/restroom) "tKz" = ( /obj/item/screwdriver, /turf/simulated/floor/plating, @@ -109791,15 +110030,8 @@ }, /area/medical/virology/lab) "tLT" = ( -/obj/effect/decal/warning_stripes/southeast, -/obj/structure/table/glass, -/obj/item/scalpel{ - pixel_y = 8 - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurplefull" - }, -/area/medical/research/restroom) +/turf/simulated/wall/rust, +/area/teleporter/abandoned) "tMa" = ( /obj/machinery/atmospherics/unary/portables_connector, /obj/machinery/portable_atmospherics/canister, @@ -109948,7 +110180,11 @@ }, /area/security/customs) "tNb" = ( -/obj/structure/cable, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plating, /area/maintenance/engineering) "tNf" = ( @@ -110426,9 +110662,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, /obj/item/radio/intercom{ dir = 4; pixel_x = 28; @@ -110437,6 +110670,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -110651,9 +110887,6 @@ }, /area/maintenance/detectives_office) "tVC" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 0; icon_state = "green" @@ -111059,7 +111292,8 @@ /obj/effect/turf_decal/box, /obj/structure/closet/crate, /obj/machinery/alarm{ - pixel_y = 24 + dir = 4; + pixel_x = -23 }, /turf/simulated/floor/plasteel{ dir = 9; @@ -111098,7 +111332,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "uaF" = ( @@ -111169,7 +111404,8 @@ }, /turf/simulated/floor/plasteel{ dir = 10; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHWEST)" }, /area/medical/research) "ubP" = ( @@ -111466,7 +111702,7 @@ /area/engine/engineering) "ufn" = ( /obj/structure/window/reinforced, -/obj/item/twohanded/required/kirbyplants, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plasteel{ icon_state = "darkblue" }, @@ -111640,7 +111876,6 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/evidence) @@ -111993,7 +112228,8 @@ pixel_y = -28 }, /turf/simulated/floor/plasteel{ - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whitehall (WEST)" }, /area/assembly/robotics) "ulb" = ( @@ -112260,10 +112496,8 @@ }, /area/security/podbay) "uoI" = ( -/obj/structure/transit_tube{ - icon_state = "D-SE"; - tag = "icon-D-SE" - }, +/obj/structure/lattice, +/obj/structure/transit_tube/diagonal/topleft, /turf/space, /area/space) "uoK" = ( @@ -112298,15 +112532,6 @@ icon_state = "darkred" }, /area/security/warden) -"uoY" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitepurplecorner" - }, -/area/medical/research/restroom) "uph" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -112645,10 +112870,19 @@ }, /area/maintenance/bar) "uuo" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/southwest, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/medical/research/restroom) "uuu" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ @@ -112684,10 +112918,6 @@ }, /area/crew_quarters/locker) "uuD" = ( -/obj/structure/disposalpipe/junction{ - dir = 8; - icon_state = "pipe-y" - }, /obj/effect/landmark/start/geneticist, /obj/structure/chair/office/light{ dir = 8 @@ -112742,13 +112972,18 @@ /obj/machinery/door_control{ id = "Genetics"; name = "Genetic Privacy Shutters Control"; - pixel_y = 26 + pixel_y = 26; + pixel_x = -4 }, /obj/item/storage/box/beakers{ pixel_x = 4; pixel_y = 4 }, /obj/item/storage/box/syringes, +/obj/machinery/light_switch{ + pixel_x = 7; + pixel_y = 27 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitepurple" @@ -113924,12 +114159,6 @@ /turf/simulated/floor/plating/airless, /area/engine/engineering) "uJo" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -113939,6 +114168,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "purplefull" }, @@ -114485,24 +114717,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/asmaint4) -"uPO" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whiteblue" - }, -/area/medical/medbay) "uPT" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light_switch{ @@ -114586,6 +114800,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -114765,6 +114980,7 @@ dir = 4; tag = "icon-bulb1 (EAST)" }, +/obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -114786,7 +115002,6 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/visiting_room) @@ -114969,6 +115184,16 @@ /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/gateway) +"uVD" = ( +/obj/structure/closet/secure_closet/scientist, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whitepurple" + }, +/area/medical/research/restroom) "uVI" = ( /obj/structure/disposalpipe/segment, /obj/machinery/firealarm{ @@ -115093,10 +115318,18 @@ /turf/simulated/floor/plasteel, /area/bridge/vip) "uXu" = ( -/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; - icon_state = "darkblue" + icon_state = "vault" }, /area/bridge) "uXz" = ( @@ -115340,12 +115573,8 @@ }, /area/security/permabrig) "vam" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Telescience" - }, -/obj/structure/barricade/wooden, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/turf/simulated/wall/r_wall, +/area/medical/research/restroom) "vap" = ( /obj/item/clothing/under/soviet, /turf/simulated/floor/light, @@ -115800,6 +116029,7 @@ /obj/machinery/atm{ pixel_x = -32 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/bridge/vip) "vgP" = ( @@ -116138,10 +116368,14 @@ /turf/simulated/floor/plating, /area/security/prisonershuttle) "vkS" = ( +/obj/structure/chair/comfy/purp{ + dir = 4 + }, +/obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel{ - icon_state = "white" + icon_state = "whitepurplefull" }, -/area/teleporter/abandoned) +/area/medical/research/restroom) "vkV" = ( /obj/item/stack/sheet/mineral/plasma, /obj/structure/table, @@ -116154,9 +116388,6 @@ /turf/simulated/floor/plating, /area/maintenance/kitchen) "vlc" = ( -/obj/machinery/newscaster{ - pixel_y = -28 - }, /obj/structure/table/glass, /obj/item/storage/box/beakers{ pixel_x = 4; @@ -116351,13 +116582,6 @@ /obj/effect/landmark/start/research_director, /turf/simulated/floor/carpet/purple, /area/crew_quarters/hor) -"vns" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" - }, -/turf/space, -/area/space) "vnu" = ( /obj/structure/rack, /obj/item/extinguisher, @@ -116994,9 +117218,6 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plating, /area/security/holding_cell) "vur" = ( @@ -117009,6 +117230,7 @@ "vuD" = ( /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -117178,10 +117400,6 @@ /turf/simulated/floor/plating, /area/maintenance/ai) "vwH" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, /obj/structure/cable{ icon_state = "4-8" }, @@ -117191,6 +117409,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkblue" @@ -117347,6 +117568,20 @@ icon_state = "neutralfull" }, /area/bridge/vip) +"vyc" = ( +/obj/machinery/atmospherics/unary/vent_scrubber{ + dir = 8; + name = "standard air scrubber"; + on = 1; + scrub_N2O = 1; + scrub_Toxins = 1 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" + }, +/area/medical/research/shallway) "vyd" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/walllocker/emerglocker{ @@ -117452,6 +117687,15 @@ /obj/structure/cable, /turf/simulated/floor/plating, /area/security/hos) +"vzq" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whiteblue" + }, +/area/assembly/robotics) "vzv" = ( /turf/simulated/floor/plasteel{ dir = 8; @@ -117556,13 +117800,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -117570,6 +117808,12 @@ icon_state = "2-8" }, /obj/structure/grille, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, /turf/simulated/floor/plating, /area/maintenance/engineering) "vAj" = ( @@ -118319,6 +118563,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "green" @@ -118370,18 +118617,21 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint4) "vJX" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/structure/cable{ icon_state = "4-8" }, /obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "vKa" = ( @@ -118510,7 +118760,8 @@ /obj/item/toy/figure/roboticist, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/assembly/robotics) "vMY" = ( @@ -118564,14 +118815,6 @@ /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel/airless, /area/toxins/test_area) -"vNO" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "D-NW"; - tag = "icon-D-NW" - }, -/turf/space, -/area/space) "vNP" = ( /obj/structure/computerframe, /turf/simulated/floor/plating, @@ -118679,7 +118922,6 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint4) "vPj" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -119000,9 +119242,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "vSV" = ( @@ -119030,9 +119270,14 @@ }, /area/maintenance/electrical) "vTj" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/teleporter/abandoned) +/obj/structure/table/glass, +/obj/item/reagent_containers/food/snacks/sliceable/braincake, +/obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurplefull" + }, +/area/medical/research/restroom) "vTk" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -119260,6 +119505,21 @@ }, /turf/simulated/floor/plating, /area/maintenance/starboard) +"vUO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurple"; + tag = "icon-whitepurple (WEST)" + }, +/area/medical/research/restroom) "vUU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -119554,7 +119814,6 @@ icon_state = "4-8" }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/securearmory) @@ -119576,7 +119835,6 @@ dir = 8 }, /turf/simulated/floor/plasteel{ - dir = 10; icon_state = "darkredfull" }, /area/security/securearmory) @@ -119689,6 +119947,15 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/cabin3) +"vZW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/teleporter/abandoned) "wap" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ @@ -120314,12 +120581,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/unary/vent_scrubber{ - name = "standard air scrubber"; - on = 1; - scrub_N2O = 1; - scrub_Toxins = 1 - }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "whitepurplefull" }, @@ -120569,13 +120831,15 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/locker/locker_toilet) "wlE" = ( -/obj/effect/decal/warning_stripes/eastnorthwest, -/obj/structure/chair/comfy/purp, -/obj/effect/landmark/start/scientist, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/barricade/wooden, /turf/simulated/floor/plasteel{ - icon_state = "whitepurplefull" + dir = 8; + icon_state = "whitepurplecorner" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "wlQ" = ( /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/wood, @@ -120724,7 +120988,8 @@ }, /turf/simulated/floor/plasteel{ dir = 10; - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whitehall (WEST)" }, /area/assembly/robotics) "wnq" = ( @@ -120854,6 +121119,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "woE" = ( @@ -120895,10 +121163,10 @@ /turf/simulated/floor/wood, /area/security/hos) "wpn" = ( -/obj/structure/transit_tube, /obj/structure/window/reinforced{ dir = 8 }, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -120952,7 +121220,7 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint4) "wpN" = ( -/obj/structure/transit_tube, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -121054,6 +121322,7 @@ }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/sw) @@ -121081,15 +121350,15 @@ /turf/simulated/floor/plasteel, /area/maintenance/electrical) "wrb" = ( -/obj/structure/transit_tube/station/reverse{ - dir = 1 - }, /obj/structure/transit_tube_pod{ dir = 8 }, /obj/machinery/ai_status_display{ pixel_y = -32 }, +/obj/structure/transit_tube/station{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -121151,6 +121420,7 @@ name = "Medbay Maintenance"; req_access = list(5) }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/asmaint) "wsa" = ( @@ -122134,7 +122404,7 @@ /area/toxins/lab) "wEh" = ( /turf/simulated/wall/r_wall, -/area/medical/research/restroom) +/area/teleporter/abandoned) "wEm" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/plasteel{ @@ -122347,6 +122617,9 @@ icon_state = "4-8" }, /mob/living/simple_animal/mouse/white, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "wGp" = ( @@ -122531,7 +122804,8 @@ }, /turf/simulated/floor/plasteel{ dir = 6; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHEAST)" }, /area/medical/research) "wIU" = ( @@ -122567,6 +122841,12 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/unary/vent_scrubber{ + name = "standard air scrubber"; + on = 1; + scrub_N2O = 1; + scrub_Toxins = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -122975,28 +123255,17 @@ pixel_x = 7; pixel_y = 14 }, -/turf/simulated/floor/plasteel{ - dir = 1 - }, -/area/security/processing) -"wOf" = ( /obj/structure/disposalpipe/segment{ - dir = 8; + dir = 1; icon_state = "pipe-c" }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, /turf/simulated/floor/plasteel{ - icon_state = "white" + dir = 1 }, -/area/medical/research/restroom) +/area/security/processing) +"wOf" = ( +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "wOn" = ( /obj/effect/decal/cleanable/dirt, /obj/item/trash/popcorn, @@ -123231,7 +123500,8 @@ }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "wRz" = ( @@ -123355,6 +123625,9 @@ icon_state = "4-8" }, /obj/structure/grille/broken, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "wSW" = ( @@ -123545,13 +123818,14 @@ }, /area/hallway/primary/central/north) "wVA" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "E-NW"; - tag = "icon-E-NW" +/obj/structure/window/reinforced, +/obj/structure/transit_tube/cap{ + dir = 4 }, -/turf/space, -/area/space) +/turf/simulated/floor/plasteel{ + icon_state = "darkblue" + }, +/area/construction/hallway) "wVP" = ( /obj/structure/falsewall, /turf/simulated/floor/plating, @@ -123752,10 +124026,6 @@ }, /area/turret_protected/ai_upload) "wXY" = ( -/obj/structure/transit_tube{ - icon_state = "D-SW"; - tag = "icon-D-SW" - }, /obj/structure/window/reinforced{ dir = 4 }, @@ -124130,6 +124400,7 @@ /obj/effect/decal/warning_stripes/yellow, /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -124285,9 +124556,12 @@ }, /area/assembly/robotics) "xfd" = ( -/obj/machinery/light{ - dir = 8 +/obj/machinery/camera{ + c_tag = "Research South Hallway"; + dir = 10; + network = list("Research","SS13") }, +/obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "whitepurple" @@ -124498,9 +124772,6 @@ /turf/simulated/floor/plating, /area/maintenance/fpmaint) "xhi" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplefull" }, @@ -124798,7 +125069,8 @@ /obj/item/mmi, /turf/simulated/floor/plasteel{ dir = 6; - icon_state = "whiteblue" + icon_state = "whiteblue"; + tag = "icon-whiteblue (SOUTHEAST)" }, /area/assembly/robotics) "xmf" = ( @@ -125119,9 +125391,6 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/hologram/holopad, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, @@ -125129,6 +125398,9 @@ icon_state = "1-4" }, /obj/effect/landmark/start/coroner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -125392,7 +125664,8 @@ }, /turf/simulated/floor/plasteel{ dir = 5; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHWEST)" }, /area/assembly/robotics) "xsB" = ( @@ -126172,13 +126445,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plating, /area/maintenance/fpmaint) -"xyQ" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/turf/simulated/wall/r_wall, -/area/security/interrogation) "xyS" = ( /obj/machinery/computer/teleporter, /obj/effect/decal/warning_stripes/southeast, @@ -126322,9 +126588,6 @@ icon_state = "2-8" }, /obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small{ - dir = 1 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -126419,14 +126682,6 @@ icon_state = "neutralfull" }, /area/engine/hardsuitstorage) -"xBT" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "E-SW"; - tag = "icon-E-SW" - }, -/turf/space, -/area/space) "xCj" = ( /obj/structure/window/reinforced{ dir = 1 @@ -126487,9 +126742,8 @@ /area/maintenance/asmaint4) "xCP" = ( /obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "W-SE"; - tag = "icon-W-SE" +/obj/structure/transit_tube/curved/flipped{ + dir = 4 }, /turf/space, /area/space) @@ -126548,7 +126802,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plasteel{ @@ -126567,7 +126820,8 @@ "xDD" = ( /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/medical/research/shallway) "xDG" = ( @@ -126635,7 +126889,8 @@ /obj/structure/table/reinforced, /turf/simulated/floor/plasteel{ dir = 4; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (EAST)" }, /area/assembly/robotics) "xEr" = ( @@ -126657,15 +126912,16 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint4) "xEA" = ( -/obj/item/twohanded/required/kirbyplants, -/obj/structure/extinguisher_cabinet{ - pixel_x = -28 - }, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/obj/structure/safe, +/obj/item/stack/ore/bluespace_crystal, +/obj/item/stack/ore/bluespace_crystal, +/obj/item/stack/ore/bluespace_crystal, +/obj/item/stack/ore/bluespace_crystal, +/obj/item/stack/ore/bluespace_crystal, +/obj/item/grown/bananapeel/bluespace, +/obj/item/slime_extract/bluespace, +/turf/simulated/floor/plating, +/area/teleporter/abandoned) "xEF" = ( /turf/simulated/floor/plasteel{ icon_state = "darkblue" @@ -126742,10 +126998,7 @@ /area/medical/morgue) "xFr" = ( /obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "D-SW"; - tag = "icon-D-SW" - }, +/obj/structure/transit_tube/diagonal/crossing, /turf/space, /area/space) "xFt" = ( @@ -127246,7 +127499,6 @@ dir = 4 }, /turf/simulated/floor/plasteel{ - dir = 6; icon_state = "bluefull" }, /area/bridge/checkpoint/south) @@ -127300,7 +127552,6 @@ /area/crew_quarters/chief) "xKK" = ( /obj/machinery/disposal, -/obj/structure/disposalpipe/trunk, /obj/machinery/firealarm{ dir = 4; pixel_x = 6; @@ -127309,9 +127560,11 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/disposalpipe/trunk, /turf/simulated/floor/plasteel{ dir = 5; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (SOUTHWEST)" }, /area/assembly/robotics) "xKL" = ( @@ -127322,24 +127575,17 @@ }, /area/medical/cmostore) "xKP" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "north bump"; - pixel_y = 26 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, /turf/simulated/floor/plasteel{ dir = 1; - icon_state = "whitepurple" + icon_state = "whitepurple"; + tag = "icon-whitepurple (NORTH)" }, /area/medical/research/nhallway) "xKT" = ( -/obj/structure/lattice, -/obj/structure/transit_tube{ - icon_state = "NW-SE" +/obj/structure/transit_tube/curved{ + dir = 4 }, +/obj/structure/lattice, /turf/space, /area/space) "xLb" = ( @@ -127949,6 +128195,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/northwest, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -128007,9 +128254,6 @@ scrub_N2O = 1; scrub_Toxins = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 0; icon_state = "green" @@ -128319,6 +128563,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/assembly/robotics) @@ -128495,17 +128740,16 @@ /turf/simulated/floor/plating, /area/security/warden) "xXf" = ( -/obj/effect/decal/warning_stripes/east, -/obj/structure/table/glass, -/obj/effect/decal/warning_stripes/northwestcorner, -/obj/item/reagent_containers/food/snacks/sliceable/braincake, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "0-4" }, +/obj/structure/barricade/wooden, +/obj/machinery/light/small, /turf/simulated/floor/plasteel{ - icon_state = "whitepurplefull" + icon_state = "purplefull" }, -/area/medical/research/restroom) +/area/teleporter/abandoned) "xXi" = ( /obj/effect/decal/warning_stripes/arrow{ dir = 4 @@ -129328,6 +129572,7 @@ dir = 4 }, /turf/simulated/floor/plasteel{ + dir = 8; icon_state = "neutralfull" }, /area/hallway/primary/central/south) @@ -129567,17 +129812,8 @@ /turf/simulated/wall, /area/maintenance/detectives_office) "ygS" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 - }, -/turf/simulated/floor/plasteel{ - icon_state = "whitepurple" - }, -/area/medical/research/restroom) +/turf/simulated/wall, +/area/teleporter/abandoned) "yhc" = ( /turf/simulated/floor/plasteel{ dir = 8; @@ -129754,6 +129990,7 @@ /obj/effect/turf_decal/siding/brown{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/light, /area/bridge/meeting_room) "yjn" = ( @@ -129940,9 +130177,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, /obj/machinery/door/airlock/command{ name = "Server Room"; req_access = list(30) @@ -129950,6 +130184,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -144341,9 +144578,9 @@ coE gum gum xAs -mzX +wgX uNi -ybH +wVA bXR aaq dZq @@ -144600,7 +144837,7 @@ wLE xBE puA uOm -ybH +tuQ bXR coE coE @@ -144849,9 +145086,9 @@ aaq bCI aaq coE -aaq +dZq acF -aaq +dZq gum gum gum @@ -145102,20 +145339,20 @@ aaq aaq aaq aaq -aaq -coE -aaq -bCI -aaq +acF +acF +acF +acF +acF +acF +acF acF aaq -coE -aaq -qVm +oKs muS kmU bRO -kWh +bXR aaq coE aaq @@ -145359,20 +145596,20 @@ aaq aaq aaq aaq -aaq -bCI -aaq -bCI -aaq acF -aaq -coE +acF +acF +acF +acF +acF +acF +acF +dZq coE -xBT -kXY +wKp uOJ jXW -wVA +coE coE dZq aaq @@ -145621,15 +145858,15 @@ bCI coE bCI coE -acF +dZq acF acF aaq -vns +dZq coE -tKX +tID coE -vns +dZq aaq dZq dZq @@ -145638,8 +145875,8 @@ coE bCI coE bCI -aaq -aaq +acF +acF aaq aaq aaq @@ -145879,24 +146116,24 @@ coE aaq coE aaq -coE acF -aaq -xCP -tID -tKX -uoI -cjl -aaq -dZq -aaq -coE -aaq -bCI -coE -bCI -coE -bCI +acF +acF +acF +acF +sPe +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF bCI coE bCI @@ -146135,25 +146372,25 @@ coE bCI bCI dZq -bCI -coE -acF aaq -xFr -xKT +acF +acF +acF +acF +acF sPe -iTF -vNO -aaq -coE -aaq -coE -aaq -aaq -coE -aaq -aaq -aaq +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF +acF coE aaq aaq @@ -146393,15 +146630,15 @@ coE coE coE coE -coE +dZq acF +dZq +dZq aaq -coE -sHT bYl -gkk -coE -coE +aaq +dZq +aaq bCI bCI bCI @@ -146654,9 +146891,9 @@ coE acF coE coE -coE -tuQ -coE +xFr +tKX +uoI coE coE aaq @@ -146910,11 +147147,11 @@ bwN coE acF aaq -dZq -aaq -rDm -aaq -aaq +xCP +coE +tKX +coE +xKT bXU qEj qEj @@ -147167,11 +147404,11 @@ bwN coE acF aaq -dZq +iTF aaq -rDm +tKX aaq -coE +iTF bXU bXU bXU @@ -147424,11 +147661,11 @@ bwN coE acF coE -dZq -coE -tuQ +kXY coE +tKX coE +sHT bXU ybU ivy @@ -147682,11 +147919,11 @@ coE acF aaq coE -aaq -rDm +tou +tKX +itZ aaq bXU -bXU cbb coE aaq @@ -147943,7 +148180,7 @@ aaq rDm aaq bXU -klb +bXU cbb rLd aaq @@ -148197,7 +148434,7 @@ acF coE coE coE -rDm +sPe coE bXU klb @@ -148454,7 +148691,7 @@ wcr acF coE coE -tou +sPe coE bXU oqc @@ -148712,7 +148949,7 @@ cTf cTf coE mSG -itZ +coE bXU bZl cbb @@ -158271,7 +158508,7 @@ sHq tNx jfk wBr -kna +wMW iRu oOo fvu @@ -158528,7 +158765,7 @@ mkL lGo mZA oKx -kna +wMW rbA oOo fvu @@ -158785,7 +159022,7 @@ gsc jhm feg cTz -kna +wMW iRu oOo ksG @@ -160557,7 +160794,7 @@ oTk dHk gmk vSU -dEi +nUy frh qUe ddi @@ -160774,7 +161011,7 @@ cmP dZN cmP nUq -bDf +cwP bdE baF gcK @@ -161288,7 +161525,7 @@ bKs cMa gfO hes -cwP +bDf kCr baF ceP @@ -161335,11 +161572,11 @@ kjT ekk hlh ybR -sVN +vam cNt lGD -sVN -cVf +ddM +cUT cQV aEh uHA @@ -161587,12 +161824,12 @@ nzf gMw yhX vAg -srk -srk +cry +cry tNb -cbC -yhX -sVN +tNb +cry +eJE jzw qwa gjD @@ -161849,14 +162086,14 @@ iuW iZQ sWp cbC -cVf -sVN +vam +cgJ cOY cPd vkS jcR -cVf -uHA +cjD +bDP xKP uJo pzW @@ -162109,12 +162346,12 @@ yhX vam ozs tKj -ozs +nrG fYC izb fJp -uHA -pgp +lxY +xKP vye gXb vsH @@ -162140,7 +162377,7 @@ pJs aoc pda puB -fGj +wKr pYt dFS fGj @@ -162363,16 +162600,16 @@ nNj cXa cbC cbC -sVN -cVf +vam +uVD fvB vTj cSd -jcR -sVN -uHA +kGZ +vUO +qPg ifq -fnI +ajY gXb pUL xdz @@ -162396,9 +162633,9 @@ wEh wEh wEh wEh -wEh -dfe -dfe +tLT +ygS +fGj gLL tzX dJx @@ -162572,13 +162809,13 @@ xBC yai mwB dMX +ivL hfx -hFg -mLE +sqA pyj qbQ qvg -dCE +mLE skB mLE dil @@ -162620,14 +162857,14 @@ gRa cXa ybR yhX -sVN +vam hgH -mAd +tKj cQS nPX -jlL +tKj cVg -uHA +bHE nfO aOd xJv @@ -162654,8 +162891,8 @@ iVN xEA dNZ rgD -dsx -dfe +tLT +wKr dFS dFM dJx @@ -162877,11 +163114,11 @@ ncZ cXa czD cbC -cVf +vam dHD jMs -cVf -sVN +eke +qjq cSc nDf uHA @@ -162911,8 +163148,8 @@ ruT gpS tdf gAF -bbJ -dfe +ygS +wKr sUN tpM dJx @@ -163134,13 +163371,13 @@ moW cXa cXa uvt -qWU -qWU -qWU -qWU -qWU -qWU -qWU +vam +vam +vam +vam +vam +vam +vam uHA hoS vye @@ -163164,12 +163401,12 @@ dwg xTh dyG wEh -hLJ -gpS +tLT +vZW kMz -trI -ehA -dfe +tLT +ygS +bbm xAu bAE hVD @@ -163350,7 +163587,7 @@ bOA bOA bwf cFK -lVo +eMO byU nZz cks @@ -163399,7 +163636,7 @@ hQl wiY nDj uHA -fEg +xKP fnI gXb wbP @@ -163422,9 +163659,9 @@ xSf xSf wEh pnv -uoY +wOf dDQ -fkL +wOf kdl bpR vJX @@ -163607,7 +163844,7 @@ coE aaq bwf mMQ -srd +uXu mMQ mMQ cks @@ -163668,7 +163905,7 @@ rKQ rKQ rKQ dzH -rKQ +oHb rKQ rKQ duY @@ -163678,14 +163915,14 @@ rKQ dyC xfd wEh -tgP +ygS wlE xXf tLT -gMU -dfe -kVJ +tLT wKr +bLQ +tLI dJx mSE nfd @@ -163864,7 +164101,7 @@ coE aaq bwf bwf -lXs +sPY cJr bwf cks @@ -163921,26 +164158,26 @@ xJf nbx rKZ sid -lBh +rKZ xDv rNO gkY -rNO +iAW jmL rNO xDv rSp dvd -lBh +eYK hYi -rNO +eYK exh wOf oFp dDR dFn ygS -dfe +fGj dIy fGj dJx @@ -164121,7 +164358,7 @@ coE aaq bwf rlm -lVo +eMO byU cKT cks @@ -164182,7 +164419,7 @@ eYK xDD oxm eCO -xDD +vyc mEE xDD xDD @@ -164196,8 +164433,8 @@ aob kQU dCL oXs -dGO -dfe +ygS +wKr rtl rNh dJx @@ -164378,7 +164615,7 @@ coE coE bwf rma -lVo +eMO byU bCr cks @@ -164413,7 +164650,7 @@ gcg czG dRL oFJ -xMi +fIC vzv oqA oKl @@ -164449,12 +164686,12 @@ tXf tXf ykx wEh -dfe -dfe -dfe -dfe -dfe -dfe +tLT +ygS +tLT +ygS +ygS +wKr rtl nte dJx @@ -164670,7 +164907,7 @@ eXx czG dRL hev -jIN +lap noj oqA jqb @@ -164712,7 +164949,7 @@ pYt lmx tLI wKr -kVJ +dFS nte keY iEY @@ -164893,11 +165130,11 @@ aaq bwf bwf lOt -sPY +bFV cdP bDR -uXu -uXu +tHP +tHP vwH amV iqb @@ -164927,7 +165164,7 @@ mck qRN dRL oFJ -xMi +fIC vzv mcd nJZ @@ -165215,7 +165452,7 @@ drv rzT dsE rru -xeT +vzq wjc fQT ykx @@ -165229,7 +165466,7 @@ uBY uBY uBY pBI -lap +xQY fkq lFG dTK @@ -165441,7 +165678,7 @@ gcg fvE csK cCM -xMi +fIC vzv oqA sRf @@ -165476,7 +165713,7 @@ dvg xFd xlY ykx -fIC +fGj eGb uBY lJs @@ -165698,7 +165935,7 @@ rnJ fXK csK aVO -xMi +fIC vzv saY dkn @@ -165955,7 +166192,7 @@ tlg eDn csK pCP -xMi +fIC vzv saY dkn @@ -166212,7 +166449,7 @@ csK jqk csK rSJ -xMi +fIC vzv oqA oKl @@ -166458,7 +166695,7 @@ gIn kRz nrh ssw -eMO +lMI geG fYm fYm @@ -166473,7 +166710,7 @@ fgD vzv oqA bRo -vyT +dIG qhT ckq bNH @@ -166726,7 +166963,7 @@ qjj rrz cBk cCM -xMi +fIC kKR fRt mDj @@ -166771,7 +167008,7 @@ phR dGe ukf eey -lap +xQY pvm gwP dXB @@ -167022,9 +167259,9 @@ xUN xpj xWm mjx -dGR +aAy mZk -dGR +aAy oeE qpk mUT @@ -167522,8 +167759,8 @@ dca dnx fau szY -gDZ uuu +mwg uuu cpN qLt @@ -167758,8 +167995,8 @@ xMi gZr uzj xYU -jWl -jWl +hiQ +hiQ xYU cNI xYU @@ -169065,8 +169302,8 @@ dfv cTu vSV dpb -drF -drF +mhI +mhI vQJ dhN iAx @@ -171513,7 +171750,7 @@ azl bcL beC beC -brG +avi beC ayI bBQ @@ -171640,7 +171877,7 @@ lLn sHA dsR sHA -uPO +vUu sHA qfe wDC @@ -171770,7 +172007,7 @@ aBe aQg aEw bkM -aQg +brG aTy aQg aBd @@ -171899,7 +172136,7 @@ pWy smD pAT jAt -dxT +gDZ wrQ iWJ mZc @@ -172542,9 +172779,9 @@ aLH ePe aTS aOu -aTS -aLH -ePe +dCE +qlc +pmZ cbZ aOR awY @@ -181066,11 +181303,11 @@ iGx uyw dAc bHO -mwg +nNu pVL ubg xpz -wwO +rzA lFu pBd ubg @@ -181323,11 +181560,11 @@ qmr qmr qmr qmr -lAU +qmr qHb ubg ubg -wwO +rzA ubg ubg ubg @@ -181572,9 +181809,9 @@ aaq aaq aaq aaq -bCI -dZq coE +coE +acF nJR wHu lBw @@ -181830,8 +182067,8 @@ aaq aaq aaq aaq -coE -coE +aaq +ozX opE sVm bub @@ -182087,8 +182324,8 @@ aaq aaq aaq aaq -dZq coE +acF paa rhG igZ @@ -182350,8 +182587,8 @@ qmr qmr qmr qmr -rzA -xyQ +vyi +vyi fnM iAK jnn @@ -182605,9 +182842,9 @@ dZq coE coE coE -acF -acF -fib +coE +coE +vyi fsq qlW oDN @@ -182863,8 +183100,8 @@ aaq aaq aaq aaq -ozX -xyQ +coE +vyi jRh skC qfc @@ -183119,8 +183356,8 @@ coE coE coE coE -acF -acF +coE +coE vyi jch tFf diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index 639ec41c742..3330c25dd19 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -437,8 +437,21 @@ /area/ruin/powered/beach) "wf" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/food/drinks/bottle/tequila{ - pixel_y = 7 +/obj/item/reagent_containers/food/drinks/zaza{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/item/reagent_containers/food/drinks/zaza{ + pixel_x = 2; + pixel_y = 8 + }, +/obj/item/reagent_containers/food/drinks/zaza{ + pixel_x = -4; + pixel_y = 8 + }, +/obj/item/reagent_containers/food/drinks/zaza{ + pixel_x = -10; + pixel_y = 8 }, /turf/simulated/floor/wood, /area/ruin/powered/beach) diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm index c0212ce9787..5404e247c38 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm @@ -24,7 +24,7 @@ /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "h" = ( -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/item/candle, /obj/item/storage/box/matches, /obj/effect/decal/cleanable/cobweb2, @@ -49,7 +49,7 @@ /obj/effect/decal/cleanable/blood{ layer = 2.5 }, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /turf/simulated/floor/wood{ broken = 1; icon_state = "wood-broken" diff --git a/_maps/map_files/RandomRuins/SpaceRuins/magestavern.dmm b/_maps/map_files/RandomRuins/SpaceRuins/magestavern.dmm index 07abf5b0bd1..df177923fdc 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/magestavern.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/magestavern.dmm @@ -340,16 +340,16 @@ "oq" = ( /obj/effect/decal/cleanable/tomato_smudge, /obj/structure/closet/crate, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /turf/simulated/floor/carpet/red, /area/ruin/unpowered) "pj" = ( @@ -427,7 +427,7 @@ "sp" = ( /obj/structure/kitchenspike, /obj/effect/decal/cleanable/blood/old, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "escape" @@ -939,7 +939,7 @@ /area/ruin/unpowered) "OD" = ( /obj/structure/table/wood/fancy/black, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/item/clothing/glasses/meson/fluff/book_berner_1, /turf/simulated/floor/carpet/black, /area/ruin/unpowered) diff --git a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm index 45de9ba28b9..86d1eac1b97 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm @@ -137,6 +137,12 @@ icon_state = "dark" }, /area/ruin/space/ancientstation/hivebot) +"bp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/warning_stripes/arrow, +/obj/structure/transit_tube/station, +/turf/simulated/floor/plasteel, +/area/ruin/space/ancientstation/thetacorridor) "bs" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -537,9 +543,7 @@ /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/rnd) "er" = ( -/obj/machinery/conveyor{ - id = null - }, +/obj/machinery/conveyor, /obj/item/circuitboard/ore_redemption, /obj/effect/decal/cleanable/dirt, /obj/item/stack/sheet/glass/fifty{ @@ -1143,7 +1147,6 @@ "ix" = ( /obj/item/wirecutters/brass{ desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch. One of the fancy signature instuments of the Chief Engineer tool set. Looks burnt and damaged. Wonder if I could find the rest of them..."; - description_info = null; toolspeed = 1 }, /turf/template_noop, @@ -1170,6 +1173,13 @@ /obj/item/shard, /turf/simulated/floor/plating/airless, /area/ruin/space/ancientstation/betanorth) +"iG" = ( +/obj/structure/transit_tube/cap{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/plasteel, +/area/ruin/space/ancientstation/betanorth) "iK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, @@ -1305,8 +1315,8 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/robot{ - icon_state = "gibup" +/obj/structure/transit_tube/cap{ + dir = 8 }, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/thetacorridor) @@ -1414,7 +1424,6 @@ "kx" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor_switch/oneway{ - id = null; obj_integrity = 70 }, /turf/simulated/floor/plasteel/airless, @@ -1570,9 +1579,7 @@ /area/ruin/space/ancientstation/betanorth) "lD" = ( /obj/structure/plasticflaps/mining, -/obj/machinery/conveyor{ - id = null - }, +/obj/machinery/conveyor, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating/airless, /area/ruin/space/ancientstation/betamincorridor) @@ -1603,9 +1610,7 @@ }, /area/ruin/space/ancientstation/proto) "mp" = ( -/obj/machinery/conveyor{ - id = null - }, +/obj/machinery/conveyor, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating/airless, /area/ruin/space/ancientstation/betamincorridor) @@ -1754,22 +1759,14 @@ /turf/simulated/floor/engine/vacuum, /area/ruin/space/ancientstation/atmos) "nt" = ( -/obj/structure/transit_tube_pod{ - dir = 4 - }, -/obj/structure/transit_tube/station/reverse{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, /obj/effect/decal/warning_stripes/arrow{ dir = 1 }, -/turf/simulated/floor/plasteel/airless, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/betanorth) "nu" = ( -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" - }, +/obj/structure/transit_tube/crossing/horizontal, /turf/template_noop, /area/template_noop) "nv" = ( @@ -1850,6 +1847,14 @@ /obj/structure/sign/mining, /turf/simulated/wall/rust, /area/ruin/space/ancientstation/betamincorridor) +"ok" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/machinery/kitchen_machine/microwave, +/turf/simulated/floor/plasteel{ + icon_state = "cafeteria" + }, +/area/ruin/space/ancientstation/kitchen) "ol" = ( /obj/machinery/door/poddoor{ id_tag = "ancient" @@ -1867,9 +1872,8 @@ /turf/simulated/floor/plating, /area/ruin/space/ancientstation/thetacorridor) "oo" = ( -/obj/structure/table, -/obj/machinery/kitchen_machine/microwave, /obj/effect/decal/cleanable/dirt, +/obj/structure/table, /turf/simulated/floor/plasteel{ icon_state = "cafeteria" }, @@ -1890,18 +1894,9 @@ /turf/simulated/floor/plating, /area/ruin/space/ancientstation/sec) "or" = ( -/obj/structure/transit_tube_pod{ - dir = 4 - }, -/obj/structure/transit_tube/station/reverse{ - dir = 1 - }, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/arrow{ - dir = 1 - }, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation) +/area/ruin/space/ancientstation/betanorth) "ot" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2113,11 +2108,11 @@ /turf/simulated/floor/plasteel/airless, /area/ruin/space/ancientstation/betaengi) "qD" = ( -/obj/structure/transit_tube{ - icon_state = "N-S" - }, -/turf/template_noop, -/area/template_noop) +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/warning_stripes/arrow, +/obj/structure/transit_tube/station, +/turf/simulated/floor/plasteel, +/area/ruin/space/ancientstation) "qK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/warning_stripes/southeast, @@ -2127,10 +2122,9 @@ /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation) "qS" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/transit_tube, -/turf/simulated/floor/plating, -/area/ruin/space/ancientstation/thetacorridor) +/obj/structure/transit_tube/horizontal, +/turf/template_noop, +/area/template_noop) "qU" = ( /obj/machinery/light{ dir = 1; @@ -2338,7 +2332,7 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/airless, +/turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/betanorth) "sS" = ( /obj/effect/decal/cleanable/dirt, @@ -2352,9 +2346,10 @@ /turf/template_noop, /area/template_noop) "sZ" = ( -/obj/structure/transit_tube/station/reverse, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/arrow, +/obj/effect/decal/remains/robot{ + icon_state = "gibup" + }, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/thetacorridor) "ta" = ( @@ -2692,6 +2687,8 @@ /obj/structure/table, /obj/item/tank/internals/oxygen, /obj/item/clothing/mask/breath, +/obj/item/tank/internals/oxygen, +/obj/item/clothing/mask/breath, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "yellow" @@ -3598,9 +3595,9 @@ /area/ruin/space/ancientstation/thetacorridor) "Dx" = ( /obj/effect/spawner/window/reinforced, -/obj/structure/transit_tube, -/turf/simulated/floor/plating/airless, -/area/ruin/space/ancientstation/betanorth) +/obj/structure/transit_tube/horizontal, +/turf/simulated/floor/plating, +/area/ruin/space/ancientstation) "Dy" = ( /obj/machinery/atmospherics/unary/vent_pump{ dir = 8 @@ -3666,9 +3663,11 @@ /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation) "DY" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/transit_tube, -/turf/simulated/floor/plating, +/obj/effect/decal/cleanable/dirt, +/obj/structure/transit_tube/cap{ + dir = 8 + }, +/turf/simulated/floor/plasteel, /area/ruin/space/ancientstation) "Ea" = ( /obj/structure/cable/yellow{ @@ -3692,9 +3691,16 @@ /turf/template_noop, /area/template_noop) "Ep" = ( -/obj/structure/transit_tube, -/turf/template_noop, -/area/template_noop) +/obj/structure/transit_tube_pod{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/warning_stripes/arrow{ + dir = 1 + }, +/obj/structure/transit_tube/station, +/turf/simulated/floor/plasteel, +/area/ruin/space/ancientstation) "Eq" = ( /obj/structure/transit_tube/station/reverse, /obj/effect/decal/cleanable/dirt, @@ -3726,7 +3732,6 @@ /turf/simulated/floor/plating/airless, /area/ruin/space/ancientstation/betacargo) "EJ" = ( -/obj/structure/table, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, @@ -3964,6 +3969,11 @@ /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/thetacorridor) +"GK" = ( +/obj/effect/spawner/window/reinforced, +/obj/structure/transit_tube/horizontal, +/turf/simulated/floor/plating/airless, +/area/ruin/space/ancientstation/betanorth) "GO" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, @@ -4087,6 +4097,13 @@ icon_state = "white" }, /area/ruin/space/ancientstation/proto) +"HY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/kitchen_machine/grill, +/turf/simulated/floor/plasteel{ + icon_state = "cafeteria" + }, +/area/ruin/space/ancientstation/kitchen) "HZ" = ( /obj/structure/lattice, /obj/item/stack/cable_coil{ @@ -4474,6 +4491,10 @@ icon_state = "whitepurple" }, /area/ruin/space/ancientstation/rnd) +"Ku" = ( +/obj/effect/decal/cleanable/fungus, +/turf/simulated/wall/rust, +/area/ruin/space/ancientstation/hydroponics) "Kv" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -5341,6 +5362,8 @@ /obj/effect/decal/cleanable/dirt, /obj/item/clothing/shoes/magboots, /obj/item/clothing/head/helmet/space/nasavoid/old, +/obj/item/clothing/head/helmet/space/nasavoid/ntblue, +/obj/item/clothing/shoes/magboots, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "yellow" @@ -5365,6 +5388,9 @@ report_danger_level = 0 }, /obj/effect/decal/cleanable/dirt, +/obj/item/clothing/suit/space/nasavoid/ntblue{ + slowdown = 4 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "yellow" @@ -5586,8 +5612,8 @@ /turf/simulated/floor/plating, /area/ruin/space/ancientstation/thetacorridor) "TB" = ( -/obj/machinery/processor, /obj/effect/decal/cleanable/dirt, +/obj/machinery/kitchen_machine/oven, /turf/simulated/floor/plasteel{ icon_state = "cafeteria" }, @@ -5830,8 +5856,9 @@ /turf/simulated/floor/plating, /area/ruin/space/ancientstation/thetacorridor) "Ve" = ( -/obj/structure/table, +/obj/effect/decal/cleanable/flour, /obj/effect/decal/cleanable/dirt, +/obj/structure/table, /turf/simulated/floor/plasteel{ icon_state = "cafeteria" }, @@ -5964,15 +5991,15 @@ }, /area/ruin/space/ancientstation/kitchen) "VH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, /obj/structure/table, -/obj/item/seeds/harebell, -/obj/item/seeds/carrot, +/obj/item/seeds/grape, /obj/item/seeds/potato, -/obj/item/seeds/ambrosia, /obj/item/seeds/poppy, -/obj/item/seeds/grape, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, +/obj/item/seeds/ambrosia, +/obj/item/seeds/harebell, +/obj/item/seeds/carrot, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/hydroponics) "VJ" = ( @@ -6146,6 +6173,8 @@ "WO" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, +/obj/item/clothing/glasses/sunglasses, +/obj/item/melee/classic_baton, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "red" @@ -6216,12 +6245,20 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/ruin/space/ancientstation) +"Xk" = ( +/obj/effect/spawner/window/reinforced, +/obj/structure/transit_tube/horizontal, +/turf/simulated/floor/plating, +/area/ruin/space/ancientstation/thetacorridor) "Xl" = ( /obj/machinery/light/small{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/blood/drip, +/obj/structure/transit_tube/cap{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation) "Xn" = ( @@ -6590,11 +6627,13 @@ /turf/template_noop, /area/template_noop) "ZQ" = ( -/obj/structure/transit_tube/station/reverse, +/obj/structure/transit_tube_pod{ + dir = 4 + }, +/obj/structure/transit_tube/station, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/warning_stripes/arrow, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation) +/area/ruin/space/ancientstation/betanorth) "ZR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/unary/cold_sink/freezer{ @@ -8368,8 +8407,8 @@ hY hY hY gP -Qs -Qs +iG +or sQ yw Rp @@ -8416,9 +8455,9 @@ Vf hY tL lB -Qs +ZQ nt -Qs +or yw Rp Pp @@ -8464,8 +8503,8 @@ ZO ZO ZO Ip +GK jR -Dx jR yw Pp @@ -8512,8 +8551,8 @@ Vf ZO ZO ZO +qS ZO -Ep sV yw Eg @@ -8560,8 +8599,8 @@ ZO ZO Vf ZO +qS ZO -Ep ZO ZO Vf @@ -8608,10 +8647,10 @@ ZO ZO ZO ZO -ZO nu ZO ZO +ZO Vf ZO ZO @@ -8656,8 +8695,8 @@ Vf ZO ZO ZO +nu ZO -Ep ZO ZO ZN @@ -8704,8 +8743,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO Vf Wc @@ -8752,8 +8791,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO ZO ZN @@ -8800,8 +8839,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO Vf Wc @@ -8848,8 +8887,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO ZO ZN @@ -8896,8 +8935,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO Vf if @@ -8944,8 +8983,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO ZO qe @@ -8992,8 +9031,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO ZO Vf @@ -9040,8 +9079,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO ZO Vf @@ -9088,10 +9127,10 @@ ZO ZO ZO ZO -ZO nu ZO ZO +ZO cp cp cp @@ -9136,8 +9175,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO ZO cp @@ -9184,8 +9223,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO cp cp @@ -9232,8 +9271,8 @@ ZO ZO ZO Zs +Dx Vv -DY Vv cp wq @@ -9280,9 +9319,9 @@ ZO ZO ZO Zs -kS -ZQ +qD Vh +kS cp Rn cG @@ -9328,7 +9367,7 @@ ZO ZO ZO Zs -Vh +DY Vh tg cp @@ -9676,8 +9715,8 @@ WM Mr Ow XV -VF -XV +Ve +oo Xo OI BJ @@ -9724,8 +9763,8 @@ WM Bc Ow Tk -Ve XV +oo XV zN BJ @@ -9773,7 +9812,7 @@ Nc Re lk EJ -XV +oo XV Ne BJ @@ -9820,7 +9859,7 @@ WM PS Ow vG -Ve +XV VF XV OI @@ -9867,9 +9906,9 @@ KU WM Ni Ow -XV -XV -XV +ok +TB +HY XV zN BJ @@ -9915,7 +9954,7 @@ KU WM PS Ow -TB +XV XV XV XV @@ -9963,7 +10002,7 @@ He WM PS Ow -oo +XV XV XV XV @@ -10007,7 +10046,7 @@ Ty Fe zU Fe -WM +Ku WM Nk Ow @@ -10256,8 +10295,8 @@ VW VW IJ Uh +Ep Vh -or Vh Zs ZO @@ -10289,7 +10328,7 @@ ZO ZO Zs Vv -DY +Vv Vv Uh Pz @@ -10304,8 +10343,8 @@ VW Yq zZ Uh +Dx Vv -DY Vv Zs ZO @@ -10337,7 +10376,7 @@ ZO ZO ZO ZO -Ep +ZO ZO Uh lh @@ -10352,8 +10391,8 @@ VW QV Uh Uh +nu ZO -Ep ZO ZO ZO @@ -10384,7 +10423,7 @@ ZO ZO ZO ZO -Ep +ZO ZO ZO hl @@ -10400,8 +10439,8 @@ VT rb Uh ZO +nu ZO -Ep ZO ZO ZO @@ -10434,7 +10473,7 @@ ZO ZO lU pB -Ep +ZO ZO Uh Uh @@ -10448,8 +10487,8 @@ Uh Uh Uh ZO +qS ZO -Ep ZO ZO ZO @@ -10476,7 +10515,7 @@ hY Xd Xd hY -Ep +ZO ZO ZO ZO @@ -10496,13 +10535,13 @@ ZO ZO ZO ZO -ZO nu ZO ZO ZO ZO ZO +ZO Vf ZO ZO @@ -10533,7 +10572,7 @@ ZO ZO ZO ZO -qD +ZO ZO ZO Vf @@ -10544,8 +10583,8 @@ ZO ZO ZO ZO +qS ZO -Ep ZO ZO ZO @@ -10577,7 +10616,7 @@ ZO ZO ZO ZO -qD +ZO ZO ZO hY @@ -10592,8 +10631,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO ZO ZO @@ -10625,7 +10664,7 @@ ZO ZO ZO ZO -Ep +ZO ZO tL hY @@ -10640,8 +10679,8 @@ ZO ZO ZO ZO +nu ZO -Ep ZO ZO ZO @@ -10673,7 +10712,7 @@ ZO ZO tz lY -qS +lY lY Id ZO @@ -10688,8 +10727,8 @@ ZO ZO ZO tz +Xk lY -qS lY tz ZO @@ -10736,7 +10775,7 @@ ZO ZO ZO tz -oK +bp sZ xD tz diff --git a/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm b/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm index 3e1490adbe7..8d1bcf560ec 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm @@ -4899,6 +4899,7 @@ /area/derelict/garden) "lQ" = ( /obj/structure/closet/crate/hydroponics, +/obj/item/seeds/wheat/meat, /turf/simulated/floor/plasteel/airless{ dir = 5; icon_state = "green" diff --git a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm index 7e75e4dfd16..00af1b38752 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm @@ -314,7 +314,7 @@ /area/ruin/unpowered) "bc" = ( /obj/effect/decal/remains/human, -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plating, /area/ruin/unpowered) "bd" = ( @@ -339,7 +339,7 @@ /turf/simulated/floor/plating, /area/ruin/unpowered) "bg" = ( -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plating, /area/ruin/unpowered) "bh" = ( @@ -353,7 +353,7 @@ }, /area/ruin/unpowered) "bj" = ( -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/effect/decal/cleanable/blood/old, /turf/simulated/floor/plasteel{ icon_state = "chapel" diff --git a/_maps/map_files/RandomZLevels/evil_santa.dmm b/_maps/map_files/RandomZLevels/evil_santa.dmm index 1c5421ecf6a..5d8e6f8bfdc 100644 --- a/_maps/map_files/RandomZLevels/evil_santa.dmm +++ b/_maps/map_files/RandomZLevels/evil_santa.dmm @@ -2948,7 +2948,7 @@ /turf/simulated/wall/shuttle, /area/vision_change_area/awaymission/evil_santa/end/hall) "xP" = ( -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plating/asteroid, /area/vision_change_area/awaymission/evil_santa/mine) "xQ" = ( @@ -4373,7 +4373,7 @@ /turf/simulated/floor/carpet, /area/vision_change_area/awaymission/evil_santa/hut_n) "KT" = ( -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /obj/effect/decal/cleanable/blood/gibs, /turf/simulated/floor/plating/asteroid, /area/vision_change_area/awaymission/evil_santa/mine) diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 6fbebe4824a..3890be3d64f 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -7098,10 +7098,10 @@ name = "meat fridge"; req_access = list(271) }, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15 diff --git a/_maps/map_files/RandomZLevels/spacebattle.dmm b/_maps/map_files/RandomZLevels/spacebattle.dmm index 395f042eca3..5dbd8ebf1d1 100644 --- a/_maps/map_files/RandomZLevels/spacebattle.dmm +++ b/_maps/map_files/RandomZLevels/spacebattle.dmm @@ -1659,9 +1659,9 @@ /area/awaymission/spacebattle/syndicate1) "fc" = ( /obj/structure/closet/crate/freezer, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/item/reagent_containers/food/snacks/meat/slab, /turf/simulated/floor/plasteel/freezer, /area/awaymission/spacebattle/freezing) @@ -1709,9 +1709,7 @@ /area/awaymission/spacebattle/engine) "fj" = ( /obj/structure/disposalpipe/segment, -/obj/structure/transit_tube{ - icon_state = "N-S" - }, +/obj/structure/transit_tube, /turf/space, /area/space) "fk" = ( @@ -4012,9 +4010,7 @@ /area/space) "lp" = ( /obj/structure/disposalpipe/segment, -/obj/structure/transit_tube{ - icon_state = "N-S" - }, +/obj/structure/transit_tube, /obj/structure/window/full/shuttle, /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) @@ -7411,9 +7407,7 @@ /area/awaymission/spacebattle/freezing) "uV" = ( /obj/structure/disposalpipe/segment, -/obj/structure/transit_tube{ - icon_state = "N-S" - }, +/obj/structure/transit_tube, /obj/structure/window/full/shuttle, /turf/simulated/floor, /area/awaymission/spacebattle/hallway11) @@ -7882,8 +7876,7 @@ master_tag = "left"; name = "interior access button"; pixel_x = -25; - pixel_y = 25; - req_access = null + pixel_y = 25 }, /turf/simulated/floor/shuttle{ icon_state = "floor4" @@ -7904,9 +7897,7 @@ /area/awaymission/spacebattle/hallway12) "wn" = ( /obj/structure/disposalpipe/segment, -/obj/structure/transit_tube{ - icon_state = "N-S" - }, +/obj/structure/transit_tube, /obj/machinery/constructable_frame{ icon = 'icons/obj/engines_and_power/singularity.dmi'; icon_state = "TheSingGen"; @@ -11229,9 +11220,7 @@ /area/awaymission/spacebattle/syndicate1) "Ff" = ( /obj/structure/disposalpipe/segment, -/obj/structure/transit_tube{ - icon_state = "N-S" - }, +/obj/structure/transit_tube, /obj/machinery/constructable_frame{ icon = 'icons/obj/engines_and_power/singularity.dmi'; icon_state = "TheSingGen"; @@ -12393,8 +12382,7 @@ master_tag = "right"; name = "exterior access button"; pixel_x = -25; - pixel_y = -25; - req_access = null + pixel_y = -25 }, /turf/space, /area/awaymission/spacebattle/syndicate1) @@ -17764,8 +17752,7 @@ master_tag = "right"; name = "interior access button"; pixel_x = 25; - pixel_y = 25; - req_access = null + pixel_y = 25 }, /turf/simulated/floor/shuttle{ icon_state = "floor4" @@ -18424,8 +18411,7 @@ master_tag = "left"; name = "exterior access button"; pixel_x = 25; - pixel_y = -25; - req_access = null + pixel_y = -25 }, /turf/space, /area/awaymission/spacebattle/syndicate1) diff --git a/_maps/map_files/RandomZLevels/terrorspiders.dmm b/_maps/map_files/RandomZLevels/terrorspiders.dmm index 01f62974844..be7441e8079 100644 --- a/_maps/map_files/RandomZLevels/terrorspiders.dmm +++ b/_maps/map_files/RandomZLevels/terrorspiders.dmm @@ -2149,10 +2149,10 @@ name = "meat fridge"; req_access = list(271) }, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, diff --git a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm index 34802fdaab3..f2f03fcf0b3 100644 --- a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm @@ -2523,10 +2523,10 @@ name = "meat fridge"; req_access = list(201) }, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, diff --git a/_maps/map_files/cerestation/cerestation.dmm b/_maps/map_files/cerestation/cerestation.dmm index cc7f7e01a4f..b8f44d74610 100644 --- a/_maps/map_files/cerestation/cerestation.dmm +++ b/_maps/map_files/cerestation/cerestation.dmm @@ -50189,7 +50189,7 @@ /obj/effect/decal/cleanable/dirt, /obj/structure/table, /obj/item/kitchen/knife, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /turf/simulated/floor/plating, /area/maintenance/asmaint5) "jtD" = ( diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 1221eb1ae68..151181b7ca4 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -252,26 +252,13 @@ }, /area/security/securearmory) "acD" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, -/obj/structure/grille, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "acE" = ( @@ -434,36 +421,20 @@ }, /area/security/securearmory) "adb" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "adg" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, /obj/structure/cable{ icon_state = "2-8" }, @@ -474,34 +445,27 @@ d2 = 2; icon_state = "0-2" }, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "adh" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, /obj/structure/cable{ d2 = 8; icon_state = "0-8" }, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "adi" = ( @@ -512,15 +476,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "adj" = ( @@ -1021,12 +979,6 @@ }, /area/security/medbay) "aey" = ( -/obj/machinery/requests_console{ - department = "Warden"; - departmentType = 7; - name = "Warden's Requests Console"; - pixel_x = -30 - }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkred" @@ -1088,11 +1040,6 @@ }, /area/security/hos) "aeE" = ( -/obj/machinery/firealarm{ - dir = 8; - name = "west fire alarm"; - pixel_x = -24 - }, /obj/effect/decal/warning_stripes/east, /obj/structure/rack, /obj/item/tank/internals/oxygen, @@ -1211,12 +1158,8 @@ /obj/structure/filingcabinet/chestdrawer, /obj/machinery/light_switch{ name = "west light switch"; - pixel_x = -24 - }, -/obj/machinery/firealarm{ - dir = 8; - name = "west fire alarm"; - pixel_x = -24 + pixel_x = -24; + pixel_y = -10 }, /turf/simulated/floor/plasteel{ dir = 8; @@ -1652,26 +1595,16 @@ }, /area/security/customs) "agt" = ( -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable{ d2 = 2; icon_state = "0-2" }, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "agu" = ( @@ -2127,6 +2060,9 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2172,8 +2108,13 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/structure/disposalpipe/sortjunction{ + dir = 4; + icon_state = "pipe-j2s"; + name = "Brig Physician"; + sortType = 24 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2184,6 +2125,9 @@ dir = 1 }, /obj/machinery/hologram/holopad, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2194,6 +2138,9 @@ }, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2492,14 +2439,6 @@ /turf/simulated/floor/plating, /area/security/permabrig) "ajj" = ( -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable{ icon_state = "1-8" }, @@ -2510,10 +2449,12 @@ d2 = 8; icon_state = "0-8" }, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "ajk" = ( @@ -2613,9 +2554,9 @@ /obj/item/stock_parts/cell/high/plus, /obj/effect/decal/warning_stripes/east, /obj/item/clothing/glasses/welding, -/obj/item/radio/intercom/department/security{ - name = "west station intercom (Security)"; - pixel_x = -28 +/obj/machinery/firealarm{ + name = "north fire alarm"; + pixel_y = 24 }, /turf/simulated/floor/plasteel, /area/security/podbay) @@ -2676,6 +2617,12 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + icon_state = "pipe-j2s"; + name = "IAA Office"; + sortType = 29 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2703,8 +2650,7 @@ icon_state = "2-8" }, /obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" + dir = 4 }, /turf/simulated/floor/plasteel{ dir = 8; @@ -2979,22 +2925,13 @@ }, /area/security/brig) "akt" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable, -/obj/structure/grille, /obj/machinery/door/poddoor/shutters/preopen{ id_tag = "HoSPriv" }, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "aku" = ( @@ -3048,6 +2985,10 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /obj/effect/decal/warning_stripes/blue/hollow, /obj/effect/decal/warning_stripes/east, +/obj/item/radio/intercom/department/security{ + name = "west station intercom (Security)"; + pixel_x = -28 + }, /turf/simulated/floor/plasteel, /area/security/podbay) "akz" = ( @@ -3125,19 +3066,9 @@ d2 = 2; icon_state = "0-2" }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "akK" = ( @@ -3168,26 +3099,13 @@ /turf/simulated/floor/plasteel, /area/security/permabrig) "akN" = ( -/obj/structure/window/reinforced/polarized{ - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos_room" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos_room" - }, /obj/structure/cable{ d2 = 8; icon_state = "0-8" }, -/obj/structure/grille, +/obj/effect/spawner/window/reinforced/polarized{ + id = "hos_room" + }, /turf/simulated/floor/plating, /area/security/hos) "akO" = ( @@ -3294,11 +3212,9 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/sortjunction{ - dir = 1; - icon_state = "pipe-j2s"; - name = "Brig Physician"; - sortType = 24 +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ dir = 8; @@ -3338,6 +3254,7 @@ name = "Security Blast Door"; opacity = 0 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/lawoffice) "ale" = ( @@ -3542,18 +3459,9 @@ d2 = 2; icon_state = "0-2" }, -/obj/structure/window/reinforced/polarized{ - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "alD" = ( @@ -4591,28 +4499,16 @@ "aoe" = ( /obj/structure/table/reinforced, /obj/item/flashlight/lamp, -/turf/simulated/floor/plasteel{ - icon_state = "cult" - }, +/turf/simulated/floor/wood, /area/lawoffice) "aof" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/structure/cable, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "aog" = ( @@ -5011,15 +4907,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "aoR" = ( @@ -5156,7 +5046,8 @@ /obj/item/pen, /obj/item/radio/intercom{ name = "west station intercom (General)"; - pixel_x = -28 + pixel_x = -28; + pixel_y = 5 }, /obj/item/radio/intercom/department/security{ name = "custom station intercom (Security)"; @@ -5290,10 +5181,6 @@ "apA" = ( /obj/machinery/vending/coffee, /obj/effect/decal/cleanable/dirt, -/obj/machinery/alarm{ - dir = 1; - pixel_y = -24 - }, /turf/simulated/floor/plasteel{ icon_state = "escape" }, @@ -5326,6 +5213,10 @@ name = "south bump"; pixel_y = -24 }, +/obj/machinery/light_switch{ + name = "east light switch"; + pixel_x = 24 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "escape" @@ -5391,18 +5282,9 @@ /area/security/prisonershuttle) "apQ" = ( /obj/structure/cable, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "hos" - }, -/obj/structure/window/reinforced/polarized{ +/obj/effect/spawner/window/reinforced/polarized{ id = "hos" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/security/hos) "apR" = ( @@ -6383,6 +6265,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -8205,6 +8090,10 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/carpet, /area/lawoffice) "avO" = ( @@ -8255,16 +8144,22 @@ /area/lawoffice) "avS" = ( /obj/machinery/hologram/holopad, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/lawoffice) "avT" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + name = "Internal Affairs Office"; + req_access = list(38) + }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/wood, /area/security/lobby) "avV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -8276,11 +8171,6 @@ /turf/simulated/floor/plasteel, /area/security/lobby) "avW" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - name = "Internal Affairs Office"; - req_access = list(38) - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -8547,6 +8437,7 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkbluecorners" @@ -8816,6 +8707,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/lawoffice) "axs" = ( @@ -8835,14 +8729,15 @@ /turf/simulated/floor/plasteel, /area/security/processing) "axu" = ( -/obj/machinery/newscaster{ - name = "south newscaster"; - pixel_y = -31 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "redcorner" +/obj/effect/spawner/window/reinforced, +/obj/machinery/door/poddoor/shutters{ + density = 0; + icon_state = "open"; + id_tag = "lawyer"; + name = "Internal Affairs Privacy Shutters"; + opacity = 0 }, +/turf/simulated/floor/plating, /area/security/lobby) "axv" = ( /obj/effect/spawner/window/reinforced, @@ -10380,9 +10275,7 @@ /obj/item/storage/box/tapes{ pixel_y = 3 }, -/turf/simulated/floor/plasteel{ - icon_state = "cult" - }, +/turf/simulated/floor/wood, /area/lawoffice) "aAJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ @@ -11295,7 +11188,6 @@ }, /area/hallway/primary/fore) "aDn" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/light{ dir = 4 }, @@ -11307,6 +11199,10 @@ c_tag = "Brig Cell Block A South"; dir = 8 }, +/obj/structure/disposalpipe/sortjunction{ + name = "Detective"; + sortType = 27 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "rampbottom" @@ -11322,6 +11218,10 @@ pixel_x = -24 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "rampbottom" @@ -11693,6 +11593,7 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -11772,6 +11673,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkblue" @@ -12077,16 +11982,17 @@ }, /area/hallway/primary/fore) "aFx" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/junction{ - dir = 1 + dir = 8 }, /turf/simulated/floor/plasteel, -/area/hallway/primary/fore) +/area/hallway/primary/starboard/east) "aFy" = ( /turf/simulated/floor/plasteel{ dir = 1; @@ -12187,6 +12093,7 @@ name = "Security Blast Door"; opacity = 0 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -12201,22 +12108,6 @@ "aFJ" = ( /turf/simulated/wall/r_wall, /area/crew_quarters/dorms) -"aFK" = ( -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/obj/structure/grille, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "aFL" = ( /turf/simulated/wall/r_wall, /area/security/evidence) @@ -12457,6 +12348,7 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "darkblue" @@ -12936,14 +12828,20 @@ /turf/simulated/wall, /area/maintenance/fsmaint2) "aHQ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, /obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" + dir = 4 }, -/turf/simulated/floor/wood, -/area/library) +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "darkredcorners" + }, +/area/security/brig) "aHR" = ( /obj/machinery/atmospherics/unary/portables_connector{ dir = 4 @@ -13006,6 +12904,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -13027,6 +12929,10 @@ /area/security/detectives_office) "aIe" = ( /obj/item/flag/clown, +/obj/item/radio/intercom{ + name = "west station intercom (General)"; + pixel_x = -28 + }, /turf/simulated/floor/wood, /area/clownoffice) "aIf" = ( @@ -13122,10 +13028,6 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -24 - }, /turf/simulated/floor/carpet/arcade, /area/crew_quarters/arcade) "aIq" = ( @@ -13142,7 +13044,12 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/sortjunction{ + dir = 1; + icon_state = "pipe-j2s"; + name = "Magistrate's Office"; + sortType = 28 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/fore) "aIs" = ( @@ -13468,13 +13375,17 @@ /turf/simulated/floor/plating, /area/maintenance/fpmaint) "aJh" = ( -/obj/structure/disposalpipe/segment{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plasteel{ - icon_state = "dark" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/area/hallway/primary/fore) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/west) "aJi" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 @@ -13482,10 +13393,6 @@ /turf/simulated/floor/carpet, /area/crew_quarters/courtroom) "aJj" = ( -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "darkred" @@ -13899,17 +13806,17 @@ /turf/simulated/floor/plasteel, /area/hallway/primary/fore) "aKA" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, +/obj/structure/table/wood/poker, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "darkred" }, /area/hallway/primary/fore) "aKB" = ( -/obj/machinery/dnaforensics, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "darkblue" @@ -13989,6 +13896,10 @@ /obj/structure/chair/comfy/black{ dir = 1 }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -24 + }, /turf/simulated/floor/carpet/arcade, /area/crew_quarters/arcade) "aKK" = ( @@ -14411,8 +14322,11 @@ /area/crew_quarters/courtroom) "aLX" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "blue" @@ -14437,6 +14351,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "redcorner" @@ -14450,6 +14367,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "bluecorner" @@ -14659,9 +14579,7 @@ /obj/item/pen, /obj/item/paper_bin/nanotrasen, /obj/effect/spawner/lootdrop/officetoys, -/turf/simulated/floor/plasteel{ - icon_state = "cult" - }, +/turf/simulated/floor/wood, /area/lawoffice) "aMP" = ( /obj/machinery/atmospherics/pipe/simple/visible/purple{ @@ -14935,9 +14853,8 @@ /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "aNM" = ( -/obj/structure/disposalpipe/junction{ - dir = 4; - icon_state = "pipe-j2" +/obj/structure/disposalpipe/segment{ + dir = 4 }, /turf/simulated/floor/plasteel{ icon_state = "bluecorner" @@ -15127,17 +15044,6 @@ }, /turf/simulated/floor/carpet/arcade, /area/crew_quarters/arcade) -"aOh" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "aOj" = ( /obj/structure/cable{ icon_state = "1-4" @@ -17058,12 +16964,6 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/dorms) -"aTH" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plasteel, -/area/hallway/primary/central/ne) "aTI" = ( /obj/structure/chair/sofa, /obj/structure/window/reinforced{ @@ -17108,6 +17008,7 @@ name = "Coroner"; req_access = list(5) }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -17165,6 +17066,10 @@ /area/medical/reception) "aTT" = ( /obj/item/twohanded/required/kirbyplants, +/obj/machinery/vending/wallmed{ + name = "West Emergency NanoMed"; + pixel_x = -25 + }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "whiteblue" @@ -17537,7 +17442,6 @@ /turf/simulated/floor/plating, /area/maintenance/fpmaint) "aVb" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -18269,8 +18173,7 @@ icon_state = "4-8" }, /obj/structure/disposalpipe/sortjunction{ - dir = 8; - icon_state = "pipe-j2s"; + dir = 4; name = "Library"; sortType = 16 }, @@ -18937,6 +18840,7 @@ "aYl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -19150,17 +19054,13 @@ /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "aYK" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" + dir = 4 }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) +/turf/simulated/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/chapel/main) "aYL" = ( /obj/machinery/light{ dir = 1 @@ -19610,6 +19510,10 @@ dir = 5 }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "aZW" = ( @@ -19758,12 +19662,9 @@ layer = 4; pixel_y = 32 }, -/obj/structure/table/wood, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 +/obj/machinery/light{ + dir = 1 }, -/obj/item/stack/packageWrap, /turf/simulated/floor/wood, /area/library) "baq" = ( @@ -19836,10 +19737,6 @@ name = "north station intercom (General)"; pixel_y = 28 }, -/obj/structure/table/wood, -/obj/item/dice/d20, -/obj/item/dice, -/obj/item/storage/box/characters, /turf/simulated/floor/wood, /area/library) "baw" = ( @@ -19861,10 +19758,11 @@ }, /area/ai_monitored/storage/eva) "bax" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/wood, -/area/library) +/obj/machinery/dnaforensics, +/turf/simulated/floor/plasteel{ + icon_state = "darkblue" + }, +/area/security/detectives_office) "bay" = ( /turf/simulated/floor/plasteel{ dir = 5; @@ -20210,6 +20108,10 @@ /area/medical/morgue) "bbB" = ( /obj/item/flag/mime, +/obj/item/radio/intercom{ + name = "west station intercom (General)"; + pixel_x = -28 + }, /turf/simulated/floor/plasteel{ icon_regular_floor = "yellowsiding"; icon_state = "tranquillite" @@ -20429,12 +20331,6 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/dorms) "bcb" = ( -/obj/structure/disposalpipe/sortjunction{ - dir = 4; - icon_state = "pipe-j2s"; - name = "Chapel"; - sortType = 17 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -20444,6 +20340,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bcc" = ( @@ -20496,29 +20395,23 @@ }, /area/maintenance/livingcomplex) "bch" = ( -/obj/structure/chair/office/dark, /obj/machinery/camera{ c_tag = "Library North" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/wood, /area/library) "bci" = ( /obj/structure/chair/office/dark, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/wood, /area/library) "bcj" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Chapel" }, -/turf/simulated/floor/wood, -/area/library) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel, +/area/chapel/main) "bck" = ( /obj/effect/spawner/window/reinforced, /obj/structure/disposalpipe/segment{ @@ -20585,11 +20478,14 @@ }, /area/chapel/office) "bcs" = ( -/obj/structure/disposalpipe/segment{ +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/wood, -/area/library) +/turf/simulated/floor/plasteel, +/area/hallway/primary/aft) "bct" = ( /obj/structure/cable{ icon_state = "1-2" @@ -20601,7 +20497,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment{ - dir = 2; + dir = 8; icon_state = "pipe-c" }, /turf/simulated/floor/plating, @@ -20978,10 +20874,6 @@ /area/hallway/secondary/entry) "bdo" = ( /obj/structure/closet/secure_closet/clown, -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /turf/simulated/floor/wood, /area/clownoffice) "bdq" = ( @@ -21007,10 +20899,6 @@ /area/clownoffice) "bds" = ( /obj/structure/closet/secure_closet/mime, -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /turf/simulated/floor/plasteel{ icon_regular_floor = "yellowsiding"; icon_state = "tranquillite" @@ -21476,6 +21364,7 @@ /area/shuttle/arrival/station) "bek" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "bel" = ( @@ -21504,17 +21393,19 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/locker) "beo" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, /obj/structure/chair/office/dark{ - dir = 8 + dir = 1 }, /turf/simulated/floor/wood, /area/library) "bep" = ( -/obj/machinery/newscaster{ - name = "east newscaster"; - pixel_x = 32; - pixel_y = 1 - }, +/obj/structure/table/wood, +/obj/item/dice/d20, +/obj/item/dice, +/obj/item/storage/box/characters, /turf/simulated/floor/wood, /area/library) "beq" = ( @@ -22227,15 +22118,10 @@ icon_state = "darkblue" }, /area/chapel/main) -"bfT" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/library) "bfU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "bfV" = ( @@ -22883,13 +22769,11 @@ /turf/simulated/floor/wood, /area/library) "bhx" = ( -/obj/structure/chair/office/dark{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "bhy" = ( @@ -23174,6 +23058,11 @@ dir = 8 }, /obj/structure/table/wood, +/obj/item/paper_bin{ + pixel_x = 1; + pixel_y = 9 + }, +/obj/item/stack/packageWrap, /turf/simulated/floor/wood, /area/library) "bii" = ( @@ -23184,8 +23073,6 @@ /obj/structure/chair/office/dark{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/wood, /area/library) "bio" = ( @@ -23227,16 +23114,17 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/sortjunction{ + dir = 4; + name = "Chapel Junction"; + sortType = 17 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -23267,6 +23155,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -23298,6 +23190,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -23667,12 +23562,11 @@ /turf/simulated/floor/plating, /area/maintenance/fpmaint) "bjk" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" +/obj/machinery/atmospherics/unary/outlet_injector/on{ + dir = 1 }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) +/turf/simulated/floor/plating/airless, +/area/space) "bjm" = ( /obj/structure/chair/sofa/corp/left, /turf/simulated/floor/carpet/black, @@ -23838,9 +23732,6 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -24019,6 +23910,9 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/west) "bki" = ( @@ -24057,12 +23951,12 @@ /turf/simulated/floor/plasteel, /area/hallway/primary/port) "bkn" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, /obj/structure/chair/office/dark{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, /turf/simulated/floor/wood, /area/library) "bko" = ( @@ -24075,6 +23969,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/west) "bkp" = ( @@ -24082,6 +23979,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "bkr" = ( @@ -24100,12 +23998,18 @@ /turf/simulated/floor/plasteel, /area/hallway/primary/central/nw) "bkt" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/access_button{ + command = "cycle_interior"; + frequency = 1450; + master_tag = "sci_maint"; + name = "interior access button"; + pixel_x = -28; + pixel_y = -5; + req_access = list(13) }, +/obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plating, -/area/maintenance/fsmaint2) +/area/maintenance/asmaint2) "bku" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -24117,6 +24021,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/west) "bkw" = ( @@ -24173,9 +24080,6 @@ /obj/item/stack/rods{ amount = 10 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/spawner/random_spawners/grille_maybe, /obj/structure/cable{ icon_state = "1-2" @@ -24201,21 +24105,23 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bkI" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/structure/cable{ + icon_state = "1-2" }, -/obj/structure/lattice/catwalk, -/turf/space, -/area/space) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/plating, +/area/maintenance/fsmaint2) "bkJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 9 @@ -24249,11 +24155,9 @@ /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bkN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/carpet, +/area/lawoffice) "bkR" = ( /obj/machinery/door/poddoor{ density = 0; @@ -24394,6 +24298,7 @@ name = "west fire alarm"; pixel_x = -24 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -24536,6 +24441,7 @@ name = "west station intercom (General)"; pixel_x = -28 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -25119,6 +25025,7 @@ name = "west bump"; pixel_x = -24 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -25202,6 +25109,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -25408,7 +25316,6 @@ /obj/machinery/light{ dir = 4 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "bnn" = ( @@ -25792,15 +25699,16 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "bop" = ( @@ -25958,9 +25866,6 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -26454,12 +26359,6 @@ /obj/machinery/vending/chinese, /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) -"bpR" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/simulated/floor/carpet, -/area/crew_quarters/mrchangs) "bpS" = ( /obj/machinery/kitchen_machine/candy_maker, /turf/simulated/floor/plasteel{ @@ -26731,6 +26630,10 @@ "bqD" = ( /obj/structure/table/wood, /obj/machinery/fishtank/bowl, +/obj/item/radio/intercom{ + name = "west station intercom (General)"; + pixel_x = -28 + }, /turf/simulated/floor/wood, /area/civilian/pet_store) "bqE" = ( @@ -26797,6 +26700,7 @@ "bqM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/library) "bqN" = ( @@ -27127,6 +27031,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -27483,10 +27388,6 @@ /turf/simulated/floor/plasteel, /area/hallway/secondary/exit) "bsQ" = ( -/obj/item/radio/intercom{ - name = "east station intercom (General)"; - pixel_x = 28 - }, /obj/effect/turf_decal/siding/wood{ dir = 1 }, @@ -27652,6 +27553,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet/black, /area/crew_quarters/bar/atrium) "btp" = ( @@ -27795,6 +27697,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/carpet, /area/library) "btW" = ( @@ -27804,16 +27709,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/carpet, /area/library) -"btX" = ( -/obj/structure/extinguisher_cabinet{ - name = "south extinguisher cabinet"; - pixel_y = -30 - }, -/obj/machinery/light, -/turf/simulated/floor/plasteel, -/area/hallway/primary/starboard/west) "btY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -27821,6 +27722,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/library) "btZ" = ( @@ -27830,6 +27735,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/library) "bua" = ( @@ -27981,6 +27889,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/library) "bux" = ( @@ -28012,6 +27921,7 @@ c_tag = "Chapel West"; dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -28135,7 +28045,7 @@ dir = 6 }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "2-4" }, /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) @@ -28167,6 +28077,7 @@ "buQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet/black, /area/crew_quarters/bar/atrium) "buR" = ( @@ -28226,6 +28137,7 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/chapel/main) "buZ" = ( @@ -29532,9 +29444,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -29550,10 +29459,6 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, @@ -29580,9 +29485,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/decal/warning_stripes/yellow, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -29691,9 +29593,6 @@ name = "Bridge"; req_access = list(19) }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -29705,7 +29604,6 @@ "byr" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) @@ -29723,9 +29621,6 @@ name = "Bridge"; req_access = list(19) }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/structure/cable{ icon_state = "1-8" }, @@ -29742,17 +29637,22 @@ /turf/simulated/floor/plasteel, /area/bridge) "byu" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/turf/simulated/floor/plasteel, -/area/hallway/primary/central/ne) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/toxins/explab) "byv" = ( /obj/machinery/hologram/holopad, /obj/machinery/firealarm{ @@ -29773,10 +29673,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/ne) "byy" = ( @@ -29800,9 +29696,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/ne) "byB" = ( @@ -29944,7 +29837,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "byR" = ( @@ -30032,6 +29924,9 @@ name = "south light switch"; pixel_y = -24 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -30150,6 +30045,9 @@ /area/hallway/secondary/exit) "bzo" = ( /obj/effect/turf_decal/siding/wood/corner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "bzp" = ( @@ -30157,6 +30055,7 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/library) "bzr" = ( @@ -30649,7 +30548,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel, @@ -30698,11 +30596,9 @@ /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "bAW" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -30724,6 +30620,10 @@ "bAY" = ( /obj/machinery/hologram/holopad, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/carpet, /area/library) "bAZ" = ( @@ -31230,7 +31130,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/command{ id_tag = "captainofficedoor"; @@ -31332,7 +31231,6 @@ /turf/simulated/floor/wood, /area/crew_quarters/captain) "bCN" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -31363,7 +31261,10 @@ /turf/simulated/floor/carpet, /area/crew_quarters/captain) "bCR" = ( -/obj/item/twohanded/required/kirbyplants, +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, /turf/simulated/floor/wood, /area/library) "bCS" = ( @@ -31405,10 +31306,6 @@ pixel_x = 6; pixel_y = 6 }, -/obj/machinery/vending/wallmed{ - name = "West Emergency NanoMed"; - pixel_x = -25 - }, /obj/item/roller, /turf/simulated/floor/plasteel{ dir = 8; @@ -31816,10 +31713,6 @@ /turf/simulated/floor/bluegrid, /area/turret_protected/ai_upload) "bEe" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -31828,13 +31721,16 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bEg" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/ne) "bEh" = ( @@ -31941,6 +31837,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -31960,7 +31860,7 @@ pixel_y = -24 }, /obj/structure/disposalpipe/trunk{ - dir = 1 + dir = 8 }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) @@ -31988,7 +31888,7 @@ req_access = list(4,5) }, /obj/structure/disposalpipe/segment{ - dir = 1; + dir = 8; icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ @@ -32108,6 +32008,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bFi" = ( @@ -32117,7 +32018,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bFj" = ( @@ -32128,13 +32028,19 @@ /area/hallway/primary/starboard/west) "bFk" = ( /obj/structure/cable{ - icon_state = "1-2" + icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plasteel, -/area/hallway/primary/starboard/east) +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + icon_state = "darkredcorners" + }, +/area/security/brig) "bFl" = ( /obj/structure/cable{ icon_state = "1-2" @@ -32403,10 +32309,10 @@ }, /area/crew_quarters/toilet) "bFT" = ( +/obj/effect/landmark/event/revenantspawn, /obj/structure/morgue{ dir = 8 }, -/obj/effect/landmark/event/revenantspawn, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -32931,6 +32837,7 @@ "bHm" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bHo" = ( @@ -32940,7 +32847,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bHp" = ( @@ -33042,13 +32948,12 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bHD" = ( @@ -33065,6 +32970,11 @@ /area/medical/morgue) "bHG" = ( /obj/structure/filingcabinet/chestdrawer/autopsy, +/obj/machinery/firealarm{ + dir = 1; + name = "south fire alarm"; + pixel_y = -24 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -33079,26 +32989,22 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/sortjunction{ - dir = 4; - name = "Sci Robotics"; - sortType = 24 - }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bHJ" = ( -/obj/machinery/firealarm{ - dir = 1; - name = "south fire alarm"; - pixel_y = -24 - }, -/turf/simulated/floor/plasteel{ - icon_state = "dark" +/obj/machinery/suit_storage_unit/atmos, +/obj/item/radio/intercom{ + name = "west station intercom (General)"; + pixel_x = -28 }, -/area/medical/morgue) +/turf/simulated/floor/plasteel, +/area/atmos) "bHK" = ( /obj/structure/chair/office/dark, /obj/effect/landmark/start/coroner, @@ -33152,12 +33058,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bHQ" = ( @@ -33167,8 +33073,9 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, -/obj/structure/disposalpipe/junction{ - icon_state = "pipe-y" +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) @@ -33580,6 +33487,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bIQ" = ( @@ -33589,6 +33500,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bIR" = ( @@ -33598,7 +33513,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bIT" = ( @@ -33905,6 +33819,7 @@ dir = 1 }, /obj/item/hand_tele, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bJN" = ( @@ -34040,7 +33955,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/starboard/east) "bKc" = ( @@ -34275,6 +34189,7 @@ /obj/effect/landmark/start/captain, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bKM" = ( @@ -34287,7 +34202,6 @@ "bKN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bKO" = ( @@ -34325,7 +34239,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/assembly/chargebay) "bKS" = ( @@ -34436,12 +34349,11 @@ }, /area/medical/morgue) "bLl" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/disposalpipe/segment, -/turf/simulated/floor/plasteel, -/area/assembly/chargebay) +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/chapel/main) "bLo" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 @@ -34711,7 +34623,6 @@ /obj/item/multitool{ pixel_x = 3 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/assembly/robotics) "bLU" = ( @@ -34759,6 +34670,10 @@ "bMb" = ( /obj/machinery/light, /obj/effect/decal/warning_stripes/south, +/obj/item/radio/intercom{ + name = "south station intercom (General)"; + pixel_y = -28 + }, /turf/simulated/floor/plasteel, /area/hallway/secondary/entry) "bMg" = ( @@ -34946,6 +34861,10 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMM" = ( @@ -34986,6 +34905,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMP" = ( @@ -35001,6 +34923,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMQ" = ( @@ -35011,6 +34936,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMR" = ( @@ -35027,6 +34955,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMS" = ( @@ -35042,6 +34973,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bMT" = ( @@ -35057,19 +34992,12 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/bluegrid, /area/assembly/chargebay) "bMV" = ( /obj/structure/cable{ icon_state = "1-4" }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /turf/simulated/floor/bluegrid, /area/assembly/chargebay) "bMW" = ( @@ -35082,9 +35010,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 6 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel, /area/assembly/chargebay) "bMX" = ( @@ -35117,8 +35042,7 @@ /area/medical/biostorage) "bMZ" = ( /obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" + dir = 4 }, /turf/simulated/floor/plasteel{ icon_state = "dark" @@ -35131,9 +35055,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel, /area/assembly/chargebay) "bNc" = ( @@ -35146,10 +35067,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -35177,9 +35094,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -35213,7 +35127,6 @@ /obj/item/stack/cable_coil, /obj/item/flash, /obj/item/flash, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/assembly/robotics) "bNj" = ( @@ -35257,20 +35170,13 @@ }, /area/medical/research) "bNl" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/sortjunction{ - dir = 1; - name = "Sci RD Office 2"; - sortType = 13 - }, -/turf/simulated/floor/plasteel{ - icon_state = "white" +/obj/structure/window/reinforced, +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 8 }, -/area/medical/research) +/turf/simulated/floor/wood, +/area/lawoffice) "bNm" = ( /obj/machinery/camera{ c_tag = "Research Access"; @@ -35345,15 +35251,17 @@ }, /area/toxins/lab) "bNq" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "whitehall" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/area/medical/research) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/fore) "bNr" = ( /obj/machinery/light{ dir = 4 @@ -35839,6 +35747,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/crew_quarters/captain) "bOz" = ( @@ -36068,7 +35977,6 @@ }, /area/medical/morgue) "bOX" = ( -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkblue" @@ -36245,7 +36153,7 @@ "bPn" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ - dir = 1 + dir = 4 }, /turf/simulated/floor/plasteel, /area/assembly/robotics) @@ -36286,7 +36194,6 @@ /turf/simulated/floor/transparent/glass/reinforced, /area/hallway/secondary/exit) "bPx" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -36777,10 +36684,6 @@ }, /area/medical/biostorage) "bQF" = ( -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "darkblue" @@ -36790,18 +36693,11 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, /area/medical/morgue) "bQH" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/light/small, /turf/simulated/floor/plasteel{ icon_state = "darkblue" @@ -36856,6 +36752,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/crew_quarters/captain) "bQO" = ( @@ -36863,7 +36760,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bQP" = ( @@ -37019,7 +36915,6 @@ name = "Morgue"; req_access = list(5,6) }, -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -37174,6 +37069,9 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/assembly/robotics) "bRt" = ( @@ -37196,6 +37094,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/assembly/robotics) "bRz" = ( @@ -37205,6 +37107,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -37240,6 +37145,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/assembly/robotics) "bRH" = ( @@ -37276,6 +37184,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -37615,7 +37527,6 @@ }, /area/medical/cloning) "bSD" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/light_switch{ name = "east light switch"; pixel_x = 24 @@ -38035,7 +37946,6 @@ /turf/simulated/floor/carpet, /area/crew_quarters/captain/bedroom) "bTC" = ( -/obj/effect/spawner/window/reinforced, /obj/structure/sign/securearea{ desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; @@ -38046,7 +37956,6 @@ d2 = 4; icon_state = "0-4" }, -/obj/structure/cable, /obj/machinery/door/poddoor/shutters{ density = 0; dir = 8; @@ -38055,6 +37964,12 @@ name = "Privacy Shutters"; opacity = 0 }, +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, /area/crew_quarters/heads) "bTE" = ( @@ -38074,6 +37989,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/crew_quarters/captain) "bTG" = ( @@ -38221,7 +38137,6 @@ }, /area/medical/cloning) "bUb" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -38242,6 +38157,7 @@ "bUe" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -38749,6 +38665,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/teleporter) "bVs" = ( @@ -38992,6 +38909,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/teleporter) "bVS" = ( @@ -38999,7 +38917,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bVT" = ( @@ -39796,10 +39713,6 @@ }, /area/medical/sleeper) "bXF" = ( -/obj/machinery/light_switch{ - name = "west light switch"; - pixel_x = -24 - }, /obj/machinery/sleeper{ dir = 4 }, @@ -40034,6 +39947,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/teleporter) "bXZ" = ( @@ -40045,6 +39961,10 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/teleporter) "bYa" = ( @@ -40054,10 +39974,13 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "2-8" }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/se) "bYb" = ( @@ -40070,6 +39993,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "blue" @@ -40151,6 +40077,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -41100,13 +41027,13 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, -/obj/structure/disposalpipe/junction{ - dir = 8; - icon_state = "pipe-y" - }, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "freezerfloor" }, @@ -41237,6 +41164,7 @@ "cax" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitered" @@ -41282,7 +41210,7 @@ /obj/structure/disposalpipe/sortjunction{ dir = 2; icon_state = "pipe-j2s"; - name = "Sci RD Office 2"; + name = "RD Office"; sortType = 13 }, /turf/simulated/floor/plasteel{ @@ -42035,8 +41963,10 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + name = "Robotics Junction"; + sortType = 14 }, /turf/simulated/floor/plasteel{ icon_state = "white" @@ -42482,6 +42412,10 @@ /obj/machinery/atmospherics/pipe/manifold/visible{ dir = 1 }, +/obj/machinery/firealarm{ + name = "north fire alarm"; + pixel_y = 24 + }, /turf/simulated/floor/plasteel/dark/telecomms, /area/toxins/server) "ccW" = ( @@ -42965,12 +42899,19 @@ name = "north bump"; pixel_y = 24 }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cet" = ( /obj/machinery/ai_status_display{ pixel_y = 32 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "ceu" = ( @@ -42978,6 +42919,9 @@ name = "north station intercom (General)"; pixel_y = 28 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cev" = ( @@ -42987,6 +42931,9 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cew" = ( @@ -42994,6 +42941,9 @@ pixel_y = 32 }, /obj/effect/decal/warning_stripes/northeastcorner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cex" = ( @@ -43001,6 +42951,10 @@ layer = 4; pixel_y = 32 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cey" = ( @@ -43008,6 +42962,9 @@ pixel_y = 32 }, /obj/effect/decal/warning_stripes/northwestcorner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cez" = ( @@ -43356,9 +43313,6 @@ /area/hallway/primary/central/se) "cfC" = ( /obj/structure/table/glass, -/obj/machinery/alarm{ - pixel_y = 24 - }, /obj/item/reagent_containers/iv_bag/salglu, /turf/simulated/floor/plasteel{ icon_state = "whiteblue" @@ -43455,6 +43409,10 @@ "cfL" = ( /obj/structure/table/glass, /obj/item/storage/toolbox/surgery, +/obj/machinery/alarm{ + dir = 8; + pixel_x = 24 + }, /turf/simulated/floor/plasteel{ icon_state = "whiteblue" }, @@ -43629,13 +43587,6 @@ icon_state = "dark" }, /area/medical/cmo) -"cfY" = ( -/obj/item/radio/intercom/department/security{ - name = "north station intercom (Security)"; - pixel_y = 25 - }, -/turf/simulated/floor/plasteel, -/area/security/main) "cfZ" = ( /obj/machinery/light/small{ dir = 4 @@ -43725,9 +43676,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, -/obj/structure/disposalpipe/junction{ - dir = 4 - }, /obj/structure/cable{ icon_state = "2-8" }, @@ -43737,6 +43685,10 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/central/south) "cgj" = ( @@ -44292,20 +44244,12 @@ }, /area/medical/medbreak) "chE" = ( -/obj/machinery/alarm{ - dir = 1; - pixel_y = -24 - }, /obj/machinery/photocopier, /turf/simulated/floor/plasteel{ icon_state = "darkblue" }, /area/medical/cmo) "chF" = ( -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /obj/effect/decal/cleanable/dirt, /obj/item/storage/box/gloves{ pixel_x = 3; @@ -44386,9 +44330,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/junction{ - dir = 4; - icon_state = "pipe-y" +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ icon_state = "white" @@ -44894,12 +44838,10 @@ /turf/simulated/floor/plating, /area/maintenance/genetics) "cjb" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/turf/simulated/floor/plasteel, -/area/hallway/primary/aft) +/obj/structure/chair/stool, +/obj/effect/spawner/lootdrop/maintenance, +/turf/simulated/floor/plating, +/area/maintenance/asmaint) "cjc" = ( /obj/structure/sign/poster/random{ pixel_x = 32 @@ -45199,11 +45141,6 @@ /turf/simulated/floor/engine, /area/toxins/explab_chamber) "cjJ" = ( -/obj/machinery/firealarm{ - dir = 1; - name = "south fire alarm"; - pixel_y = -24 - }, /obj/machinery/atmospherics/pipe/simple/visible{ dir = 9 }, @@ -46083,9 +46020,9 @@ "cmh" = ( /obj/structure/closet/secure_closet/ntrep, /obj/machinery/firealarm{ - dir = 4; - name = "east fire alarm"; - pixel_x = 24 + dir = 1; + name = "south fire alarm"; + pixel_y = -24 }, /turf/simulated/floor/wood, /area/ntrep) @@ -46460,10 +46397,6 @@ /obj/machinery/light{ dir = 1 }, -/obj/item/radio/intercom{ - name = "north station intercom (General)"; - pixel_y = 28 - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitegreen" @@ -48974,13 +48907,13 @@ }, /area/medical/virology/lab) "cur" = ( -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /obj/structure/closet/l3closet, /obj/item/clothing/mask/gas, /obj/effect/decal/warning_stripes/southwest, +/obj/item/radio/intercom{ + name = "south station intercom (General)"; + pixel_y = -28 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -48993,6 +48926,10 @@ on = 1 }, /obj/effect/decal/warning_stripes/southeast, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -24 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49131,6 +49068,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49153,6 +49093,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49172,6 +49115,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49182,6 +49128,9 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49198,6 +49147,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49400,6 +49352,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49416,6 +49371,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -49706,7 +49664,7 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment{ - dir = 2; + dir = 8; icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ @@ -50025,7 +49983,6 @@ /turf/simulated/floor/plating, /area/maintenance/genetics) "cxc" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "1-2" }, @@ -50354,20 +50311,12 @@ /turf/simulated/wall, /area/toxins/xenobiology) "cxO" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, +/obj/effect/turf_decal/siding/wood, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/genetics) +/turf/simulated/floor/wood/fancy/cherry, +/area/crew_quarters/bar/atrium) "cxP" = ( /obj/structure/chair/stool, /turf/simulated/floor/plasteel{ @@ -50381,10 +50330,6 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, @@ -50400,9 +50345,6 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -50440,9 +50382,6 @@ /obj/machinery/light{ dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -50973,9 +50912,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -52146,10 +52082,6 @@ }, /area/toxins/misc_lab) "cCp" = ( -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /obj/structure/dispenser, /turf/simulated/floor/plasteel, /area/atmos) @@ -53457,19 +53389,9 @@ d2 = 2; icon_state = "0-2" }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cFD" = ( @@ -53726,7 +53648,8 @@ dir = 1 }, /obj/structure/disposalpipe/segment{ - dir = 4 + dir = 4; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) @@ -53809,18 +53732,12 @@ /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "cGl" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/disposalpipe/junction{ - dir = 8; - icon_state = "pipe-j2" +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" }, -/turf/simulated/floor/plasteel, -/area/hallway/primary/aft) +/turf/simulated/floor/carpet, +/area/library) "cGm" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, @@ -53835,9 +53752,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "cGo" = ( @@ -54055,6 +53969,12 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/sortjunction{ + dir = 1; + icon_state = "pipe-j2s"; + name = "Mechanic"; + sortType = 30 + }, /turf/simulated/floor/plasteel{ icon_state = "yellow" }, @@ -54212,15 +54132,9 @@ d2 = 8; icon_state = "1-8" }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cHb" = ( @@ -54257,7 +54171,7 @@ /obj/item/reagent_containers/food/snacks/meat, /obj/item/reagent_containers/food/snacks/meat/corgi, /obj/item/reagent_containers/food/snacks/meat/corgi, -/obj/item/reagent_containers/food/snacks/meat/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/item/kitchen/knife, /obj/effect/decal/cleanable/cobweb2, /turf/simulated/floor/plating, @@ -54297,19 +54211,9 @@ /area/hallway/primary/aft) "cHk" = ( /obj/structure/cable/yellow, -/obj/structure/window/reinforced/polarized{ - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cHl" = ( @@ -54483,21 +54387,18 @@ /turf/simulated/floor/plating, /area/assembly/assembly_line) "cHG" = ( -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plasteel, -/area/hallway/primary/aft) -"cHI" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/disposalpipe/sortjunction{ - dir = 8; - icon_state = "pipe-j2s"; - name = "Engineering Main"; - sortType = 4 +/turf/simulated/floor/carpet, +/area/library) +"cHI" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" }, -/turf/simulated/floor/plasteel, -/area/hallway/primary/aft) +/turf/simulated/floor/carpet, +/area/chapel/main) "cHJ" = ( /obj/structure/reagent_dispensers/watertank, /obj/structure/sign/poster/official/random{ @@ -54646,6 +54547,10 @@ /turf/simulated/floor/plasteel, /area/engine/break_room) "cHW" = ( +/obj/item/radio/intercom{ + name = "west station intercom (General)"; + pixel_x = -28 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitegreen" @@ -54866,18 +54771,9 @@ icon_state = "1-4" }, /obj/structure/cable/yellow, -/obj/structure/window/reinforced/polarized{ - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cIx" = ( @@ -54914,18 +54810,9 @@ d2 = 8; icon_state = "0-8" }, -/obj/structure/window/reinforced/polarized{ - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cIz" = ( @@ -55075,6 +54962,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "cIQ" = ( @@ -55243,15 +55131,20 @@ /turf/simulated/floor/plasteel, /area/assembly/assembly_line) "cJk" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, /obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" + dir = 4 }, -/turf/simulated/floor/plasteel, -/area/hallway/primary/aft) +/turf/simulated/floor/plating, +/area/maintenance/engineering) "cJl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -55265,10 +55158,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "cJn" = ( @@ -55951,6 +55841,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "cKL" = ( @@ -55960,6 +55851,7 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "cKM" = ( @@ -56702,10 +56594,6 @@ /turf/simulated/floor/plasteel, /area/maintenance/asmaint) "cMG" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "yellowcorner" @@ -56908,13 +56796,19 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint) "cNf" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 5; - max_integrity = 1e+007 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + name = "NTR Office"; + sortType = 26 + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/central/south) "cNg" = ( /obj/structure/sign/barsign, /turf/simulated/wall, @@ -57220,6 +57114,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "yellow" }, @@ -57230,6 +57127,10 @@ icon_state = "1-8" }, /obj/item/twohanded/required/kirbyplants, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "yellowcorner" }, @@ -57454,6 +57355,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "cOr" = ( @@ -57472,6 +57374,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "cOt" = ( @@ -57610,6 +57513,7 @@ codes_txt = "patrol;next_patrol=AIE"; location = "AftH" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "cOL" = ( @@ -58100,10 +58004,13 @@ }, /area/toxins/xenobiology) "cPL" = ( -/obj/structure/disposalpipe/segment, /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "cautioncorner" @@ -58938,6 +58845,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/engineering) "cRG" = ( @@ -58981,6 +58892,12 @@ dir = 10 }, /obj/structure/grille/broken, +/obj/structure/disposalpipe/sortjunction{ + dir = 8; + icon_state = "pipe-j2s"; + name = "Engineering Main"; + sortType = 4 + }, /turf/simulated/floor/plating, /area/maintenance/engineering) "cRJ" = ( @@ -59003,15 +58920,9 @@ d2 = 4; icon_state = "0-4" }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cRK" = ( @@ -59607,12 +59518,14 @@ /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "cSX" = ( -/obj/structure/chair/wood, -/obj/structure/cable{ - icon_state = "1-2" +/obj/structure/extinguisher_cabinet{ + name = "east extinguisher cabinet"; + pixel_x = 27 }, -/turf/simulated/floor/carpet, -/area/crew_quarters/mrchangs) +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/gateway) "cSZ" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/heat_exchanging{ @@ -60662,6 +60575,10 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/engineering) "cUZ" = ( @@ -61140,22 +61057,9 @@ d2 = 4; icon_state = "0-4" }, -/obj/structure/window/reinforced/polarized{ - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "ceoffice" }, -/obj/structure/grille, /turf/simulated/floor/plating, /area/engine/chiefs_office) "cVV" = ( @@ -61512,12 +61416,15 @@ }, /area/engine/engineering) "cWJ" = ( +/obj/item/twohanded/required/kirbyplants, /obj/structure/disposalpipe/segment{ - dir = 2; + dir = 1; icon_state = "pipe-c" }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/chapel/main) "cWK" = ( /obj/effect/decal/warning_stripes/east, /obj/structure/closet/radiation, @@ -61880,7 +61787,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "cXA" = ( @@ -62330,9 +62236,15 @@ /turf/simulated/floor/plasteel, /area/engine/engineering) "cYw" = ( -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "cautioncorner" + }, +/area/hallway/primary/aft) "cYx" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/heat_exchanging, @@ -62519,8 +62431,9 @@ dir = 1; icon_state = "pipe-c" }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/area/maintenance/asmaint) "cYS" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -62772,11 +62685,9 @@ }, /area/hallway/secondary/exit) "cZE" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/wood, +/area/lawoffice) "cZF" = ( /obj/structure/closet/cardboard{ icon_closed = "cardboard_engineering"; @@ -63028,12 +62939,16 @@ /turf/simulated/floor/plasteel, /area/engine/engineering) "daj" = ( -/obj/machinery/door/airlock/maintenance, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass{ + name = "Chapel Office"; + req_access = list(22) }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/chapel/office) "dak" = ( /obj/machinery/camera{ c_tag = "Departure Lounge South"; @@ -63114,12 +63029,9 @@ /turf/simulated/wall/r_wall, /area/engine/engineering) "day" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/carpet, +/area/chapel/main) "daA" = ( /obj/structure/cable{ icon_state = "4-8" @@ -64077,10 +63989,10 @@ /turf/space, /area/solar/starboard) "ddC" = ( -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" +/obj/structure/transit_tube/junction{ + dir = 4 }, -/obj/structure/lattice/catwalk, +/obj/structure/lattice, /turf/space, /area/space) "ddD" = ( @@ -64864,9 +64776,9 @@ name = "north fire alarm"; pixel_y = 24 }, -/obj/structure/transit_tube{ - dir = 4; - icon_state = "Block" +/obj/structure/transit_tube/station, +/obj/structure/transit_tube_pod{ + dir = 8 }, /turf/simulated/floor/plasteel{ icon_state = "dark" @@ -64885,6 +64797,9 @@ name = "north station intercom (General)"; pixel_y = 28 }, +/obj/structure/transit_tube/cap{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "blue" @@ -64892,7 +64807,7 @@ /area/maintenance/atmospherics) "dfD" = ( /obj/effect/spawner/window/reinforced, -/obj/structure/transit_tube, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plating, /area/maintenance/atmospherics) "dfE" = ( @@ -64900,10 +64815,7 @@ layer = 4; pixel_y = 32 }, -/obj/structure/transit_tube/station, -/obj/structure/transit_tube_pod{ - dir = 8 - }, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -65208,11 +65120,6 @@ }, /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/mug, -/obj/machinery/power/apc{ - name = "south bump"; - pixel_y = -24 - }, -/obj/structure/cable, /obj/effect/turf_decal/siding/wood{ dir = 1 }, @@ -65387,6 +65294,12 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 26 + }, +/obj/structure/cable, /turf/simulated/floor/wood, /area/crew_quarters/mrchangs) "dhr" = ( @@ -66461,10 +66374,6 @@ /obj/machinery/camera{ c_tag = "Central Hallway North-West" }, -/obj/structure/extinguisher_cabinet{ - name = "north extinguisher cabinet"; - pixel_y = 30 - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "bluecorner" @@ -66474,6 +66383,10 @@ /obj/machinery/light{ dir = 1 }, +/obj/structure/extinguisher_cabinet{ + name = "north extinguisher cabinet"; + pixel_y = 30 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "bluecorner" @@ -66524,10 +66437,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/item/radio/intercom{ - name = "east station intercom (General)"; - pixel_x = 28 - }, /obj/machinery/atmospherics/unary/vent_pump/on, /obj/structure/cable{ icon_state = "1-2" @@ -66763,10 +66672,6 @@ dir = 8 }, /obj/effect/landmark/join_late_cyborg, -/obj/item/radio/intercom{ - name = "west station intercom (General)"; - pixel_x = -28 - }, /obj/machinery/computer/cryopod/robot{ pixel_x = -30; pixel_y = 30 @@ -66914,8 +66819,8 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint) "dla" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, /turf/simulated/floor/plating, /area/maintenance/asmaint) @@ -67164,18 +67069,16 @@ }, /area/aisat/maintenance) "dlN" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/universal, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/structure/disposalpipe/junction{ + icon_state = "pipe-y" }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "dlO" = ( -/obj/structure/chair/stool, -/obj/effect/spawner/lootdrop/maintenance, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/universal, /turf/simulated/floor/plating, /area/maintenance/asmaint) "dlP" = ( @@ -67372,13 +67275,9 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dmq" = ( -/obj/effect/spawner/lootdrop/maintenance, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/item/twohanded/required/kirbyplants, +/turf/simulated/floor/wood, +/area/lawoffice) "dmr" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance/double, @@ -67402,10 +67301,12 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint) "dmu" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/spawner/window/reinforced, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/assembly/robotics) "dmv" = ( /obj/structure/cable{ icon_state = "4-8" @@ -67494,9 +67395,11 @@ /turf/simulated/floor/engine/insulated, /area/maintenance/turbine) "dmF" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/visible/purple, -/turf/space, +/obj/structure/disposaloutlet, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/simulated/floor/plating/airless, /area/maintenance/asmaint) "dmG" = ( /obj/effect/spawner/window/reinforced, @@ -67555,9 +67458,10 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dmN" = ( +/obj/effect/spawner/window/reinforced, /obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/airless, -/area/maintenance/asmaint2) +/turf/simulated/floor/plating, +/area/maintenance/asmaint) "dmO" = ( /obj/structure/cable{ d2 = 2; @@ -67639,12 +67543,13 @@ }, /area/aisat) "dmW" = ( -/obj/structure/transit_tube, +/obj/structure/transit_tube/horizontal, +/obj/structure/lattice, /turf/space, /area/space) "dmX" = ( -/obj/structure/transit_tube{ - icon_state = "E-W-Pass" +/obj/structure/transit_tube/junction{ + dir = 8 }, /obj/structure/lattice, /turf/space, @@ -67666,12 +67571,12 @@ }, /area/turret_protected/ai) "dmZ" = ( -/obj/structure/transit_tube, /obj/effect/spawner/window/reinforced, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plating, /area/turret_protected/aisat_interior) "dna" = ( -/obj/structure/transit_tube, +/obj/structure/transit_tube/horizontal, /turf/simulated/floor/plating, /area/turret_protected/aisat_interior) "dnb" = ( @@ -67704,10 +67609,7 @@ }, /area/turret_protected/ai) "dng" = ( -/obj/machinery/atmospherics/unary/outlet_injector/on{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, +/turf/space, /area/maintenance/asmaint) "dni" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -67767,21 +67669,18 @@ /obj/machinery/atmospherics/unary/portables_connector{ dir = 8 }, +/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dno" = ( -/obj/structure/transit_tube{ - dir = 8; - icon_state = "Block" +/obj/structure/transit_tube/cap{ + dir = 8 }, /turf/simulated/floor/plating, /area/turret_protected/aisat_interior) "dnp" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/structure/disposaloutlet, -/turf/simulated/floor/plating/airless, +/obj/structure/lattice, +/turf/space, /area/maintenance/asmaint2) "dnq" = ( /obj/structure/cable{ @@ -68045,16 +67944,6 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint) "dnQ" = ( -/obj/machinery/access_button{ - command = "cycle_interior"; - frequency = 1450; - master_tag = "sci_maint"; - name = "interior access button"; - pixel_x = -28; - pixel_y = -5; - req_access = list(13) - }, -/obj/effect/decal/warning_stripes/west, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 6 }, @@ -68542,6 +68431,9 @@ pixel_x = -24 }, /obj/machinery/portable_atmospherics/canister/air, +/obj/item/radio/intercom{ + pixel_y = 23 + }, /turf/simulated/floor/plating, /area/aisat/atmospherics) "dpD" = ( @@ -68599,6 +68491,9 @@ }, /obj/item/stack/sheet/mineral/plasma, /obj/item/clothing/head/welding, +/obj/item/radio/intercom{ + pixel_y = 23 + }, /turf/simulated/floor/plating, /area/aisat/maintenance) "dpM" = ( @@ -68873,15 +68768,16 @@ pixel_y = 7 }, /obj/item/pen/multi, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -22 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" }, /area/turret_protected/ai) "drq" = ( -/obj/machinery/alarm{ - pixel_y = 24 - }, /obj/structure/chair{ dir = 8 }, @@ -69231,7 +69127,10 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/engineering) "dsP" = ( @@ -69267,12 +69166,12 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/plating, -/area/maintenance/engineering) -"dsW" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) +"dsW" = ( +/turf/simulated/wall/r_wall, +/area/space) "dsX" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -69485,10 +69384,9 @@ }, /area/quartermaster/office) "dAN" = ( -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/security/detectives_office) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/east) "dBn" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock{ @@ -69817,17 +69715,6 @@ /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, /area/security/range) -"dVs" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "dVu" = ( /obj/structure/table, /obj/machinery/alarm{ @@ -70018,6 +69905,12 @@ icon_state = "cafeteria" }, /area/crew_quarters/kitchen) +"eiL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/central/south) "eja" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable{ @@ -70545,6 +70438,9 @@ name = "south newscaster"; pixel_y = -31 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "eKG" = ( @@ -70845,36 +70741,16 @@ /turf/simulated/floor/plating, /area/security/warden) "eZr" = ( -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) -"eZu" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" +/obj/structure/chair{ + dir = 8 }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" +/obj/effect/landmark/start/security_officer, +/obj/item/radio/intercom/department/security{ + name = "north station intercom (Security)"; + pixel_y = 25 }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) +/turf/simulated/floor/plasteel, +/area/security/main) "eZH" = ( /obj/structure/reagent_dispensers/watertank, /obj/machinery/atmospherics/unary/vent_pump/on, @@ -70883,21 +70759,6 @@ icon_state = "whitepurple" }, /area/toxins/launch) -"eZP" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "fba" = ( /obj/structure/cable{ d2 = 2; @@ -71749,20 +71610,15 @@ }, /area/security/brig) "fVD" = ( -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" +/obj/machinery/light/small{ + dir = 4 }, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" +/obj/item/radio/intercom{ + name = "east station intercom (General)"; + pixel_x = 28 }, /turf/simulated/floor/plating, -/area/crew_quarters/dorms) +/area/maintenance/genetics) "fWY" = ( /obj/structure/cable{ icon_state = "2-4" @@ -71973,10 +71829,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, @@ -71984,6 +71836,7 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -72163,10 +72016,6 @@ dir = 1 }, /obj/effect/turf_decal/siding/wood/corner, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -72182,7 +72031,6 @@ }, /area/security/range) "gwS" = ( -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "yellow" @@ -72462,6 +72310,17 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/simulated/floor/plating, /area/maintenance/asmaint2) +"gNo" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/medical/morgue) "gNq" = ( /obj/effect/spawner/random_spawners/grille_maybe, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -73248,7 +73107,8 @@ dir = 4 }, /obj/structure/disposalpipe/segment{ - dir = 4 + dir = 2; + icon_state = "pipe-c" }, /turf/simulated/floor/plasteel{ dir = 8; @@ -73630,17 +73490,14 @@ /turf/simulated/floor/plating, /area/maintenance/cafeteria) "ibg" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" +/obj/machinery/light_switch{ + name = "south light switch"; + pixel_y = -24 }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" +/turf/simulated/floor/plasteel{ + icon_state = "whiteblue" }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) +/area/medical/sleeper) "ibv" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 @@ -74305,22 +74162,6 @@ }, /turf/simulated/floor/carpet/purple, /area/maintenance/server) -"iOx" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "iPr" = ( /turf/simulated/floor/plasteel{ icon_state = "darkblue" @@ -74406,27 +74247,11 @@ /area/crew_quarters/bar/atrium) "iYB" = ( /obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 }, /turf/simulated/floor/plating, /area/maintenance/asmaint) -"iZs" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "iZN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dust, @@ -74620,7 +74445,6 @@ /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar) "jkT" = ( @@ -74856,6 +74680,13 @@ /obj/effect/spawner/random_spawners/cobweb_right_frequent, /turf/simulated/floor/plating, /area/maintenance/apmaint) +"jvb" = ( +/obj/structure/transit_tube/curved{ + dir = 4 + }, +/obj/structure/lattice, +/turf/space, +/area/space) "jvC" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 @@ -75110,6 +74941,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/engineering) "jSX" = ( @@ -75439,9 +75271,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -75499,21 +75328,6 @@ icon_state = "dark" }, /area/security/warden) -"kjf" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "kjl" = ( /obj/machinery/door_control{ id = "maint_house"; @@ -75560,6 +75374,10 @@ pixel_y = -30 }, /obj/machinery/papershredder, +/obj/machinery/alarm{ + dir = 8; + pixel_x = 24 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "darkblue" @@ -75983,7 +75801,7 @@ /area/medical/cloning) "kIR" = ( /obj/structure/lattice/catwalk, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, +/obj/machinery/atmospherics/pipe/simple/visible/yellow, /turf/space, /area/space) "kJr" = ( @@ -76394,6 +76212,13 @@ /obj/structure/girder, /turf/simulated/floor/plating, /area/maintenance/asmaint) +"lll" = ( +/obj/structure/transit_tube/curved/flipped{ + dir = 4 + }, +/obj/structure/lattice, +/turf/space, +/area/space) "llO" = ( /obj/item/radio/intercom{ name = "north station intercom (General)"; @@ -77114,9 +76939,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/junction{ - dir = 4; - icon_state = "pipe-j2" +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) @@ -78255,6 +78080,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "njA" = ( @@ -78502,6 +78331,12 @@ icon_state = "neutralfull" }, /area/maintenance/engineering) +"ntA" = ( +/obj/structure/sign/poster/random{ + pixel_x = 32 + }, +/turf/simulated/floor/wood, +/area/library) "nui" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -78717,6 +78552,17 @@ icon_state = "dark" }, /area/hydroponics) +"nKh" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "yellowcorner" + }, +/area/hallway/primary/aft) "nKt" = ( /obj/structure/rack{ dir = 1 @@ -78937,18 +78783,6 @@ icon_state = "whitepurple" }, /area/toxins/launch) -"nYU" = ( -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/grille, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "nZS" = ( /obj/effect/decal/warning_stripes/northwest, /obj/machinery/atmospherics/unary/portables_connector, @@ -79134,18 +78968,6 @@ icon_state = "cafeteria" }, /area/medical/research/restroom) -"ooN" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "ooS" = ( /obj/structure/cable{ d1 = 1; @@ -79406,10 +79228,6 @@ }, /area/hydroponics) "oHW" = ( -/obj/machinery/alarm{ - dir = 4; - pixel_x = -24 - }, /obj/structure/sink{ dir = 8; pixel_x = -12; @@ -80162,8 +79980,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" + dir = 4 }, /turf/simulated/floor/plating, /area/maintenance/engineering) @@ -80244,7 +80061,8 @@ /obj/machinery/computer/crew, /obj/item/radio/intercom{ name = "east station intercom (General)"; - pixel_x = 28 + pixel_x = 28; + pixel_y = 5 }, /turf/simulated/floor/plasteel{ dir = 5; @@ -80635,6 +80453,10 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/asmaint) +"qbk" = ( +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/space) "qbw" = ( /obj/effect/turf_decal/siding/wood{ dir = 5 @@ -80884,7 +80706,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/hallway/primary/aft) "qlm" = ( @@ -81400,6 +81221,10 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, /turf/simulated/floor/wood/fancy/cherry, /area/crew_quarters/bar/atrium) "qKo" = ( @@ -81635,6 +81460,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/carpet, /area/lawoffice) "qTv" = ( @@ -81716,6 +81542,11 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/apmaint) +"qYV" = ( +/obj/structure/transit_tube/crossing/horizontal, +/obj/structure/lattice/catwalk, +/turf/space, +/area/space) "qZx" = ( /obj/structure/table/glass, /obj/item/clipboard, @@ -81957,21 +81788,6 @@ /obj/structure/table, /turf/simulated/floor/plating, /area/storage/secure) -"rmc" = ( -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/grille, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "rmn" = ( /obj/structure/closet/secure_closet/cargotech, /obj/effect/decal/warning_stripes/yellow/hollow, @@ -82204,6 +82020,16 @@ /obj/machinery/light{ dir = 8 }, +/obj/machinery/requests_console{ + department = "Warden"; + departmentType = 7; + name = "Warden's Requests Console"; + pixel_x = -30 + }, +/obj/machinery/firealarm{ + name = "north fire alarm"; + pixel_y = 24 + }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "darkred" @@ -82290,22 +82116,6 @@ }, /turf/simulated/floor/engine, /area/toxins/mixing) -"rFJ" = ( -/obj/structure/cable/yellow, -/obj/structure/window/reinforced/polarized{ - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "ceoffice" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "ceoffice" - }, -/obj/structure/grille, -/turf/simulated/floor/plating, -/area/engine/chiefs_office) "rGg" = ( /obj/structure/cable{ icon_state = "1-2" @@ -82337,7 +82147,8 @@ "rIF" = ( /obj/item/radio/intercom{ name = "east station intercom (General)"; - pixel_x = 28 + pixel_x = 28; + pixel_y = 5 }, /obj/machinery/flasher{ id = "brigmedflash"; @@ -82853,6 +82664,13 @@ }, /turf/simulated/floor/engine, /area/toxins/mixing) +"spb" = ( +/obj/structure/transit_tube/curved/flipped{ + dir = 8 + }, +/obj/structure/lattice, +/turf/space, +/area/space) "sqy" = ( /obj/machinery/light, /turf/simulated/floor/plasteel{ @@ -83003,6 +82821,12 @@ icon_state = "darkred" }, /area/security/prisonershuttle) +"szF" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/west) "szV" = ( /obj/structure/chair/stool, /turf/simulated/floor/plasteel{ @@ -83083,7 +82907,7 @@ /area/hallway/primary/central/sw) "sDN" = ( /obj/structure/morgue{ - dir = 8 + dir = 1 }, /turf/simulated/floor/plasteel{ dir = 6; @@ -83906,6 +83730,19 @@ icon_state = "dark" }, /area/aisat) +"tvW" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/west) "txi" = ( /obj/structure/cable{ icon_state = "4-8" @@ -84135,10 +83972,33 @@ icon_state = "freezerfloor" }, /area/maintenance/apmaint) +"tGb" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/sortjunction{ + name = "Morgue"; + sortType = 25 + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/east) +"tGd" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/hallway/primary/starboard/east) "tGS" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/engine, /area/engine/mechanic_workshop) +"tGW" = ( +/obj/structure/transit_tube/curved{ + dir = 8 + }, +/obj/structure/lattice, +/turf/space, +/area/space) "tHc" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ @@ -84889,22 +84749,6 @@ /obj/item/toy/figure/assistant, /turf/simulated/floor/plasteel, /area/crew_quarters/locker) -"uND" = ( -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; - id = "holodeck" - }, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "holodeck" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/dorms) "uOI" = ( /obj/structure/door_assembly/door_assembly_research{ anchored = 1 @@ -85088,7 +84932,6 @@ /obj/item/stamp/qm, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/item/qm_quest_tablet{ - pixel_y = 0; pixel_x = -12 }, /turf/simulated/floor/plasteel, @@ -85133,7 +84976,6 @@ /turf/simulated/floor/plating, /area/maintenance/port) "uXX" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, @@ -85143,6 +84985,10 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/disposalpipe/junction{ + dir = 1; + icon_state = "pipe-j2" + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -85688,6 +85534,10 @@ /obj/structure/mecha_wreckage/ripley/firefighter, /turf/simulated/floor/engine, /area/maintenance/server) +"vxQ" = ( +/obj/effect/decal/warning_stripes/northwest, +/turf/simulated/floor/plating, +/area/maintenance/asmaint2) "vyb" = ( /obj/effect/decal/cleanable/fungus, /turf/simulated/wall, @@ -85746,6 +85596,12 @@ icon_state = "dark" }, /area/security/warden) +"vBs" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/lawoffice) "vBJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -85962,6 +85818,10 @@ /obj/machinery/vending/snack, /obj/machinery/light, /obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -24 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "escape" @@ -86141,6 +86001,10 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -86633,16 +86497,6 @@ "wtL" = ( /turf/simulated/wall/r_wall, /area/maintenance/xenozoo) -"wuv" = ( -/obj/machinery/light_switch{ - name = "east light switch"; - pixel_x = 24 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "escape" - }, -/area/security/customs2) "wvx" = ( /obj/structure/table/reinforced, /obj/item/gun/energy/laser/practice, @@ -87215,10 +87069,6 @@ pixel_y = -32 }, /obj/effect/decal/warning_stripes/south, -/obj/item/radio/intercom{ - name = "east station intercom (General)"; - pixel_x = 28 - }, /turf/simulated/floor/plasteel, /area/hallway/secondary/entry) "xcT" = ( @@ -87334,6 +87184,9 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "xgd" = ( @@ -88231,16 +88084,7 @@ /turf/simulated/floor/carpet, /area/civilian/vacantoffice) "yjM" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 4; - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - id = "holodeck" - }, -/obj/structure/window/reinforced/polarized{ - dir = 8; +/obj/effect/spawner/window/reinforced/polarized{ id = "holodeck" }, /turf/simulated/floor/plating, @@ -111340,7 +111184,7 @@ cwF cvo cER hFD -ckO +cYw cJZ cLy cLi @@ -111865,7 +111709,7 @@ cKb cRC cRC cUc -cRG +cJk cNB cLi uTI @@ -112122,7 +111966,7 @@ cLq cRK cRC cRC -cRG +cJk cWn cOx uTI @@ -112379,7 +112223,7 @@ cLv cRE cSS cKb -cRG +cJk cNB cOx uTI @@ -112636,7 +112480,7 @@ cLv cRE cTd cKb -cRG +cJk cNB cLi lTl @@ -112893,7 +112737,7 @@ cOr cOV cKb cKb -cRG +cJk cNB cLi cLi @@ -113342,7 +113186,7 @@ aUF bfe bhP bmk -aUF +cSX cZa aSA djW @@ -113408,8 +113252,8 @@ cPb dsG dsG dsO -dsW -dsW +cNB +cNB pzr cZw dar @@ -113565,8 +113409,8 @@ uQe fYH aef ago -aie -gSV +akV +bFk alc anZ aqY @@ -113652,7 +113496,7 @@ cng cvp cFa cFt -cGl +cfl cGW cKe cLC @@ -113825,9 +113669,9 @@ hdV aig ajO ald -aKs -aKs -asN +cZE +cZE +bkN qTn avS avN @@ -113909,7 +113753,7 @@ uTI uTI cFa cFk -cGi +cGp ckO cKf pKG @@ -114079,8 +113923,8 @@ ahu afs aeg ago -aie -atE +aso +aHQ alc aob ara @@ -114166,7 +114010,7 @@ cCM uTI cFa cFt -cGi +cGp ckO cKb cLE @@ -114341,11 +114185,11 @@ ajQ alc aoe aMO -aod -aod +dmq +vBs avW -aod -aod +bNl +dmq aoe aAI aCb @@ -114423,7 +114267,7 @@ cwU uTI cFa cFl -cGi +cGp ckO cKb cKb @@ -114599,7 +114443,7 @@ aIo aod aod aIo -avd +axu avT axu aIo @@ -114680,7 +114524,7 @@ cCN uTI cFa cFt -cGi +cGp ckO cKf cLD @@ -114937,7 +114781,7 @@ cwV cvq cvq cFt -cGi +cGp ckO cKf cLG @@ -115107,7 +114951,7 @@ tUB afv aeg aqX -aie +aso ajR alo aAz @@ -115194,7 +115038,7 @@ cCO cEd cvx cFt -cGg +bcs vJo cKf cLF @@ -115451,7 +115295,7 @@ jQO cDW cvx cFk -cGi +cGp ckO cKb cJx @@ -115708,7 +115552,7 @@ cwO cEe cvx cFt -cGi +cGp ckO cKb cJx @@ -115965,7 +115809,7 @@ cwO cEe cvx cFt -cGi +cGp ckO cKb cLH @@ -116201,7 +116045,7 @@ bXr ljb cbe bZd -cdN +eiL cgh vJM cgZ @@ -116479,7 +116323,7 @@ cAL cDY cvx cFt -cGi +cGp ckO cKk ckO @@ -116736,12 +116580,12 @@ cvx cvx cvx cFr -cfl -cHG +cGp +cHD qkZ -cHG -cJk -cfz +cHD +cJl +cHD cHD cNS cJZ @@ -116926,7 +116770,7 @@ aDm aFy aFF aFF -aUq +bNq aGx aFF aSN @@ -116997,10 +116841,10 @@ cGp cHD cHL cHD -cHI -cjb +cJl cHD -cMV +cHD +nKh cJZ cRR cPl @@ -117163,7 +117007,7 @@ aov api eZh ago -akV +aso alb anI nrc @@ -117181,7 +117025,7 @@ aCo aCJ aDl aEh -aFx +aHq aHq aIr aKg @@ -117438,7 +117282,7 @@ aCx aDk aFF aFF -aGx +aFF aHT aIO aKz @@ -117695,7 +117539,7 @@ aEi aFw aFw aFw -aJh +aFw aKy aEj aPb @@ -117744,7 +117588,7 @@ gpA iVV iVV cex -bKQ +cNf bwN chc chc @@ -117777,7 +117621,7 @@ cRR cTg cFC cHa -rFJ +cHk cRR cRR cZP @@ -118738,8 +118582,8 @@ aRx bdN bgT biR -bpR -cSX +boU +cUi dgH aDN bhq @@ -118956,7 +118800,7 @@ acy aiv xzR asn -wuv +amJ amJ aoD apE @@ -120009,7 +119853,7 @@ axe aGF aIg aJo -aKD +bax axe aNU aLP @@ -120266,7 +120110,7 @@ axe aGE aIg aJo -aKC +aKD axe aNU aOI @@ -120292,7 +120136,7 @@ uTI uTI diP bsJ -byu +byA bwf bxv byX @@ -120523,7 +120367,7 @@ axe fyo aIg aJo -dAN +aKC axe aNU aOI @@ -120549,7 +120393,7 @@ uTI uTI bmi bsL -byu +byA bwi bxv aZO @@ -120599,7 +120443,7 @@ cJE cLJ cGK cTh -cTh +bHJ cSb cTh cCp @@ -120806,7 +120650,7 @@ bmi bmi bmi bsK -byu +byA bwh bxv bxv @@ -121321,8 +121165,8 @@ bpA bpA bvD byx -aTH -aTH +bpA +bpA bEg bFi bHo @@ -122097,7 +121941,7 @@ bxx djh bAh bHy -bAk +bCZ bEp aTT bCW @@ -122294,7 +122138,7 @@ vZX nCT qFz wxU -cfY +aoJ adY amm amN @@ -122551,7 +122395,7 @@ ags lio qOo wxU -alF +eZr alF alF amQ @@ -122683,9 +122527,9 @@ dkT cQZ doE lTl -lTl +uTI dmX -lTl +uTI lTl uTI uTI @@ -122868,7 +122712,7 @@ bJQ eWm bAk bHy -btX +buW bEp aTU bDf @@ -122940,9 +122784,9 @@ cQZ cQZ doE lTl -uTI -dmW -uTI +lll +lTl +jvb lTl uTI uTI @@ -123196,11 +123040,11 @@ dkV dkV cQZ doE -lTl -uTI -dmW -uTI -lTl +doE +qYV +doE +qYV +doE uTI uTI uTI @@ -123400,7 +123244,7 @@ caA caA bXJ bZk -ccu +ibg caA cfA chl @@ -123454,10 +123298,10 @@ dlx cQZ doE lTl -uTI -dmW -uTI +tGW lTl +spb +doE uTI uTI iUc @@ -123710,10 +123554,10 @@ dkV dkV cQZ doE -doE -doE +uTI +uTI ddC -doE +uTI ddM ddO kIR @@ -124149,7 +123993,7 @@ kZd vDP brf wPc -jtW +cxO dnk bAk bHy @@ -126169,17 +126013,17 @@ awH ayg awF awl -eZu -ooN -eZP +yjM +yjM +yjM xyo -eZu -eZr +yjM +yjM xyo -iOx -ibg -ibg -dVs +yjM +yjM +yjM +yjM aPk aVw aVP @@ -126436,7 +126280,7 @@ sHt sHt sHt sHt -aOh +yjM xVt aPm aSM @@ -126693,7 +126537,7 @@ sHt sHt sHt sHt -aOh +yjM xVt pWb aNQ @@ -126950,7 +126794,7 @@ pwU sHt sHt sHt -kjf +yjM aBm aPm aSM @@ -127241,7 +127085,7 @@ bAk bEu aYo bLj -bHJ +aZT bEu bMY bOV @@ -127493,8 +127337,8 @@ bwr eVW bzh bAk -bHA -bJb +tvW +szF aTN aYl bEx @@ -127711,12 +127555,12 @@ ylx ylx ylx atG -iZs +yjM yjM aOI xyo -uND -fVD +yjM +yjM xyo aOI aOI @@ -127750,11 +127594,11 @@ bwr rUR beb bAk -bHy +aJh bAk bEu aYr -bbA +gNo bHL bEu bLK @@ -128007,11 +127851,11 @@ ioG beb beb bAp -bHy +aJh bCZ bEu aYq -aZT +bMZ bHK bKe bFX @@ -128264,7 +128108,7 @@ jtT blb bzk bAs -bHy +aJh bAk bEu aZU @@ -128323,7 +128167,7 @@ cJu cKw cJt cLZ -cNf +cBQ dbE cyJ chf @@ -128485,9 +128329,9 @@ uTI uTI uTI aOI -aFK -nYU -rmc +yjM +yjM +yjM aOI aOI aIF @@ -128521,11 +128365,11 @@ xhE jtT bzj bAr -bHy +aJh buW bEu qzo -bMZ +aZT bOX bOX bOX @@ -128580,7 +128424,7 @@ cJt cJt cIj cIj -cNf +cBQ dbE fDl chf @@ -128592,7 +128436,7 @@ chf dkZ cUm cYg -csL +dmr cBP uTI uTI @@ -128778,7 +128622,7 @@ hZf jtT jjn bAr -bHy +aJh bAk bEu bob @@ -128837,7 +128681,7 @@ cJv cKA cJt cMc -cNf +cBQ dbE cyJ chf @@ -128849,9 +128693,9 @@ lsc dkS dlA dfM -csL +cjb cBQ -uTI +afO uTI uTI uTI @@ -129017,7 +128861,7 @@ kKR kKR qKL qKL -bjk +aGY bcb beb dhs @@ -129035,7 +128879,7 @@ hQc vbu bzk bAr -bHy +aJh bJc bEu bby @@ -129094,7 +128938,7 @@ csL cIj cKS cMb -cNf +cBQ kIe eMx dgZ @@ -129104,10 +128948,10 @@ djm eUX chf dla -cps +csL dlN -dml -dmt +cYi +dmN dmF dng uTI @@ -129361,11 +129205,11 @@ chf iDA dwF iYB -cYg +cYR dlO -dmr -cBQ -uTI +dml +dmt +bjk uTI uTI uTI @@ -129531,7 +129375,7 @@ aMz aGX aMz aMz -bkt +vnb bck beb bdV @@ -129788,7 +129632,7 @@ aGX aTZ fyD aGX -bkI +doE bcn beb bdW @@ -130045,7 +129889,7 @@ dvr yig oVG aHP -bkt +vnb bck beb bei @@ -130084,7 +129928,7 @@ bXQ caY bWg ceq -cfZ +fVD chG ciZ cga @@ -130302,7 +130146,7 @@ aMz aGX aGX aGX -bkN +aGY bcm beb beb @@ -130559,24 +130403,24 @@ aCO gwT aGX aWb -aYK -bct bfn -bfR -bfR -bfR -bfR -bfR -bfR -bfR -bfR -bfR +bct +bkI +bkI +bkI +bkI +bkI +bkI +bkI +bkI +bkI +bkI bPx byQ bAW aVb bCN -bFk +bCN bHC bwv bKa @@ -130838,7 +130682,7 @@ bHH bKb bKb bKR -bLl +bUl bMV bLE bHX @@ -131333,7 +131177,7 @@ aWg aGY bau bau -btl +bjF bih bia bju @@ -131632,10 +131476,10 @@ coi cpV cSe crL -hHY +byu cvT cpR -cxO +cxD hSk cts mEo @@ -131846,9 +131690,9 @@ aGX aWA aYY bqj -aHQ +bfU bhx -bij +bfU bkp bfU bfU @@ -131889,10 +131733,10 @@ cod cpR csA crL -hHY +byu crL cpR -cxO +cxD cAe jnc kGe @@ -132104,9 +131948,9 @@ bbh bau bau bch -bem -bfY -bkn +bcp +bcp +bkK bcp blj blj @@ -132360,10 +132204,10 @@ aGX bbh bau bav -bci -btl -bfZ -bkn +bcp +bij +bij +bkK bcp blj blj @@ -132384,7 +132228,7 @@ bId bNh bPa bRy -bPo +dmu bPo bId crH @@ -132406,7 +132250,7 @@ crL cuS cpR cxI -cxO +cxD csr csr csr @@ -132617,10 +132461,10 @@ aGX bbh bau bao -bcs -beo +bci +bem +bfY beo -bkK bcp bcp blj @@ -132873,12 +132717,12 @@ kuS aGX bbh bau -bax -bcj +ntA +bci bep -bfT -wjB -bjF +bfZ +bkn +ntA bll bcp boG @@ -132920,7 +132764,7 @@ ctv cuX bIi cpI -cxO +cxD csr mRB cYu @@ -133177,7 +133021,7 @@ bYm cuV bIi bQX -cxO +cxD csr qwN qbV @@ -133400,7 +133244,7 @@ bpY buy btj buV -blj +cHG bxV bau bFs @@ -133434,7 +133278,7 @@ bLR cvF bIi cxU -cxO +cxD csr onN ugD @@ -133477,9 +133321,9 @@ bGG bGG dbg bGH -uTI -uTI -uTI +dsW +dsW +qbk uTI uTI uTI @@ -133657,7 +133501,7 @@ bqc wjB btb buV -blj +cHG bxW bau bwv @@ -133691,7 +133535,7 @@ ctC cvF bIi cxM -cxO +cxD csr mcq qAN @@ -133733,9 +133577,9 @@ bGH dlD dgy bGG -bGH -bGH -bGH +cuQ +vxQ +bkt bZZ bZZ bZZ @@ -133914,7 +133758,7 @@ bcp brA btl buV -blj +cHG bCS bau bFv @@ -133991,7 +133835,7 @@ dlJ bGG bGG cjA -dmb +bGG dnQ dnR dnS @@ -134171,12 +134015,12 @@ bqd brB brG buV -blj +cGl bCR bau bFu bkH -bwv +tGd bDq bGF bIi @@ -134433,7 +134277,7 @@ aYP aYP bFz bHQ -bJq +tGb bJq bKT bSz @@ -134450,7 +134294,7 @@ ccp cdL ceN chO -bNl +bJk cln mbq qqL @@ -134676,8 +134520,8 @@ bcu ber bga bis -bvN -bcD +daj +bLl bld blw bmI @@ -134685,8 +134529,8 @@ bmT buz brI buY -khg -bjD +day +cWJ aYP bFw bkL @@ -134707,7 +134551,7 @@ bJB bJB bJB chN -bNq +tml bTw tml vic @@ -134760,9 +134604,9 @@ cuQ cQC dlP bGG -dmq -dmu -dmN +cAU +bZZ +dnp dnp lTl uTI @@ -135017,10 +134861,8 @@ cuQ cJQ bGG bGG -cZE -bGH -lTl -lTl +bGG +bZZ lTl uTI uTI @@ -135036,6 +134878,8 @@ uTI uTI uTI uTI +uTI +uTI abp uTI uTI @@ -135200,7 +135044,7 @@ szV buA khg khg -bya +aYK aYQ bwv bkL @@ -135274,7 +135118,7 @@ cuQ cuQ cuQ cuQ -cZE +bGG bGH bGH uTI @@ -135457,10 +135301,10 @@ khg khg khg khg -khg -bEl -bwv -bkL +cHI +bcj +dAN +aFx bwv bDq bGL @@ -135531,7 +135375,7 @@ cQC dlj dlz cuQ -cZE +bGG dbg bGH lTl @@ -135780,15 +135624,15 @@ rOj oiL kZk ioj -cWJ +bGG cXz -cYw -cYw -cYw -cYw -cYR +bGG +bGG +bGG +bGG +bGG cuQ -cZE +bGG bPA bZZ uTI @@ -136043,9 +135887,9 @@ cuQ cuQ cuQ bGG -cZE +bGG cuQ -cZE +bGG cLh bZZ uTI @@ -136300,9 +136144,9 @@ cuQ uTI cuQ cuQ -daj +dgf cuQ -cZE +bGG bKl cMs lTl @@ -136557,9 +136401,9 @@ bZZ uTI bZZ bGG -cWJ -cYw -day +bGG +bGG +bGG cMs bGH uTI diff --git a/_maps/map_files/generic/CentComm.dmm b/_maps/map_files/generic/CentComm.dmm index 8fb0a518045..bf80e7554a1 100644 --- a/_maps/map_files/generic/CentComm.dmm +++ b/_maps/map_files/generic/CentComm.dmm @@ -6456,7 +6456,6 @@ height = 11; id = "specops_away"; name = "centcom bay 3"; - no_spin = 1; top_left_corner = 8; top_right_corner = 1; turf_type = /turf/simulated/floor; diff --git a/_maps/map_files/generic/z2_old.dmm b/_maps/map_files/generic/z2_old.dmm index b476204ac52..6bd31fac037 100644 --- a/_maps/map_files/generic/z2_old.dmm +++ b/_maps/map_files/generic/z2_old.dmm @@ -6116,7 +6116,6 @@ height = 11; id = "specops_away"; name = "centcom bay 3"; - no_spin = 1; top_left_corner = 8; top_right_corner = 1; width = 5 diff --git a/_maps/map_files/shuttles/ferry_meat.dmm b/_maps/map_files/shuttles/ferry_meat.dmm index 558df020698..aca9a9bee30 100644 --- a/_maps/map_files/shuttles/ferry_meat.dmm +++ b/_maps/map_files/shuttles/ferry_meat.dmm @@ -50,8 +50,8 @@ /obj/item/grenade/clusterbuster/meat, /obj/item/reagent_containers/food/snacks/meat/corgi, /obj/item/reagent_containers/food/snacks/meat/ham, -/obj/item/reagent_containers/food/snacks/meat/human, -/obj/item/reagent_containers/food/snacks/meat/monkey, +/obj/item/reagent_containers/food/snacks/meat/humanoid/human, +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /obj/item/reagent_containers/food/snacks/meat/pug, /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, /obj/item/reagent_containers/food/snacks/meat/syntiflesh, diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 552d5afef4d..dd9e9dc8f98 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -9,7 +9,7 @@ Pipes -> Pipelines Pipelines + Other Objects -> Pipe network */ /obj/machinery/atmospherics - anchored = 1 + anchored = TRUE resistance_flags = FIRE_PROOF max_integrity = 200 plane = GAME_PLANE @@ -17,21 +17,32 @@ Pipelines + Other Objects -> Pipe network active_power_usage = 0 power_channel = ENVIRON on_blueprints = TRUE - var/can_unwrench = 0 + layer = GAS_PIPE_HIDDEN_LAYER //under wires + /// Generic over VISIBLE and HIDDEN, should be less than 0.01, or you'll reorder non-pipe things. + var/layer_offset = 0.0 + /// Can this be unwrenched? + var/can_unwrench = FALSE /// Can this be put under a tile? var/can_be_undertile = FALSE - - var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber - var/connected_to = 1 //same as above, currently not used for anything - var/icon_connect_type = "" //"-supply" or "-scrubbers" - + /// If the machine is currently operating or not. + var/on = FALSE + + // Vars below this point are all pipe related + // I know not all subtypes are pipes, but this helps + + /// Type of pipes this machine can connect to + var/list/connect_types = list(CONNECT_TYPE_NORMAL) + /// What this machine is connected to + var/connected_to = CONNECT_TYPE_NORMAL + /// Icon suffix for connection, can be "-supply" or "-scrubbers" + var/icon_connect_type = "" + /// Directions to initialize in to grab pipes var/initialize_directions = 0 - + /// Pipe colour, not used for all subtypes var/pipe_color - var/obj/item/pipe/stored + /// Pipe image, not used for all subtypes var/image/pipe_image - layer = GAS_PIPE_HIDDEN_LAYER //under wires - var/layer_offset = 0.0 // generic over VISIBLE and HIDDEN, should be less than 0.01, or you'll reorder non-pipe things + /obj/machinery/atmospherics/New() if (!armor) @@ -50,13 +61,10 @@ Pipelines + Other Objects -> Pipe network SSair.atmos_machinery += src /obj/machinery/atmospherics/proc/atmos_init() - if(can_unwrench) - stored = new(src, make_from = src) // Updates all pipe overlays and underlays update_underlays() /obj/machinery/atmospherics/Destroy() - QDEL_NULL(stored) SSair.atmos_machinery -= src SSair.deferred_pipenet_rebuilds -= src for(var/mob/living/L in src) //ventcrawling is serious business @@ -72,7 +80,7 @@ Pipelines + Other Objects -> Pipe network radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) // Icons/overlays/underlays -/obj/machinery/atmospherics/update_icon() +/obj/machinery/atmospherics/update_icon_state() switch(level) if(1) plane = FLOOR_PLANE @@ -86,9 +94,8 @@ Pipelines + Other Objects -> Pipe network pipe_image.plane = HUD_PLANE /obj/machinery/atmospherics/proc/check_icon_cache() - if(!istype(SSair.icon_manager)) + if(!SSair.icon_manager) return FALSE - return TRUE /obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node) @@ -98,47 +105,37 @@ Pipelines + Other Objects -> Pipe network return node.pipe_color -/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) +/obj/machinery/atmospherics/proc/add_underlay(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type) if(node) if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor) - //underlays += SSair.icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node)) underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) else - //underlays += SSair.icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node)) underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) else if(T.transparent_floor) //we want to keep pipes under transparent floors connected normally underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) else - //underlays += SSair.icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color) underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type) /obj/machinery/atmospherics/proc/update_underlays() - if(check_icon_cache()) - return 1 - else - return 0 + return check_icon_cache() // Connect types /obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2) - var/i - var/list1[] = atmos1.connect_types - var/list2[] = atmos2.connect_types - for(i=1,i<=list1.len,i++) - var/j - for(j=1,j<=list2.len,j++) + var/list/list1 = atmos1.connect_types + var/list/list2 = atmos2.connect_types + for(var/i in 1 to length(list1)) + for(var/j in 1 to length(list2)) if(list1[i] == list2[j]) var/n = list1[i] return n return 0 /obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2) - var/i - var/list1[] = atmos1.connect_types - var/list2[] = pipe2.connect_types - for(i=1,i<=list1.len,i++) - var/j - for(j=1,j<=list2.len,j++) + var/list/list1 = atmos1.connect_types + var/list/list2 = pipe2.connect_types + for(var/i in 1 to length(list1)) + for(var/j in 1 to length(list2)) if(list1[i] == list2[j]) var/n = list1[i] return n @@ -182,7 +179,7 @@ Pipelines + Other Objects -> Pipe network //(De)construction /obj/machinery/atmospherics/attackby(obj/item/W, mob/user) var/turf/T = get_turf(src) - if(can_unwrench && istype(W, /obj/item/wrench)) + if(can_unwrench && W.tool_behaviour == TOOL_WRENCH) if(level == 1 && T.transparent_floor && istype(src, /obj/machinery/atmospherics/pipe)) to_chat(user, span_danger("You can't interact with something that's under the floor!")) return @@ -247,14 +244,11 @@ Pipelines + Other Objects -> Pipe network user.throw_at(general_direction, pressures/10, pressures/50) /obj/machinery/atmospherics/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - if(can_unwrench) - if(stored) - stored.forceMove(get_turf(src)) - if(!disassembled) - stored.obj_integrity = stored.max_integrity * 0.5 - transfer_fingerprints_to(stored) - stored = null + if(can_unwrench && !(flags & NODECONSTRUCT)) + var/obj/item/pipe/stored = new(loc, null, null, src) + if(!disassembled) + stored.obj_integrity = stored.max_integrity * 0.5 + transfer_fingerprints_to(stored) ..() /obj/machinery/atmospherics/on_construction(D, P, C) @@ -267,7 +261,8 @@ Pipelines + Other Objects -> Pipe network level = (T.intact || !can_be_undertile) ? 2 : 1 else level = 2 - update_icon() + + update_icon(UPDATE_ICON_STATE) add_fingerprint(usr) if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets SSair.machinery_to_construct.Add(src) @@ -283,7 +278,7 @@ Pipelines + Other Objects -> Pipe network build_network() // Find a connecting /obj/machinery/atmospherics in specified direction. -/obj/machinery/atmospherics/proc/findConnecting(var/direction) +/obj/machinery/atmospherics/proc/findConnecting(direction) for(var/obj/machinery/atmospherics/target in get_step(src,direction)) var/can_connect = check_connect_types(target, src) if(can_connect && (target.initialize_directions & get_dir(target,src))) @@ -319,9 +314,9 @@ Pipelines + Other Objects -> Pipe network user.remove_ventcrawl() user.forceMove(src.loc) user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.") - user.canmove = 0 + user.canmove = FALSE spawn(1) - user.canmove = 1 + user.canmove = TRUE /obj/machinery/atmospherics/AltClick(mob/living/user) user.handle_ventcrawl(src) @@ -329,7 +324,7 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/can_crawl_through() return 1 -/obj/machinery/atmospherics/proc/change_color(var/new_color) +/obj/machinery/atmospherics/proc/change_color(new_color) //only pass valid pipe colors please ~otherwise your pipe will turn invisible if(!pipe_color_check(new_color)) return @@ -338,9 +333,10 @@ Pipelines + Other Objects -> Pipe network update_icon() // Additional icon procs -/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction) +/obj/machinery/atmospherics/proc/universal_underlays(obj/machinery/atmospherics/node, direction) var/turf/T = get_turf(src) - if(!istype(T)) return + if(!istype(T)) + return if(node) var/node_dir = get_dir(src,node) if(node.icon_connect_type == "-supply") @@ -360,7 +356,7 @@ Pipelines + Other Objects -> Pipe network add_underlay_adapter(T, , direction, "-scrubbers") add_underlay_adapter(T, , direction, "") -/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays +/obj/machinery/atmospherics/proc/add_underlay_adapter(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type) //modified from add_underlay, does not make exposed underlays if(node) if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor) underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) @@ -384,3 +380,21 @@ Pipelines + Other Objects -> Pipe network //Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. /obj/machinery/atmospherics/proc/can_see_pipes() return TRUE + + +/** + * Turns the machine either on, or off. If this is done by a user, display a message to them. + * + * NOTE: Only applies to atmospherics machines which can be toggled on or off, such as pumps, or other devices. + * + * Arguments: + * * user - the mob who is toggling the machine. + */ +/obj/machinery/atmospherics/proc/toggle(mob/living/user) + if(!powered()) + return + on = !on + update_icon() + if(user) + to_chat(user, span_notice("You toggle [src] [on ? "on" : "off"].")) + diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 9a6d17301b8..55f0c97edb1 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -15,7 +15,7 @@ var/obj/machinery/power/generator/generator - anchored = 1 + anchored = TRUE density = 1 can_unwrench = 1 @@ -107,14 +107,20 @@ else side_inverted = FALSE to_chat(user, span_notice("You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.")) + update_appearance(UPDATE_DESC|UPDATE_ICON) + + +/obj/machinery/atmospherics/binary/circulator/update_desc(updates = ALL) + . = ..() desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side." -/obj/machinery/atmospherics/binary/circulator/update_icon() - ..() +/obj/machinery/atmospherics/binary/circulator/update_icon_state() //this gets called everytime atmos is updated in the circulator (alot) + ..() if(stat & (BROKEN|NOPOWER)) icon_state = "circ[side]-p" - else if(last_pressure_delta > 0) + return + if(last_pressure_delta > 0) if(last_pressure_delta > ONE_ATMOSPHERE) icon_state = "circ[side]-run" else @@ -122,4 +128,4 @@ else icon_state = "circ[side]-off" - return 1 + diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 429dc6eb3e2..f53ef614142 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -14,8 +14,8 @@ connect_types = list(1,2,3) //connects to regular, supply and scrubbers pipes - var/on = 0 - var/releasing = 1 //0 = siphoning, 1 = releasing + on = FALSE + var/releasing = TRUE // FALSE = siphoning, TRUE = releasing var/external_pressure_bound = ONE_ATMOSPHERE var/input_pressure_min = 0 @@ -61,23 +61,13 @@ air1.volume = 1000 air2.volume = 1000 -/obj/machinery/atmospherics/binary/volume_pump/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - add_underlay(T, node1, turn(dir, -180)) - add_underlay(T, node2, dir) -/obj/machinery/atmospherics/binary/dp_vent_pump/update_icon(var/safety = 0) - ..() +/obj/machinery/atmospherics/binary/dp_vent_pump/update_overlays() + . = ..() if(!check_icon_cache()) return - overlays.Cut() - var/vent_icon = "vent" var/turf/T = get_turf(src) @@ -92,7 +82,9 @@ else vent_icon += "[on ? "[releasing ? "out" : "in"]" : "off"]" - overlays += SSair.icon_manager.get_atmos_icon("device", , , vent_icon) + . += SSair.icon_manager.get_atmos_icon("device", state = vent_icon) + update_pipe_image() + /obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays() if(..()) @@ -198,11 +190,11 @@ if(signal.data["purge"]) pressure_checks &= ~1 - releasing = 0 + releasing = FALSE if(signal.data["stabilize"])//the fact that this was "stabalize" shows how many fucks people give about these wonders, none pressure_checks |= 1 - releasing = 1 + releasing = TRUE if(signal.data["set_input_pressure"] != null) input_pressure_min = between( diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index ebd0b09f2d1..d4e7df13f97 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -9,7 +9,7 @@ can_unwrench = 1 - var/on = 0 + on = FALSE var/target_pressure = ONE_ATMOSPHERE var/id = null @@ -25,7 +25,7 @@ radio_connection = null return ..() -/obj/machinery/atmospherics/binary/passive_gate/update_icon() +/obj/machinery/atmospherics/binary/passive_gate/update_icon_state() ..() icon_state = "[on ? "on" : "off"]" @@ -173,13 +173,9 @@ if(.) investigate_log("was set to [target_pressure] kPa by [key_name_log(usr)]", INVESTIGATE_ATMOS) -/obj/machinery/atmospherics/binary/passive_gate/proc/toggle() - if(powered()) - on = !on - update_icon() /obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params) - if(!istype(W, /obj/item/wrench)) + if(W.tool_behaviour != TOOL_WRENCH) return ..() if(on) to_chat(user, span_alert("You cannot unwrench this [src], turn it off first.")) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 79e7f3a0392..8ff332a4f27 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -21,7 +21,7 @@ Thus, the two variables affect pump operation are set in New(): can_unwrench = 1 - var/on = 0 + on = FALSE var/target_pressure = ONE_ATMOSPHERE var/id = null @@ -54,10 +54,6 @@ Thus, the two variables affect pump operation are set in New(): set_max() return ..() -/obj/machinery/atmospherics/binary/pump/proc/toggle() - if(powered()) - on = !on - update_icon() /obj/machinery/atmospherics/binary/pump/proc/set_max() if(powered()) @@ -74,7 +70,7 @@ Thus, the two variables affect pump operation are set in New(): icon_state = "map_on" on = 1 -/obj/machinery/atmospherics/binary/pump/update_icon() +/obj/machinery/atmospherics/binary/pump/update_icon_state() ..() if(!powered()) @@ -226,17 +222,16 @@ Thus, the two variables affect pump operation are set in New(): if(.) investigate_log("was set to [target_pressure] kPa by [key_name_log(usr)]", INVESTIGATE_ATMOS) -/obj/machinery/atmospherics/binary/pump/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/binary/pump/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/binary/pump/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) rename_interactive(user, W) return - else if(!istype(W, /obj/item/wrench)) + else if(W.tool_behaviour != TOOL_WRENCH) return ..() if(!(stat & NOPOWER) && on) to_chat(user, span_alert("You cannot unwrench this [src], turn it off first.")) diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index 6ec97f49ef7..cb45bd86a2a 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -7,7 +7,9 @@ can_unwrench = 1 - var/open = 0 + var/open = FALSE + var/animating = FALSE + /obj/machinery/atmospherics/binary/valve/examine(mob/user) . = ..() @@ -17,11 +19,10 @@ open = 1 icon_state = "map_valve1" -/obj/machinery/atmospherics/binary/valve/update_icon(animation) +/obj/machinery/atmospherics/binary/valve/update_icon_state() ..() - - if(animation) - flick("valve[src.open][!src.open]",src) + if(animating) + flick("valve[open][!open]",src) else icon_state = "valve[open]" @@ -35,8 +36,8 @@ add_underlay(T, node2, get_dir(src, node2)) /obj/machinery/atmospherics/binary/valve/proc/open() - open = 1 - update_icon() + open = TRUE + update_icon(UPDATE_ICON_STATE) parent1.update = 0 parent2.update = 0 parent1.reconcile_air() @@ -44,8 +45,8 @@ return /obj/machinery/atmospherics/binary/valve/proc/close() - open = 0 - update_icon() + open = FALSE + update_icon(UPDATE_ICON_STATE) investigate_log("was closed by [usr ? key_name_log(usr) : "a remote signal"]", INVESTIGATE_ATMOS) return @@ -58,8 +59,10 @@ /obj/machinery/atmospherics/binary/valve/attack_hand(mob/user) add_fingerprint(usr) - update_icon(1) + animating = TRUE + update_icon(UPDATE_ICON_STATE) sleep(10) + animating = FALSE if(open) close() else @@ -97,13 +100,12 @@ open = 1 icon_state = "map_valve1" -/obj/machinery/atmospherics/binary/valve/digital/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/binary/valve/digital/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) -/obj/machinery/atmospherics/binary/valve/digital/update_icon() +/obj/machinery/atmospherics/binary/valve/digital/update_icon_state() ..() if(!powered()) icon_state = "valve[open]nopower" diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 8c6f529924e..6b43a2a078c 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -21,7 +21,7 @@ Thus, the two variables affect pump operation are set in New(): can_unwrench = 1 - var/on = 0 + on = FALSE var/transfer_rate = 200 var/id = null @@ -54,10 +54,6 @@ Thus, the two variables affect pump operation are set in New(): set_max() return ..() -/obj/machinery/atmospherics/binary/volume_pump/proc/toggle() - if(powered()) - on = !on - update_icon() /obj/machinery/atmospherics/binary/volume_pump/proc/set_max() if(powered()) @@ -78,7 +74,7 @@ Thus, the two variables affect pump operation are set in New(): ..() set_frequency(frequency) -/obj/machinery/atmospherics/binary/volume_pump/update_icon() +/obj/machinery/atmospherics/binary/volume_pump/update_icon_state() ..() if(!powered()) @@ -223,17 +219,16 @@ Thus, the two variables affect pump operation are set in New(): if(.) investigate_log("was set to [transfer_rate] L/s by [key_name_log(usr)]", INVESTIGATE_ATMOS) -/obj/machinery/atmospherics/binary/volume_pump/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/binary/volume_pump/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/binary/volume_pump/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) rename_interactive(user, W) return - else if(!istype(W, /obj/item/wrench)) + else if(W.tool_behaviour != TOOL_WRENCH) return ..() if(!(stat & NOPOWER) && on) to_chat(user, span_alert("You cannot unwrench this [src], turn it off first.")) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index e3b9843331f..4b289ff3976 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -59,10 +59,6 @@ set_max() return ..() -/obj/machinery/atmospherics/trinary/filter/proc/toggle() - if(powered()) - on = !on - update_icon() /obj/machinery/atmospherics/trinary/filter/proc/set_max() if(powered()) @@ -79,7 +75,7 @@ icon_state = "mmap" flipped = 1 -/obj/machinery/atmospherics/trinary/filter/update_icon() +/obj/machinery/atmospherics/trinary/filter/update_icon_state() ..() if(flipped) @@ -93,7 +89,7 @@ icon_state += on ? "on" : "off" else icon_state += "off" - on = 0 + on = FALSE /obj/machinery/atmospherics/trinary/filter/update_underlays() if(..()) @@ -111,11 +107,10 @@ add_underlay(T, node3, dir) -/obj/machinery/atmospherics/trinary/filter/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/trinary/filter/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/trinary/filter/process_atmos() ..() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index a8d3ad4b64b..ef33bee1320 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -44,17 +44,13 @@ icon_state = "mmap" flipped = 1 -/obj/machinery/atmospherics/trinary/mixer/proc/toggle() - if(powered()) - on = !on - update_icon() /obj/machinery/atmospherics/trinary/mixer/proc/set_max() if(powered()) target_pressure = MAX_OUTPUT_PRESSURE update_icon() -/obj/machinery/atmospherics/trinary/mixer/update_icon(safety = 0) +/obj/machinery/atmospherics/trinary/mixer/update_icon_state() ..() if(flipped) @@ -68,7 +64,7 @@ icon_state += on ? "on" : "off" else icon_state += "off" - on = 0 + on = FALSE /obj/machinery/atmospherics/trinary/mixer/update_underlays() if(..()) @@ -87,10 +83,9 @@ add_underlay(T, node3, dir) /obj/machinery/atmospherics/trinary/mixer/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() + if(!..()) + return + update_icon() /obj/machinery/atmospherics/trinary/mixer/New() ..() diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 5aaf574eb09..62b78c697e1 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -3,7 +3,7 @@ initialize_directions = SOUTH|NORTH|WEST use_power = IDLE_POWER_USE - var/on = 0 + on = FALSE layer = GAS_PIPE_VISIBLE_LAYER + GAS_FILTER_OFFSET layer_offset = GAS_FILTER_OFFSET diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm index 28b2e9158c9..669a6f32b6c 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm @@ -11,6 +11,7 @@ can_unwrench = 1 var/state = TVALVE_STATE_STRAIGHT + var/animation = FALSE /obj/machinery/atmospherics/trinary/tvalve/bypass icon_state = "map_tvalve1" @@ -25,7 +26,8 @@ flipped = 1 state = TVALVE_STATE_SIDE -/obj/machinery/atmospherics/trinary/tvalve/update_icon(animation) +/obj/machinery/atmospherics/trinary/tvalve/update_icon_state() + ..() var/flipstate = "" if(flipped) flipstate = "m" @@ -95,8 +97,10 @@ /obj/machinery/atmospherics/trinary/tvalve/attack_hand(mob/usermob) add_fingerprint(usr) - update_icon(1) + animation = TRUE + update_icon(UPDATE_ICON_STATE) sleep(10) + animation = FALSE switch_side() /obj/machinery/atmospherics/trinary/tvalve/digital // can be controlled by AI @@ -125,15 +129,13 @@ flipped = 1 state = TVALVE_STATE_SIDE -/obj/machinery/atmospherics/trinary/tvalve/digital/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/trinary/tvalve/digital/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) -/obj/machinery/atmospherics/trinary/tvalve/digital/update_icon() +/obj/machinery/atmospherics/trinary/tvalve/digital/update_icon_state() ..() - if(!powered()) icon_state = "tvalvenopower" diff --git a/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm b/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm index 5b98899daa9..396c7b7ec47 100644 --- a/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm @@ -7,20 +7,19 @@ name = "cold sink" desc = "Cools gas when connected to pipe network" - var/on = 0 + on = FALSE var/current_temperature = T20C var/current_heat_capacity = 50000 //totally random -/obj/machinery/atmospherics/unary/cold_sink/update_icon() +/obj/machinery/atmospherics/unary/cold_sink/update_icon_state() ..() if(node) icon_state = "intact_[on?("on"):("off")]" else icon_state = "exposed" - - on = 0 + on = FALSE /obj/machinery/atmospherics/unary/cold_sink/process_atmos() ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/generator_input.dm b/code/ATMOSPHERICS/components/unary_devices/generator_input.dm index 8aebc6f7d54..35a92f0c1fc 100644 --- a/code/ATMOSPHERICS/components/unary_devices/generator_input.dm +++ b/code/ATMOSPHERICS/components/unary_devices/generator_input.dm @@ -8,7 +8,7 @@ var/update_cycle -/obj/machinery/atmospherics/unary/generator_input/update_icon() +/obj/machinery/atmospherics/unary/generator_input/update_icon_state() ..() if(node) diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm index b64f24e5a66..67f9e576926 100644 --- a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm @@ -11,7 +11,7 @@ var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null var/update_cycle -/obj/machinery/atmospherics/unary/heat_exchanger/update_icon() +/obj/machinery/atmospherics/unary/heat_exchanger/update_icon_state() ..() if(node) diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm index 8415fc2d881..2459b3ca074 100644 --- a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm @@ -7,20 +7,19 @@ name = "heat reservoir" desc = "Heats gas when connected to pipe network" - var/on = 0 + on = FALSE var/current_temperature = T20C var/current_heat_capacity = 50000 //totally random -/obj/machinery/atmospherics/unary/heat_reservoir/update_icon() +/obj/machinery/atmospherics/unary/heat_reservoir/update_icon_state() ..() if(node) icon_state = "intact_[on?("on"):("off")]" else icon_state = "exposed" - - on = 0 + on = FALSE /obj/machinery/atmospherics/unary/heat_reservoir/process_atmos() ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm index 76c6062e5dd..0b9b9bf2da3 100644 --- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm @@ -14,7 +14,7 @@ frequency = ATMOS_TANKS_FREQ - var/on = 0 + on = FALSE var/injecting = 0 var/volume_rate = 50 @@ -38,9 +38,7 @@ /obj/machinery/atmospherics/unary/outlet_injector/init_multitool_menu() multitool_menu = new /datum/multitool_menu/idtag/freq/outlet_injector(src) -/obj/machinery/atmospherics/unary/outlet_injector/update_icon() - ..() - +/obj/machinery/atmospherics/unary/outlet_injector/update_icon_state() if(!powered()) icon_state = "off" else @@ -54,11 +52,10 @@ return add_underlay(T, node, dir) -/obj/machinery/atmospherics/unary/outlet_injector/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/unary/outlet_injector/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/unary/outlet_injector/process_atmos() ..() @@ -162,7 +159,7 @@ return*/ /obj/machinery/atmospherics/unary/outlet_injector/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) if(!(stat & NOPOWER) && on) to_chat(user, span_danger("You cannot unwrench this [src], turn if off first.")) return 1 diff --git a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm index b7b4d63b013..d269d4e62d9 100644 --- a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm +++ b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm @@ -9,19 +9,16 @@ dir = SOUTH initialize_directions = SOUTH - var/on = 0 + on = FALSE var/oxygen_content = 10 -/obj/machinery/atmospherics/unary/oxygen_generator/update_icon() - ..() - +/obj/machinery/atmospherics/unary/oxygen_generator/update_icon_state() if(node) icon_state = "intact_[on?("on"):("off")]" else icon_state = "exposed_off" - - on = 0 + on = FALSE /obj/machinery/atmospherics/unary/oxygen_generator/New() ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm b/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm index 5c1458b963d..57df3b794a9 100644 --- a/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm @@ -11,17 +11,17 @@ var/obj/machinery/portable_atmospherics/connected_device - var/on = 0 + on = FALSE /obj/machinery/atmospherics/unary/portables_connector/Destroy() if(connected_device) connected_device.disconnect() return ..() -/obj/machinery/atmospherics/unary/portables_connector/update_icon() - ..() +/obj/machinery/atmospherics/unary/portables_connector/update_icon_state() icon_state = "connector" + /obj/machinery/atmospherics/unary/portables_connector/update_underlays() if(..()) underlays.Cut() @@ -38,7 +38,7 @@ parent.update = 1 /obj/machinery/atmospherics/unary/portables_connector/attackby(var/obj/item/W as obj, var/mob/user as mob, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) if(connected_device) to_chat(user, span_danger("You cannot unwrench this [src], detach [connected_device] first.")) return 1 diff --git a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm index b53c5134e71..e4f23c963fe 100644 --- a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm +++ b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm @@ -10,15 +10,15 @@ name = "thermal tansfer plate" desc = "Transfers heat to and from an area" -/obj/machinery/atmospherics/unary/thermal_plate/update_icon() - ..() +/obj/machinery/atmospherics/unary/thermal_plate/update_icon_state() var/prefix = "" //var/suffix="_idle" // Also available: _heat, _cool - if(level == 1 && istype(loc, /turf/simulated)) + if(level == 1 && issimulatedturf(loc)) prefix = "h" icon_state = "[prefix]off" + /obj/machinery/atmospherics/unary/thermal_plate/process_atmos() ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm index 08af292d62e..342eebee1da 100644 --- a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm @@ -3,10 +3,11 @@ initialize_directions = SOUTH layer = TURF_LAYER+0.1 var/id_tag + /// The current air contents of this device var/datum/gas_mixture/air_contents - + /// Our one pipe node (we're unary) var/obj/machinery/atmospherics/node - + /// The pipenet we are plugged into var/datum/pipeline/parent /obj/machinery/atmospherics/unary/New() diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index d3ac2bf11ef..7b78ed0c724 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -13,14 +13,14 @@ layer = GAS_PIPE_VISIBLE_LAYER + GAS_SCRUBBER_OFFSET layer_offset = GAS_SCRUBBER_OFFSET - can_unwrench = 1 - var/open = 0 + can_unwrench = TRUE + var/open = FALSE var/area/initial_loc var/area_uid - var/on = 0 - var/releasing = 1 //0 = siphoning, 1 = releasing + on = FALSE + var/releasing = TRUE // FALSE = siphoning, TRUE = releasing var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND var/internal_pressure_bound = INTERNAL_PRESSURE_BOUND @@ -35,7 +35,7 @@ var/internal_pressure_bound_default = INTERNAL_PRESSURE_BOUND var/pressure_checks_default = PRESSURE_CHECKS - var/welded = 0 // Added for aliens -- TLE + var/welded = FALSE // Added for aliens -- TLE var/weld_burst_pressure = 50 * ONE_ATMOSPHERE //the (internal) pressure at which welded covers will burst off frequency = ATMOS_VENTSCRUB @@ -43,17 +43,17 @@ var/radio_filter_out var/radio_filter_in - connect_types = list(1,2) //connects to regular and supply pipes + connect_types = list(CONNECT_TYPE_NORMAL, CONNECT_TYPE_SUPPLY) //connects to regular and supply pipes /obj/machinery/atmospherics/unary/vent_pump/on - on = 1 + on = TRUE icon_state = "map_vent_out" /obj/machinery/atmospherics/unary/vent_pump/siphon - releasing = 0 + releasing = FALSE /obj/machinery/atmospherics/unary/vent_pump/siphon/on - on = 1 + on = TRUE icon_state = "map_vent_in" /obj/machinery/atmospherics/unary/vent_pump/New() @@ -77,16 +77,13 @@ ..() air_contents.volume = 1000 -/obj/machinery/atmospherics/unary/vent_pump/update_icon(safety = 0) - ..() - - plane = GAME_PLANE +/obj/machinery/atmospherics/unary/vent_pump/update_overlays() + . = ..() + plane = FLOOR_PLANE if(!check_icon_cache()) return - overlays.Cut() - var/vent_icon = "vent" var/turf/T = get_turf(src) @@ -103,10 +100,11 @@ else vent_icon += "[on ? "[releasing ? "out" : "in"]" : "off"]" - overlays += SSair.icon_manager.get_atmos_icon("device", , , vent_icon) + . += SSair.icon_manager.get_atmos_icon("device", state = vent_icon) update_pipe_image() + /obj/machinery/atmospherics/unary/vent_pump/update_underlays() if(..()) underlays.Cut() @@ -119,7 +117,8 @@ if(node) add_underlay(T, node, dir, node.icon_connect_type) else - add_underlay(T,, dir) + add_underlay(T, direction = dir) + /obj/machinery/atmospherics/unary/vent_pump/hide() update_icon() @@ -249,11 +248,11 @@ if(signal.data["purge"] != null) pressure_checks &= ~1 - releasing = 0 + releasing = FALSE if(signal.data["stabilize"] != null) pressure_checks |= 1 - releasing = 1 + releasing = TRUE if(signal.data["power"] != null) on = text2num(signal.data["power"]) @@ -348,7 +347,7 @@ else to_chat(user, "The vent is welded.") return 1 - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) if(!(stat & NOPOWER) && on) to_chat(user, span_danger("You cannot unwrench this [src], turn it off first.")) return 1 @@ -409,11 +408,10 @@ if(welded) . += span_notice("It seems welded shut.") -/obj/machinery/atmospherics/unary/vent_pump/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/unary/vent_pump/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/unary/vent_pump/proc/set_tag(new_tag) if(frequency == ATMOS_VENTSCRUB) diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index 40e5afcfd6b..1dccfceccbb 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -19,7 +19,7 @@ var/list/turf/simulated/adjacent_turfs = list() - var/on = 0 + on = FALSE var/scrubbing = 1 //0 = siphoning, 1 = scrubbing var/scrub_O2 = 0 var/scrub_N2 = 0 @@ -96,16 +96,12 @@ use_power(amount, power_channel) return 1 -/obj/machinery/atmospherics/unary/vent_scrubber/update_icon(var/safety = 0) - ..() - - plane = GAME_PLANE - +/obj/machinery/atmospherics/unary/vent_scrubber/update_overlays() + . = ..() + plane = FLOOR_PLANE if(!check_icon_cache()) return - overlays.Cut() - var/scrubber_icon = "scrubber" var/turf/T = get_turf(src) @@ -116,12 +112,14 @@ scrubber_icon += "off" else scrubber_icon += "[on ? "[scrubbing ? "on" : "in"]" : "off"]" + if(welded) scrubber_icon = "scrubberweld" - overlays += SSair.icon_manager.get_atmos_icon("device", , , scrubber_icon) + . += SSair.icon_manager.get_atmos_icon("device", state = scrubber_icon) update_pipe_image() + /obj/machinery/atmospherics/unary/vent_scrubber/update_underlays() if(..()) underlays.Cut() @@ -134,7 +132,7 @@ if(node) add_underlay(T, node, dir, node.icon_connect_type) else - add_underlay(T,, dir) + add_underlay(T, direction = dir) /obj/machinery/atmospherics/unary/vent_scrubber/set_frequency(new_frequency) SSradio.remove_object(src, frequency) @@ -343,11 +341,10 @@ update_icon() return -/obj/machinery/atmospherics/unary/vent_scrubber/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() +/obj/machinery/atmospherics/unary/vent_scrubber/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/atmospherics/unary/vent_scrubber/proc/set_tag(new_tag) if(frequency == ATMOS_VENTSCRUB) @@ -370,7 +367,7 @@ playsound(loc, 'sound/weapons/bladeslice.ogg', 100, TRUE) /obj/machinery/atmospherics/unary/vent_scrubber/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) if(!(stat & NOPOWER) && on) to_chat(user, span_danger("You cannot unwrench this [src], turn it off first.")) return 1 diff --git a/code/ATMOSPHERICS/datum_icon_manager.dm b/code/ATMOSPHERICS/datum_icon_manager.dm index ca1325bd9c0..cc8e88209f2 100644 --- a/code/ATMOSPHERICS/datum_icon_manager.dm +++ b/code/ATMOSPHERICS/datum_icon_manager.dm @@ -6,38 +6,35 @@ // atmospherics devices. //-------------------------------------------- -/proc/pipe_color_lookup(var/color) - for(var/C in GLOB.pipe_colors) - if(color == GLOB.pipe_colors[C]) - return "[C]" +/proc/pipe_color_lookup(color) + for(var/check_color in GLOB.pipe_colors) + if(color == GLOB.pipe_colors[check_color]) + return "[check_color]" -/proc/pipe_color_check(var/color) +/proc/pipe_color_check(color) if(!color) - return 1 - for(var/C in GLOB.pipe_colors) - if(color == GLOB.pipe_colors[C]) - return 1 - return 0 + return TRUE + for(var/check_color in GLOB.pipe_colors) + if(color == GLOB.pipe_colors[check_color]) + return TRUE + return FALSE //-------------------------------------------- // Icon cache generation //-------------------------------------------- /datum/pipe_icon_manager - var/list/pipe_icons[] - var/list/manifold_icons[] - var/list/device_icons[] - var/list/underlays[] - //var/list/underlays_down[] - //var/list/underlays_exposed[] - //var/list/underlays_intact[] - //var/list/pipe_underlays_exposed[] - //var/list/pipe_underlays_intact[] + var/list/pipe_icons + var/list/manifold_icons + var/list/device_icons + var/list/underlays + /datum/pipe_icon_manager/New() check_icons() -/datum/pipe_icon_manager/proc/get_atmos_icon(var/device, var/dir, var/color, var/state) + +/datum/pipe_icon_manager/proc/get_atmos_icon(device, dir, color, state) check_icons() device = "[device]" @@ -54,16 +51,7 @@ return device_icons[state] if("underlay") return underlays[state + dir + color] - //if("underlay_intact") - // return underlays_intact[state + dir + color] - // if("underlay_exposed") - // return underlays_exposed[state + dir + color] - // if("underlay_down") - // return underlays_down[state + dir + color] - // if("pipe_underlay_exposed") - // return pipe_underlays_exposed[state + dir + color] - // if("pipe_underlay_intact") - // return pipe_underlays_intact[state + dir + color] + /datum/pipe_icon_manager/proc/check_icons() if(!pipe_icons) @@ -72,85 +60,85 @@ gen_manifold_icons() if(!device_icons) gen_device_icons() - //if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact) if(!underlays) gen_underlay_icons() + /datum/pipe_icon_manager/proc/gen_pipe_icons() if(!pipe_icons) - pipe_icons = new() + pipe_icons = list() - var/icon/pipe = new('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi') + var/icon/pipe = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi') for(var/state in pipe.IconStates()) if(!state || findtext(state, "map")) continue var/cache_name = state - var/image/I = image('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi', icon_state = state) - pipe_icons[cache_name] = I + var/image/img = image('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi', icon_state = state) + pipe_icons[cache_name] = img for(var/pipe_color in GLOB.pipe_colors) - I = image('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi', icon_state = state) - I.color = GLOB.pipe_colors[pipe_color] - pipe_icons[state + "[GLOB.pipe_colors[pipe_color]]"] = I + img = image('icons/obj/pipes_and_stuff/atmospherics/atmos/pipes.dmi', icon_state = state) + img.color = GLOB.pipe_colors[pipe_color] + pipe_icons[state + "[GLOB.pipe_colors[pipe_color]]"] = img - pipe = new ('icons/obj/pipes_and_stuff/atmospherics/atmos/heat.dmi') + pipe = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/heat.dmi') for(var/state in pipe.IconStates()) if(!state || findtext(state, "map")) continue pipe_icons["hepipe" + state] = image('icons/obj/pipes_and_stuff/atmospherics/atmos/heat.dmi', icon_state = state) - pipe = new ('icons/obj/pipes_and_stuff/atmospherics/atmos/junction.dmi') + pipe = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/junction.dmi') for(var/state in pipe.IconStates()) if(!state || findtext(state, "map")) continue pipe_icons["hejunction" + state] = image('icons/obj/pipes_and_stuff/atmospherics/atmos/junction.dmi', icon_state = state) + /datum/pipe_icon_manager/proc/gen_manifold_icons() if(!manifold_icons) - manifold_icons = new() + manifold_icons = list() - var/icon/pipe = new('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi') + var/icon/pipe = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi') for(var/state in pipe.IconStates()) if(findtext(state, "clamps")) - var/image/I = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) - manifold_icons[state] = I + var/image/img = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) + manifold_icons[state] = img continue if(findtext(state, "core") || findtext(state, "4way")) - var/image/I = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) - manifold_icons[state] = I + var/image/img = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) + manifold_icons[state] = img for(var/pipe_color in GLOB.pipe_colors) - I = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) - I.color = GLOB.pipe_colors[pipe_color] - manifold_icons[state + GLOB.pipe_colors[pipe_color]] = I + img = image('icons/obj/pipes_and_stuff/atmospherics/atmos/manifold.dmi', icon_state = state) + img.color = GLOB.pipe_colors[pipe_color] + manifold_icons[state + GLOB.pipe_colors[pipe_color]] = img + /datum/pipe_icon_manager/proc/gen_device_icons() if(!device_icons) - device_icons = new() - - var/icon/device + device_icons = list() - device = new('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_pump.dmi') + var/icon/device = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_pump.dmi') for(var/state in device.IconStates()) if(!state || findtext(state, "map")) continue device_icons["vent" + state] = image('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_pump.dmi', icon_state = state) - device = new('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_scrubber.dmi') + device = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_scrubber.dmi') for(var/state in device.IconStates()) if(!state || findtext(state, "map")) continue device_icons["scrubber" + state] = image('icons/obj/pipes_and_stuff/atmospherics/atmos/vent_scrubber.dmi', icon_state = state) -/datum/pipe_icon_manager/proc/gen_underlay_icons() +/datum/pipe_icon_manager/proc/gen_underlay_icons() if(!underlays) - underlays = new() + underlays = list() - var/icon/pipe = new('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi') + var/icon/pipe = icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi') for(var/state in pipe.IconStates()) if(state == "") @@ -158,10 +146,11 @@ var/cache_name = state - for(var/D in GLOB.cardinal) - var/image/I = image(icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER) - underlays[cache_name + "[D]"] = I + for(var/change_dir in GLOB.cardinal) + var/image/img = image(icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi', icon_state = state, dir = change_dir), layer = GAS_PIPE_HIDDEN_LAYER) + underlays[cache_name + "[change_dir]"] = img for(var/pipe_color in GLOB.pipe_colors) - I = image(icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER) - I.color = GLOB.pipe_colors[pipe_color] - underlays[state + "[D]" + "[GLOB.pipe_colors[pipe_color]]"] = I + img = image(icon('icons/obj/pipes_and_stuff/atmospherics/atmos/pipe_underlays.dmi', icon_state = state, dir = change_dir), layer = GAS_PIPE_HIDDEN_LAYER) + img.color = GLOB.pipe_colors[pipe_color] + underlays[state + "[change_dir]" + "[GLOB.pipe_colors[pipe_color]]"] = img + diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index 17e280260a0..92fc52fe520 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -16,9 +16,9 @@ ..() initialize_directions = dir -/obj/machinery/atmospherics/pipe/cap/hide(var/i) +/obj/machinery/atmospherics/pipe/cap/hide(i) if(level == 1 && istype(loc, /turf/simulated)) - invisibility = i ? INVISIBILITY_ABSTRACT : 0 + invisibility = i ? INVISIBILITY_MAXIMUM : 0 update_icon() /obj/machinery/atmospherics/pipe/cap/pipeline_expansion() @@ -47,22 +47,21 @@ ..() -/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color) +/obj/machinery/atmospherics/pipe/cap/change_color(new_color) ..() //for updating connected atmos device pipes (i.e. vents, manifolds, etc) if(node) node.update_underlays() -/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0) - ..() +/obj/machinery/atmospherics/pipe/cap/update_overlays() + . = ..() if(!check_icon_cache()) return alpha = 255 + . += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type) - overlays.Cut() - overlays += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type) /obj/machinery/atmospherics/pipe/cap/atmos_init() ..() diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index ec91fdc8db9..80249c6f6eb 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -60,9 +60,9 @@ hide(T.intact) update_icon() -/obj/machinery/atmospherics/pipe/manifold/hide(var/i) +/obj/machinery/atmospherics/pipe/manifold/hide(i) if(level == 1 && istype(loc, /turf/simulated)) - invisibility = i ? INVISIBILITY_ABSTRACT : 0 + invisibility = i ? INVISIBILITY_MAXIMUM : 0 /obj/machinery/atmospherics/pipe/manifold/pipeline_expansion() return list(node1, node2, node3) @@ -106,7 +106,7 @@ update_icon() ..() -/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color) +/obj/machinery/atmospherics/pipe/manifold/change_color(new_color) ..() //for updating connected atmos device pipes (i.e. vents, manifolds, etc) if(node1) @@ -116,21 +116,30 @@ if(node3) node3.update_underlays() -/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0) - ..() + +/obj/machinery/atmospherics/pipe/manifold/update_overlays() + . = ..() if(!check_icon_cache()) return alpha = 255 - overlays.Cut() - overlays += SSair.icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) - overlays += SSair.icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) + . += SSair.icon_manager.get_atmos_icon("manifold", color = pipe_color, state = "core" + icon_connect_type) + . += SSair.icon_manager.get_atmos_icon("manifold", state = "clamps" + icon_connect_type) + update_underlays() + + +/obj/machinery/atmospherics/pipe/manifold/update_underlays() + if(!..()) + return + underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) return + var/turf/source_turf = get_turf(src) + if(!istype(source_turf)) + return + var/list/directions = list(NORTH, SOUTH, EAST, WEST) var/node1_direction = get_dir(src, node1) var/node2_direction = get_dir(src, node2) @@ -138,16 +147,13 @@ directions -= dir - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) + directions -= add_underlay(source_turf, node1, node1_direction, icon_connect_type) + directions -= add_underlay(source_turf, node2, node2_direction, icon_connect_type) + directions -= add_underlay(source_turf, node3, node3_direction, icon_connect_type) - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) + for(var/check_dir in directions) + add_underlay(source_turf, direction = check_dir, icon_connect_type = src.icon_connect_type) -/obj/machinery/atmospherics/pipe/manifold/update_underlays() - ..() - update_icon() // A check to make sure both nodes exist - self-delete if they aren't present /obj/machinery/atmospherics/pipe/manifold/check_nodes_exist() diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index 237251b3803..d2a23a12534 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -76,7 +76,7 @@ ..() -/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color) +/obj/machinery/atmospherics/pipe/manifold4w/change_color(new_color) ..() //for updating connected atmos device pipes (i.e. vents, manifolds, etc) if(node1) @@ -88,20 +88,30 @@ if(node4) node4.update_underlays() -/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0) - ..() + +/obj/machinery/atmospherics/pipe/manifold4w/update_overlays() + . = ..() if(!check_icon_cache()) return alpha = 255 - overlays.Cut() - overlays += SSair.icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) - overlays += SSair.icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) + + . += SSair.icon_manager.get_atmos_icon("manifold", color = pipe_color, state = "4way" + icon_connect_type) + . += SSair.icon_manager.get_atmos_icon("manifold", state = "clamps_4way" + icon_connect_type) + update_underlays() + + +/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() + if(!..()) + return + underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) return + var/turf/source_turf = get_turf(src) + if(!istype(source_turf)) + return + var/list/directions = list(NORTH, SOUTH, EAST, WEST) var/node1_direction = get_dir(src, node1) var/node2_direction = get_dir(src, node2) @@ -110,17 +120,13 @@ directions -= dir - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) - directions -= add_underlay(T,node4,node4_direction,icon_connect_type) - - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) + directions -= add_underlay(source_turf, node1, node1_direction, icon_connect_type) + directions -= add_underlay(source_turf, node2, node2_direction, icon_connect_type) + directions -= add_underlay(source_turf, node3, node3_direction, icon_connect_type) + directions -= add_underlay(source_turf, node4, node4_direction, icon_connect_type) -/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() - ..() - update_icon() + for(var/check_dir in directions) + add_underlay(source_turf, direction = check_dir, icon_connect_type = src.icon_connect_type) // A check to make sure both nodes exist - self-delete if they aren't present @@ -131,9 +137,9 @@ // 1: 1-4 nodes exist, we continue existing return 1 -/obj/machinery/atmospherics/pipe/manifold4w/hide(var/i) +/obj/machinery/atmospherics/pipe/manifold4w/hide(i) if(level == 1 && istype(loc, /turf/simulated)) - invisibility = i ? INVISIBILITY_ABSTRACT : 0 + invisibility = i ? INVISIBILITY_MAXIMUM : 0 /obj/machinery/atmospherics/pipe/manifold4w/atmos_init() ..() diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm index 73f6af89986..f69dcc5f422 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm @@ -129,7 +129,7 @@ /obj/machinery/atmospherics/pipe/simple/pipeline_expansion() return list(node1, node2) -/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color) +/obj/machinery/atmospherics/pipe/simple/change_color(new_color) ..() //for updating connected atmos device pipes (i.e. vents, manifolds, etc) if(node1) @@ -137,20 +137,24 @@ if(node2) node2.update_underlays() -/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0) - ..() + +/obj/machinery/atmospherics/pipe/simple/update_overlays() + . = ..() if(!check_icon_cache()) - return + return . alpha = 255 - overlays.Cut() - if(node1 && node2) - overlays += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type) + . += SSair.icon_manager.get_atmos_icon("pipe", color = pipe_color, state = pipe_icon + "intact" + icon_connect_type) else - overlays += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type) + . += SSair.icon_manager.get_atmos_icon("pipe", color = pipe_color, state = pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type) + + +/obj/machinery/atmospherics/pipe/simple/update_underlays() + return + // A check to make sure both nodes exist - self-delete if they aren't present /obj/machinery/atmospherics/pipe/simple/check_nodes_exist() @@ -160,9 +164,7 @@ // 1: 1-2 nodes exist, we continue existing return 1 -/obj/machinery/atmospherics/pipe/simple/update_underlays() - return -/obj/machinery/atmospherics/pipe/simple/hide(var/i) +/obj/machinery/atmospherics/pipe/simple/hide(i) if(level == 1 && istype(loc, /turf/simulated)) - invisibility = i ? INVISIBILITY_ABSTRACT : 0 + invisibility = i ? INVISIBILITY_MAXIMUM : 0 diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm index ea2a32824e8..508f4399c69 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm @@ -32,16 +32,21 @@ connect_types = list(1,2,3) icon_state = "map_universal" -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) - ..() - +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_overlays() + . = list() if(!check_icon_cache()) - return + return . alpha = 255 - overlays.Cut() - overlays += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + . += SSair.icon_manager.get_atmos_icon("pipe", color = pipe_color, state = "universal") + update_underlays() + + +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() + if(!check_icon_cache()) + return + underlays.Cut() if(node1) @@ -49,19 +54,16 @@ if(node2) universal_underlays(node2) else - var/node2_dir = turn(get_dir(src,node1),-180) - universal_underlays(,node2_dir) + var/node2_dir = turn(get_dir(src,node1), -180) + universal_underlays(direction = node2_dir) else if(node2) universal_underlays(node2) - var/node1_dir = turn(get_dir(src,node2),-180) - universal_underlays(,node1_dir) + var/node1_dir = turn(get_dir(src,node2), -180) + universal_underlays(direction = node1_dir) else - universal_underlays(,dir) - universal_underlays(,turn(dir, -180)) + universal_underlays(direction = dir) + universal_underlays(direction = turn(dir, -180)) -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() - ..() - update_icon() /obj/machinery/atmospherics/pipe/simple/hidden/yellow color = PIPE_COLOR_YELLOW diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm index 963d38fe82d..05d7099f56f 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm @@ -43,31 +43,33 @@ connect_types = list(1,2,3) icon_state = "map_universal" -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) - ..() +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_overlays() + . = list() if(!check_icon_cache()) - return + return . alpha = 255 - overlays.Cut() - overlays += SSair.icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") - underlays.Cut() + . += SSair.icon_manager.get_atmos_icon("pipe", color = pipe_color, state = "universal") + update_underlays() + +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() + if(!check_icon_cache()) + return + + underlays.Cut() if(node1) universal_underlays(node1) if(node2) universal_underlays(node2) else var/node1_dir = get_dir(node1,src) - universal_underlays(,node1_dir) + universal_underlays(direction = node1_dir) else if(node2) universal_underlays(node2) else - universal_underlays(,dir) - universal_underlays(,turn(dir, -180)) + universal_underlays(direction = dir) + universal_underlays(direction = turn(dir, -180)) -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() - ..() - update_icon() diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index ebb3f07a7c9..8c505818f79 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -45,7 +45,7 @@ //This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile /obj/effect/hotspot - anchored = 1 + anchored = TRUE mouse_opacity = MOUSE_OPACITY_TRANSPARENT icon = 'icons/goonstation/effects/fire.dmi' icon_state = "1" diff --git a/code/__DEFINES/action.dm b/code/__DEFINES/action.dm index a74d261f782..dd60badb0f1 100644 --- a/code/__DEFINES/action.dm +++ b/code/__DEFINES/action.dm @@ -1,10 +1,10 @@ //Action availability flags -#define AB_CHECK_RESTRAINED 1 -#define AB_CHECK_STUNNED 2 -#define AB_CHECK_LYING 4 -#define AB_CHECK_CONSCIOUS 8 -#define AB_TRANSFER_MIND 16 -#define AB_CHECK_TURF 32 +#define AB_CHECK_RESTRAINED (1<<0) +#define AB_CHECK_STUNNED (1<<1) +#define AB_CHECK_LYING (1<<2) +#define AB_CHECK_CONSCIOUS (1<<3) +#define AB_TRANSFER_MIND (1<<4) +#define AB_CHECK_TURF (1<<5) //Advanced action types //Those actions have cooldown, and unavailable until it ends diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 97cfd10d818..19550d20ff3 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -26,27 +26,27 @@ //Please don't edit these values without speaking to Errorage first ~Carn //Admin Permissions -#define R_BUILDMODE 1 -#define R_ADMIN 2 -#define R_BAN 4 -#define R_EVENT 8 -#define R_SERVER 16 -#define R_DEBUG 32 -#define R_POSSESS 64 -#define R_PERMISSIONS 128 -#define R_STEALTH 256 -#define R_REJUVINATE 512 -#define R_VAREDIT 1024 -#define R_SOUNDS 2048 -#define R_SPAWN 4096 -#define R_MOD 8192 -#define R_MENTOR 16384 -#define R_PROCCALL 32768 -#define R_VIEWRUNTIMES 65536 +#define R_BUILDMODE (1<<0) +#define R_ADMIN (1<<1) +#define R_BAN (1<<2) +#define R_EVENT (1<<3) +#define R_SERVER (1<<4) +#define R_DEBUG (1<<5) +#define R_POSSESS (1<<6) +#define R_PERMISSIONS (1<<7) +#define R_STEALTH (1<<8) +#define R_REJUVINATE (1<<9) +#define R_VAREDIT (1<<10) +#define R_SOUNDS (1<<11) +#define R_SPAWN (1<<12) +#define R_MOD (1<<13) +#define R_MENTOR (1<<14) +#define R_PROCCALL (1<<15) +#define R_VIEWRUNTIMES (1<<16) -#define R_MAXPERMISSION 65536 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. +#define R_MAXPERMISSION (1<<16)//This holds the maximum value for a permission. It is used in iteration, so keep it updated. -#define R_HOST 131071 // Sum of all permissions to allow easy setting +#define R_HOST (~0) // Sum of all permissions to allow easy setting #define ADMIN_QUE(user,display) "[display]" #define ADMIN_FLW(user,display) "[display]" diff --git a/code/__DEFINES/bots.dm b/code/__DEFINES/bots.dm index c283445d0ad..3ced8569059 100644 --- a/code/__DEFINES/bots.dm +++ b/code/__DEFINES/bots.dm @@ -26,12 +26,12 @@ #define BOT_NO_ROUTE 17 // no destination beacon found (or no route) //Bot types -#define SEC_BOT 1 // Secutritrons (Beepsky) and ED-209s -#define MULE_BOT 2 // MULEbots -#define FLOOR_BOT 4 // Floorbots -#define CLEAN_BOT 8 // Cleanbots -#define MED_BOT 16 // Medibots -#define HONK_BOT 32 // Honkbots +#define SEC_BOT (1<<0) // Secutritrons (Beepsky) and ED-209s +#define MULE_BOT (1<<1) // MULEbots +#define FLOOR_BOT (1<<2) // Floorbots +#define CLEAN_BOT (1<<3) // Cleanbots +#define MED_BOT (1<<4) // Medibots +#define HONK_BOT (1<<5) // Honkbots //Sentience types #define SENTIENCE_ORGANIC 1 diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm index b1c3f75413f..e433856cd00 100644 --- a/code/__DEFINES/clothing.dm +++ b/code/__DEFINES/clothing.dm @@ -1,13 +1,13 @@ //Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. -#define HIDEGLOVES 1 //APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDESUITSTORAGE 2 //APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDEJUMPSUIT 4 //APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDESHOES 8 //APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDETAIL 16 //APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDEMASK 32 //APPLIES ONLY TO HELMETS/MASKS!! -#define HIDEHEADSETS 64 //APPLIES ONLY TO HELMETS/MASKS!! (headsets and such) -#define HIDEGLASSES 128 //APPLIES ONLY TO HELMETS/MASKS!! -#define HIDENAME 256 //APPLIES ONLY TO HELMETS/MASKS!! Dictates whether we appear as unknown. +#define HIDEGLOVES (1<<0) //APPLIES ONLY TO THE EXTERIOR SUIT!! +#define HIDESUITSTORAGE (1<<1) //APPLIES ONLY TO THE EXTERIOR SUIT!! +#define HIDEJUMPSUIT (1<<2) //APPLIES ONLY TO THE EXTERIOR SUIT!! +#define HIDESHOES (1<<3) //APPLIES ONLY TO THE EXTERIOR SUIT!! +#define HIDETAIL (1<<4) //APPLIES ONLY TO THE EXTERIOR SUIT!! +#define HIDEMASK (1<<5) //APPLIES ONLY TO HELMETS/MASKS!! +#define HIDEHEADSETS (1<<6) //APPLIES ONLY TO HELMETS/MASKS!! (headsets and such) +#define HIDEGLASSES (1<<7) //APPLIES ONLY TO HELMETS/MASKS!! +#define HIDENAME (1<<8) //APPLIES ONLY TO HELMETS/MASKS!! Dictates whether we appear as unknown. // slots #define slot_back 1 @@ -44,24 +44,24 @@ //Cant seem to find a mob bitflags area other than the powers one // bitflags for clothing parts -#define HEAD 1 -#define UPPER_TORSO 2 -#define LOWER_TORSO 4 -#define LEG_LEFT 8 -#define LEG_RIGHT 16 -#define LEGS 24 -#define FOOT_LEFT 32 -#define FOOT_RIGHT 64 -#define FEET 96 -#define ARM_LEFT 128 -#define ARM_RIGHT 256 -#define ARMS 384 -#define HAND_LEFT 512 -#define HAND_RIGHT 1024 -#define HANDS 1536 -#define FULL_BODY 2047 -#define TAIL 4096 -#define WING 8192 +#define HEAD (1<<0) +#define UPPER_TORSO (1<<1) +#define LOWER_TORSO (1<<2) +#define LEG_LEFT (1<<3) +#define LEG_RIGHT (1<<4) +#define LEGS (LEG_LEFT|LEG_RIGHT) +#define FOOT_LEFT (1<<5) +#define FOOT_RIGHT (1<<6) +#define FEET (FOOT_LEFT|FOOT_RIGHT) +#define ARM_LEFT (1<<7) +#define ARM_RIGHT (1<<8) +#define ARMS (ARM_LEFT|ARM_RIGHT) +#define HAND_LEFT (1<<9) +#define HAND_RIGHT (1<<10) +#define HANDS (HAND_LEFT|HAND_RIGHT) +#define FULL_BODY (HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS) +#define TAIL (1<<12) +#define WING (1<<13) // bitflags for the percentual amount of protection a piece of clothing which covers the body part offers. // Used with human/proc/get_heat_protection() and human/proc/get_cold_protection() @@ -80,11 +80,11 @@ #define THERMAL_PROTECTION_HAND_RIGHT 0.025 //flags for covering body parts -#define GLASSESCOVERSEYES 1 -#define MASKCOVERSEYES 2 // get rid of some of the other mess in these flags -#define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes -#define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head -#define HEADCOVERSMOUTH 16 +#define GLASSESCOVERSEYES (1<<0) +#define MASKCOVERSEYES (1<<1) // get rid of some of the other mess in these flags +#define HEADCOVERSEYES (1<<2) // feel free to realloc these numbers for other purposes +#define MASKCOVERSMOUTH (1<<3) // on other items, these are just for mask/head +#define HEADCOVERSMOUTH (1<<4) // Suit sensor levels #define SUIT_SENSOR_OFF 0 diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 41f4e049fb0..6cb84115565 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -1,8 +1,10 @@ -#define COLOR_INPUT_DISABLED "#F0F0F0" -#define COLOR_INPUT_ENABLED "#D3B5B5" +#define COLOR_INPUT_DISABLED "#F0F0F0" +#define COLOR_INPUT_ENABLED "#D3B5B5" +#define COLOR_DARK_INPUT_DISABLED "#202020" +#define COLOR_DARK_INPUT_ENABLED "#494949" #define COLOR_RED "#FF0000" -#define COLOR_CULT_RED "#960000" +#define COLOR_CULT_RED "#960000" #define COLOR_GREEN "#00FF00" #define COLOR_BLUE "#0000FF" #define COLOR_CYAN "#00FFFF" diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index c3a336e2629..06279990547 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -34,22 +34,22 @@ #define JITTER "jitter" //I hate adding defines like this but I'd much rather deal with bitflags than lists and string searches -#define BRUTELOSS 1 -#define FIRELOSS 2 -#define TOXLOSS 4 -#define OXYLOSS 8 -#define SHAME 16 -#define OBLITERATION 32 +#define BRUTELOSS (1<<0) +#define FIRELOSS (1<<1) +#define TOXLOSS (1<<2) +#define OXYLOSS (1<<3) +#define SHAME (1<<4) +#define OBLITERATION (1<<5) //Bitflags defining which status effects could be or are inflicted on a mob -#define CANSTUN 1 -#define CANWEAKEN 2 -#define CANPARALYSE 4 -#define CANPUSH 8 -#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes. -#define IGNORESLOWDOWN 32 -#define IGNORE_SPEED_CHANGES 64 -#define GODMODE 128 +#define CANSTUN (1<<0) +#define CANWEAKEN (1<<1) +#define CANPARALYSE (1<<2) +#define CANPUSH (1<<3) +#define PASSEMOTES (1<<4) //Mob has a cortical borer or holders inside of it that need to see emotes. +#define IGNORESLOWDOWN (1<<5) +#define IGNORE_SPEED_CHANGES (1<<6) +#define GODMODE (1<<7) //Health Defines #define HEALTH_THRESHOLD_CRIT 0 diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index d9fe90f9bd5..7eda05c4df1 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -226,6 +226,10 @@ #define COMSIG_AREA_ENTERED "area_entered" ///from base of area/Exited(): (atom/movable/M) #define COMSIG_AREA_EXITED "area_exited" +///from base of area/Entered(): (atom/movable/M) +#define COMSIG_ATOM_ENTERED_AREA "atom_entered_area" +///from base of area/Exited(): (atom/movable/M) +#define COMSIG_ATOM_EXITED_AREA "atom_exited_area" // /turf signals @@ -567,6 +571,19 @@ ///from [/obj/effect/mine/proc/triggermine]: #define COMSIG_MINE_TRIGGERED "minegoboom" +/// Defib-specific signals + +/// Called when a defibrillator is first applied to someone. (mob/living/user, mob/living/target, harmful) +#define COMSIG_DEFIB_PADDLES_APPLIED "defib_paddles_applied" + /// Defib is out of power. + #define COMPONENT_BLOCK_DEFIB_DEAD (1<<0) + /// Something else: we won't have a custom message for this and should let the defib handle it. + #define COMPONENT_BLOCK_DEFIB_MISC (1<<1) +/// Called when a defib has been successfully used, and a shock has been applied. (mob/living/user, mob/living/target, harmful, successful) +#define COMSIG_DEFIB_SHOCK_APPLIED "defib_zap" +/// Called when a defib's cooldown has run its course and it is once again ready. () +#define COMSIG_DEFIB_READY "defib_ready" + // /obj/item signals for economy ///called when an item is sold by the exports subsystem #define COMSIG_ITEM_SOLD "item_sold" diff --git a/code/__DEFINES/directions.dm b/code/__DEFINES/directions.dm new file mode 100644 index 00000000000..150f0e37c5e --- /dev/null +++ b/code/__DEFINES/directions.dm @@ -0,0 +1,34 @@ +//Directions (already defined on BYOND natively, purely here for reference) +/// define purely for readability, cables especially need to use this as `NO_DIRECTION` represents a "node" +#define NO_DIRECTION 0 +//#define NORTH 1 +//#define SOUTH 2 +//#define EAST 4 +//#define WEST 8 +//#define NORTHEAST 5 +//#define SOUTHEAST 6 +//#define NORTHWEST 9 +//#define SOUTHWEST 10 + +// Multi-z directions +//#define UP 16 +//#define DOWN 32 + +/// Using the ^ operator or XOR, we can compared TRUE East and West bits against our direction, +/// since XOR will only return TRUE if one bit is False and the other is True, if East is 0, that bit will return TRUE +/// and if West is 1, then that bit will return 0 +/// hence EAST (0010) XOR EAST|WEST (0011) --> WEST (0001) + +///Flips a direction along the horizontal axis, will convert E -> W, W -> E, NE -> NW, SE -> SW, etc +#define FLIP_DIR_HORIZONTALLY(dir) ((dir & (EAST|WEST)) ? dir ^ (EAST|WEST) : dir) +///Flips a direction along the vertical axis, will convert N -> S, S -> N, NE -> SE, SW -> NW, etc +#define FLIP_DIR_VERTICALLY(dir) ((dir & (NORTH|SOUTH)) ? dir ^ (NORTH|SOUTH) : dir) + +/// for directions, each cardinal direction only has 1 TRUE bit, so `1000` or `0100` for example, so when you subtract 1 +/// from a cardinal direction it results in that directions initial TRUE bit always switching to FALSE, so if you & check it +/// against its initial self, it will return false, indicating that the direction is straight and not diagonal + +/// returns TRUE if direction is diagonal and false if not +#define IS_DIR_DIAGONAL(dir) (dir & (dir - 1)) +/// returns TRUE if direction is cardinal and false if not +#define IS_DIR_CARDINAL(dir) (!IS_DIR_DIAGONAL(dir)) diff --git a/code/__DEFINES/diseases.dm b/code/__DEFINES/diseases.dm index 0cc04c49b65..25219ab6859 100644 --- a/code/__DEFINES/diseases.dm +++ b/code/__DEFINES/diseases.dm @@ -13,8 +13,8 @@ #define BIOHAZARD "BIOHAZARD THREAT!" //Spread Flags -#define NON_CONTAGIOUS 0 //virus can't spread -#define BITES 1 //virus can spread with bites -#define BLOOD 2 //virus can spread with infected blood -#define CONTACT 4 //virus can spread with any touch -#define AIRBORNE 8 //virus spreads through the air +#define NON_CONTAGIOUS (1<<0) //virus can't spread +#define BITES (1<<1) //virus can spread with bites +#define BLOOD (1<<2) //virus can spread with infected blood +#define CONTACT (1<<3) //virus can spread with any touch +#define AIRBORNE (1<<4) //virus spreads through the air diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 11ef9cccd13..bbd23310766 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -2,38 +2,39 @@ #define NONE 0 //FLAGS BITMASK -#define STOPSPRESSUREDMAGE 1 // This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. -#define NODROP 2 // 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 NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler -#define AIRTIGHT 8 // mask allows internals -#define HANDSLOW 16 // If an item has this flag, it will slow you to carry it -#define CONDUCT 32 // conducts electricity (metal etc.) -#define ABSTRACT 64 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way -#define ON_BORDER 128 // item has priority to check when entering or leaving -#define PREVENT_CLICK_UNDER 256 -#define NODECONSTRUCT 512 +#define STOPSPRESSUREDMAGE (1<<0) // This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. +#define NODROP (1<<1) // 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 NOBLUDGEON (1<<2) // when an item has this it produces no "X has been hit by Y with Z" message with the default handler +#define AIRTIGHT (1<<3) // mask allows internals +#define HANDSLOW (1<<4) // If an item has this flag, it will slow you to carry it +#define CONDUCT (1<<5) // conducts electricity (metal etc.) +#define ABSTRACT (1<<6) // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way +#define ON_BORDER (1<<7) // item has priority to check when entering or leaving +#define PREVENT_CLICK_UNDER (1<<8) +#define NODECONSTRUCT (1<<9) -#define EARBANGPROTECT 1024 +#define EARBANGPROTECT (1<<10) -#define NOSLIP 1024 //prevents from slipping on wet floors, in space etc +#define NOSLIP (1<<10) //prevents from slipping on wet floors, in space etc -#define NOPICKUP 2048 // This flags makes it so an item cannot be picked in hands +#define NOPICKUP (1<<11) // This flags makes it so an item cannot be picked in hands -#define HEADBANGPROTECT 4096 +#define HEADBANGPROTECT (1<<12) -#define BLOCK_GAS_SMOKE_EFFECT 8192 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! -#define THICKMATERIAL 8192 //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. (NOTE: flag shared with BLOCK_GAS_SMOKE_EFFECT) +#define BLOCK_GAS_SMOKE_EFFECT (1<<13) // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! +#define THICKMATERIAL (1<<13) //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. (NOTE: flag shared with BLOCK_GAS_SMOKE_EFFECT) -#define DROPDEL 16384 // When dropped, it calls qdel on itself +#define DROPDEL (1<<14) // When dropped, it calls qdel on itself -#define BLOCKHEADHAIR 32768 // temporarily removes the user's hair overlay. Leaves facial hair. -#define BLOCKHAIR 65536 // temporarily removes the user's hair, facial and otherwise. +#define BLOCKHEADHAIR (1<<15) // temporarily removes the user's hair overlay. Leaves facial hair. +#define BLOCKFACIALHAIR (1<<16) // temporarily removes the user's facial hair overlay. Leaves head hair. +#define BLOCKHAIR (1<<17) // temporarily removes the user's hair, facial and otherwise. -#define NO_PIXEL_RANDOM_DROP 131072 // If dropped, it wont have a randomized pixel_x/pixel_y +#define NO_PIXEL_RANDOM_DROP (1<<18) // If dropped, it wont have a randomized pixel_x/pixel_y -#define BLOCK_CAPSAICIN 262144 // Prevents from passing capsaicin onto human +#define BLOCK_CAPSAICIN (1<<19) // Prevents from passing capsaicin onto human -#define NOSHARPENING 524288 // Prevents from sharpening item with whetstone +#define NOSHARPENING 1048576 // Prevents from sharpening item with whetstone // Update flags for [/atom/proc/update_appearance] /// Update the atom's name @@ -50,36 +51,36 @@ /* Secondary atom flags, for the flags_2 var, denoted with a _2 */ -#define SLOWS_WHILE_IN_HAND_2 1 -#define NO_EMP_WIRES_2 2 -#define HOLOGRAM_2 4 -#define FROZEN_2 8 -#define STATIONLOVING_2 16 -#define INFORM_ADMINS_ON_RELOCATE_2 32 -#define BANG_PROTECT_2 64 +#define SLOWS_WHILE_IN_HAND_2 (1<<0) +#define NO_EMP_WIRES_2 (1<<1) +#define HOLOGRAM_2 (1<<2) +#define FROZEN_2 (1<<3) +#define STATIONLOVING_2 (1<<4) +#define INFORM_ADMINS_ON_RELOCATE_2 (1<<5) +#define BANG_PROTECT_2 (1<<6) // An item worn in the ear slot with HEALS_EARS will heal your ears each // Life() tick, even if normally your ears would be too damaged to heal. -#define HEALS_EARS_2 128 +#define HEALS_EARS_2 (1<<7) // A mob with OMNITONGUE has no restriction in the ability to speak // languages that they know. So even if they wouldn't normally be able to // through mob or tongue restrictions, this flag allows them to ignore // those restrictions. -#define OMNITONGUE_2 256 +#define OMNITONGUE_2 (1<<8) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity -#define TESLA_IGNORE_2 512 +#define TESLA_IGNORE_2 (1<<9) // Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. -#define NO_MAT_REDEMPTION_2 1024 +#define NO_MAT_REDEMPTION_2 (1<<10) // LAVA_PROTECT used on the flags_2 variable for both SUIT and HEAD items, and stops lava damage. Must be present in both to stop lava damage. -#define LAVA_PROTECT_2 2048 +#define LAVA_PROTECT_2 (1<<11) -#define OVERLAY_QUEUED_2 4096 +#define OVERLAY_QUEUED_2 (1<<12) -#define CHECK_RICOCHET_2 8192 +#define CHECK_RICOCHET_2 (1<<13) #define BLOCKS_LIGHT_2 16384 @@ -92,22 +93,22 @@ #define HAS_SOCKS 4 //Species Body Flags -#define HAS_HEAD_ACCESSORY 1 -#define HAS_TAIL 2 -#define TAIL_OVERLAPPED 4 -#define HAS_SKIN_TONE 8 -#define HAS_ICON_SKIN_TONE 16 -#define HAS_SKIN_COLOR 32 -#define HAS_HEAD_MARKINGS 64 -#define HAS_BODY_MARKINGS 128 -#define HAS_TAIL_MARKINGS 256 -#define TAIL_WAGGING 512 -#define NO_EYES 1024 -#define HAS_ALT_HEADS 2048 -#define HAS_WING 4096 -#define HAS_BODYACC_COLOR 8192 -#define BALD 16384 -#define ALL_RPARTS 32768 +#define HAS_HEAD_ACCESSORY (1<<0) +#define HAS_TAIL (1<<1) +#define TAIL_OVERLAPPED (1<<2) +#define HAS_SKIN_TONE (1<<3) +#define HAS_ICON_SKIN_TONE (1<<4) +#define HAS_SKIN_COLOR (1<<5) +#define HAS_HEAD_MARKINGS (1<<6) +#define HAS_BODY_MARKINGS (1<<7) +#define HAS_TAIL_MARKINGS (1<<8) +#define TAIL_WAGGING (1<<9) +#define NO_EYES (1<<10) +#define HAS_ALT_HEADS (1<<11) +#define HAS_WING (1<<12) +#define HAS_BODYACC_COLOR (1<<13) +#define BALD (1<<14) +#define ALL_RPARTS (1<<15) //Pre-baked combinations of the above body flags #define HAS_BODY_ACCESSORY (HAS_TAIL|HAS_WING) @@ -120,22 +121,21 @@ //bitflags for door switches. -#define OPEN 1 -#define IDSCAN 2 -#define BOLTS 4 -#define SHOCK 8 -#define SAFE 16 - -//flags for pass_flags -#define PASSTABLE 1 -#define PASSGLASS 2 -#define PASSGRILLE 4 -#define PASSBLOB 8 -#define PASSMOB 16 -#define LETPASSTHROW 32 -#define PASSFENCE 64 -#define PASSDOOR 128 -#define PASS_OTHER_THINGS 256 +#define OPEN (1<<0) +#define IDSCAN (1<<1) +#define BOLTS (1<<2) +#define SHOCK (1<<3) +#define SAFE (1<<4) + +#define PASSTABLE (1<<0) +#define PASSGLASS (1<<1) +#define PASSGRILLE (1<<2) +#define PASSBLOB (1<<3) +#define PASSMOB (1<<4) +#define LETPASSTHROW (1<<5) +#define PASSFENCE (1<<6) +#define PASSDOOR (1<<7) +#define PASS_OTHER_THINGS (1<<8) #define PASS_EVERYTHING (PASSTABLE|PASSGLASS|PASSGRILLE|PASSBLOB|PASSMOB|LETPASSTHROW|PASSFENCE|PASSDOOR|PASS_OTHER_THINGS) // for /datum/var/datum_flags @@ -149,23 +149,23 @@ #define NO_RUINS 4 //ITEM INVENTORY SLOT BITMASKS -#define SLOT_OCLOTHING 1 -#define SLOT_ICLOTHING 2 -#define SLOT_GLOVES 4 -#define SLOT_EYES 8 -#define SLOT_EARS 16 -#define SLOT_MASK 32 -#define SLOT_HEAD 64 -#define SLOT_FEET 128 -#define SLOT_ID 256 -#define SLOT_BELT 512 -#define SLOT_BACK 1024 -#define SLOT_POCKET 2048 //this is to allow items with a w_class of 3 or 4 to fit in pockets. -#define SLOT_DENYPOCKET 4096 //this is to deny items with a w_class of 2 or 1 to fit in pockets. -#define SLOT_TWOEARS 8192 -#define SLOT_PDA 16384 -#define SLOT_TIE 32768 -#define SLOT_NECK 65536 +#define SLOT_OCLOTHING (1<<0) +#define SLOT_ICLOTHING (1<<1) +#define SLOT_GLOVES (1<<2) +#define SLOT_EYES (1<<3) +#define SLOT_EARS (1<<4) +#define SLOT_MASK (1<<5) +#define SLOT_HEAD (1<<6) +#define SLOT_FEET (1<<7) +#define SLOT_ID (1<<8) +#define SLOT_BELT (1<<9) +#define SLOT_BACK (1<<10) +#define SLOT_POCKET (1<<11) //this is to allow items with a w_class of 3 or 4 to fit in pockets. +#define SLOT_DENYPOCKET (1<<12) //this is to deny items with a w_class of 2 or 1 to fit in pockets. +#define SLOT_TWOEARS (1<<13) +#define SLOT_PDA (1<<14) +#define SLOT_TIE (1<<15) +#define SLOT_NECK (1<<16) //ORGAN TYPE FLAGS #define AFFECT_ROBOTIC_ORGAN 1 @@ -184,18 +184,18 @@ #define NO_MALF_EFFECT (1<<8) //So malf cannot blow certain things #define NO_MOUSTACHING (1<<9) //Saves from super hairgrowium shenanigans -#define MEAT 1 -#define VEGETABLES 2 -#define RAW 4 -#define JUNKFOOD 8 -#define GRAIN 16 -#define FRUIT 32 -#define DAIRY 64 -#define FRIED 128 -#define ALCOHOL 256 -#define SUGAR 512 -#define EGG 1024 -#define GROSS 2048 -#define TOXIC 4096 +#define MEAT (1<<0) +#define VEGETABLES (1<<1) +#define RAW (1<<2) +#define JUNKFOOD (1<<3) +#define GRAIN (1<<4) +#define FRUIT (1<<5) +#define DAIRY (1<<6) +#define FRIED (1<<7) +#define ALCOHOL (1<<8) +#define SUGAR (1<<9) +#define EGG (1<<10) +#define GROSS (1<<11) +#define TOXIC (1<<12) GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 26f271b82d9..d1c08d831bf 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -73,10 +73,11 @@ // The kind of things granted by HUD items in game, that do not manifest as // on-screen icons, but rather go to examine text. -#define EXAMINE_HUD_SECURITY_READ "security_read" -#define EXAMINE_HUD_SECURITY_WRITE "security_write" -#define EXAMINE_HUD_MEDICAL "medical" -#define EXAMINE_HUD_SKILLS "skills" +#define EXAMINE_HUD_SECURITY_READ (1<<0) //"security_read" +#define EXAMINE_HUD_SECURITY_WRITE (1<<1) //"security_write" +#define EXAMINE_HUD_MEDICAL (1<<2) //"medical" +#define EXAMINE_HUD_SKILLS (1<<3) //"skills" +#define EXAMINE_HUD_BOTANY (1<<4) //"botany" // Consider these images/atoms as part of the UI/HUD (apart of the appearance_flags) diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm index a7614b1c366..b065d72c431 100644 --- a/code/__DEFINES/language.dm +++ b/code/__DEFINES/language.dm @@ -1,22 +1,55 @@ -//Languages! -#define LANGUAGE_HUMAN 1 -#define LANGUAGE_ALIEN 2 -#define LANGUAGE_DOG 4 -#define LANGUAGE_CAT 8 -#define LANGUAGE_BINARY 16 -#define LANGUAGE_OTHER 32768 +// Language keys. +#define LANGUAGE_NONE "None" +#define LANGUAGE_NOISE "Noise" +#define LANGUAGE_UNATHI "Sinta'unathi" +#define LANGUAGE_TAJARAN "Siik'tajr" +#define LANGUAGE_VULPKANIN "Canilunzt" +#define LANGUAGE_SKRELL "Skrellian" +#define LANGUAGE_VOX "Vox-pidgin" +#define LANGUAGE_DIONA "Rootspeak" +#define LANGUAGE_TRINARY "Trinary" +#define LANGUAGE_KIDAN "Chittin" +#define LANGUAGE_SLIME "Bubblish" +#define LANGUAGE_GREY "Psionic Communication" +#define LANGUAGE_DRASK "Orluum" +#define LANGUAGE_MOTH "Tkachi" +#define LANGUAGE_GALACTIC_COMMON "Galactic Common" +#define LANGUAGE_SOL_COMMON "Sol Common" +#define LANGUAGE_TRADER "Tradeband" +#define LANGUAGE_GUTTER "Gutter" +#define LANGUAGE_CLOWN "Clownish" +#define LANGUAGE_NEO_RUSSIAN "Neo-Russkiya" +#define LANGUAGE_WRYN "Wryn Hivemind" +#define LANGUAGE_XENOS "Xenomorph" +#define LANGUAGE_HIVE_XENOS "Xenomorph Hivemind" +#define LANGUAGE_HIVE_TERRORSPIDER "Spider Hivemind" +#define LANGUAGE_HIVE_CHANGELING "Changeling Hivemind" +#define LANGUAGE_HIVE_EVENTLING "Infiltrated Changeling Hivemind" +#define LANGUAGE_HIVE_SHADOWLING "Shadowling Hivemind" +#define LANGUAGE_HIVE_ABDUCTOR "Abductor Mindlink" +#define LANGUAGE_HIVE_GOLEM "Golem Mindlink" +#define LANGUAGE_HIVE_BORER "Cortical Link" +#define LANGUAGE_BINARY "Robot Talk" +#define LANGUAGE_DRONE_BINARY "Drone Talk" +#define LANGUAGE_DRONE "Drone" +#define LANGUAGE_HIVE_SWARMER "Swarmer" +#define LANGUAGE_MONKEY_HUMAN "Chimpanzee" +#define LANGUAGE_MONKEY_SKRELL "Neara" +#define LANGUAGE_MONKEY_UNATHI "Stok" +#define LANGUAGE_MONKEY_TAJARAN "Farwa" +#define LANGUAGE_MONKEY_VULPKANIN "Wolpin" -#define LANGUAGE_UNIVERSAL 65535 -//Language flags. -#define WHITELISTED 1 // Language is available if the speaker is whitelisted. -#define RESTRICTED 2 // Language can only be accquired by spawning or an admin. -#define HIVEMIND 16 // Broadcast to all mobs with this language. -#define NONGLOBAL 32 // Do not add to general languages list -#define INNATE 64 // All mobs can be assumed to speak and understand this language (audible emotes) -#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message -#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems -#define NOBABEL 512 // Not granted by book of babel. Typically antag languages. +// Language flags. +#define WHITELISTED (1<<0) // Language is available if the speaker is whitelisted. +#define RESTRICTED (1<<1) // Language can only be accquired by spawning or an admin. +#define HIVEMIND (1<<4) // Broadcast to all mobs with this language. +#define NONGLOBAL (1<<5) // Do not add to general languages list +#define INNATE (1<<6) // All mobs can be assumed to speak and understand this language (audible emotes) +#define NO_TALK_MSG (1<<7) // Do not show the "\The [speaker] talks into \the [radio]" message +#define NO_STUTTER (1<<8) // No stuttering, slurring, or other speech problems +#define NOBABEL (1<<9) // Not granted by book of babel. Typically antag languages. +#define UNIQUE (1<<10) // Secondary languages for species. //Auto-accent level defines. #define AUTOHISS_OFF 0 diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 687490ed47e..608a444003d 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -21,63 +21,25 @@ #define APC_FULLY_CHARGED 2 //computer3 error codes, move lower in the file when it passes dev -Sayu - #define PROG_CRASH 1 // Generic crash - #define MISSING_PERIPHERAL 2 // Missing hardware - #define BUSTED_ASS_COMPUTER 4 // Self-perpetuating error. BAC will continue to crash forever. - #define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing. - #define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried. - #define NETWORK_FAILURE 32 - -#define IMPRINTER 1 //For circuits. Uses glass/chemicals. -#define PROTOLATHE 2 //New stuff. Uses glass/metal/chemicals -#define AUTOLATHE 4 //Uses glass/metal only. -#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually. -#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars. -#define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab -#define BIOGENERATOR 64 //Uses biomass -#define SMELTER 128 //uses various minerals + #define PROG_CRASH (1<<0) // Generic crash + #define MISSING_PERIPHERAL (1<<1) // Missing hardware + #define BUSTED_ASS_COMPUTER (1<<2) // Self-perpetuating error. BAC will continue to crash forever. + #define MISSING_PROGRAM (1<<3) // Some files try to automatically launch a program. This is that failing. + #define FILE_DRM (1<<4) // Some files want to not be copied/moved. This is them complaining that you tried. + #define NETWORK_FAILURE (1<<5) + +#define IMPRINTER (1<<0) //For circuits. Uses glass/chemicals. +#define PROTOLATHE (1<<1) //New stuff. Uses glass/metal/chemicals +#define AUTOLATHE (1<<2) //Uses glass/metal only. +#define CRAFTLATHE (1<<3) //Uses fuck if I know. For use eventually. +#define MECHFAB (1<<4) //Remember, objects utilising this flag should have construction_time and construction_cost vars. +#define PODFAB (1<<5) //Used by the spacepod part fabricator. Same idea as the mechfab +#define BIOGENERATOR (1<<6) //Uses biomass +#define SMELTER (1<<7) //uses various minerals //Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable. #define HYDRO_SPEED_MULTIPLIER 1 -//Modular computer/NTNet defines - -//Modular computer part defines -#define MC_CPU "CPU" -#define MC_HDD "HDD" -#define MC_SDD "SDD" -#define MC_CARD "CARD" -#define MC_NET "NET" -#define MC_PRINT "PRINT" -#define MC_CELL "CELL" -#define MC_CHARGE "CHARGE" -#define MC_AI "AI" - -//NTNet stuff, for modular computers - // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) -#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet -#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices -#define NTNET_COMMUNICATION 3 // Communication (messaging) -#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. - -//NTNet transfer speeds, used when downloading/uploading a file/program. -#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal -#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal -#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection - -//Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. -#define MAX_NTNET_LOGS 300 -#define MIN_NTNET_LOGS 10 - -//Program bitflags -#define PROGRAM_ALL 7 -#define PROGRAM_CONSOLE 1 -#define PROGRAM_LAPTOP 2 -#define PROGRAM_TABLET 4 -//Program states -#define PROGRAM_STATE_KILLED 0 -#define PROGRAM_STATE_BACKGROUND 1 -#define PROGRAM_STATE_ACTIVE 2 // Demotion Console (card/minor/*) departments #define TARGET_DEPT_GENERIC 1 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index ea60af8cb86..8dfdc2945a3 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -1,16 +1,6 @@ //Object specific defines #define CANDLE_LUM 3 //For how bright candles are -//Directions (already defined on BYOND natively, purely here for reference) -//#define NORTH 1 -//#define SOUTH 2 -//#define EAST 4 -//#define WEST 8 -//#define NORTHEAST 5 -//#define SOUTHEAST 6 -//#define NORTHWEST 9 -//#define SOUTHWEST 10 - //Security levels #define SEC_LEVEL_GREEN 0 #define SEC_LEVEL_BLUE 1 @@ -179,39 +169,39 @@ #define MFOAM_IRON 2 //Human Overlays Indexes///////// -#define BODY_LAYER 43 -#define MUTANTRACE_LAYER 42 -#define WING_UNDERLIMBS_LAYER 41 -#define TAIL_UNDERLIMBS_LAYER 40 //Tail split-rendering. -#define LIMBS_LAYER 39 -#define INTORGAN_LAYER 38 -#define MARKINGS_LAYER 37 -#define UNDERWEAR_LAYER 36 -#define MUTATIONS_LAYER 35 -#define H_DAMAGE_LAYER 34 -#define UNIFORM_LAYER 33 -#define SHOES_LAYER 32 -#define OVER_SHOES_LAYER 31 -#define ID_LAYER 30 -#define GLOVES_LAYER 29 -#define EARS_LAYER 28 -#define SUIT_LAYER 27 -#define BELT_LAYER 26 //Possible make this an overlay of somethign required to wear a belt? -#define NECK_LAYER 25 -#define SUIT_STORE_LAYER 24 -#define BACK_LAYER 23 -#define HEAD_ACCESSORY_LAYER 22 -#define FHAIR_LAYER 21 -#define GLASSES_LAYER 20 -#define HAIR_LAYER 19 //TODO: make part of head layer? -#define HEAD_ACC_OVER_LAYER 18 //Select-layer rendering. -#define FHAIR_OVER_LAYER 17 //Select-layer rendering. -#define GLASSES_OVER_LAYER 16 //Select-layer rendering. -#define WING_LAYER 15 -#define TAIL_LAYER 14 //bs12 specific. this hack is probably gonna come back to haunt me -#define FACEMASK_LAYER 13 -#define OVER_MASK_LAYER 12 //Select-layer rendering. -#define HEAD_LAYER 11 +#define MUTANTRACE_LAYER 43 +#define WING_UNDERLIMBS_LAYER 42 +#define TAIL_UNDERLIMBS_LAYER 41 //Tail split-rendering. +#define LIMBS_LAYER 40 +#define INTORGAN_LAYER 39 +#define MARKINGS_LAYER 38 +#define UNDERWEAR_LAYER 37 +#define MUTATIONS_LAYER 36 +#define H_DAMAGE_LAYER 35 +#define UNIFORM_LAYER 34 +#define SHOES_LAYER 33 +#define OVER_SHOES_LAYER 32 +#define ID_LAYER 31 +#define GLOVES_LAYER 30 +#define EARS_LAYER 29 +#define SUIT_LAYER 28 +#define BELT_LAYER 27 //Possible make this an overlay of somethign required to wear a belt? +#define NECK_LAYER 26 +#define SUIT_STORE_LAYER 25 +#define BACK_LAYER 24 +#define HEAD_ACCESSORY_LAYER 23 +#define FHAIR_LAYER 22 +#define GLASSES_LAYER 21 +#define HAIR_LAYER 20 //TODO: make part of head layer? +#define HEAD_ACC_OVER_LAYER 19 //Select-layer rendering. +#define FHAIR_OVER_LAYER 18 //Select-layer rendering. +#define GLASSES_OVER_LAYER 17 //Select-layer rendering. +#define WING_LAYER 16 +#define TAIL_LAYER 15 //bs12 specific. this hack is probably gonna come back to haunt me +#define FACEMASK_LAYER 14 +#define OVER_MASK_LAYER 13 //Select-layer rendering. +#define HEAD_LAYER 12 +#define OVER_HEAD_LAYER 11 #define COLLAR_LAYER 10 #define HANDCUFF_LAYER 9 #define LEGCUFF_LAYER 8 @@ -222,7 +212,7 @@ #define FIRE_LAYER 3 //If you're on fire #define MISC_LAYER 2 #define FROZEN_LAYER 1 -#define TOTAL_LAYERS 43 +#define TOTAL_LAYERS 44 ///Access Region Codes/// #define REGION_ALL 0 @@ -385,7 +375,7 @@ #define EXPLOSION_BLOCK_PROC -1 // The SQL version required by this version of the code -#define SQL_VERSION 31 +#define SQL_VERSION 33 // Vending machine stuff #define CAT_NORMAL 1 @@ -412,9 +402,9 @@ // Defib stats /// Past this much time the patient is unrecoverable (in deciseconds). -#define DEFIB_TIME_LIMIT 300 SECONDS +#define DEFIB_TIME_LIMIT (300 SECONDS) /// Brain damage starts setting in on the patient after some time left rotting. -#define DEFIB_TIME_LOSS 60 SECONDS +#define DEFIB_TIME_LOSS (60 SECONDS) //different types of atom colorations #define ADMIN_COLOUR_PRIORITY 1 //only used by rare effects like greentext coloring mobs and when admins varedit color @@ -489,15 +479,15 @@ #define SYMPTOM_ACTIVATION_PROB 3 // Atmos stuff that fucking terrifies me -#define LINDA_SPAWN_HEAT 1 -#define LINDA_SPAWN_20C 2 -#define LINDA_SPAWN_TOXINS 4 -#define LINDA_SPAWN_OXYGEN 8 -#define LINDA_SPAWN_CO2 16 -#define LINDA_SPAWN_NITROGEN 32 -#define LINDA_SPAWN_N2O 64 -#define LINDA_SPAWN_AGENT_B 128 -#define LINDA_SPAWN_AIR 256 +#define LINDA_SPAWN_HEAT (1<<0) +#define LINDA_SPAWN_20C (1<<1) +#define LINDA_SPAWN_TOXINS (1<<2) +#define LINDA_SPAWN_OXYGEN (1<<3) +#define LINDA_SPAWN_CO2 (1<<4) +#define LINDA_SPAWN_NITROGEN (1<<5) +#define LINDA_SPAWN_N2O (1<<6) +#define LINDA_SPAWN_AGENT_B (1<<7) +#define LINDA_SPAWN_AIR (1<<8) /// Send to the primary Discord webhook #define DISCORD_WEBHOOK_PRIMARY "PRIMARY" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 1469782fad1..104c46a08c4 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -1,12 +1,12 @@ ///////////////////ORGAN DEFINES/////////////////// // Organ defines. -#define ORGAN_BROKEN 1 -#define ORGAN_ROBOT 2 -#define ORGAN_SPLINTED 4 -#define ORGAN_DEAD 8 -#define ORGAN_MUTATED 16 -#define ORGAN_INT_BLEED 32 +#define ORGAN_BROKEN (1<<0) +#define ORGAN_ROBOT (1<<1) +#define ORGAN_SPLINTED (1<<2) +#define ORGAN_DEAD (1<<3) +#define ORGAN_MUTATED (1<<4) +#define ORGAN_INT_BLEED (1<<5) #define PROCESS_ACCURACY 10 @@ -86,24 +86,24 @@ #define SYNTHETIC 2 // Appearance change flags -#define APPEARANCE_UPDATE_DNA 1 -#define APPEARANCE_RACE 2|APPEARANCE_UPDATE_DNA -#define APPEARANCE_GENDER 4|APPEARANCE_UPDATE_DNA -#define APPEARANCE_SKIN 8 -#define APPEARANCE_HAIR 16 -#define APPEARANCE_HAIR_COLOR 32 -#define APPEARANCE_SECONDARY_HAIR_COLOR 64 -#define APPEARANCE_FACIAL_HAIR 128 -#define APPEARANCE_FACIAL_HAIR_COLOR 256 -#define APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR 512 -#define APPEARANCE_EYE_COLOR 1024 +#define APPEARANCE_UPDATE_DNA (1<<0) +#define APPEARANCE_RACE (1<<1|APPEARANCE_UPDATE_DNA) +#define APPEARANCE_GENDER (1<<2|APPEARANCE_UPDATE_DNA) +#define APPEARANCE_SKIN (1<<3) +#define APPEARANCE_HAIR (1<<4) +#define APPEARANCE_HAIR_COLOR (1<<5) +#define APPEARANCE_SECONDARY_HAIR_COLOR (1<<6) +#define APPEARANCE_FACIAL_HAIR (1<<7) +#define APPEARANCE_FACIAL_HAIR_COLOR (1<<8) +#define APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR (1<<9) +#define APPEARANCE_EYE_COLOR (1<<10) #define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_SECONDARY_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR|APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR -#define APPEARANCE_HEAD_ACCESSORY 2048 -#define APPEARANCE_MARKINGS 4096 -#define APPEARANCE_BODY_ACCESSORY 8192 -#define APPEARANCE_ALT_HEAD 16384 +#define APPEARANCE_HEAD_ACCESSORY (1<<11) +#define APPEARANCE_MARKINGS (1<<12) +#define APPEARANCE_BODY_ACCESSORY (1<<13) +#define APPEARANCE_ALT_HEAD (1<<14) #define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY|APPEARANCE_ALT_HEAD -#define APPEARANCE_ALL 32767 +#define APPEARANCE_ALL APPEARANCE_RACE|APPEARANCE_GENDER|APPEARANCE_SKIN|APPEARANCE_EYE_COLOR|APPEARANCE_ALL_HAIR|APPEARANCE_ALL_BODY #define STAMINA_REGEN_BLOCK_TIME (10 SECONDS) @@ -181,11 +181,11 @@ #define TINT_BLIND 3 //Threshold of tint level to obscure vision fully #define EYE_SHINE_THRESHOLD 6 //dark_view threshold past which a humanoid's eyes will 'shine' in the dark. -#define STATUS_UPDATE_HEALTH 1 -#define STATUS_UPDATE_STAT 2 -#define STATUS_UPDATE_STAMINA 8 -#define STATUS_UPDATE_BLIND 16 -#define STATUS_UPDATE_NEARSIGHTED 64 +#define STATUS_UPDATE_HEALTH (1<<0) +#define STATUS_UPDATE_STAT (1<<1) +#define STATUS_UPDATE_STAMINA (1<<2) +#define STATUS_UPDATE_BLIND (1<<3) +#define STATUS_UPDATE_NEARSIGHTED (1<<4) #define STATUS_UPDATE_NONE 0 #define STATUS_UPDATE_ALL (~0) diff --git a/code/__DEFINES/organ_defines.dm b/code/__DEFINES/organ_defines.dm index 06300d2d299..f71a01b32c0 100644 --- a/code/__DEFINES/organ_defines.dm +++ b/code/__DEFINES/organ_defines.dm @@ -54,3 +54,6 @@ #define ORGAN_MANIPULATION_NOEFFECT 1 #define ORGAN_MANIPULATION_ABDUCTOR 2 +/// used for species that can see without eyes +#define NO_VISION_ORGAN "no_vision_organ" + diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 11c09d747fe..b781d9496c2 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -1,42 +1,42 @@ //Preference toggles -#define SOUND_ADMINHELP 1 -#define SOUND_MIDI 2 -#define SOUND_AMBIENCE 4 -#define SOUND_LOBBY 8 -#define SOUND_HEARTBEAT 32 -#define SOUND_BUZZ 64 -#define SOUND_INSTRUMENTS 128 -#define SOUND_MENTORHELP 256 -#define SOUND_DISCO 512 -#define SOUND_AI_VOICE 1024 -#define SOUND_PRAYERNOTIFY 2048 +#define SOUND_ADMINHELP (1<<0) +#define SOUND_MIDI (1<<1) +#define SOUND_AMBIENCE (1<<2) +#define SOUND_LOBBY (1<<3) +#define SOUND_HEARTBEAT (1<<5) // 16 is lost, don't touch because it's prefs +#define SOUND_BUZZ (1<<6) +#define SOUND_INSTRUMENTS (1<<7) +#define SOUND_MENTORHELP (1<<8) +#define SOUND_DISCO (1<<9) +#define SOUND_AI_VOICE (1<<10) +#define SOUND_PRAYERNOTIFY (1<<11) #define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP|SOUND_DISCO|SOUND_AI_VOICE|SOUND_PRAYERNOTIFY) -#define PREFTOGGLE_CHAT_OOC 1 -#define PREFTOGGLE_CHAT_DEAD 2 -#define PREFTOGGLE_CHAT_GHOSTEARS 4 -#define PREFTOGGLE_CHAT_GHOSTSIGHT 8 -#define PREFTOGGLE_CHAT_PRAYER 16 -#define PREFTOGGLE_CHAT_RADIO 32 -#define PREFTOGGLE_AZERTY 64 -#define PREFTOGGLE_CHAT_DEBUGLOGS 128 -#define PREFTOGGLE_CHAT_LOOC 256 -#define PREFTOGGLE_CHAT_GHOSTRADIO 512 -#define PREFTOGGLE_SHOW_TYPING 1024 -#define PREFTOGGLE_DISABLE_SCOREBOARD 2048 -#define PREFTOGGLE_DISABLE_KARMA_REMINDER 4096 -#define PREFTOGGLE_MEMBER_PUBLIC 8192 -#define PREFTOGGLE_CHAT_NO_ADMINLOGS 16384 -#define PREFTOGGLE_DONATOR_PUBLIC 32768 -#define PREFTOGGLE_CHAT_NO_TICKETLOGS 65536 -#define PREFTOGGLE_UI_DARKMODE 131072 -#define PREFTOGGLE_DISABLE_KARMA 262144 -#define PREFTOGGLE_CHAT_NO_MENTORTICKETLOGS 524288 -#define PREFTOGGLE_TYPING_ONCE 1048576 -#define PREFTOGGLE_AMBIENT_OCCLUSION 2097152 -#define PREFTOGGLE_CHAT_GHOSTPDA 4194304 -#define PREFTOGGLE_NUMPAD_TARGET 8388608 +#define PREFTOGGLE_CHAT_OOC (1<<0) +#define PREFTOGGLE_CHAT_DEAD (1<<1) +#define PREFTOGGLE_CHAT_GHOSTEARS (1<<2) +#define PREFTOGGLE_CHAT_GHOSTSIGHT (1<<3) +#define PREFTOGGLE_CHAT_PRAYER (1<<4) +#define PREFTOGGLE_CHAT_RADIO (1<<5) +#define PREFTOGGLE_AZERTY (1<<6) +#define PREFTOGGLE_CHAT_DEBUGLOGS (1<<7) +#define PREFTOGGLE_CHAT_LOOC (1<<8) +#define PREFTOGGLE_CHAT_GHOSTRADIO (1<<9) +#define PREFTOGGLE_SHOW_TYPING (1<<10) +#define PREFTOGGLE_DISABLE_SCOREBOARD (1<<11) +#define PREFTOGGLE_DISABLE_KARMA_REMINDER (1<<12) +#define PREFTOGGLE_MEMBER_PUBLIC (1<<13) +#define PREFTOGGLE_CHAT_NO_ADMINLOGS (1<<14) +#define PREFTOGGLE_DONATOR_PUBLIC (1<<15) +#define PREFTOGGLE_CHAT_NO_TICKETLOGS (1<<16) +#define PREFTOGGLE_UI_DARKMODE (1<<17) +#define PREFTOGGLE_DISABLE_KARMA (1<<18) +#define PREFTOGGLE_CHAT_NO_MENTORTICKETLOGS (1<<19) +#define PREFTOGGLE_TYPING_ONCE (1<<20) +#define PREFTOGGLE_AMBIENT_OCCLUSION (1<<21) +#define PREFTOGGLE_CHAT_GHOSTPDA (1<<22) +#define PREFTOGGLE_NUMPAD_TARGET (1<<23) #define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm index 2172af93c3f..0d5444360be 100644 --- a/code/__DEFINES/radio.dm +++ b/code/__DEFINES/radio.dm @@ -1,5 +1,4 @@ -#define DISPLAY_FREQ 1435 //status displays #define ATMOS_FIRE_FREQ 1437 //air alarms #define ENGINE_FREQ 1438 //engine components #define ATMOS_VENTSCRUB 1439 //vents, scrubbers, atmos control diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 564247455e3..5adb7da9ce5 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -5,14 +5,14 @@ #define REAGENT_OVERDOSE_EFFECT 1 #define REAGENT_OVERDOSE_FLAGS 2 // container_type defines -#define INJECTABLE 1 // Makes it possible to add reagents through droppers and syringes. -#define DRAWABLE 2 // Makes it possible to remove reagents through syringes. +#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. -#define REFILLABLE 4 // Makes it possible to add reagents through any reagent container. -#define DRAINABLE 8 // Makes it possible to remove reagents through any reagent container. +#define REFILLABLE (1<<3) // Makes it possible to add reagents through any reagent container. +#define DRAINABLE (1<<4) // Makes it possible to remove reagents through any reagent container. -#define TRANSPARENT 16 // Used on containers which you want to be able to see the reagents off. -#define AMOUNT_VISIBLE 32 // For non-transparent containers that still have the general amount of reagents in them visible. +#define TRANSPARENT (1<<5) // Used on containers which you want to be able to see the reagents off. +#define AMOUNT_VISIBLE (1<<6) // For non-transparent containers that still have the general amount of reagents in them visible. // Is an open container for all intents and purposes. #define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT) diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index a77a63cfcd6..9d647fec8e9 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -43,8 +43,13 @@ #define ANTAGHUD 3 //for clothing visor toggles, these determine which vars to toggle -#define VISOR_FLASHPROTECT (1<<0) -#define VISOR_TINT (1<<1) -#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses -#define VISOR_DARKNESSVIEW (1<<3) -#define VISOR_INVISVIEW (1<<4) +#define VISOR_FLASHPROTECT (1<<0) +#define VISOR_TINT (1<<1) +#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses +#define VISOR_DARKNESSVIEW (1<<3) +#define VISOR_INVISVIEW (1<<4) +#define VISOR_HUDTYPE (1<<5) +#define VISOR_EXAM_EXTENTIONS (1<<6) + + +#define VISOR_FULL_HUD (VISOR_HUDTYPE|VISOR_EXAM_EXTENTIONS) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 11f779692d8..e34a81282b1 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -10,11 +10,11 @@ #define STATUS_CLOSE -1 // Close the interface // bitflags for machine stat variable -#define BROKEN 1 -#define NOPOWER 2 -#define POWEROFF 4 // tbd -#define MAINT 8 // under maintaince -#define EMPED 16 // temporary broken by EMP pulse +#define BROKEN (1<<0) +#define NOPOWER (1<<1) +#define POWEROFF (1<<2) // tbd +#define MAINT (1<<3) // under maintaince +#define EMPED (1<<4) // temporary broken by EMP pulse /* Shuttles diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3c2181f8f93..dcc2deffba4 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -80,6 +80,7 @@ #define INIT_ORDER_CARGO_QUESTS -23 #define INIT_ORDER_NIGHTSHIFT -24 #define INIT_ORDER_NANOMOB -25 +#define INIT_ORDER_GAME_EVENTS -26 #define INIT_ORDER_PATH -50 #define INIT_ORDER_PERSISTENCE -95 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 8183767ec15..1dd34ff1a1c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -44,14 +44,14 @@ // Setup languages for(var/language_name in GLOB.all_languages) - var/datum/language/L = GLOB.all_languages[language_name] - if(!(L.flags & NONGLOBAL)) - GLOB.language_keys[":[lowertext(L.key)]"] = L - GLOB.language_keys[".[lowertext(L.key)]"] = L - GLOB.language_keys["#[lowertext(L.key)]"] = L - GLOB.language_keys[":[sanitize_english_string_to_russian(L.key)]"] = L - GLOB.language_keys[".[sanitize_english_string_to_russian(L.key)]"] = L - GLOB.language_keys["#[sanitize_english_string_to_russian(L.key)]"] = L + var/datum/language/language = GLOB.all_languages[language_name] + if(!(language.flags & NONGLOBAL)) + GLOB.language_keys[":[lowertext(language.key)]"] = language + GLOB.language_keys[".[lowertext(language.key)]"] = language + GLOB.language_keys["#[lowertext(language.key)]"] = language + GLOB.language_keys[":[sanitize_english_string_to_russian(language.key)]"] = language + GLOB.language_keys[".[sanitize_english_string_to_russian(language.key)]"] = language + GLOB.language_keys["#[sanitize_english_string_to_russian(language.key)]"] = language var/rkey = 0 for(var/spath in subtypesof(/datum/species)) diff --git a/code/__HELPERS/path.dm b/code/__HELPERS/path.dm index 10daae7ee77..ecad98b7fd4 100644 --- a/code/__HELPERS/path.dm +++ b/code/__HELPERS/path.dm @@ -39,6 +39,25 @@ path.Cut(1, 2) return path + +/proc/is_path_exist(atom/source, atom/target, pass_flags = PASSTABLE|PASSGRILLE|PASSFENCE|PASSMOB) + var/obj/dummy = new(source.loc) + dummy.pass_flags |= pass_flags + dummy.density = TRUE + for(var/turf/turf in getline(source, target)) + if(!turf.CanPass(dummy, turf, 1)) + qdel(dummy) + return FALSE + for(var/atom/movable/AM in turf) + if(AM == source || AM == dummy) + continue + if(!AM.CanPass(dummy, turf, 1)) + qdel(dummy) + return FALSE + qdel(dummy) + return TRUE + + /** * A helper macro to see if it's possible to step from the first turf into the second one, minding things like door access and directional windows. * Note that this can only be used inside the [datum/pathfind][pathfind datum] since it uses variables from said datum. diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index efd68afed06..a39cc927b5b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -737,7 +737,7 @@ Returns 1 if the chain up to the area contains the given typepath var/obj/corner = new() corner.loc = X corner.density = 1 - corner.anchored = 1 + corner.anchored = TRUE corner.icon = X.icon corner.icon_state = replacetext(X.icon_state, "_s", "_f") corner.tag = "delete me" diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index e3d450ad800..6618eb1d9aa 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -46,7 +46,9 @@ GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals", //1 "CMO Office", "Chemistry", "Research", "RD Office", //10, 11, 12 ,13 "Robotics", "HoP Office", "Library", "Chapel", //14, 15, 16, 17 "Captain's Office", "Bar", "Kitchen", "Hydroponics", //18, 19, 20, 21 - "Janitor Closet","Genetics","Brig Physician", "Morgue")) //22, 23, 24, 25 + "Janitor Closet","Genetics","Brig Physician", "Morgue", //22, 23, 24, 25 + "NTRep Office", "Detective", "Magistrate's Office", "IAA Office", //26, 27, 28, 29 + "Mechanic")) // 30 GLOBAL_LIST_INIT(hit_appends, list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 1d87b5f1bfe..0e48557ed89 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -3,7 +3,7 @@ var/actiontooltipstyle = "" screen_loc = null var/ordered = TRUE - + var/datum/keybinding/mob/trigger_action_button/linked_keybind /obj/screen/movable/action_button/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) if(locked && could_be_click_lag()) // in case something bad happend and game realised we dragged our ability instead of pressing it @@ -34,6 +34,9 @@ /obj/screen/movable/action_button/Click(location,control,params) var/list/modifiers = params2list(params) + if(modifiers["ctrl"] && modifiers["shift"]) + INVOKE_ASYNC(src, PROC_REF(set_to_keybind), usr) + return TRUE if(usr.next_click > world.time) return FALSE usr.changeNext_click(1) @@ -62,16 +65,43 @@ animate(src, transform = matrix(), time = 0.3 SECONDS, alpha = prev_alpha) return TRUE +/obj/screen/movable/action_button/proc/set_to_keybind(mob/user) + var/keybind_to_set_to = sanitize_russian_key_to_english(input(user, "What keybind do you want to set this action button to? You can use non-single keys, but they must be in the correct case, f.e. \"Space\" or \"CtrlE\"") as text) + if(length(keybind_to_set_to) == 1) + keybind_to_set_to = uppertext(keybind_to_set_to) + if(keybind_to_set_to) + if(linked_keybind) + clean_up_keybinds(user) + var/datum/keybinding/mob/trigger_action_button/triggerer = new + triggerer.linked_action = linked_action + user.client.active_keybindings[keybind_to_set_to] += list(triggerer) + linked_keybind = triggerer + triggerer.binded_to = keybind_to_set_to + to_chat(user, span_info("[src] has been binded to [keybind_to_set_to]!")) + else if(linked_keybind) + clean_up_keybinds(user) + to_chat(user, span_info("Your active keybinding on [src] has been cleared.")) + /obj/screen/movable/action_button/AltClick(mob/user) . = linked_action.AltTrigger() linked_action.UpdateButtonIcon() +/obj/screen/movable/action_button/proc/clean_up_keybinds(mob/owner) + if(linked_keybind) + owner.client.active_keybindings[linked_keybind.binded_to] -= (linked_keybind) + if(!length(owner.client.active_keybindings[linked_keybind.binded_to])) + owner.client.active_keybindings[linked_keybind.binded_to] = null + owner.client.active_keybindings -= linked_keybind.binded_to + QDEL_NULL(linked_keybind) + //Hide/Show Action Buttons ... Button /obj/screen/movable/action_button/hide_toggle name = "Hide Buttons" - desc = "Shift-click any button to reset its position, and Control-click it to lock/unlock its position. Alt-click this button to reset all buttons to their default positions." + desc = "Shift-click any button to reset its position, and Control-click it to lock/unlock its position. \ +
Alt-click this button to reset all buttons to their default positions. \ +
Control-Shift-click on any button to bind it to a hotkey." icon = 'icons/mob/actions/actions.dmi' icon_state = "bg_default" var/hidden = FALSE @@ -140,7 +170,14 @@ /obj/screen/movable/action_button/MouseEntered(location, control, params) if(!QDELETED(src)) - openToolTip(usr, src, params, title = name, content = desc, theme = actiontooltipstyle) + if(!linked_keybind) + openToolTip(usr, src, params, title = name, content = desc, theme = actiontooltipstyle) + else + var/list/desc_information = list() + desc_information += desc + desc_information += "This action is currently bound to the [linked_keybind.binded_to] key." + desc_information = desc_information.Join(" ") + openToolTip(usr, src, params, title = name, content = desc_information, theme = actiontooltipstyle) /obj/screen/movable/action_button/MouseExited() diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index 12d6c020331..0804ceb287f 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,6 +1,7 @@ /mob/dead/observer/create_mob_hud() if(client && !hud_used) hud_used = new /datum/hud/ghost(src) + SEND_SIGNAL(src, COMSIG_MOB_HUD_CREATED) /obj/screen/ghost icon = 'icons/mob/screen_ghost.dmi' diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 248ea88aa78..3bb9e41f6ee 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -279,8 +279,27 @@ if(!choice) return TRUE + if(PL["alt"]) + AltClick(usr, choice) + return + return set_selected_zone(choice) +/obj/screen/zone_sel/AltClick(mob/user, choice) + + if(user.next_click > world.time || user.next_move > world.time) + return FALSE + user.changeNext_click(1) + + var/obj/item/holding_item = user.get_active_hand() + var/old_selecting = selecting + if(!istype(holding_item)) + return FALSE + if(!set_selected_zone(choice, FALSE)) + return FALSE + holding_item.melee_attack_chain(user, user) + set_selected_zone(old_selecting, FALSE) + /obj/screen/zone_sel/MouseEntered(location, control, params) MouseMove(location, control, params) @@ -378,7 +397,7 @@ return BODY_ZONE_WING -/obj/screen/zone_sel/proc/set_selected_zone(choice) +/obj/screen/zone_sel/proc/set_selected_zone(choice, update_overlay = TRUE) if(!hud || !hud.mymob) return FALSE @@ -388,7 +407,8 @@ if(choice != selecting) selecting = choice hud.mymob.zone_selected = choice - update_icon(UPDATE_OVERLAYS) + if(update_overlay) + update_icon(UPDATE_OVERLAYS) return TRUE diff --git a/code/controllers/subsystem/game_events.dm b/code/controllers/subsystem/game_events.dm new file mode 100644 index 00000000000..75e0214624d --- /dev/null +++ b/code/controllers/subsystem/game_events.dm @@ -0,0 +1,25 @@ +///This is a subsystem, which helps to process game modes through time. +SUBSYSTEM_DEF(game_events) + name = "Game events" + wait = 5 MINUTES + cpu_display = SS_CPUDISPLAY_LOW + offline_implications = "Timed Gamemode events and other events won't be processed. No immediate action is needed." + ss_id = "game_modes" + init_order = INIT_ORDER_GAME_EVENTS + var/list/processing = list() + +/datum/controller/subsystem/game_events/Initialize() + return + +/datum/controller/subsystem/game_events/proc/add_to_process(datum/event) + if(!istype(event)) + return FALSE + processing |= event + return TRUE + +/datum/controller/subsystem/game_events/fire(resumed) + for(var/datum/event as anything in processing) + if(event.process() == PROCESS_KILL) + processing -= event + + diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index dda48fc7f27..4be246df7da 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -531,8 +531,7 @@ SUBSYSTEM_DEF(jobs) if(equipped != 1) var/obj/item/clothing/glasses/G = H.glasses if(istype(G) && !G.prescription) - G.prescription = TRUE - G.name = "prescription [G.name]" + G.upgrade_prescription() H.update_nearsighted_effects() return H diff --git a/code/controllers/subsystem/processing/transittube.dm b/code/controllers/subsystem/processing/transittube.dm new file mode 100644 index 00000000000..1e9f4ec8ed6 --- /dev/null +++ b/code/controllers/subsystem/processing/transittube.dm @@ -0,0 +1,7 @@ +PROCESSING_SUBSYSTEM_DEF(transit_tube) + name = "Transit Tubes" + wait = 1 + flags = SS_NO_INIT|SS_BACKGROUND + offline_implications = "Transit tubes will no longer function. Admin intervention recommended, but shuttle call not required." + cpu_display = SS_CPUDISPLAY_DEFAULT + ss_id = "transit_tube" diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 92bc5e437c1..823e70b46c5 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -32,6 +32,7 @@ SUBSYSTEM_DEF(shuttle) var/points_per_crate = 5 //points gained per crate returned var/points_per_intel = 250 //points gained per intel returned var/centcom_message = null //Remarks from Centcom on how well you checked the last order. + var/datum/money_account/cargo_money_account var/list/techLevels = list() var/list/shoppinglist = list() var/list/requestlist = list() @@ -45,6 +46,8 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/Initialize() ordernum = rand(1,9000) + cargo_money_account = GLOB.department_accounts["Cargo"] + if(!emergency) WARNING("No /obj/docking_port/mobile/emergency placed on the map!") if(!backup_shuttle) diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index af8d9c4e464..a6c26c47b36 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -37,7 +37,7 @@ SUBSYSTEM_DEF(spacedrift) continue if(!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0)) - AM.inertia_dir = 0 + AM.inertia_dir = NONE if(!AM.inertia_dir) AM.inertia_last_loc = null @@ -53,7 +53,7 @@ SUBSYSTEM_DEF(spacedrift) AM.inertia_moving = FALSE AM.inertia_next_move = world.time + AM.inertia_move_delay if(AM.loc == old_loc) - AM.inertia_dir = 0 + AM.inertia_dir = NONE AM.setDir(old_dir) AM.inertia_last_loc = AM.loc diff --git a/code/datums/action.dm b/code/datums/action.dm index fc52021eebd..380701e6ac1 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -13,14 +13,13 @@ var/icon_icon = 'icons/mob/actions/actions.dmi' var/mob/owner -/datum/action/New(var/Target) +/datum/action/New(Target) target = Target button = new button.linked_action = src button.name = name button.actiontooltipstyle = buttontooltipstyle - if(desc) - button.desc = desc + button.desc = desc /datum/action/Destroy() if(owner) @@ -54,6 +53,7 @@ if(user.client) user.client.screen -= button + button.clean_up_keybinds(user) button.moved = FALSE //so the button appears in its normal position when given to another owner. button.locked = FALSE diff --git a/code/datums/cache/apc.dm b/code/datums/cache/apc.dm index 29f74b35d5b..b27897d94ba 100644 --- a/code/datums/cache/apc.dm +++ b/code/datums/cache/apc.dm @@ -28,7 +28,7 @@ GLOBAL_DATUM_INIT(apc_repository, /datum/repository/apc, new()) "Environment" = Status[A.environment_channel + 1], "CellPct" = A.cell ? round(A.cell.percent(), 1) : 0, "CellStatus" = A.cell ? chg[A.charging + 1] : "M", - "Load" = round(A.lastused_total, 1) + "Load" = round(A.last_used_total, 1) ) cache_entry.timestamp = world.time + 5 SECONDS diff --git a/code/datums/components/defibrillator.dm b/code/datums/components/defibrillator.dm new file mode 100644 index 00000000000..d17a6c78443 --- /dev/null +++ b/code/datums/components/defibrillator.dm @@ -0,0 +1,387 @@ +/** + * A component for an item that attempts to defibrillate a mob when activated. + */ +/datum/component/defib + /// If this is being used by a borg or not, with necessary safeties applied if so. + var/robotic + /// If it should penetrate space suits + var/combat + /// If combat is true, this determines whether or not it should always cause a heart attack. + var/heart_attack_chance + /// Whether the safeties are enabled or not + var/safety + /// If the defib is actively performing a defib cycle + var/busy = FALSE + /// Cooldown length for this defib in deciseconds + var/cooldown + /// Whether or not we're currently on cooldown + var/on_cooldown = FALSE + /// How fast the defib should work. + var/speed_multiplier + /// If true, EMPs will have no effect. + var/emp_proof + /// If true, this cannot be emagged. + var/emag_proof + /// uid to an item that should be making noise and handling things that our direct parent shouldn't be concerned with. + var/actual_unit_uid + +/** + * Create a new defibrillation component. + * + * Arguments: + * * robotic - whether this should be treated like a borg module. + * * cooldown - Minimum time possible between shocks. + * * speed_multiplier - Speed multiplier for defib do-afters. + * * combat - If true, the defib can zap through hardsuits. + * * heart_attack_chance - If combat and safeties are off, the % chance for this to cause a heart attack on harm intent. + * * safe_by_default - If true, safety will be enabled by default. + * * emp_proof - If true, safety won't be switched by emp. Note that the device itself can still have behavior from it, it's just that the component will not. + * * emag_proof - If true, safety won't be switched by emag. Note that the device itself can still have behavior from it, it's just that the component will not. + * * actual_unit - Unit which the component's parent is based from, such as a large defib unit or a borg. The actual_unit will make the sounds and be the "origin" of visible messages, among other things. + */ +/datum/component/defib/Initialize(robotic, cooldown = 5 SECONDS, speed_multiplier = 1, combat = FALSE, heart_attack_chance = 100, safe_by_default = TRUE, emp_proof = FALSE, emag_proof = FALSE, obj/item/actual_unit = null) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + + src.robotic = robotic + src.speed_multiplier = speed_multiplier + src.cooldown = cooldown + src.combat = combat + src.heart_attack_chance = heart_attack_chance + safety = safe_by_default + src.emp_proof = emp_proof + src.emag_proof = emag_proof + + if(actual_unit) + actual_unit_uid = actual_unit.UID() + + var/effect_target = isnull(actual_unit) ? parent : actual_unit + + RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(trigger_defib)) + RegisterSignal(effect_target, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag)) + RegisterSignal(effect_target, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp)) + +/** + * Get the "parent" that effects (emags, EMPs) should be applied onto. + */ +/datum/component/defib/proc/get_effect_target() + var/actual_unit = locateUID(actual_unit_uid) + if(!actual_unit) + return parent + return actual_unit + +/datum/component/defib/proc/on_emp(obj/item/unit) + SIGNAL_HANDLER // COMSIG_ATOM_EMP_ACT + if(emp_proof) + return + + if(safety) + safety = FALSE + unit.visible_message(span_warning("[unit] beeps: Safety protocols disabled!")) + playsound(get_turf(unit), 'sound/machines/defib_saftyoff.ogg', 50, 0) + else + safety = TRUE + unit.visible_message(span_notice("[unit] beeps: Safety protocols enabled!")) + playsound(get_turf(unit), 'sound/machines/defib_saftyon.ogg', 50, 0) + +/datum/component/defib/proc/on_emag(obj/item/unit, mob/user) + SIGNAL_HANDLER // COMSIG_ATOM_EMAG_ACT + if(emag_proof) + return + safety = !safety + if(user && !robotic) + to_chat(user, span_warning("You silently [safety ? "disable" : "enable"] [unit]'s safety protocols with the card.")) + +/datum/component/defib/proc/set_cooldown(how_short) + on_cooldown = TRUE + addtimer(CALLBACK(src, PROC_REF(end_cooldown)), how_short) + +/datum/component/defib/proc/end_cooldown() + on_cooldown = FALSE + SEND_SIGNAL(parent, COMSIG_DEFIB_READY) + +/** + * Start the defibrillation process when triggered by a signal. + */ +/datum/component/defib/proc/trigger_defib(obj/item/paddles, mob/living/carbon/human/target, mob/living/user) + SIGNAL_HANDLER // COMSIG_ITEM_ATTACK + // This includes some do-afters, so we have to pass it off asynchronously + INVOKE_ASYNC(src, PROC_REF(defibrillate), user, target) + return TRUE + +/** + * Perform a defibrillation. + */ +/datum/component/defib/proc/defibrillate(mob/living/user, mob/living/carbon/human/target) + // Before we do all the hard work, make sure we aren't already defibbing someone + if(busy) + return + + var/parent_unit = locateUID(actual_unit_uid) + var/should_cause_harm = user.a_intent == INTENT_HARM && !safety + + // Find what the defib should be referring to itself as + var/atom/defib_ref + if(parent_unit) + defib_ref = parent_unit + else if(robotic) + defib_ref = user + if(!defib_ref) // Contingency + defib_ref = parent + + // check what the unit itself has to say about how the defib went + var/application_result = SEND_SIGNAL(parent, COMSIG_DEFIB_PADDLES_APPLIED, user, target, should_cause_harm) + + if(application_result & COMPONENT_BLOCK_DEFIB_DEAD) + user.visible_message(span_notice("[defib_ref] beeps: Unit is unpowered.")) + playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0) + return + + if(on_cooldown) + to_chat(user, span_notice("[defib_ref] is recharging.")) + return + + if(application_result & COMPONENT_BLOCK_DEFIB_MISC) + return // the unit should handle this + + if(!istype(target)) + if(robotic) + to_chat(user, span_notice("This unit is only designed to work on humanoid lifeforms.")) + else + to_chat(user, span_notice("The instructions on [defib_ref] don't mention how to defibrillate that...")) + return + + if(should_cause_harm && combat && heart_attack_chance == 100) + combat_fibrillate(user, target) + SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) + busy = FALSE + return + + if(should_cause_harm) + fibrillate(user, target) + SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) + return + + user.visible_message( + span_warning("[user] begins to place [parent] on [target.name]'s chest."), + span_warning("You begin to place [parent] on [target.name]'s chest."), + ) + + busy = TRUE + var/mob/dead/observer/ghost = target.get_ghost(TRUE) + if(ghost?.can_reenter_corpse) + to_chat(ghost, "[span_ghostalert("Your heart is being defibrillated. Return to your body if you want to be revived!")] (Verbs -> Ghost -> Re-enter corpse)") + window_flash(ghost.client) + SEND_SOUND(ghost, sound('sound/effects/genetics.ogg')) + + if(!do_after(user, 3 SECONDS * speed_multiplier * gettoolspeedmod(user), target = target)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + busy = FALSE + return + + user.visible_message( + span_notice("[user] places [parent] on [target.name]'s chest."), + span_warning("You place [parent] on [target.name]'s chest."), + ) + playsound(get_turf(defib_ref), 'sound/machines/defib_charge.ogg', 50, 0) + + if(ghost && !ghost.client && !QDELETED(ghost)) + log_debug("Ghost of name [ghost.name] is bound to [target.real_name], but lacks a client. Deleting ghost.") + QDEL_NULL(ghost) + + + + if(!do_after(user, 2 SECONDS * speed_multiplier * gettoolspeedmod(user), target = target)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + busy = FALSE + return + + if(istype(target.wear_suit, /obj/item/clothing/suit/space) && !combat) + user.visible_message(span_notice("[defib_ref] buzzes: Patient's chest is obscured. Operation aborted.")) + playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0) + busy = FALSE + return + + + if(target.undergoing_cardiac_arrest()) + var/obj/item/organ/internal/heart/heart = target.get_organ_slot(INTERNAL_ORGAN_HEART) + if(!heart) + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.")) + else if(heart.is_dead()) + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Heart necrosis detected.")) + if(!heart || heart.is_dead()) + playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0) + busy = FALSE + return + + target.set_heartattack(FALSE) + SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) + SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) + set_cooldown(cooldown) + user.visible_message(span_boldnotice("[defib_ref] pings: Cardiac arrhythmia corrected.")) + target.visible_message(span_warning("[target]'s body convulses a bit."), span_userdanger("You feel a jolt, and your heartbeat seems to steady.")) + playsound(get_turf(defib_ref), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(get_turf(defib_ref), "bodyfall", 50, 1) + playsound(get_turf(defib_ref), 'sound/machines/defib_success.ogg', 50, 0) + target.shock_internal_organs(100) + busy = FALSE + return + + if(target.stat != DEAD && !HAS_TRAIT(target, TRAIT_FAKEDEATH)) + user.visible_message(span_notice("[defib_ref] buzzes: Patient is not in a valid state. Operation aborted.")) + playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0) + busy = FALSE + return + + target.visible_message(span_warning("[target]'s body convulses a bit.")) + playsound(get_turf(defib_ref), "bodyfall", 50, 1) + playsound(get_turf(defib_ref), 'sound/machines/defib_zap.ogg', 50, 1, -1) + ghost = target.get_ghost(TRUE) // We have to double check whether the dead guy has entered their body during the above + + var/defib_success = TRUE + + // Run through some quick failure states after shocking. + var/time_dead = world.time - target.timeofdeath + + if(time_dead > DEFIB_TIME_LIMIT) + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")) + defib_success = FALSE + else if(target.getBruteLoss() >= 180 || target.getFireLoss() >= 180 || target.getCloneLoss() >= 180) + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Severe tissue damage detected.")) + defib_success = FALSE + else if(target.blood_volume < BLOOD_VOLUME_SURVIVE) + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Patient blood volume critically low.")) + defib_success = FALSE + else if(!target.get_organ_slot(INTERNAL_ORGAN_BRAIN)) //So things like headless clings don't get outed + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - No brain detected within patient.")) + defib_success = FALSE + else if(ghost) + if(!ghost.can_reenter_corpse || target.suiciding) // DNR or AntagHUD + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - No electrical brain activity detected.")) + else + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed - Patient's brain is unresponsive. Further attempts may succeed.")) + defib_success = FALSE + else if((NOCLONE in target.mutations) || !target.mind || !(target.mind.is_revivable()) || HAS_TRAIT(target, TRAIT_FAKEDEATH) || target.suiciding) // these are a bit more arbitrary + user.visible_message(span_boldnotice("[defib_ref] buzzes: Resuscitation failed.")) + defib_success = FALSE + + if(!defib_success) + playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0) + else + // Heal oxy and tox damage type by as much as we're under -100 health + var/damage_above_threshold = -(min(target.health, HEALTH_THRESHOLD_DEAD) - HEALTH_THRESHOLD_DEAD) + var/heal_amount = damage_above_threshold + 5 + target.adjustOxyLoss(-heal_amount) + target.adjustToxLoss(-heal_amount) + + // Inflict some brain damage scaling with time spent dead + var/defib_time_brain_damage = min(100 * time_dead / DEFIB_TIME_LIMIT, 99) // 20 from 1 minute onward, +20 per minute up to 99 + if(time_dead > DEFIB_TIME_LOSS && defib_time_brain_damage > target.getBrainLoss()) + target.setBrainLoss(defib_time_brain_damage) + + target.update_revive() + target.KnockOut() + target.Paralyse(12 SECONDS) + target.emote("gasp") + + if(target.getBrainLoss() >= 100) + playsound(get_turf(defib_ref), 'sound/machines/defib_saftyoff.ogg', 50, 0) + user.visible_message(span_boldnotice("[defib_ref] chimes: Minimal brain activity detected, brain treatment recommended for full resuscitation.")) + else + playsound(get_turf(defib_ref), 'sound/machines/defib_success.ogg', 50, 0) + user.visible_message(span_boldnotice("[defib_ref] pings: Resuscitation successful.")) + + SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) + if(ishuman(target.pulledby)) // for some reason, pulledby isnt a list despite it being possible to be pulled by multiple people + excess_shock(user, target, target.pulledby, defib_ref) + for(var/obj/item/grab/G in target.grabbed_by) + if(ishuman(G.assailant)) + excess_shock(user, target, G.assailant, defib_ref) + + target.med_hud_set_health() + target.med_hud_set_status() + target.shock_internal_organs(100) + SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) + add_attack_logs(user, target, "Revived with [defib_ref]") + SSblackbox.record_feedback("tally", "players_revived", 1, "defibrillator") + SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, defib_success) + set_cooldown(cooldown) + busy = FALSE + +/** + * Inflict stamina loss (and possibly inflict cardiac arrest) on someone. + * + * Arguments: + * * user - wielder of the defib + * * target - person getting shocked + */ +/datum/component/defib/proc/fibrillate(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return + busy = TRUE + target.visible_message( + span_danger("[user] has touched [target.name] with [parent]!"), + span_userdanger("[user] has touched [target.name] with [parent]!"), + ) + target.adjustStaminaLoss(50) + target.Weaken(4 SECONDS) + playsound(get_turf(parent), 'sound/machines/defib_zap.ogg', 50, 1, -1) + target.emote("gasp") + if(combat && prob(heart_attack_chance)) + target.set_heartattack(TRUE) + SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) + add_attack_logs(user, target, "Stunned with [parent]") + target.shock_internal_organs(100) + set_cooldown(cooldown) + busy = FALSE + +/* + * Pass excess shock from a defibrillation into someone else. + * + * Arguments: + * * user - The person using the defib + * * origin - The person the shock was originally applied to, the person being defibrillated + * * affecting - The person the shock is spreading to and negatively affecting. + * * cell_location - item holding the power source. +*/ +/datum/component/defib/proc/excess_shock(mob/user, mob/living/origin, mob/living/carbon/human/affecting, obj/item/cell_location) + if(user == affecting) + return + var/power_source + if(robotic) + power_source = user + else + if(cell_location) + power_source = locate(/obj/item/stock_parts/cell) in cell_location + + if(!power_source) + return + + if(electrocute_mob(affecting, power_source, origin)) // shock anyone touching them >:) + var/obj/item/organ/internal/heart/heart = affecting.get_organ_slot(INTERNAL_ORGAN_HEART) + if(istype(heart) && heart.parent_organ_zone == BODY_ZONE_CHEST && affecting.has_both_hands()) // making sure the shock will go through their heart (drask hearts are in their head), and that they have both arms so the shock can cross their heart inside their chest + affecting.visible_message(span_danger("[affecting]'s entire body shakes as a shock travels up [affecting.p_their()] arm!"), \ + span_userdanger("You feel a powerful shock travel up your [affecting.hand ? affecting.get_organ(BODY_ZONE_L_ARM) : affecting.get_organ(BODY_ZONE_R_ARM)] and back down your [affecting.hand ? affecting.get_organ(BODY_ZONE_R_ARM) : affecting.get_organ(BODY_ZONE_L_ARM)]!")) + affecting.set_heartattack(TRUE) + + +/datum/component/defib/proc/combat_fibrillate(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return + busy = TRUE + target.adjustStaminaLoss(60) + target.emote("gasp") + add_attack_logs(user, target, "Stunned with [parent]") + if(target.incapacitated()) + add_attack_logs(user, target, "Gave a heart attack with [parent]") + target.set_heartattack(TRUE) + target.visible_message( + span_danger("[user] has touched [target.name] with [parent]!"), + span_userdanger("[user] has touched [target.name] with [parent]!"), + ) + playsound(get_turf(parent), 'sound/machines/defib_zap.ogg', 50, TRUE, -1) + set_cooldown(cooldown) + target.Weaken(4 SECONDS) + return + target.Weaken(4 SECONDS) + target.shock_internal_organs(100) + target.visible_message(span_danger("[user] touches [target] lightly with [parent]!")) + set_cooldown(2.5 SECONDS) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index e62d5d35c30..11283d480d2 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -165,6 +165,10 @@ GLOBAL_VAR_INIT(record_id_num, 1001) G.fields["notes"] = H.gen_record else G.fields["notes"] = "No notes found." + if(H.exploit_record && !jobban_isbanned(H, "Records")) + G.fields["exploit_record"] = H.exploit_record + else + G.fields["exploit_record"] = "No notes found." general += G //Medical Record diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 3191d873d02..cd78cee5c9f 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1144,7 +1144,7 @@ to_chat(usr, "Mob doesn't exist anymore") return - if(H.remove_language(rem_language.name)) + if(H.remove_language(rem_language)) to_chat(usr, "Removed [rem_language] from [H].") log_and_message_admins("has removed language [rem_language] from [key_name(H)]") else diff --git a/code/datums/diseases/viruses/advance/symptoms/deafness.dm b/code/datums/diseases/viruses/advance/symptoms/deafness.dm index 381fe5a9be3..f07b6bc32a8 100644 --- a/code/datums/diseases/viruses/advance/symptoms/deafness.dm +++ b/code/datums/diseases/viruses/advance/symptoms/deafness.dm @@ -34,11 +34,5 @@ Bonus if(3, 4) to_chat(M, span_warning(pick("You hear a ringing in your ear.", "Your ears pop."))) if(5) - if(!(DEAF in M.mutations)) - to_chat(M, span_userdanger("Your ears pop and begin ringing loudly!")) - M.BecomeDeaf() - spawn(200) - if(M) - to_chat(M, span_warning("The ringing in your ears fades...")) - M.CureDeaf() - return + to_chat(M, span_userdanger("Your ears pop and begin ringing loudly!")) + M.Deaf(40 SECONDS) diff --git a/code/datums/diseases/viruses/transformation.dm b/code/datums/diseases/viruses/transformation.dm index 1c221e4cdeb..9061abbab54 100644 --- a/code/datums/diseases/viruses/transformation.dm +++ b/code/datums/diseases/viruses/transformation.dm @@ -55,7 +55,7 @@ return affected_mob.notransform = 1 - affected_mob.canmove = 0 + affected_mob.canmove = FALSE affected_mob.icon = null affected_mob.overlays.Cut() affected_mob.invisibility = INVISIBILITY_ABSTRACT diff --git a/code/datums/emote/emote.dm b/code/datums/emote/emote.dm index 3501ffed071..7cc28dd5eb3 100644 --- a/code/datums/emote/emote.dm +++ b/code/datums/emote/emote.dm @@ -220,10 +220,10 @@ for(var/mob/dead/observer/ghost in viewers(user)) ghost.show_message(span_deadsay("[displayed_msg]"), EMOTE_VISIBLE) - else if((emote_type & (EMOTE_AUDIBLE|EMOTE_SOUND)) && !user.mind?.miming) + else if((emote_type & (EMOTE_AUDIBLE|EMOTE_SOUND)) && user.mind && !user.mind.miming) user.audible_message(displayed_msg, deaf_message = span_italics("You see how [user] [msg]")) else - user.visible_message(displayed_msg, blind_message = span_italics("You hear how someone [msg]")) + user.visible_message(displayed_msg) if(!(emote_type & (EMOTE_FORCE_NO_RUNECHAT|EMOTE_SOUND)) && !isobserver(user)) runechat_emote(user, msg) diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 5ecd9ea1ad3..a5f64ed42fa 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -4,6 +4,7 @@ . = ..() var/obj/machinery/hologram/holopad/H = origin H.move_hologram(eye_user, loc) + ai_detector_visible = FALSE // Holocalls dont trigger the Ai Detector //this datum manages it's own references diff --git a/code/datums/keybindings/mob.dm b/code/datums/keybindings/mob.dm index 8f9c48a4411..b593215a923 100644 --- a/code/datums/keybindings/mob.dm +++ b/code/datums/keybindings/mob.dm @@ -131,6 +131,14 @@ . = ..() C.body_toggle_head() +/datum/keybinding/mob/target_cycle/chest + name = "Выбрать грудь/крылья" + keys = list("Numpad5") + +/datum/keybinding/mob/target_cycle/chest/down(client/C) + . = ..() + C.body_chest() + /datum/keybinding/mob/target_cycle/r_arm name = "Выбрать правую руку/кисть" keys = list("Numpad4") @@ -147,6 +155,14 @@ . = ..() C.body_l_arm() +/datum/keybinding/mob/target_cycle/groin + name = "Выбрать пах/хвост" + keys = list("Numpad2") + +/datum/keybinding/mob/target_cycle/groin/down(client/C) + . = ..() + C.body_groin() + /datum/keybinding/mob/target_cycle/r_leg name = "Выбрать правую ногу/ступню" keys = list("Numpad1") @@ -191,12 +207,10 @@ /datum/keybinding/mob/target/chest name = "Выбрать грудь" body_part = BODY_ZONE_CHEST - keys = list("Numpad5") -/datum/keybinding/mob/target/groin - name = "Выбрать пах" - body_part = BODY_ZONE_PRECISE_GROIN - keys = list("Numpad2") +/datum/keybinding/mob/target/wing + name = "Выбрать крылья" + body_part = BODY_ZONE_WING /datum/keybinding/mob/target/r_arm name = "Выбрать правую руку" @@ -214,6 +228,14 @@ name = "Выбрать левую кисть" body_part = BODY_ZONE_PRECISE_L_HAND +/datum/keybinding/mob/target/groin + name = "Выбрать пах" + body_part = BODY_ZONE_PRECISE_GROIN + +/datum/keybinding/mob/target/tail + name = "Выбрать хвост" + body_part = BODY_ZONE_TAIL + /datum/keybinding/mob/target/r_leg name = "Выбрать правую ногу" body_part = BODY_ZONE_R_LEG @@ -229,3 +251,14 @@ /datum/keybinding/mob/target/l_foot name = "Выбрать левую ступню" body_part = BODY_ZONE_PRECISE_L_FOOT + +/datum/keybinding/mob/trigger_action_button // Don't add a name to this, shouldn't show up in the prefs menu + var/datum/action/linked_action + var/binded_to // these are expected to actually get deleted at some point, to prevent hard deletes we need to know where to remove them from the clients list + +/datum/keybinding/mob/trigger_action_button/down(client/C) + . = ..() + if(C.mob.next_click > world.time) + return + linked_action.Trigger() + linked_action.UpdateButtonIcon() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 99729309552..ebed4a37b6c 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -2455,46 +2455,20 @@ log_and_message_admins("has opened [S]'s law manager.") if("unemag") var/mob/living/silicon/robot/R = current - if(istype(R)) - R.emagged = 0 - if(R.module) - if(R.activated(R.module.emag)) - R.module_active = null - if(R.module_state_1 == R.module.emag) - R.module_state_1 = null - R.contents -= R.module.emag - else if(R.module_state_2 == R.module.emag) - R.module_state_2 = null - R.contents -= R.module.emag - else if(R.module_state_3 == R.module.emag) - R.module_state_3 = null - R.contents -= R.module.emag - R.clear_supplied_laws() - R.laws = new /datum/ai_laws/crewsimov - log_admin("[key_name(usr)] has un-emagged [key_name(current)]") - message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]") + if(!istype(R)) + return + R.unemag() + log_admin("[key_name(usr)] has un-emagged [key_name(current)]") + message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]") if("unemagcyborgs") - if(isAI(current)) - var/mob/living/silicon/ai/ai = current - for(var/mob/living/silicon/robot/R in ai.connected_robots) - R.emagged = 0 - if(R.module) - if(R.activated(R.module.emag)) - R.module_active = null - if(R.module_state_1 == R.module.emag) - R.module_state_1 = null - R.contents -= R.module.emag - else if(R.module_state_2 == R.module.emag) - R.module_state_2 = null - R.contents -= R.module.emag - else if(R.module_state_3 == R.module.emag) - R.module_state_3 = null - R.contents -= R.module.emag - R.clear_supplied_laws() - R.laws = new /datum/ai_laws/crewsimov - log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs") - message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs") + if(!isAI(current)) + return + var/mob/living/silicon/ai/ai = current + for(var/mob/living/silicon/robot/R in ai.connected_robots) + R.unemag() + log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs") + message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs") else if(href_list["common"]) switch(href_list["common"]) @@ -2758,7 +2732,7 @@ SSticker.mode.shadows -= src special_role = null current.spellremove(current) - current.remove_language("Shadowling Hivemind") + current.remove_language(LANGUAGE_HIVE_SHADOWLING) else if(src in SSticker.mode.shadowling_thralls) SSticker.mode.remove_thrall(src,0) diff --git a/code/datums/multitool_menu.dm b/code/datums/multitool_menu.dm index 546a187d3cb..b164d10d5dd 100644 --- a/code/datums/multitool_menu.dm +++ b/code/datums/multitool_menu.dm @@ -282,7 +282,7 @@ var/list/tags = list() if(!frequency) return tags - for(var/obj/machinery/atmospherics/air_sensor/sensor in GLOB.machines) + for(var/obj/machinery/atmospherics/air_sensor/sensor as anything in GLOB.gas_sensors) if(!(sensor.id_tag && sensor.frequency == frequency)) continue tags |= sensor.id_tag diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index a8db8a0ae99..ec9ccf325dc 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -87,9 +87,9 @@ equip_item(H, suit_store, slot_s_store) if(l_hand) - H.put_in_l_hand(new l_hand(H)) + H.equip_to_slot_if_possible(new l_hand(H.loc), slot_l_hand, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE) if(r_hand) - H.put_in_r_hand(new r_hand(H)) + H.equip_to_slot_if_possible(new r_hand(H.loc), slot_r_hand, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE) if(pda) equip_item(H, pda, slot_wear_pda) diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index cec12385793..0454c304237 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -223,7 +223,7 @@ id = /obj/item/card/id/centcom backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8ar = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8ar = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/storage/box/responseteam = 1, /obj/item/gun/energy/gun/blueshield = 1, @@ -716,8 +716,8 @@ H.rename_character(null, "[rank_list.len ? pick(rank_list) : "[H.gender==FEMALE ? pick(GLOB.first_names_female) : pick(GLOB.first_names_male)]"] [H.gender==FEMALE ? pick(GLOB.last_names_female) : pick(GLOB.last_names)]") - H.add_language("Neo-Russkiya") - H.set_default_language(GLOB.all_languages["Neo-Russkiya"]) + H.add_language(LANGUAGE_NEO_RUSSIAN) + H.set_default_language(GLOB.all_languages[LANGUAGE_NEO_RUSSIAN]) var/obj/item/card/id/I = H.wear_id if(istype(I)) diff --git a/code/datums/outfits/outfit_security_clown.dm b/code/datums/outfits/outfit_security_clown.dm index dea615cdc30..fc0a5e2fffb 100644 --- a/code/datums/outfits/outfit_security_clown.dm +++ b/code/datums/outfits/outfit_security_clown.dm @@ -107,7 +107,7 @@ genemutcheck(H, GLOB.comicblock, null, MUTCHK_FORCED) H.dna.default_blocks.Add(GLOB.comicblock) H.check_mutations = TRUE - H.add_language("Clownish") + H.add_language(LANGUAGE_CLOWN) var/clownsecurity_rank = pick("Офицер", "Кадет", "Новобранец", "Рядовой", "Ефрейтор", "Сержант", "Детектив", "Оперуполномоченный", "Расследователь", "Охранник", "Полевой офицер") if(is_physician) diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 6bca31b35cc..9a1ca5a6df6 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -33,7 +33,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) to_chat(user, span_warning("[user.ranged_ability.name] has been disabled.")) user.ranged_ability.remove_ranged_ability(user) return TRUE //TRUE for failed, FALSE for passed. - user.changeNext_click(CLICK_CD_CLICK_ABILITY) user.face_atom(target) return FALSE @@ -222,6 +221,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) if(!can_cast(user, charge_check, TRUE)) return FALSE + user.changeNext_click(CLICK_CD_CLICK_ABILITY) + if(ishuman(user)) var/mob/living/carbon/human/caster = user if(caster.remoteview_target) diff --git a/code/datums/spells/alien_spells/neurotoxin_spit.dm b/code/datums/spells/alien_spells/neurotoxin_spit.dm index 66913cc2e65..a147c2a984d 100644 --- a/code/datums/spells/alien_spells/neurotoxin_spit.dm +++ b/code/datums/spells/alien_spells/neurotoxin_spit.dm @@ -16,12 +16,15 @@ return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/alien_spell/neurotoxin/update_icon() +/obj/effect/proc_holder/spell/alien_spell/neurotoxin/update_icon_state() if(!action) return action.button_icon_state = "alien_neurotoxin_[active]" action.UpdateButtonIcon() +//sets charge_check = FALSE so that you can cancel spell while it's charging +/obj/effect/proc_holder/spell/alien_spell/neurotoxin/can_cast(mob/user, charge_check = FALSE, show_message) + . = ..() /obj/effect/proc_holder/spell/alien_spell/neurotoxin/cast(list/targets, mob/living/carbon/user) var/target = targets[1] @@ -40,6 +43,20 @@ return TRUE +//sets charge_check = FALSE so that you can cancel spell while it's charging +/obj/effect/proc_holder/spell/alien_spell/neurotoxin/Click() + if(cast_check(FALSE, FALSE, usr)) + choose_targets(usr) + return TRUE + +//removes line (user.changeNext_click(CLICK_CD_CLICK_ABILITY)) in parent proc to quick toggle spell +/obj/effect/proc_holder/spell/alien_spell/neurotoxin/InterceptClickOn(mob/user, params, atom/target) + if(user.ranged_ability != src) + to_chat(user, span_warning("[user.ranged_ability.name] has been disabled.")) + user.ranged_ability.remove_ranged_ability(user) + else + targeting.InterceptClickOn(user, params, target, src) + /obj/effect/proc_holder/spell/alien_spell/neurotoxin/after_cast(list/targets, mob/user) . = ..() if(should_remove_click_intercept(user)) diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm index 120c6f04468..7b1276db852 100644 --- a/code/datums/spells/knock.dm +++ b/code/datums/spells/knock.dm @@ -50,6 +50,7 @@ name = "Greater Knock" desc = "On first cast, will remove access restrictions on all airlocks on the station, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!" + action_icon_state = "greater_knock" base_cooldown = 20 SECONDS cooldown_min = 20 SECONDS invocation = "MAIOR OXIN FIERA" diff --git a/code/datums/spells/lavaland_spells/conjure_skulls.dm b/code/datums/spells/lavaland_spells/conjure_skulls.dm new file mode 100644 index 00000000000..9b702615c4f --- /dev/null +++ b/code/datums/spells/lavaland_spells/conjure_skulls.dm @@ -0,0 +1,23 @@ +/obj/effect/proc_holder/spell/aoe/conjure/legion_skulls + name = "Summon Skulls" + desc = "This spell summons three friendly to you legion's skulls." + + school = "lavaland" + base_cooldown = 15 SECONDS + clothes_req = TRUE + human_req = TRUE + invocation = "TRAKI SUMON!" + invocation_type = "shout" + action_icon_state = "sumon_skulls" + + summon_type = list(/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion) + summon_amt = 3 + aoe_range = 1 + + cast_sound = 'sound/magic/forcewall.ogg' + +/obj/effect/proc_holder/spell/aoe/conjure/legion_skulls/cast(list/targets, mob/living/user = usr) + . = ..() + + for(var/mob/skull in .) + skull.faction += user.faction diff --git a/code/datums/spells/lavaland_spells/goliath_dash.dm b/code/datums/spells/lavaland_spells/goliath_dash.dm new file mode 100644 index 00000000000..97a9d785fcc --- /dev/null +++ b/code/datums/spells/lavaland_spells/goliath_dash.dm @@ -0,0 +1,52 @@ +/obj/effect/proc_holder/spell/goliath_dash + name = "Goliath Dash" + desc = "Make a dash followed by an attack with the tentacles of goliath" + school = "lavaland" + base_cooldown = 20 SECONDS + clothes_req = TRUE + human_req = FALSE + invocation = "RAGET'RE BRAN!" + invocation_type = "shout" + action_icon_state = "goliath_dash" + need_active_overlay = TRUE + +/obj/effect/proc_holder/spell/goliath_dash/create_new_targeting() + return new /datum/spell_targeting/clicked_atom + +/obj/effect/proc_holder/spell/goliath_dash/cast(list/targets, mob/user = usr) + var/target = targets[1] + + user.stop_pulling() + user.unbuckle_all_mobs(TRUE) + user.buckled?.unbuckle_mob(user, TRUE) + user.pulledby?.stop_pulling() + + user.layer = LOW_LANDMARK_LAYER + + for(var/i in 1 to 7) + if(QDELETED(user)) + return + + user.canmove = FALSE + var/direction = get_dir(user, target) + var/turf/next_step = get_step(user, direction) + user.face_atom(target) + + if(!is_path_exist(user, next_step, PASSTABLE|PASSFENCE)) + break + + user.forceMove(next_step) + playsound(user.loc, pick('sound/effects/footstep/heavy1.ogg', 'sound/effects/footstep/heavy2.ogg'), 100, TRUE) + sleep(0.05 SECONDS) + + if(QDELETED(user)) + return + + user.layer = initial(user.layer) + user.canmove = TRUE + visible_message(span_warning("[user] unleashes tentacles from the ground around it!")) + + for(var/d in GLOB.alldirs) + var/turf/E = get_step(user, d) + new /obj/effect/temp_visual/goliath_tentacle(E, user) + diff --git a/code/datums/spells/lavaland_spells/goliath_tentacles.dm b/code/datums/spells/lavaland_spells/goliath_tentacles.dm new file mode 100644 index 00000000000..65f5c740339 --- /dev/null +++ b/code/datums/spells/lavaland_spells/goliath_tentacles.dm @@ -0,0 +1,18 @@ +/obj/effect/proc_holder/spell/goliath_tentacles + name = "Summon Tentacles" + desc = "Summons a goliath tentacle attack on clicked tile" + school = "lavaland" + base_cooldown = 15 SECONDS + clothes_req = TRUE + human_req = TRUE + invocation = "SOGESE DE RAGET'RE!" + invocation_type = "shout" + action_icon_state = "goliath_tentacles" + need_active_overlay = TRUE + +/obj/effect/proc_holder/spell/goliath_tentacles/create_new_targeting() + return new /datum/spell_targeting/clicked_atom + +/obj/effect/proc_holder/spell/goliath_tentacles/cast(list/targets, mob/user = usr) + var/turf/target_turf = get_turf(targets[1]) + new /obj/effect/temp_visual/goliath_tentacle/original(target_turf, user) diff --git a/code/datums/spells/lavaland_spells/watchers_look.dm b/code/datums/spells/lavaland_spells/watchers_look.dm new file mode 100644 index 00000000000..2f96f99eb1c --- /dev/null +++ b/code/datums/spells/lavaland_spells/watchers_look.dm @@ -0,0 +1,42 @@ +/obj/effect/proc_holder/spell/watchers_look + name = "Watcher's Look" + desc = "Shoot one of the watcher's beams. To change the mode, use alt-click on the icon." + invocation = "ONI DRAKT'CEHOR!" + invocation_type = "shout" + base_cooldown = 8 SECONDS + action_icon_state = "watcher_normal" + action_background_icon_state = "" + need_active_overlay = TRUE + var/projectiles_icons = list( + "watcher_normal" = /obj/item/projectile/watcher, + "watcher_fire" = /obj/item/projectile/temp/basilisk/magmawing, + "watcher_ice" = /obj/item/projectile/temp/basilisk/icewing) + var/selected_projectile = 1 + + +/obj/effect/proc_holder/spell/watchers_look/create_new_targeting() + return new /datum/spell_targeting/clicked_atom + + +/obj/effect/proc_holder/spell/watchers_look/cast(list/targets, mob/user = usr) + var/target = targets[1] + var/turf/T = user.loc + var/turf/U = get_step(user, user.dir) + if(!istype(U) || !istype(T)) + return FALSE + var/projectile_type = projectiles_icons[projectiles_icons[selected_projectile]] + var/obj/item/projectile/proj = new projectile_type(T) + proj.current = get_turf(user) + proj.original = target + proj.firer = user + proj.preparePixelProjectile(target, get_turf(target), user, targeting.click_params) + proj.fire() + user.newtonian_move(get_dir(U, T)) + return TRUE + + +/obj/effect/proc_holder/spell/watchers_look/AltClick(mob/user) + //switch to next type of projectile and update action's icon + selected_projectile = selected_projectile % length(projectiles_icons) + 1 + action.button_icon_state = projectiles_icons[selected_projectile] + action.UpdateButtonIcon() diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index e18d5f855f6..c543fb49786 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -238,6 +238,7 @@ clothes_req = TRUE invocation = "TARCOL GRANDI ZHERI" invocation_type = "shout" + action_icon_state = "shield_greater" large = TRUE @@ -377,7 +378,7 @@ return T -/obj/effect/proc_holder/spell/fireball/update_icon() +/obj/effect/proc_holder/spell/fireball/update_icon_state() if(!action) return action.button_icon_state = "fireball[active]" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index d210c8d92fa..03d3861fae6 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -764,12 +764,11 @@ /datum/status_effect/transient/eye_blurry/calc_decay() if(ishuman(owner)) var/mob/living/carbon/human/H = owner + var/obj/item/organ/vision = H.dna?.species?.get_vision_organ(H) - if(isnull(H.dna.species.vision_organ)) //species has no eyes + if(vision && vision == NO_VISION_ORGAN) //species has no eyes return ..() - var/obj/item/organ/vision = H.get_int_organ(H.dna.species.vision_organ) - if(!vision || vision.is_bruised() || vision.is_traumatized()) // doesn't decay if you have damaged eyesight. return 0 @@ -794,10 +793,10 @@ if((BLINDNESS in H.mutations)) return 0 - if(isnull(H.dna.species.vision_organ)) // species that have no eyes - return ..() + var/obj/item/organ/vision = H.dna?.species?.get_vision_organ(H) - var/obj/item/organ/vision = H.get_int_organ(H.dna.species.vision_organ) + if(vision && vision == NO_VISION_ORGAN) // species that have no eyes + return ..() if(!vision || vision.is_traumatized() || vision.is_bruised()) //got no eyes or broken eyes return 0 diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 9ebd298b067..300212a7d87 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -47,12 +47,13 @@ linked_alert = null return ..() -/datum/status_effect/process() - if(!owner) +/datum/status_effect/process(seconds_per_tick) + SHOULD_NOT_OVERRIDE(TRUE) + if(QDELETED(owner)) qdel(src) return if(tick_interval <= world.time) - tick() + tick(seconds_per_tick) tick_interval = world.time + initial(tick_interval) if(duration != -1 && duration < world.time) on_timeout() @@ -60,7 +61,7 @@ /datum/status_effect/proc/on_apply() //Called whenever the buff is applied; returning FALSE will cause it to autoremove itself. return TRUE -/datum/status_effect/proc/tick() //Called every tick. +/datum/status_effect/proc/tick(seconds_per_tick) //Called every tick. /datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null /datum/status_effect/proc/on_timeout() // Called specifically whenever the status effect expires. /datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index d857e8f5db0..21428cc26f9 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -46,6 +46,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY var/manifest = "" var/amount = null var/cost = null + var/credits_cost = 0 var/containertype = /obj/structure/closet/crate var/containername = null var/access = null @@ -79,6 +80,9 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY if(SSshuttle.points <= cost) to_chat(user, span_warning("There are insufficient supply points for this request.")) return FALSE + if(credits_cost && SSshuttle.cargo_money_account.money <= credits_cost) + to_chat(user, span_warning("There are not enough money on cargo account for this request.")) + return FALSE if(!length(required_tech)) return TRUE for(var/tech_id in required_tech) @@ -242,12 +246,20 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY /datum/supply_packs/emergency/syndicate name = "ERROR_NULL_ENTRY" - contains = list(/obj/item/storage/box/syndicate) - cost = 560 - containertype = /obj/structure/closet/crate + contains = list() + cost = 0 + credits_cost = 2500 + containertype = /obj/structure/closet/crate/syndicate containername = "crate" hidden = 1 - order_limit = 5 + +/datum/supply_packs/emergency/syndicate/New() + var/list/items = GLOB.uplink_items.Copy() + while(contains.len < 3) + var/datum/uplink_item/item = pick_n_take(items) + if(istype(item, /datum/uplink_item/racial) || item.hijack_only || item.cost > 20) + continue + contains.Add(item.item) /datum/supply_packs/emergency/highrisk name = "HEADER" @@ -1731,7 +1743,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY /obj/item/mixing_bowl, /obj/item/reagent_containers/food/condiment/enzyme, /obj/item/reagent_containers/food/condiment/sugar, - /obj/item/reagent_containers/food/snacks/meat/monkey, + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/reagent_containers/food/snacks/grown/banana) diff --git a/code/datums/syndiesupplypacks.dm b/code/datums/syndiesupplypacks.dm index 0ffbcd05b7c..ac9334d67c2 100644 --- a/code/datums/syndiesupplypacks.dm +++ b/code/datums/syndiesupplypacks.dm @@ -1066,7 +1066,7 @@ GLOBAL_LIST_INIT(all_syndie_supply_groups, list(SYNDIE_SUPPLY_EMERGENCY,SYNDIE_S /obj/item/mixing_bowl, /obj/item/reagent_containers/food/condiment/enzyme, /obj/item/reagent_containers/food/condiment/sugar, - /obj/item/reagent_containers/food/snacks/meat/monkey, + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/reagent_containers/food/snacks/grown/banana) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index aca61304049..f6ecff491ae 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -587,7 +587,7 @@ name = "Anomaly extract" desc = "The result of the work of scientists on mixing an experimental stable mutagen with the core of a pyroclastic anomaly. Gives the user the opportunity to become a slime and heat himself up." item = /obj/item/anomaly_extract - cost = 50 + cost = 40 race = list("Slime People") //Plasmaman diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index f2624fddc48..5c3d5cc349e 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -58,7 +58,6 @@ /datum/weather/rad_storm/proc/status_alarm(active) //Makes the status displays show the radiation warning for those who missed the announcement. if(active) - post_status("alert", "radiation") + post_status(STATUS_DISPLAY_ALERT, "radiation") else - post_status("blank") - post_status("shuttle") + post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 74a98095883..d745ab1d319 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -174,7 +174,9 @@ switch(action) // Toggles the cut/mend status. if("cut") - if(!istype(I, /obj/item/wirecutters) && !user.can_admin_interact()) + if(!I) + return + if(I.tool_behaviour != TOOL_WIRECUTTER && !user.can_admin_interact()) to_chat(user, "You need wirecutters!") return @@ -185,7 +187,9 @@ // Pulse a wire. if("pulse") - if(!istype(I, /obj/item/multitool) && !user.can_admin_interact()) + if(!I) + return + if(I.tool_behaviour != TOOL_MULTITOOL && !user.can_admin_interact()) to_chat(user, "You need a multitool!") return diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 45f27e5481a..e124d06c5f9 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -12,7 +12,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event var/channel_name = "Station Announcements" var/announcement_type = "Оповещение" var/admin_announcement = 0 // Admin announcements are received regardless of being in range of a radio, unless you're in the lobby to prevent metagaming - var/language = "Galactic Common" + var/language = LANGUAGE_GALACTIC_COMMON /datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0) sound = new_sound @@ -44,7 +44,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event title = "Оповещение о безопасности" announcement_type = "Оповещение о безопасности" -/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from, var/msg_language) +/datum/announcement/proc/Announce(message as text, new_title = "", new_sound = null, do_newscast = newscast, msg_sanitized = 0, from, msg_language) if(!message) return diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 6e031aa824e..c2763b987df 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -24,12 +24,12 @@ var/power_equip = TRUE var/power_light = TRUE var/power_environ = TRUE - var/used_equip = FALSE - var/used_light = FALSE - var/used_environ = FALSE - var/static_equip - var/static_light = FALSE - var/static_environ + var/used_equip = 0 + var/used_light = 0 + var/used_environ = 0 + var/static_equip = 0 + var/static_light = 0 + var/static_environ = 0 var/has_gravity = TRUE var/list/apc = list() @@ -150,29 +150,37 @@ cameras += C return cameras + /area/proc/air_doors_close() - if(!air_doors_activated) - air_doors_activated = TRUE - for(var/obj/machinery/door/firedoor/D in firedoors) - if(!D.welded) - D.activate_alarm() - if(D.operating) - D.nextstate = FD_CLOSED - else if(!D.density) - spawn(0) - D.close() + if(air_doors_activated) + return + air_doors_activated = TRUE + for(var/obj/machinery/door/firedoor/firedoor as anything in firedoors) + if(!firedoor.is_operational()) + continue + firedoor.activate_alarm() + if(firedoor.welded) + continue + if(firedoor.operating && firedoor.operating != DOOR_CLOSING) + firedoor.nextstate = FD_CLOSED + else if(!firedoor.density) + INVOKE_ASYNC(firedoor, TYPE_PROC_REF(/obj/machinery/door/firedoor, close)) + /area/proc/air_doors_open() - if(air_doors_activated) - air_doors_activated = FALSE - for(var/obj/machinery/door/firedoor/D in firedoors) - if(!D.welded) - D.deactivate_alarm() - if(D.operating) - D.nextstate = OPEN - else if(D.density) - spawn(0) - D.open() + if(!air_doors_activated) + return + air_doors_activated = FALSE + for(var/obj/machinery/door/firedoor/firedoor as anything in firedoors) + if(!firedoor.is_operational()) + continue + firedoor.deactivate_alarm() + if(firedoor.welded) + continue + if(firedoor.operating && firedoor.operating != DOOR_OPENING) + firedoor.nextstate = FD_OPEN + else if(firedoor.density) + INVOKE_ASYNC(firedoor, TYPE_PROC_REF(/obj/machinery/door/firedoor, open)) /area/Destroy() @@ -234,22 +242,33 @@ * Try to close all the firedoors in the area */ /area/proc/ModifyFiredoors(opening) - if(firedoors) - firedoors_last_closed_on = world.time - for(var/FD in firedoors) - var/obj/machinery/door/firedoor/D = FD - var/cont = !D.welded - if(cont && opening) //don't open if adjacent area is on fire - for(var/I in D.affecting_areas) - var/area/A = I - if(A.fire) - cont = FALSE - break - if(cont && D.is_operational()) - if(D.operating) - D.nextstate = opening ? FD_OPEN : FD_CLOSED - else if(!(D.density ^ opening)) - INVOKE_ASYNC(D, (opening ? TYPE_PROC_REF(/obj/machinery/door/firedoor, open) : TYPE_PROC_REF(/obj/machinery/door/firedoor, close))) + if(!firedoors) + return + firedoors_last_closed_on = world.time + for(var/obj/machinery/door/firedoor/firedoor in firedoors) + if(!firedoor.is_operational()) + continue + var/valid = TRUE + if(opening) //don't open if adjacent area is on fire + for(var/area/check as anything in firedoor.affecting_areas) + if(check.fire) + valid = FALSE + break + if(!valid) + continue + + // At this point, the area is safe and the door is technically functional. + + INVOKE_ASYNC(firedoor, (opening ? TYPE_PROC_REF(/obj/machinery/door/firedoor, deactivate_alarm) : TYPE_PROC_REF(/obj/machinery/door/firedoor, activate_alarm))) + if(firedoor.welded) + continue // Alarm is toggled, but door stuck + if(firedoor.operating) + if((firedoor.operating == DOOR_OPENING && opening) || (firedoor.operating == DOOR_CLOSING && !opening)) + continue + else + firedoor.nextstate = opening ? FD_OPEN : FD_CLOSED + else if(firedoor.density == opening) + INVOKE_ASYNC(firedoor, (opening ? TYPE_PROC_REF(/obj/machinery/door/firedoor, open) : TYPE_PROC_REF(/obj/machinery/door/firedoor, close))) /** * Generate a firealarm alert for this area @@ -350,9 +369,8 @@ /area/proc/set_fire_alarm_effect() fire = TRUE mouse_opacity = MOUSE_OPACITY_TRANSPARENT - for(var/alarm in firealarms) - var/obj/machinery/firealarm/F = alarm - F.update_fire_light(fire) + for(var/obj/machinery/firealarm/alarm as anything in firealarms) + alarm.update_fire_light(fire) if(area_emergency_mode) //Fires are not legally allowed if the power is off return for(var/obj/machinery/light/light as anything in lights_cache) @@ -363,40 +381,40 @@ /area/proc/unset_fire_alarm_effects() fire = FALSE mouse_opacity = MOUSE_OPACITY_TRANSPARENT - for(var/alarm in firealarms) - var/obj/machinery/firealarm/F = alarm - F.update_fire_light(fire) + for(var/obj/machinery/firealarm/alarm as anything in firealarms) + alarm.update_fire_light(fire) if(area_emergency_mode) //The lights stay red until the crisis is resolved return for(var/obj/machinery/light/light as anything in lights_cache) light.fire_mode = FALSE light.update() -/area/proc/updateicon() - var/weather_icon - for(var/V in SSweather.processing) - var/datum/weather/W = V - if(W.stage != END_STAGE && (src in W.impacted_areas)) - W.update_areas() + +/area/update_icon_state() + var/weather_icon = FALSE + for(var/datum/weather/weather as anything in SSweather.processing) + if(weather.stage != END_STAGE && (src in weather.impacted_areas)) + weather.update_areas() weather_icon = TRUE if(!weather_icon) icon_state = null -/area/space/updateicon() + +/area/space/update_icon_state() icon_state = null + /* #define EQUIP 1 #define LIGHT 2 #define ENVIRON 3 */ -/area/proc/powered(var/chan) // return true if the area has power to given channel - +/area/proc/powered(chan) // return true if the area has power to given channel if(!requires_power) - return 1 + return TRUE if(always_unpowered) - return 0 + return FALSE switch(chan) if(EQUIP) return power_equip @@ -404,11 +422,10 @@ return power_light if(ENVIRON) return power_environ - - return 0 + return FALSE /area/space/powered(chan) //Nope.avi - return 0 + return FALSE /** * Called when the area power status changes @@ -417,12 +434,12 @@ */ /area/proc/power_change() for(var/obj/machinery/machine as anything in machinery_cache) // for each machine in the area - machine.power_change() // reverify power status (to update icons etc.) - + machine.power_change() // reverify power status (to update icons etc.) + update_icon(UPDATE_ICON_STATE) SEND_SIGNAL(src, COMSIG_AREA_POWER_CHANGE) - updateicon() -/area/proc/usage(var/chan) + +/area/proc/usage(chan) var/used = 0 switch(chan) if(LIGHT) @@ -456,7 +473,7 @@ used_light = 0 used_environ = 0 -/area/proc/use_power(var/amount, var/chan) +/area/proc/use_power(amount, chan) switch(chan) if(EQUIP) used_equip += amount @@ -465,7 +482,7 @@ if(ENVIRON) used_environ += amount -/area/proc/use_battery_power(var/amount, var/chan) +/area/proc/use_battery_power(amount, chan) switch(chan) if(EQUIP) used_equip += amount @@ -478,6 +495,7 @@ /area/Entered(atom/movable/arrived) SEND_SIGNAL(src, COMSIG_AREA_ENTERED, arrived) + SEND_SIGNAL(arrived, COMSIG_ATOM_ENTERED_AREA, src) var/area/newarea var/area/oldarea @@ -521,6 +539,7 @@ /area/Exited(atom/movable/departed) SEND_SIGNAL(src, COMSIG_AREA_EXITED, departed) + SEND_SIGNAL(departed, COMSIG_ATOM_EXITED_AREA, src) /area/proc/gravitychange(gravitystate = 0, area/our_area) our_area.has_gravity = gravitystate diff --git a/code/game/area/areas/depot-areas.dm b/code/game/area/areas/depot-areas.dm index 1152193a671..14bce56f583 100644 --- a/code/game/area/areas/depot-areas.dm +++ b/code/game/area/areas/depot-areas.dm @@ -36,25 +36,36 @@ var/obj/machinery/computer/syndicate_depot/syndiecomms/comms_computer = null var/obj/structure/fusionreactor/reactor -/area/syndicate_depot/core/updateicon() + +/area/syndicate_depot/core/proc/update_state() if(destroyed) - icon_state = null invisibility = INVISIBILITY_MAXIMUM else if(on_peaceful) - icon_state = "green" invisibility = INVISIBILITY_LIGHTING else if(used_self_destruct) - icon_state = "radiation" invisibility = INVISIBILITY_LIGHTING else if(called_backup) - icon_state = "red" invisibility = INVISIBILITY_LIGHTING else if(local_alarm) - icon_state = "bluenew" invisibility = INVISIBILITY_LIGHTING else - icon_state = null invisibility = INVISIBILITY_MAXIMUM + update_icon(UPDATE_ICON_STATE) + + +/area/syndicate_depot/core/update_icon_state() + if(invisibility == INVISIBILITY_MAXIMUM) + icon_state = null + return + else if(on_peaceful) + icon_state = "green" + else if(used_self_destruct) + icon_state = "radiation" + else if(called_backup) + icon_state = "red" + else if(local_alarm) + icon_state = "bluenew" + /area/syndicate_depot/core/proc/reset_alert() @@ -84,7 +95,7 @@ detected_pod = FALSE detected_double_agent = FALSE mine_trigger_count = 0 - updateicon() + update_state() if(!istype(reactor)) for(var/obj/structure/fusionreactor/R in src) @@ -116,7 +127,7 @@ if(!used_self_destruct) add_game_logs("Depot code: DELTA: [reason]" + list_show(hostile_list, TRUE), triggered) activate_self_destruct(reason, FALSE, null) - updateicon() + update_icon(UPDATE_ICON_STATE) /area/syndicate_depot/core/proc/locker_looted() if(!something_looted) @@ -208,7 +219,7 @@ message_admins("- SYNDI DEPOT VISITOR: [ADMIN_FULLMONTY(M)]") list_add(M, hostile_list) peaceful_list = list() - updateicon() + update_icon(UPDATE_ICON_STATE) /area/syndicate_depot/core/proc/local_alarm(reason, silent) if(local_alarm) @@ -229,7 +240,7 @@ var/mob/living/simple_animal/bot/ed209/syndicate/B = new /mob/living/simple_animal/bot/ed209/syndicate(get_turf(S)) list_add(B, guard_list) B.depotarea = src - updateicon() + update_icon(UPDATE_ICON_STATE) /area/syndicate_depot/core/proc/call_backup(reason, silent) if(called_backup || used_self_destruct) @@ -261,7 +272,7 @@ list_add(S, guard_list) else if(!silent) announce_here("Depot Communications Offline", "Comms computer is damaged, destroyed or depowered. Unable to call in backup from Syndicate HQ.") - updateicon() + update_icon(UPDATE_ICON_STATE) /area/syndicate_depot/core/proc/activate_self_destruct(reason, containment_failure, mob/user) if(used_self_destruct) @@ -273,7 +284,7 @@ called_backup = TRUE activate_lockdown(TRUE) lockout_computers() - updateicon() + update_icon(UPDATE_ICON_STATE) despawn_guards() if(containment_failure) announce_here("Depot Code DELTA", reason) @@ -295,7 +306,7 @@ else log_debug("Depot: [src] called activate_self_destruct with no reactor.") message_admins("Syndicate Depot lacks reactor to initiate self-destruct. Must be destroyed manually via admin bomb(25, 35, 45, 55).") - updateicon() + update_icon(UPDATE_ICON_STATE) /area/syndicate_depot/core/proc/activate_lockdown() if(used_lockdown) @@ -323,9 +334,8 @@ A.update_icon() /area/syndicate_depot/core/proc/toggle_falsewalls() - for(var/obj/structure/falsewall/plastitanium/F in src) - spawn(0) - F.toggle() + for(var/obj/structure/falsewall/plastitanium/wall in src) + INVOKE_ASYNC(wall, TYPE_PROC_REF(/obj/structure/falsewall, toggle)) /area/syndicate_depot/core/proc/toggle_teleport_beacon() for(var/obj/machinery/bluespace_beacon/syndicate/B in machinery_cache) diff --git a/code/game/area/ss13_areas.dm b/code/game/area/ss13_areas.dm index d1e47580223..9cc70a08022 100644 --- a/code/game/area/ss13_areas.dm +++ b/code/game/area/ss13_areas.dm @@ -70,11 +70,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station dynamic_lighting = DYNAMIC_LIGHTING_FORCED parallax_movedir = NORTH sound_environment = SOUND_ENVIRONMENT_ROOM -/* -/area/shuttle/arrival //dont have this, but at once... - name = "\improper Arrival Shuttle" -/area/shuttle/arrival/pre_game +/area/shuttle/arrival + name = "\improper Arrival Shuttle" +/* +/area/shuttle/arrival/pre_game //dont have this, but at once... icon_state = "shuttle2" */ /area/shuttle/arrival/station diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a78ae6fc560..e9cb968118f 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -9,6 +9,7 @@ /atom layer = TURF_LAYER plane = GAME_PLANE + appearance_flags = TILE_BOUND var/level = 2 var/flags = NONE var/flags_2 = NONE @@ -178,7 +179,7 @@ alternate_appearances = null QDEL_NULL(reagents) - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT LAZYCLEARLIST(overlays) LAZYCLEARLIST(priority_overlays) @@ -301,7 +302,7 @@ return /atom/proc/emp_act(severity) - return + SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity) //amount of water acting : temperature of water in kelvin : object that called it (for shennagins) /atom/proc/water_act(volume, temperature, source, method = REAGENT_TOUCH) @@ -434,7 +435,7 @@ /// Updates the icon of the atom /atom/proc/update_icon(updates = ALL) SHOULD_NOT_SLEEP(TRUE) - //SHOULD_CALL_PARENT(TRUE) + SHOULD_CALL_PARENT(TRUE) if(updates == NONE) return // NONE is being sent on purpose, and thus no signal should be sent. @@ -540,6 +541,9 @@ return /atom/proc/emag_act(mob/user) + SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT, user) + +/atom/proc/unemag() return /atom/proc/cmag_act(mob/user) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0dd27f74ce1..14622b6bfe1 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,34 +1,31 @@ /atom/movable - layer = 3 - appearance_flags = TILE_BOUND + layer = OBJ_LAYER + appearance_flags = TILE_BOUND|PIXEL_SCALE glide_size = 8 // Default, adjusted when mobs move based on their movement delays var/last_move = null - var/anchored = 0 + var/anchored = FALSE var/move_resist = MOVE_RESIST_DEFAULT var/move_force = MOVE_FORCE_DEFAULT var/pull_force = PULL_FORCE_DEFAULT - // var/elevation = 2 - not used anywhere var/move_speed = 10 var/l_move_time = 1 var/datum/thrownthing/throwing = null var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported var/throw_range = 7 - var/no_spin = 0 - var/no_spin_thrown = 0 - var/moved_recently = 0 + var/no_spin_thrown = FALSE var/mob/pulledby = null var/atom/movable/pulling var/throwforce = 0 - var/canmove = 1 + var/canmove = TRUE var/pull_push_speed_modifier = 1 - var/inertia_dir = 0 + var/inertia_dir = NONE var/atom/inertia_last_loc - var/inertia_moving = 0 + var/inertia_moving = FALSE var/inertia_next_move = 0 var/inertia_move_delay = 5 - - var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move + /// NONE:0 not doing a diagonal move. FIRST_DIAG_STEP:1 and SECOND_DIAG_STEP:2 doing the first/second step of the diagonal move. + var/moving_diagonally = NONE var/list/client_mobs_in_contents /// Either FALSE, [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE] @@ -64,6 +61,7 @@ /atom/movable/Destroy() unbuckle_all_mobs(force = TRUE) + QDEL_NULL(em_block) . = ..() if(loc) @@ -104,8 +102,10 @@ if(!(AM.can_be_pulled(src, force, show_message))) return FALSE - if(pulling && AM == pulling && src == AM.pulledby) // are we trying to pull something we are already pulling? - return FALSE + if(pulling) + if(AM == pulling && src == AM.pulledby) // are we trying to pull something we are already pulling? + return FALSE + stop_pulling() // Clear yourself from targets `pulledby`. var/atom/movable/previous_puller = null if(AM.pulledby) @@ -135,7 +135,6 @@ pulling.pulledby = null var/mob/living/ex_pulled = pulling pulling = null - pulledby = null if(isliving(ex_pulled)) var/mob/living/L = ex_pulled L.update_canmove()// mob gets up if it was lyng down in a chokehold @@ -317,7 +316,7 @@ var/area/old_area = get_area(src) var/area/new_area = get_area(destination) loc = destination - moving_diagonally = 0 + moving_diagonally = NONE if(old_loc) old_loc.Exited(src, destination) @@ -346,7 +345,7 @@ Moved(old_loc, NONE, TRUE) - return 1 + return TRUE /atom/movable/proc/move_to_null_space() @@ -391,36 +390,36 @@ //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below -//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting -//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm +//Return FALSE to have src start/keep drifting in a no-grav area and TRUE to stop/not start drifting +//Mobs should return TRUE if they should be able to move of their own volition, see client/Move() in mob_movement.dm //movement_dir == 0 when stopping or any dir when trying to move -/atom/movable/proc/Process_Spacemove(var/movement_dir = 0) +/atom/movable/proc/Process_Spacemove(movement_dir = 0) if(has_gravity(src)) - return 1 + return TRUE if(pulledby && !pulledby.pulling) - return 1 + return TRUE if(throwing) - return 1 + return TRUE if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier - return 1 + return TRUE - return 0 + return FALSE /atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity if(!loc || Process_Spacemove(0)) - inertia_dir = 0 - return 0 + inertia_dir = NONE + return FALSE inertia_dir = direction if(!direction) - return 1 + return TRUE inertia_last_loc = loc SSspacedrift.processing[src] = src - return 1 + return TRUE //called when src is thrown into hit_atom @@ -510,7 +509,7 @@ pulledby.stop_pulling() throwing = TT - if(spin && !no_spin && !no_spin_thrown) + if(spin && !no_spin_thrown) SpinAnimation(5, 1) SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin) @@ -548,8 +547,8 @@ last_move = buckled_mob.last_move inertia_dir = last_move buckled_mob.inertia_dir = last_move - return 0 - return 1 + return FALSE + return TRUE /atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) return FALSE @@ -557,12 +556,12 @@ /atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE) . = AM.force_pushed(src, force, direction) if(!silent && .) - visible_message("[src] сильно толка[pluralize_ru(src.gender,"ет","ют")] [AM]!", "Вы сильно толкаете [AM]!") + visible_message(span_warning("[src] сильно толка[pluralize_ru(gender,"ет","ют")] [AM]!"), span_warning("Вы сильно толкаете [AM]!")) /atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE) . = AM.move_crushed(src, force, direction) if(!silent && .) - visible_message("[src] сокруша[pluralize_ru(src.gender,"ет","ют")] [AM]!", "Вы сокрушили [AM]!") + visible_message(span_danger("[src] сокруша[pluralize_ru(gender,"ет","ют")] [AM]!"), span_danger("Вы сокрушили [AM]!")) /atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) return FALSE @@ -571,7 +570,7 @@ if(istype(mover) && mover.checkpass(PASS_OTHER_THINGS)) return TRUE if(mover in buckled_mobs) - return 1 + return TRUE return ..() /atom/movable/proc/get_spacemove_backup() @@ -679,5 +678,5 @@ /atom/movable/proc/decompile_act(obj/item/matter_decompiler/C, mob/user) // For drones to decompile mobs and objs. See drone for an example. return FALSE -/atom/movable/proc/get_pull_push_speed_modifier(var/current_delay) +/atom/movable/proc/get_pull_push_speed_modifier(current_delay) return pull_push_speed_modifier diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 8c68685956e..86c0f37a9c7 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -168,7 +168,7 @@ add_fingerprint(usr) SStgui.update_uis(src) -/obj/machinery/dna_scannernew/MouseDrop_T(atom/movable/O, mob/user) +/obj/machinery/dna_scannernew/MouseDrop_T(atom/movable/O, mob/user, params) if(!istype(O)) return if(O.loc == user) //no you can't pull things out of your ass @@ -189,23 +189,23 @@ return if(occupant) to_chat(user, "The [src] is already occupied!") - return + return TRUE var/mob/living/L = O if(!istype(L) || L.buckled) return if(L.abiotic()) to_chat(user, "Subject cannot have abiotic items on.") - return + return TRUE if(L.has_buckled_mobs()) //mob attached to us to_chat(user, "[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.") - return + return TRUE if(L == user) visible_message("[user] climbs into the [src].") else visible_message("[user] puts [L.name] into the [src].") put_in(L) - if(user.pulling == L) - user.stop_pulling() + L.pulledby?.stop_pulling() + return TRUE /obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params) if(exchange_parts(user, I)) diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index f1cba274123..ef13ba789fe 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -187,7 +187,7 @@ /obj/effect/self_deleting density = 0 opacity = 0 - anchored = 1 + anchored = TRUE icon = null desc = "" //layer = 15 diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index eafee6caf07..02e084c0d77 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -58,7 +58,7 @@ H.drop_item_ground(W) H.regenerate_icons() H.SetStunned(2 SECONDS) - H.canmove = 0 + H.canmove = FALSE H.icon = null H.invisibility = INVISIBILITY_ABSTRACT var/has_greater_form = H.dna.species.greater_form //cache this diff --git a/code/game/gamemodes/antag_paradise/antag_paradise.dm b/code/game/gamemodes/antag_paradise/antag_paradise.dm index 8ef25bb18c0..84a1e3ed777 100644 --- a/code/game/gamemodes/antag_paradise/antag_paradise.dm +++ b/code/game/gamemodes/antag_paradise/antag_paradise.dm @@ -34,27 +34,44 @@ to_chat(world, "The current game mode is - Antag Paradise") to_chat(world, "Traitors, thieves, vampires and changelings, oh my! Stay safe as these forces work to bring down the station.") +/datum/game_mode/antag_paradise/process() + if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) + return PROCESS_KILL -/datum/game_mode/antag_paradise/pre_setup() - var/players = num_players() - calculate_antags(players) + var/list/antag_possibilities = list() + antag_possibilities[ROLE_VAMPIRE] = get_alive_players_for_role(ROLE_VAMPIRE) + antag_possibilities[ROLE_CHANGELING] = get_alive_players_for_role(ROLE_CHANGELING) + antag_possibilities[ROLE_TRAITOR] = get_alive_players_for_role(ROLE_TRAITOR) + antag_possibilities[ROLE_THIEF] = get_alive_players_for_role(ROLE_THIEF, list("Vox" = 4)) + roll_antagonists(antag_possibilities) + initiate_antags() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs +/datum/game_mode/antag_paradise/proc/roll_antagonists(list/antag_possibilities, roundstart = FALSE) + pre_antags = list() + pre_double_antags = list() + + var/players = roundstart ? num_players() : num_station_players() + calculate_antags(players) var/scale = CONFIG_GET(number/traitor_scaling) ? CONFIG_GET(number/traitor_scaling) : 10 - var/antags_amount = 1 + round(players / scale) - var/special_antag_amount = 1 + round(players / 50) + var/antags_amount + var/special_antag_amount + + antags_amount = 1 + round(players / scale) + //Special antag spawning not on roundstart is currently disabled for testing purposes. + special_antag_amount = roundstart ? 1 + round(players / 50) : 0 + + antags_amount = antags_amount - length(GLOB.antagonists) + if(antags_amount <= 0) + return - var/list/datum/mind/possible_vampires = get_players_for_role(ROLE_VAMPIRE) - var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) - var/list/datum/mind/possible_traitors = get_players_for_role(ROLE_TRAITOR) - var/list/datum/mind/possible_thieves = get_players_for_role(ROLE_THIEF, list("Vox" = 4)) + if(special_antag_type == ROLE_NINJA && !roundstart) + special_antag_type = pick(ROLE_HIJACKER, ROLE_THIEF, ROLE_MALF_AI) switch(special_antag_type) if(ROLE_HIJACKER) for(var/i in 1 to special_antag_amount) - var/datum/mind/special_antag = pick_n_take(possible_traitors) + var/datum/mind/special_antag = pick_n_take(antag_possibilities[ROLE_TRAITOR]) if(special_antag) special_antag.restricted_roles = restricted_jobs special_antag.special_role = SPECIAL_ROLE_TRAITOR @@ -63,23 +80,24 @@ if(ROLE_THIEF) for(var/i in 1 to special_antag_amount) - var/datum/mind/special_antag = pick_n_take(possible_thieves) + var/datum/mind/special_antag = pick_n_take(antag_possibilities[ROLE_THIEF]) if(special_antag) - listclearduplicates(special_antag, possible_thieves) + listclearduplicates(special_antag, antag_possibilities[ROLE_THIEF]) special_antag.special_role = SPECIAL_ROLE_THIEF special_antag.restricted_roles = restricted_jobs pre_antags[special_antag] = ROLE_THIEF antags_amount-- if(ROLE_MALF_AI) - var/datum/mind/special_antag = safepick(get_players_for_role(ROLE_MALF_AI)) - if(special_antag) - special_antag.restricted_roles = (restricted_jobs|protected_jobs|protected_jobs_AI) - special_antag.restricted_roles -= "AI" - special_antag.special_role = SPECIAL_ROLE_TRAITOR - SSjobs.new_malf = special_antag.current - pre_antags[special_antag] = ROLE_MALF_AI - antags_amount-- + if(special_antag_amount) + var/datum/mind/special_antag = roundstart ? safepick(get_players_for_role(ROLE_MALF_AI)) : safepick(get_alive_players_for_role(ROLE_MALF_AI)) + if(special_antag) + special_antag.restricted_roles = (restricted_jobs|protected_jobs|protected_jobs_AI) + special_antag.restricted_roles -= "AI" + special_antag.special_role = SPECIAL_ROLE_TRAITOR + SSjobs.new_malf = special_antag.current + pre_antags[special_antag] = ROLE_MALF_AI + antags_amount-- if(ROLE_NINJA) if(length(GLOB.ninjastart)) @@ -99,7 +117,7 @@ var/antag_type = pick_weight_classic(antags_weights) switch(antag_type) if(ROLE_VAMPIRE) - var/datum/mind/vampire = pick_n_take(possible_vampires) + var/datum/mind/vampire = pick_n_take(antag_possibilities[ROLE_VAMPIRE]) if(!vampire) continue if(vampire.current.client.prefs.species in secondary_protected_species) @@ -110,7 +128,7 @@ vampire.restricted_roles = (restricted_jobs|vampire_restricted_jobs) pre_antags[vampire] = ROLE_VAMPIRE if(ROLE_CHANGELING) - var/datum/mind/changeling = pick_n_take(possible_changelings) + var/datum/mind/changeling = pick_n_take(antag_possibilities[ROLE_CHANGELING]) if(!changeling) continue if(changeling.current.client.prefs.species in secondary_protected_species) @@ -121,7 +139,7 @@ changeling.restricted_roles = restricted_jobs pre_antags[changeling] = ROLE_CHANGELING if(ROLE_TRAITOR) - var/datum/mind/traitor = pick_n_take(possible_traitors) + var/datum/mind/traitor = pick_n_take(antag_possibilities[ROLE_TRAITOR]) if(!traitor) continue if(traitor.special_role) @@ -130,10 +148,10 @@ traitor.restricted_roles = restricted_jobs pre_antags[traitor] = ROLE_TRAITOR if(ROLE_THIEF) - var/datum/mind/thief = pick_n_take(possible_thieves) + var/datum/mind/thief = pick_n_take(antag_possibilities[ROLE_THIEF]) if(!thief) continue - listclearduplicates(thief, possible_thieves) + listclearduplicates(thief, antag_possibilities[ROLE_THIEF]) if(thief.special_role) continue thief.special_role = SPECIAL_ROLE_THIEF @@ -174,6 +192,17 @@ pre_double_antags[antag] = ROLE_CHANGELING break +/datum/game_mode/antag_paradise/pre_setup() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + var/list/antag_possibilities = list() + antag_possibilities[ROLE_VAMPIRE] = get_players_for_role(ROLE_VAMPIRE) + antag_possibilities[ROLE_CHANGELING] = get_players_for_role(ROLE_CHANGELING) + antag_possibilities[ROLE_TRAITOR] = get_players_for_role(ROLE_TRAITOR) + antag_possibilities[ROLE_THIEF] = get_players_for_role(ROLE_THIEF, list("Vox" = 4)) + + roll_antagonists(antag_possibilities, TRUE) /datum/game_mode/antag_paradise/proc/calculate_antags(players) var/list/special_antags_list @@ -228,6 +257,7 @@ antag.add_antag_datum(ninja_datum) addtimer(CALLBACK(src, PROC_REF(initiate_antags)), rand(1 SECONDS, 10 SECONDS)) + SSgame_events.add_to_process(src) ..() diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 37691e30755..dd22c72f752 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -228,7 +228,7 @@ /mob/living/simple_animal/hostile/blob/blobbernaut/proc/blob_talk() var/message = input(src, "Announce to the overmind", "Blob Telepathy") - var/rendered = "Blob Telepathy, [name]([overmind]) states, \"[message]\"" + var/rendered = "Blob Telepathy, [name]([overmind]) states, \"[message]\"" if(message) for(var/mob/M in GLOB.mob_list) if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut)) diff --git a/code/game/gamemodes/blob/blobs/captured_nuke.dm b/code/game/gamemodes/blob/blobs/captured_nuke.dm index 1841cbbb4fb..d9312ba261b 100644 --- a/code/game/gamemodes/blob/blobs/captured_nuke.dm +++ b/code/game/gamemodes/blob/blobs/captured_nuke.dm @@ -10,12 +10,11 @@ START_PROCESSING(SSobj, src) N?.forceMove(src) -/obj/structure/blob/captured_nuke/update_icon() - ..() - cut_overlays() - var/image/nuke_overlay = image('icons/mob/blob.dmi', "blob_nuke_overlay") - nuke_overlay.appearance_flags = RESET_COLOR - add_overlay(nuke_overlay) + +/obj/structure/blob/captured_nuke/update_overlays() + . = ..() + . += mutable_appearance('icons/mob/blob.dmi', "blob_nuke_overlay", appearance_flags = RESET_COLOR) + /obj/structure/blob/captured_nuke/Destroy() for(var/obj/machinery/nuclearbomb/O in contents) diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index 96f3e0a2382..6f227fd858e 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -12,23 +12,53 @@ /obj/structure/blob/shield/core point_return = 0 -/obj/structure/blob/shield/update_icon() - ..() + +/obj/structure/blob/shield/check_integrity() + var/old_compromised_integrity = compromised_integrity if(obj_integrity < max_integrity * 0.5) - icon_state = "[initial(icon_state)]_damaged" - name = "weakened [initial(name)]" - desc = "A wall of twitching tendrils." + compromised_integrity = TRUE + else + compromised_integrity = FALSE + if(old_compromised_integrity != compromised_integrity) + update_state() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) + + +/obj/structure/blob/shield/update_state() + if(compromised_integrity) atmosblock = FALSE else - icon_state = initial(icon_state) - name = initial(name) - desc = initial(desc) atmosblock = TRUE air_update_turf(1) + +/obj/structure/blob/shield/update_name(updates = ALL) + . = ..() + if(compromised_integrity) + name = "weakened [initial(name)]" + else + name = initial(name) + + +/obj/structure/blob/shield/update_desc(updates = ALL) + . = ..() + if(compromised_integrity) + desc = "A wall of twitching tendrils." + else + desc = initial(desc) + + +/obj/structure/blob/shield/update_icon_state() + if(compromised_integrity) + icon_state = "[initial(icon_state)]_damaged" + else + icon_state = initial(icon_state) + + /obj/structure/blob/shield/CanPass(atom/movable/mover, turf/target, height=0) - if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 - return 0 + if(istype(mover) && mover.checkpass(PASSBLOB)) + return TRUE + return FALSE /obj/structure/blob/shield/reflective name = "reflective blob" diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index cd35d1ead0f..87c5f619e28 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -89,8 +89,7 @@ if(!message) return - var/verb = "states," - var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [verb] \"[message]\"" + var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) states, \"[message]\"" for(var/mob/M in GLOB.mob_list) if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut)) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 801e65227bc..72efb8ba7f6 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -6,7 +6,7 @@ desc = "Some blob creature thingy" density = 0 opacity = 1 - anchored = 1 + anchored = TRUE max_integrity = 30 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. @@ -14,6 +14,8 @@ var/brute_resist = 0.5 //multiplies brute damage by this var/fire_resist = 1 //multiplies burn damage by this var/atmosblock = FALSE //if the blob blocks atmos and heat spread + /// If a threshold is reached, resulting in shifting variables + var/compromised_integrity = FALSE var/mob/camera/blob/overmind creates_cover = TRUE @@ -21,7 +23,7 @@ ..() GLOB.blobs += src setDir(pick(GLOB.cardinal)) - update_icon() + check_integrity() if(atmosblock) air_update_turf(1) ConsumeTile() @@ -41,6 +43,12 @@ /obj/structure/blob/BlockSuperconductivity() return atmosblock +/obj/structure/blob/proc/check_integrity() + return + +/obj/structure/blob/proc/update_state() + return + /obj/structure/blob/CanPass(atom/movable/mover, turf/target, height=0) if(height==0) return 1 @@ -75,7 +83,7 @@ return 0 if(obj_integrity < max_integrity) obj_integrity = min(max_integrity, obj_integrity + 1) - update_icon() + check_integrity() health_timestamp = world.time + 10 // 1 seconds @@ -193,7 +201,7 @@ /obj/structure/blob/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(. && obj_integrity > 0) - update_icon() + check_integrity() /obj/structure/blob/proc/change_to(var/type) if(!ispath(type)) @@ -240,20 +248,45 @@ max_integrity = 25 brute_resist = 0.25 -/obj/structure/blob/normal/update_icon() - ..() + +/obj/structure/blob/normal/check_integrity() + var/old_compromised_integrity = compromised_integrity if(obj_integrity <= 15) - icon_state = "blob_damaged" - name = "fragile blob" - desc = "A thin lattice of slightly twitching tendrils." + compromised_integrity = TRUE + else + compromised_integrity = FALSE + if(old_compromised_integrity != compromised_integrity) + update_state() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) + + +/obj/structure/blob/normal/update_state() + if(compromised_integrity) brute_resist = 0.5 - else if(overmind) - icon_state = "blob" - name = "blob" - desc = "A thick wall of writhing tendrils." + else brute_resist = 0.25 + + +/obj/structure/blob/normal/update_name(updates = ALL) + . = ..() + if(compromised_integrity) + name = "fragile blob" + else + name = "[overmind ? "blob" : "dead blob"]" + + +/obj/structure/blob/normal/update_desc(updates = ALL) + . = ..() + if(compromised_integrity) + desc = "A thin lattice of slightly twitching tendrils." + else + desc = "A thick wall of [overmind ? "writhing" : "lifeless"] tendrils." + + +/obj/structure/blob/normal/update_icon_state() + if(compromised_integrity) + icon_state = "blob_damaged" else icon_state = "blob" - name = "dead blob" - desc = "A thick wall of lifeless tendrils." - brute_resist = 0.25 + + diff --git a/code/game/gamemodes/clockwork/clockwork_gateway.dm b/code/game/gamemodes/clockwork/clockwork_gateway.dm index 1695cd823b0..3a8d3135878 100644 --- a/code/game/gamemodes/clockwork/clockwork_gateway.dm +++ b/code/game/gamemodes/clockwork/clockwork_gateway.dm @@ -51,13 +51,27 @@ countdown.stop() visible_message("[src] begins to pulse uncontrollably... you might want to run!") sound_to_playing_players(volume = 50, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/magic/clockwork/clockcult_gateway_disrupted.ogg')) - icon_state = "clockwork_gateway_disrupted" + update_icon(UPDATE_ICON_STATE) resistance_flags |= INDESTRUCTIBLE sleep(2.7 SECONDS) explosion(src, 1, 3, 8, 8) sound_to_playing_players('sound/effects/explosionfar.ogg', volume = 50) qdel(src) + +/obj/structure/clockwork/functional/celestial_gateway/update_icon_state() + if(!countdown || !countdown.started) + icon_state = "clockwork_gateway_disrupted" + return + switch(seconds_until_activation) + if(-INFINITY to GATEWAY_REEBE_FOUND) + icon_state = "clockwork_gateway_charging" + if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) + icon_state = "clockwork_gateway_active" + if(GATEWAY_RATVAR_COMING to INFINITY) + icon_state = "clockwork_gateway_closing" + + /obj/structure/clockwork/functional/celestial_gateway/ex_act(severity) var/damage = max((obj_integrity * 0.7) / severity, 100) take_damage(damage, BRUTE, "bomb", 0) @@ -105,17 +119,17 @@ sound_to_playing_players('sound/magic/clockwork/invoke_general.ogg', 30, FALSE) sound_to_playing_players(volume = 20, channel = CHANNEL_JUSTICAR_ARK, pressure_affected = FALSE, S = sound('sound/magic/clockwork/clockcult_gateway_charging.ogg', TRUE)) first_sound_played = TRUE - icon_state = "clockwork_gateway_charging" + update_icon(UPDATE_ICON_STATE) if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) if(!second_sound_played) sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, pressure_affected = FALSE, S = sound('sound/magic/clockwork/clockcult_gateway_active.ogg', TRUE)) second_sound_played = TRUE - icon_state = "clockwork_gateway_active" + update_icon(UPDATE_ICON_STATE) if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL) if(!third_sound_played) sound_to_playing_players(volume = 40, channel = CHANNEL_JUSTICAR_ARK, pressure_affected = FALSE, S = sound('sound/magic/clockwork/clockcult_gateway_closing.ogg', TRUE)) third_sound_played = TRUE - icon_state = "clockwork_gateway_closing" + update_icon(UPDATE_ICON_STATE) if(GATEWAY_RATVAR_ARRIVAL to INFINITY) if(!purpose_fulfilled) countdown.stop() diff --git a/code/game/gamemodes/clockwork/clockwork_items.dm b/code/game/gamemodes/clockwork/clockwork_items.dm index 14741815479..f61aded9cc0 100644 --- a/code/game/gamemodes/clockwork/clockwork_items.dm +++ b/code/game/gamemodes/clockwork/clockwork_items.dm @@ -10,13 +10,29 @@ var/list/plush_colors = list("red fox plushie" = "redfox", "black fox plushie" = "blackfox", "blue fox plushie" = "bluefox", "orange fox plushie" = "orangefox", "corgi plushie" = "corgi", "black cat plushie" = "blackcat", "deer plushie" = "deer", "octopus plushie" = "loveable", "facehugger plushie" = "huggable") - var/plushy = FALSE + var/plushy + /obj/item/clockwork/clockslab/Initialize(mapload) . = ..() enchants = GLOB.clockslab_spells +/obj/item/clockwork/clockslab/update_name(updates = ALL) + . = ..() + name = plushy ? plushy : initial(name) + + +/obj/item/clockwork/clockslab/update_desc(updates = ALL) + . = ..() + desc = plushy ? "An adorable, soft, and cuddly plushie." : initial(desc) + + +/obj/item/clockwork/clockslab/update_icon_state() + icon = plushy ? 'icons/obj/toy.dmi' : 'icons/obj/clockwork.dmi' + icon_state = plushy ? plush_colors[plushy] : initial(icon_state) + + /obj/item/clockwork/clockslab/update_overlays() . = ..() if(enchant_type) @@ -37,13 +53,11 @@ return if(alert(user, "Do you want to reveal clockwork slab?","Revealing!","Yes","No") != "Yes") return - name = "clockwork slab" - desc = "A strange metal tablet. A clock in the center turns around and around." - icon = 'icons/obj/clockwork.dmi' - icon_state = "clock_slab" attack_verb = null deplete_spell() - plushy = FALSE + plushy = null + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + if(!isclocker(user)) to_chat(user, "\"Now now, this is for my servants, not you.\"") if(iscarbon(user)) @@ -51,17 +65,15 @@ carbon.Weaken(10 SECONDS) carbon.Stuttering(20 SECONDS) return + if(enchant_type == HIDE_SPELL) to_chat(user, "You disguise your tool as some little toy.") playsound(user, 'sound/magic/cult_spell.ogg', 15, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - var/chosen_plush = pick(plush_colors) - name = chosen_plush - desc = "An adorable, soft, and cuddly plushie." - icon = 'icons/obj/toy.dmi' - icon_state = plush_colors[chosen_plush] + plushy = pick(plush_colors) attack_verb = list("poofed", "bopped", "whapped","cuddled","fluffed") enchant_type = CASTING_SPELL - plushy = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + if(enchant_type == TELEPORT_SPELL) var/list/possible_altars = list() var/list/altars = list() @@ -225,8 +237,7 @@ enchants = GLOB.spear_spells /obj/item/twohanded/ratvarian_spear/update_icon_state() - icon_state = "ratvarian_spear[wielded]" - + icon_state = "ratvarian_spear[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/ratvarian_spear/update_overlays() . = ..() @@ -313,7 +324,6 @@ . = ..() enchants = GLOB.spear_spells - /obj/item/clock_borg_spear/update_overlays() . = ..() if(enchant_type) @@ -370,13 +380,12 @@ enchants = GLOB.hammer_spells /obj/item/twohanded/clock_hammer/update_icon_state() - icon_state = "clock_hammer[wielded]" - + icon_state = "clock_hammer[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/clock_hammer/update_overlays() . = ..() if(enchant_type) - . +="clock_hammer0_overlay_[enchant_type]" + . += "clock_hammer0_overlay_[enchant_type]" /obj/item/twohanded/clock_hammer/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!isliving(hit_atom)) @@ -576,14 +585,10 @@ . = ..() enchants = GLOB.shield_spells -/obj/item/shield/clock_buckler/update_icon() - update_overlays() - return ..() - /obj/item/shield/clock_buckler/update_overlays() - cut_overlays() + . = ..() if(enchant_type) - overlays += "brass_buckler_overlay_[enchant_type]" + . += "brass_buckler_overlay_[enchant_type]" /obj/item/shield/clock_buckler/attack_self(mob/user) . = ..() @@ -1167,7 +1172,7 @@ name = "integration cog" desc = "You shouldn't see that! Call dev on that!" icon = null - anchored = 1 + anchored = TRUE active_power_usage = 100 // In summary it costs 500 power. Most areas costs around 800, with top being medbay at around 8000. Fair number. var/obj/machinery/power/apc/apc var/next_whoosh = 120 @@ -1294,7 +1299,7 @@ /obj/item/clockwork/shard/update_overlays() . = ..() if(enchant_type) - . +="shard_overlay_[enchant_type]" + . += "shard_overlay_[enchant_type]" /obj/item/clockwork/shard/attack_self(mob/user) if(!isclocker(user) && isliving(user)) diff --git a/code/game/gamemodes/clockwork/clockwork_misc.dm b/code/game/gamemodes/clockwork/clockwork_misc.dm index fe03c247b1b..eae4ebfb3a5 100644 --- a/code/game/gamemodes/clockwork/clockwork_misc.dm +++ b/code/game/gamemodes/clockwork/clockwork_misc.dm @@ -91,8 +91,11 @@ /obj/effect/decal/cleanable/blood/gibs/clock/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/blood/gibs/clock/update_icon() + +/obj/effect/decal/cleanable/blood/gibs/clock/update_icon(updates = ALL) color = "#FFFFFF" + . = ..(NONE) + /obj/effect/decal/cleanable/blood/gibs/clock/dry() return diff --git a/code/game/gamemodes/clockwork/clockwork_mob.dm b/code/game/gamemodes/clockwork/clockwork_mob.dm index 7ecdbb32c51..1fce1d4ba54 100644 --- a/code/game/gamemodes/clockwork/clockwork_mob.dm +++ b/code/game/gamemodes/clockwork/clockwork_mob.dm @@ -155,7 +155,7 @@ investigate_log("was chewed through by a clock mouse in [get_area(F)]([F.x], [F.y], [F.z] - [ADMIN_JMP(F)])","wires") C.deconstruct() -/mob/living/simple_animal/mouse/clockwork/splat(var/obj/item/item = null, var/mob/living/user = null) +/mob/living/simple_animal/mouse/clockwork/splat(obj/item/item = null, mob/living/user = null) return /mob/living/simple_animal/mouse/clockwork/toast() diff --git a/code/game/gamemodes/clockwork/clockwork_soulvessel.dm b/code/game/gamemodes/clockwork/clockwork_soulvessel.dm index b2d5637adec..142935afda6 100644 --- a/code/game/gamemodes/clockwork/clockwork_soulvessel.dm +++ b/code/game/gamemodes/clockwork/clockwork_soulvessel.dm @@ -21,15 +21,14 @@ chosen_ghost = ghost break if(!chosen_ghost) - icon_state = searching_icon searching = TRUE + update_icon(UPDATE_ICON_STATE) to_chat(user, "Capture failed! The soul has already fled its mortal frame. You attempt to bring it back...") var/list/candidates = SSghost_spawns.poll_candidates("Would you like to play as a Servant of Ratvar?", ROLE_CLOCKER, FALSE, poll_time = 10 SECONDS, source = /obj/item/mmi/robotic_brain/clockwork) if(length(candidates)) chosen_ghost = pick(candidates) searching = FALSE - if(!brainmob?.key) - icon_state = blank_icon + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) if(!M) return FALSE if(!chosen_ghost) @@ -61,10 +60,9 @@ brainmob.key = candidate.key brainmob.name = "[pick(list("Nycun", "Oenib", "Havsbez", "Ubgry", "Fvreen"))]-[rand(10, 99)]" brainmob.real_name = brainmob.name - name = "[src] ([brainmob.name])" brainmob.mind.assigned_role = "Soul Vessel Cube" visible_message("[src] chimes quietly.") - become_occupied(occupied_icon) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) if(SSticker.mode.add_clocker(brainmob.mind)) brainmob.create_log(CONVERSION_LOG, "[brainmob.mind] been converted by [src.name]") diff --git a/code/game/gamemodes/clockwork/clockwork_structures.dm b/code/game/gamemodes/clockwork/clockwork_structures.dm index b8ab532148f..c3995892d8e 100644 --- a/code/game/gamemodes/clockwork/clockwork_structures.dm +++ b/code/game/gamemodes/clockwork/clockwork_structures.dm @@ -22,6 +22,7 @@ var/death_sound = 'sound/effects/forge_destroy.ogg' var/canbehidden = FALSE var/hidden = FALSE + var/hidden_type var/list/choosable_items = list( "rack" = /obj/structure/rack, "table" = /obj/structure/table, @@ -31,6 +32,72 @@ "bookcase" = /obj/structure/bookcase ) +/obj/structure/clockwork/functional/update_name(updates = ALL) + . = ..() + if(!hidden) + name = initial(name) + return + switch(hidden_type) + if("rack") + name = "rack" + if("table") + name = "table" + if("wooden table") + name = "wooden table" + if("personal closet") + name = "personal closet" + if("girder") + name = "girder" + if("bookcase") + name = "bookcase" + + +/obj/structure/clockwork/functional/update_desc(updates = ALL) + . = ..() + if(!hidden) + desc = initial(desc) + return + switch(hidden_type) + if("rack") + desc = "Different from the Middle Ages version.
It's held together by a couple of bolts." + if("table") + desc = "A square piece of metal standing on four metal legs. It can not move.
The top is screwed on, but the main bolts are also visible." + if("wooden table") + desc = "Do not apply fire to this. Rumour says it burns easily.
The top is screwed on, but the main bolts are also visible." + if("personal closet") + desc = "It's a secure locker for personnel. The first card swiped gains control." + if("girder") + desc = "The bolts are lodged in place." + if("bookcase") + desc = null + + +/obj/structure/clockwork/functional/update_icon_state() + if(!hidden) + icon = initial(icon) + icon_state = anchored ? "[initial(icon_state)]-off" : initial(icon_state) + return + switch(hidden_type) + if("rack") + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + if("table") + icon = 'icons/obj/smooth_structures/table.dmi' + icon_state = "table" + if("wooden table") + icon = 'icons/obj/smooth_structures/wood_table.dmi' + icon_state = "wood_table" + if("personal closet") + icon = 'icons/obj/closet.dmi' + icon_state = "secureoff" + if("girder") + icon = 'icons/obj/structures.dmi' + icon_state = "girder" + if("bookcase") + icon = 'icons/obj/library.dmi' + icon_state = "book-0" + + /obj/structure/clockwork/functional/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clockwork/clockslab) && isclocker(user)) if(I.enchant_type == HIDE_SPELL && canbehidden) @@ -59,11 +126,7 @@ add_fingerprint(user) anchored = !anchored to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") - if(!anchored) - icon_state = "[initial(icon_state)]-off" - else - icon_state = "[initial(icon_state)]" - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE return ..() @@ -81,45 +144,12 @@ /obj/structure/clockwork/functional/proc/toggle_hide(chosen_type) hidden = !hidden if(!hidden) - name = initial(name) - desc = initial(desc) - icon = initial(icon) - if(!anchored) - icon_state = "[initial(icon_state)]-off" - else - icon_state = "[initial(icon_state)]" + hidden_type = null + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return FALSE - switch(chosen_type) - if("rack") - name = "rack" - desc = "Different from the Middle Ages version.
It's held together by a couple of bolts." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - if("table") - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move.
The top is screwed on, but the main bolts are also visible." - icon = 'icons/obj/smooth_structures/table.dmi' - icon_state = "table" - if("wooden table") - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily.
The top is screwed on, but the main bolts are also visible." - icon = 'icons/obj/smooth_structures/wood_table.dmi' - icon_state = "wood_table" - if("personal closet") - name = "personal closet" - desc = "It's a secure locker for personnel. The first card swiped gains control." - icon = 'icons/obj/closet.dmi' - icon_state = "secureoff" - if("girder") - name = "girder" - desc = "The bolts are lodged in place." - icon = 'icons/obj/structures.dmi' - icon_state = "girder" - if("bookcase") - name = "bookcase" - desc = null - icon = 'icons/obj/library.dmi' - icon_state = "book-0" + + hidden_type = chosen_type + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return TRUE /obj/structure/clockwork/functional/beacon @@ -231,6 +261,62 @@ STOP_PROCESSING(SSprocessing, src) return ..() + +/obj/structure/clockwork/functional/altar/update_name(updates = ALL) + . = ..() + if(!hidden) + name = initial(name) + return + switch(hidden_type) + if("potted plant") + name = "potted plant" + if("chair") + name = "chair" + if("stool") + name = "stool" + if("broken grille") + name = "grille" + + +/obj/structure/clockwork/functional/altar/update_desc(updates = ALL) + . = ..() + if(!hidden) + desc = initial(desc) + return + switch(hidden_type) + if("potted plant") + desc = null + if("chair") + desc = "You sit in this. Either by will or force." + if("stool") + desc = "Apply butt." + if("broken grille") + desc = "A flimsy framework of metal rods." + + +/obj/structure/clockwork/functional/altar/update_icon_state() + if(!hidden) + icon = initial(icon) + if(!anchored) + icon_state = "[initial(icon_state)]-off" + return + icon_state = first_stage ? "[initial(icon_state)]-fast" : initial(icon_state) + return + switch(hidden_type) + if("potted plant") + icon = 'icons/obj/flora/plants.dmi' + icon_state = "plant-[rand(1,36)]" + if("chair") + icon = 'icons/obj/chairs.dmi' + icon_state = "chair" + if("stool") + icon = 'icons/obj/chairs.dmi' + icon_state = "stool" + if("broken grille") + icon = 'icons/obj/structures.dmi' + icon_state = "brokengrille" + + /obj/structure/clockwork/functional/altar/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clockwork/clockslab) && isclocker(user)) if(hidden) @@ -269,50 +355,16 @@ to_chat(usr, "There is a structure here!") return TRUE anchored = !anchored + update_icon(UPDATE_ICON_STATE) to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") if(!anchored) stop_convert(TRUE) STOP_PROCESSING(SSprocessing, src) else - icon_state = "[initial(icon_state)]" START_PROCESSING(SSprocessing, src) - update_icon() return TRUE return ..() -/obj/structure/clockwork/functional/altar/toggle_hide(chosen_type) - hidden = !hidden - if(!hidden) - name = initial(name) - desc = initial(desc) - icon = initial(icon) - if(!anchored) - icon_state = "[initial(icon_state)]-off" - else - icon_state = "[initial(icon_state)]" - return FALSE - switch(chosen_type) - if("potted plant") - name = "potted plant" - desc = null - icon = 'icons/obj/flora/plants.dmi' - icon_state = "plant-[rand(1,36)]" - if("chair") - name = "chair" - desc = "You sit in this. Either by will or force." - icon = 'icons/obj/chairs.dmi' - icon_state = "chair" - if("stool") - name = "stool" - desc = "Apply butt." - icon = 'icons/obj/chairs.dmi' - icon_state = "stool" - if("broken grille") - name = "grille" - desc = "A flimsy framework of metal rods." - icon = 'icons/obj/structures.dmi' - icon_state = "brokengrille" - return TRUE /obj/structure/clockwork/functional/altar/process() for(var/mob/living/M in range(1, src)) @@ -356,7 +408,7 @@ target.visible_message("[src] begins to glow a piercing amber!", "You feel something start to invade your mind...") glow = new (get_turf(src)) animate(glow, alpha = 255, time = 8 SECONDS) - icon_state = "[initial(icon_state)]-fast" + update_icon(UPDATE_ICON_STATE) /obj/structure/clockwork/functional/altar/proc/second_stage_check(var/mob/living/carbon/human/target) second_stage = TRUE @@ -381,10 +433,7 @@ second_stage = FALSE convert_timer = 0 converting = null - if(anchored) - icon_state = "[initial(icon_state)]" - else - icon_state = "[initial(icon_state)]-off" + update_icon(UPDATE_ICON_STATE) if(!silent) visible_message("[src] slowly stops glowing!") @@ -452,6 +501,11 @@ if(!hidden && (isclocker(user) || isobserver(user))) . += "There's [cog_slots - cogscarab_list.len] cogscarab ready. [timer_fabrictor ? "And it's creating another one now" : "It stopped creating."]." + +/obj/structure/clockwork/functional/cogscarab_fabricator/update_icon_state() + icon_state = anchored ? "[initial(icon_state)]-off" : initial(icon_state) + + /obj/structure/clockwork/functional/cogscarab_fabricator/Initialize(mapload) . = ..() GLOB.clockwork_fabricators += src @@ -490,17 +544,15 @@ return TRUE add_fingerprint(user) anchored = !anchored + update_icon(UPDATE_ICON_STATE) to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") if(!anchored) - icon_state = "[initial(icon_state)]-off" if(timer_fabrictor) deltimer(timer_fabrictor) timer_fabrictor = null else - icon_state = "[initial(icon_state)]" if(cog_slots < MAX_COGSCRAB_PER_FABRICATOR) timer_fabrictor = addtimer(CALLBACK(src, PROC_REF(open_slot)), TIME_NEW_COGSCRAB SECONDS) - update_icon() return TRUE /obj/structure/clockwork/functional/cogscarab_fabricator/toggle_hide(chosen_type) diff --git a/code/game/gamemodes/clockwork/cogscarab.dm b/code/game/gamemodes/clockwork/cogscarab.dm index b866143694c..c63b78796ff 100644 --- a/code/game/gamemodes/clockwork/cogscarab.dm +++ b/code/game/gamemodes/clockwork/cogscarab.dm @@ -55,8 +55,8 @@ /mob/living/silicon/robot/cogscarab/Initialize(mapload) . = ..() - remove_language("Robot Talk") - add_language("Drone Talk", 1) + remove_language(LANGUAGE_BINARY) + add_language(LANGUAGE_DRONE_BINARY, 1) if(radio) radio.wires.cut(WIRE_RADIO_TRANSMIT) diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm index 6746aada31f..54ec37a807d 100644 --- a/code/game/gamemodes/cult/blood_magic.dm +++ b/code/game/gamemodes/cult/blood_magic.dm @@ -682,7 +682,7 @@ to_chat(user, "You empower [target] with blood, recharging its ability to shift!") playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE) S.uses = 4 - S.icon_state = "shifter" + S.update_icon(UPDATE_ICON_STATE) else to_chat(user, "[target] is already at full charge!") return @@ -827,7 +827,7 @@ var/turf/T = get_turf(target) if(T) for(var/obj/effect/decal/cleanable/blood/B in view(T, 2)) - if(B.blood_state == BLOOD_STATE_HUMAN && (B.can_bloodcrawl_in() || istype(B, /obj/effect/decal/cleanable/blood/slime))) + if(B.blood_state == BLOOD_STATE_HUMAN && (B.can_bloodcrawl_in() || istype(B, /obj/effect/decal/cleanable/blood/slime) || istype(B, /obj/effect/decal/cleanable/blood/drask))) if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam temp += 30 else diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 966cf5d63ca..930b97455d0 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -6,10 +6,18 @@ throw_range = 5 w_class = WEIGHT_CLASS_SMALL -/obj/item/tome/New() - if(SSticker.mode) + +/obj/item/tome/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/tome/update_icon_state() + if(SSticker?.cultdat) icon_state = SSticker.cultdat.tome_icon - ..() + else + icon_state = initial(icon_state) + /obj/item/melee/cultblade name = "cult blade" @@ -25,11 +33,20 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sprite_sheets_inhand = list("Skrell" = 'icons/mob/clothing/species/skrell/held.dmi') // To stop skrell stabbing themselves in the head -/obj/item/melee/cultblade/New() - if(SSticker.mode) + +/obj/item/melee/cultblade/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/melee/cultblade/update_icon_state() + if(SSticker?.cultdat) icon_state = SSticker.cultdat.sword_icon item_state = SSticker.cultdat.sword_icon - ..() + else + icon_state = initial(icon_state) + item_state = initial(item_state) + /obj/item/melee/cultblade/attack(mob/living/target, mob/living/carbon/human/user) if(!iscultist(user)) @@ -265,7 +282,7 @@ prefix = "darkened" claw_damage_increase = 4 -/obj/item/whetstone/cult/update_icon() +/obj/item/whetstone/cult/update_icon_state() icon_state = "cult_sharpener[used ? "_used" : ""]" /obj/item/whetstone/cult/attackby(obj/item/I, mob/user, params) @@ -348,6 +365,11 @@ else . += "It seems drained." + +/obj/item/cult_shift/update_icon_state() + icon_state = "shifter[uses > 0 ? "" : "_drained"]" + + /obj/item/cult_shift/proc/handle_teleport_grab(turf/T, mob/user) var/mob/living/carbon/C = user if(C.pulling) @@ -389,8 +411,7 @@ if(turfs) uses-- var/turf/destination = pick(turfs) - if(uses <= 0) - icon_state ="shifter_drained" + update_icon(UPDATE_ICON_STATE) playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir) @@ -591,8 +612,8 @@ qdel(spear_act) ..() -/obj/item/twohanded/cult_spear/update_icon() - icon_state = "bloodspear[wielded]" +/obj/item/twohanded/cult_spear/update_icon_state() + icon_state = "bloodspear[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/cult_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) var/turf/T = get_turf(hit_atom) diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index e6fff3140b9..242a7999d9e 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -46,6 +46,13 @@ var/list/choosable_items = list("A coder forgot to set this" = /obj/item/grown/bananapeel) var/creation_message = "A dank smoke comes out, and you pass out. When you come to, you notice a %ITEM%!" + +/obj/structure/cult/functional/Initialize(mapload) + . = ..() + if(cult_icon_changing) + update_icon(UPDATE_ICON_STATE) + + /obj/structure/cult/functional/obj_destruction() visible_message(death_message) playsound(src, death_sound, 50, TRUE) @@ -57,15 +64,21 @@ . += "The magic in [src] is weak, it will be ready to use again in [get_ETA()]." . += "[src] is [anchored ? "":"not "]secured to the floor." + +/obj/structure/cult/functional/update_icon_state() + var/init_icon = initial(icon_state) + if(!SSticker || !SSticker.cultdat || !cult_icon_changing) + icon_state = init_icon + return + icon_state = anchored ? SSticker.cultdat.get_icon("[init_icon]") : SSticker.cultdat.get_icon("[init_icon]_off") + + /obj/structure/cult/functional/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user)) add_fingerprint(user) anchored = !anchored + update_icon(UPDATE_ICON_STATE) to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") - if(!anchored) - icon_state = SSticker.cultdat?.get_icon("[initial(icon_state)]_off") - else - icon_state = SSticker.cultdat?.get_icon("[initial(icon_state)]") return return ..() @@ -143,10 +156,6 @@ choosable_items = list("Eldritch Whetstone" = /obj/item/whetstone/cult, "Flask of Unholy Water" = /obj/item/reagent_containers/food/drinks/bottle/unholywater, "Construct Shell" = /obj/structure/constructshell) -/obj/structure/cult/functional/altar/Initialize(mapload) - . = ..() - if(cult_icon_changing) - icon_state = SSticker.cultdat?.altar_icon_state /obj/structure/cult/functional/forge name = "daemon forge" @@ -164,10 +173,6 @@ choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/flagellant_robe, "Mirror Shield" = /obj/item/shield/mirror) -/obj/structure/cult/functional/forge/Initialize(mapload) - . = ..() - if(cult_icon_changing) - icon_state = SSticker.cultdat?.forge_icon_state /obj/structure/cult/functional/forge/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/grab)) @@ -253,8 +258,7 @@ GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list( ) START_PROCESSING(SSobj, src) - if(cult_icon_changing) - icon_state = SSticker.cultdat?.pylon_icon_state + /obj/structure/cult/functional/pylon/attack_hand(mob/living/user)//override as it should not create anything return @@ -329,10 +333,6 @@ GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list( choosable_items = list("Shuttle Curse" = /obj/item/shuttle_curse, "Zealot's Blindfold" = /obj/item/clothing/glasses/hud/health/night/cultblind, "Veil Shifter" = /obj/item/cult_shift) //Add void torch to veil shifter spawn -/obj/structure/cult/functional/archives/Initialize(mapload) - . = ..() - if(cult_icon_changing) - icon_state = SSticker.cultdat?.archives_icon_state /obj/effect/gateway name = "gateway" diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 4dcc53f700b..40c0dfbc0e8 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -20,11 +20,20 @@ force = 16 scribe_multiplier = 0.1 -/obj/item/melee/cultblade/dagger/New() - ..() - if(SSticker.mode) + +/obj/item/melee/cultblade/dagger/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/melee/cultblade/dagger/update_icon_state() + if(SSticker?.cultdat) icon_state = SSticker.cultdat.dagger_icon item_state = SSticker.cultdat.dagger_icon + else + icon_state = initial(icon_state) + item_state = initial(item_state) + /obj/item/melee/cultblade/dagger/examine(mob/user) . = ..() diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 54d0e6c2bdc..fe0dd160f1c 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -513,7 +513,7 @@ structure_check() searches for nearby cultist structures required for the invoca desc += "The void feels like it's trying to pull you to the [dir2text(get_dir(T, origin))], in the direction of space sector [origin.z]!" else - inner_portal.icon_state = "lava" + inner_portal.update_icon(UPDATE_ICON_STATE) light_color = LIGHT_COLOR_FIRE desc += "
A tear in reality reveals a coursing river of lava... something recently teleported here from the Lavaland Mines!" @@ -967,6 +967,11 @@ structure_check() searches for nearby cultist structures required for the invoca cultist_name = "Summon [SSticker.cultdat ? SSticker.cultdat.entity_name : "your god"]" cultist_desc = "tears apart dimensional barriers, calling forth [SSticker.cultdat ? SSticker.cultdat.entity_title3 : "your god"]." + +/obj/effect/rune/narsie/update_icon_state() + icon_state = used ? "rune_large_distorted" : initial(icon_state) + + /obj/effect/rune/narsie/check_icon() return @@ -993,7 +998,7 @@ structure_check() searches for nearby cultist structures required for the invoca ..() SEND_SOUND(world, 'sound/effects/narsie_summon.ogg') to_chat(world, "The veil... is... TORN!!!--") - icon_state = "rune_large_distorted" + update_icon(UPDATE_ICON_STATE) var/turf/T = get_turf(src) sleep(40) new /obj/singularity/narsie/large(T) //Causes Nar'Sie to spawn even if the rune has been removed diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 6309e81654e..50e1527e2b8 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -112,8 +112,8 @@ /** * Called by the gameticker. */ -/datum/game_mode/process() - return FALSE +/datum/game_mode/process(wait) + return PROCESS_KILL /** @@ -312,6 +312,44 @@ return candidates +/** + * Works like get_players_for_role, but for alive mobs. + */ +/datum/game_mode/proc/get_alive_players_for_role(role, list/preferred_species) + var/list/players = list() + var/list/candidates = list() + + // Assemble a list of active players without jobbans and role enabled + for(var/mob/living/player in GLOB.alive_mob_list) + if(!player.client || !player.has_valid_preferences() \ + || jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, role) \ + || !player_old_enough_antag(player.client, role) || player.client.skip_antag \ + || !(role in player.client.prefs.be_special)) + continue + + players += player + + // Shuffle the players list so that it becomes ping-independent. + players = shuffle(players) + + // Get a list of all the people who want to be the antagonist for this round, except those with incompatible species + for(var/mob/living/player in players) + if(length(protected_species) && (player.client.prefs.species in protected_species)) + continue + if(length(restricted_jobs) && (player.mind.assigned_role in restricted_jobs)) + continue + if(player.mind.has_antag_datum(/datum/antagonist) || player.mind.offstation_role || player.mind.special_role) + continue + + player_draft_log += "[player.key] had [role] enabled, so we are drafting them." + candidates += player.mind + if(length(preferred_species)) + var/prefered_species_mod = preferred_species[player.client.prefs.species] + if(isnum(prefered_species_mod)) + for (var/i in 1 to prefered_species_mod) //prefered mod + candidates += player.mind + + return candidates /datum/game_mode/proc/latespawn(mob/player) @@ -324,6 +362,15 @@ if(player.client && player.ready) .++ +/datum/game_mode/proc/num_station_players() + . = 0 + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(!player) + continue + + if(player.client && player.mind && !player.mind.offstation_role && !player.mind.special_role) + .++ + /datum/game_mode/proc/num_players_started() . = 0 diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 896d17f0462..b642c35c58a 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -101,9 +101,9 @@ GLOBAL_LIST_EMPTY(cortical_stacks) //Stacks for 'leave nobody behind' objective. vox.s_tone = rand(1, 6) vox.languages = list() // Removing language from chargen. vox.flavor_text = "" - vox.add_language("Vox-pidgin") - vox.add_language("Galactic Common") - vox.add_language("Tradeband") + vox.add_language(LANGUAGE_VOX) + vox.add_language(LANGUAGE_GALACTIC_COMMON) + vox.add_language(LANGUAGE_TRADER) head_organ.h_style = "Short Vox Quills" head_organ.f_style = "Shaved" vox.change_hair_color(97, 79, 25) //Same as the species default colour. diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 246fcfc500d..53a03dfe0f7 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -265,7 +265,7 @@ name = "doomsday device" icon_state = "nuclearbomb_base" desc = "A weapon which disintegrates all organic life in a large area." - anchored = 1 + anchored = TRUE density = 1 atom_say_verb = "blares" speed_process = TRUE // Disgusting fix. Please remove once #12952 is merged @@ -421,10 +421,10 @@ uses = 1 /datum/action/innate/ai/break_fire_alarms/Activate() - for(var/obj/machinery/firealarm/F in GLOB.machines) - if(!is_station_level(F.z)) + for(var/obj/machinery/firealarm/alarm as anything in GLOB.firealarms) + if(!is_station_level(alarm.z)) continue - F.emagged = TRUE + alarm.emagged = TRUE to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE) diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 0293f158e98..9058f184417 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -90,7 +90,7 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops icon = 'icons/obj/meteor.dmi' icon_state = "small" density = 1 - anchored = 1 + anchored = TRUE var/hits = 4 var/hitpwr = 2 //Level of ex_act to be called on hit. var/dest diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 4951975a8d6..96e07f42e11 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -35,17 +35,25 @@ if(ismob(loc)) to_chat(loc, "Your vest is now [flags & NODROP ? "locked" : "unlocked"].") + +/obj/item/clothing/suit/armor/abductor/vest/update_icon_state() + switch(mode) + if(VEST_STEALTH) + icon_state = "vest_stealth" + if(VEST_COMBAT) + icon_state = "vest_combat" + + /obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode() switch(mode) if(VEST_STEALTH) mode = VEST_COMBAT DeactivateStealth() armor = combat_armor - icon_state = "vest_combat" if(VEST_COMBAT)// TO STEALTH mode = VEST_STEALTH armor = stealth_armor - icon_state = "vest_stealth" + update_icon(UPDATE_ICON_STATE) if(ishuman(loc)) var/mob/living/carbon/human/H = loc H.update_inv_wear_suit() @@ -158,6 +166,15 @@ var/mob/living/marked = null var/obj/machinery/abductor/console/console + +/obj/item/abductor/gizmo/update_icon_state() + switch(mode) + if(GIZMO_SCAN) + icon_state = "gizmo_scan" + if(GIZMO_MARK) + icon_state = "gizmo_mark" + + /obj/item/abductor/gizmo/attack_self(mob/user) if(!ScientistCheck(user)) return @@ -167,10 +184,9 @@ if(mode == GIZMO_SCAN) mode = GIZMO_MARK - icon_state = "gizmo_mark" else mode = GIZMO_SCAN - icon_state = "gizmo_scan" + update_icon(UPDATE_ICON_STATE) to_chat(user, "You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE") /obj/item/abductor/gizmo/attack(mob/living/M, mob/user) @@ -283,16 +299,24 @@ item_state = "silencer" var/mode = MIND_DEVICE_MESSAGE + +/obj/item/abductor/mind_device/update_icon_state() + switch(mode) + if(MIND_DEVICE_MESSAGE) + icon_state = "mind_device_message" + if(MIND_DEVICE_CONTROL) + icon_state = "mind_device_control" + + /obj/item/abductor/mind_device/attack_self(mob/user) if(!ScientistCheck(user)) return if(mode == MIND_DEVICE_MESSAGE) mode = MIND_DEVICE_CONTROL - icon_state = "mind_device_control" else mode = MIND_DEVICE_MESSAGE - icon_state = "mind_device_message" + update_icon(UPDATE_ICON_STATE) to_chat(user, "You switch the device to [mode == MIND_DEVICE_MESSAGE ? "TRANSMISSION" : "COMMAND"] MODE") /obj/item/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params) @@ -385,7 +409,7 @@
Congratulations! You are now trained for invasive xenobiology research!"} -/obj/item/paper/abductor/update_icon() +/obj/item/paper/abductor/update_icon_state() return /obj/item/paper/abductor/AltClick() @@ -424,12 +448,12 @@ Congratulations! You are now trained for invasive xenobiology research!"} txt = "probing" to_chat(usr, "You switch the baton to [txt] mode.") - update_icon() + update_icon(UPDATE_ICON_STATE) for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() -/obj/item/abductor_baton/update_icon() +/obj/item/abductor_baton/update_icon_state() switch(mode) if(BATON_STUN) icon_state = "wonderprodStun" @@ -727,6 +751,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} buildstackamount = 1 framestackamount = 1 canSmoothWith = null + can_be_flipped = FALSE frame = /obj/structure/table_frame/abductor /obj/machinery/optable/abductor @@ -764,9 +789,8 @@ Congratulations! You are now trained for invasive xenobiology research!"} ignore_flags = TRUE var/base_icon = "alien_mender_brute" -/obj/item/reagent_containers/applicator/abductor/update_icon() +/obj/item/reagent_containers/applicator/abductor/update_icon_state() var/reag_pct = round((reagents.total_volume / volume) * 100) - switch(reag_pct) if(51 to 100) icon_state = "[base_icon]_full[applying ? "_active" : ""]" diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 008b584ef96..9b070793273 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -19,7 +19,7 @@ var/mind_control_duration = 1800 var/active_mind_control = FALSE -/obj/item/organ/internal/heart/gland/update_icon() +/obj/item/organ/internal/heart/gland/update_icon_state() return /obj/item/organ/internal/heart/gland/proc/ownerCheck() @@ -129,7 +129,7 @@ /obj/item/organ/internal/heart/gland/slime/insert(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) ..() owner.faction |= "slime" - owner.add_language("Bubblish") + owner.add_language(LANGUAGE_SLIME) /obj/item/organ/internal/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 9fa839246ce..9d714a0aaff 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -17,7 +17,13 @@ eject_abductee() return ..() -/obj/machinery/abductor/experiment/MouseDrop_T(mob/living/carbon/human/target, mob/user) + +/obj/machinery/abductor/experiment/update_icon_state() + icon_state = "experiment[occupant ? "" : "-open"]" + + + +/obj/machinery/abductor/experiment/MouseDrop_T(mob/living/carbon/human/target, mob/user, params) if(stat) return if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target)) @@ -26,18 +32,19 @@ return if(occupant) to_chat(user, "[src] is already occupied.") - return //occupied + return TRUE //occupied if(target.buckled) return if(target.has_buckled_mobs()) //mob attached to us to_chat(user, "[target] will not fit into [src] because [target.p_they()] [target.p_have()] a slime latched onto [target.p_their()] head.") - return + return TRUE visible_message("[user] puts [target] into the [src].") target.forceMove(src) occupant = target - icon_state = "experiment" + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) + return TRUE /obj/machinery/abductor/experiment/attack_hand(mob/user) if(..()) @@ -195,7 +202,7 @@ var/mob/living/carbon/human/H = grabbed.affecting H.forceMove(src) occupant = H - icon_state = "experiment" + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) qdel(G) return @@ -218,4 +225,4 @@ return occupant.forceMove(get_turf(src)) occupant = null - icon_state = "experiment-open" + update_icon(UPDATE_ICON_STATE) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm index f618ff658c2..ddb547be8bb 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm @@ -3,7 +3,7 @@ desc = "Use this to transport to and from human habitat" icon = 'icons/obj/abductor.dmi' icon_state = "alien-pad-idle" - anchored = 1 + anchored = TRUE var/turf/teleport_target /obj/machinery/abductor/pad/proc/Warp(mob/living/target) diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 5c666279e2a..d42c937ac03 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -2,11 +2,12 @@ name = "host brain" real_name = "host brain" tts_seed = "Gman" + var/host_resisting = FALSE /mob/living/captive_brain/say(message) if(client) if(client.prefs.muted & MUTE_IC) - to_chat(src, "You cannot speak in IC (muted).") + to_chat(src, span_warning("Вы не можете говорить в IC (muted).")) return if(client.handle_spam_prevention(message,MUTE_IC)) return @@ -19,8 +20,8 @@ if(stat == DEAD) return say_dead(message) var/mob/living/simple_animal/borer/B = loc - to_chat(src, "You whisper silently, \"[message]\"") - to_chat(B.host, "The captive mind of [src] whispers, \"[message]\"") + to_chat(src, "Вы тихо шепчете, \"[message]\"") + to_chat(B.host, "Пленённый разум [src] шепчет, \"[message]\"") for(var/mob/M in GLOB.mob_list) if(M.mind && isobserver(M)) @@ -37,20 +38,25 @@ /mob/living/captive_brain/resist() var/mob/living/simple_animal/borer/B = loc - to_chat(src, "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).") - to_chat(B.host, "You feel the captive mind of [src] begin to resist your control.") + if(host_resisting) + to_chat(src, span_notice("Вы уже пытаетесь вернуть своё тело!")) + return + host_resisting = TRUE + to_chat(src, span_userdanger("Вы начинаете упорно сопротивляться контролю паразита (это займёт примерно минуту).")) + to_chat(B.host, span_userdanger("Вы чувствуете, как пленённый разум [src] начинает сопротивляться.")) var/delay = (rand(350,450) + B.host.getBrainLoss()) - addtimer(CALLBACK(src, PROC_REF(return_control), B), delay) - + do_mob(src, B.host, delay, only_use_extra_checks = TRUE) + return_control(B) + host_resisting = FALSE /mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B) if(!B || !B.controlling) return B.host.adjustBrainLoss(rand(5,10)) - to_chat(src, "With an immense exertion of will, you regain control of your body!") - to_chat(B.host, "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.") + to_chat(src, span_userdanger("Огромным усилием воли вы вновь обретаете контроль над своим телом!")) + to_chat(B.host, span_userdanger("Вы чувствуете, как мозг носителя уходит из под вашего контроля. Вы успеваете разорвать связь прежде, чем сильные нейронные импульсы смогут навредить вам.")) B.detach() @@ -61,9 +67,9 @@ speak_emote = list("chirrups") emote_hear = list("chirrups") tts_seed = "Gman_e2" - response_help = "pokes" + response_help = "pokes" response_disarm = "prods the" - response_harm = "stomps on the" + response_harm = "stomps on the" icon_state = "brainslug" icon_living = "brainslug" icon_dead = "brainslug_dead" @@ -89,8 +95,6 @@ "Septenary", "Octonary", "Novenary", "Decenary", "Undenary", "Duodenary", ) var/talk_inside_host = FALSE // So that borers don't accidentally give themselves away on a botched message - var/used_dominate - var/attempting_to_dominate = FALSE // To prevent people from spam opening the Dominate Victim input var/chemicals = 10 // Chemicals used for reproduction and chemical injection. var/max_chems = 250 var/mob/living/carbon/human/host // Human host for the brain worm. @@ -102,7 +106,6 @@ var/leaving = FALSE var/hiding = FALSE var/datum/action/innate/borer/talk_to_host/talk_to_host_action = new - var/datum/action/innate/borer/infest_host/infest_host_action = new var/datum/action/innate/borer/toggle_hide/toggle_hide_action = new var/datum/action/innate/borer/talk_to_borer/talk_to_borer_action = new var/datum/action/innate/borer/talk_to_brain/talk_to_brain_action = new @@ -111,25 +114,24 @@ var/datum/action/innate/borer/leave_body/leave_body_action = new var/datum/action/innate/borer/make_chems/make_chems_action = new var/datum/action/innate/borer/make_larvae/make_larvae_action = new - var/datum/action/innate/borer/freeze_victim/freeze_victim_action = new var/datum/action/innate/borer/torment/torment_action = new /mob/living/simple_animal/borer/New(atom/newloc, var/gen=1) ..(newloc) remove_from_all_data_huds() generation = gen - add_language("Cortical Link") - notify_ghosts("A cortical borer has been created in [get_area(src)]!", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK) + add_language(LANGUAGE_HIVE_BORER) + notify_ghosts("Мозговой червь появился в [get_area(src)]!", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK) real_name = "Cortical Borer [rand(1000,9999)]" truename = "[borer_names[min(generation, borer_names.len)]] [rand(1000,9999)]" GrantBorerActions() /mob/living/simple_animal/borer/attack_ghost(mob/user) if(cannotPossess(user)) - to_chat(user, "Upon using the antagHUD you forfeited the ability to join the round.") + to_chat(user, span_boldnotice("Upon using the antagHUD you forfeited the ability to join the round.")) return if(jobban_isbanned(user, "Syndicate")) - to_chat(user, "You are banned from antagonists!") + to_chat(user, span_warning("You are banned from antagonists!")) return if(key) return @@ -155,42 +157,40 @@ /mob/living/simple_animal/borer/say(message, verb = "says", sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE) var/list/message_pieces = parse_languages(message) for(var/datum/multilingual_say_piece/S in message_pieces) - if(!istype(S.speaking, /datum/language/corticalborer) && loc == host && !talk_inside_host) - to_chat(src, span_warning("You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications.")) + if(S.speaking != GLOB.all_languages[LANGUAGE_HIVE_BORER] && loc == host && !talk_inside_host) + Communicate(message) return return ..() -/mob/living/simple_animal/borer/verb/Communicate() - set category = "Borer" - set name = "Converse with Host" - set desc = "Send a silent message to your host." - +/mob/living/simple_animal/borer/proc/Communicate(var/sended_message) if(!host) - to_chat(src, "You do not have a host to communicate with!") + to_chat(src, "У вас нет носителя!") return if(stat) - to_chat(src, "You cannot do that in your current state.") + to_chat(src, "Сейчас вы не в состоянии этого сделать.") return if(host.stat == DEAD) - to_chat(src, "Мозг носителя не способен воспринимать вас сейчас!") + to_chat(src, span_warning("Мозг носителя не способен воспринимать вас сейчас!")) return - var/input = stripped_input(src, "Please enter a message to tell your host.", "Borer", "") - if(!input) + if(!sended_message) //If we use "say", it won't ask us to write the message twice. + sended_message = stripped_input(src, "Введите сообщение для носителя.", "Borer", "") + + if(!sended_message) return if(src && !QDELETED(src) && !QDELETED(host)) var/say_string = (docile) ? "slurs" :"states" if(host) - to_chat(host, "[truename] [say_string]: [input]") - add_say_logs(src, input, host, "BORER") + to_chat(host, "[truename] [say_string]: [sended_message]") + add_say_logs(src, sended_message, host, "BORER") for(var/M in GLOB.dead_mob_list) if(isobserver(M)) - to_chat(M, "Borer Communication from [truename] ([ghost_follow_link(src, ghost=M)]): [input]") - to_chat(src, "[truename] [say_string]: [input]") + to_chat(M, "Borer Communication from [truename] ([ghost_follow_link(src, ghost=M)]): [sended_message]") + to_chat(src, "[truename] [say_string]: [sended_message]") host.verbs += /mob/living/proc/borer_comm talk_to_borer_action.Grant(host) @@ -201,10 +201,10 @@ if(talk_inside_host) talk_inside_host = FALSE - to_chat(src, "You will no longer talk audibly while inside a host.") + to_chat(src, span_notice("Теперь вы будете говорить в сознание носителя.")) else talk_inside_host = TRUE - to_chat(src, "You will now be able to audibly speak from inside of a host.") + to_chat(src, span_notice("Теперь вы сможете говорить, находясь внутри носителя.")) /mob/living/proc/borer_comm() set name = "Converse with Borer" @@ -218,7 +218,7 @@ if(!B) return - var/input = stripped_input(src, "Please enter a message to tell the borer.", "Message", "") + var/input = stripped_input(src, "Введите сообщение для мозгового червя.", "Сообщение", "") if(!input) return @@ -236,14 +236,14 @@ set desc = "Communicate mentally with the trapped mind of your host." if(src.stat == DEAD) - to_chat(src, "Мозг жертвы не способен воспринимать вас в этом состоянии!") + to_chat(src, span_warning("Мозг жертвы не способен воспринимать вас в этом состоянии!")) return var/mob/living/simple_animal/borer/B = has_brain_worms() if(!B || !B.host_brain) return var/mob/living/captive_brain/CB = B.host_brain - var/input = stripped_input(src, "Please enter a message to tell the trapped mind.", "Message", "") + var/input = stripped_input(src, "Введите сообщение для пленённого разума.", "Сообщение", "") if(!input) return @@ -264,18 +264,20 @@ if(!stat && host.stat != DEAD) if(host.reagents.has_reagent("sugar")) + if(!docile) + if(controlling) - to_chat(host, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.") + to_chat(host, span_notice("Вы чувствуете усыпляющий поток сахара в крови вашего носителя, убаюкивающий вас до бессилия..")) else - to_chat(src, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.") + to_chat(src, span_notice("Вы чувствуете усыпляющий поток сахара в крови вашего носителя, убаюкивающий вас до бессилия..")) docile = TRUE else if(docile) if(controlling) - to_chat(host, "You shake off your lethargy as the sugar leaves your host's blood.") + to_chat(host, span_notice("Вы приходите в себя, когда сахар покидает кровь вашего носителя.")) else - to_chat(src, "You shake off your lethargy as the sugar leaves your host's blood.") + to_chat(src, span_notice("Вы приходите в себя, когда сахар покидает кровь вашего носителя.")) docile = FALSE if(chemicals < max_chems) @@ -283,7 +285,7 @@ if(controlling) if(docile) - to_chat(host, "You are feeling far too docile to continue controlling your host...") + to_chat(host, span_notice("Вы слишком обессилели для того, чтобы продолжать контролировать тело носителя...")) host.release_control() return @@ -301,96 +303,68 @@ /mob/living/simple_animal/borer/UnarmedAttack(mob/living/carbon/human/M) if(istype(M)) - to_chat(src, span_notice("You analyze [M]'s vitals.")) + to_chat(src, span_notice("Вы анализируете жизненные показатели [M].")) healthscan(src, M, 1, TRUE) +/obj/effect/proc_holder/spell/borer_infest + name = "Infest" + desc = "Infest a suitable humanoid host." + base_cooldown = 0 + clothes_req = FALSE + action_icon_state = "infest" + action_background_icon_state = "bg_alien" + selection_activated_message = span_notice("Вы приготовились заразить жертву. Left-click чтобы применить способность!") + selection_deactivated_message = span_notice("Вы прекратили свои попытки заразить жертву.") + need_active_overlay = TRUE + human_req = FALSE + var/infesting = FALSE + +/obj/effect/proc_holder/spell/borer_infest/create_new_targeting() + var/datum/spell_targeting/click/T = new() + T.range = 1 + T.click_radius = -1 + return T + +/obj/effect/proc_holder/spell/borer_infest/can_cast(mob/living/user, charge_check = TRUE, show_message = FALSE) + + if (is_ventcrawling(user) || !src || user.stat || infesting) + return FALSE + . = ..() -/mob/living/simple_animal/borer/verb/infest() - set category = "Borer" - set name = "Infest" - set desc = "Infest a suitable humanoid host." - - if(host) - to_chat(src, "You are already within a host.") - return - - if(stat) - to_chat(src, "You cannot infest a target in your current state.") - return - - var/list/choices = list() - for(var/mob/living/carbon/human/H in view(1,src)) - var/obj/item/organ/external/head/head = H.get_organ(BODY_ZONE_HEAD) - if(head.is_robotic()) - continue - if(H.stat != DEAD && Adjacent(H) && !H.has_brain_worms()) - choices += H - - var/mob/living/carbon/human/M = tgui_input_list(src,"Who do you wish to infest?", "Infest", choices) - - if(!M || !src) - return - - if(!Adjacent(M)) - return - - if(M.has_brain_worms()) - to_chat(src, "You cannot infest someone who is already infested!") - return - - if(incapacitated()) - return - - to_chat(src, "You slither up [M] and begin probing at [M.p_their()] ear canal...") - - if(!do_after(src, 50, target = M)) - to_chat(src, "As [M] moves away, you are dislodged and fall to the ground.") - return - - if(!M || !src) - return +/obj/effect/proc_holder/spell/borer_infest/valid_target(mob/living/carbon/human/target, user) + return istype(target) && target.stat != DEAD - if(stat) - to_chat(src, "You cannot infest a target in your current state.") - return +/obj/effect/proc_holder/spell/borer_infest/cast(list/targets, mob/living/simple_animal/borer/user) + var/mob/living/carbon/human/target = targets[1] - if(M.stat == DEAD) - to_chat(src, "That is not an appropriate target.") + if(!target) return - if(M in view(1, src)) - to_chat(src, "You wiggle into [M]'s ear.") - /* - if(!M.stat) - to_chat(M, "Something disgusting and slimy wiggles into your ear!") - */ // Let's see how stealthborers work out - - perform_infestation(M) + infesting = TRUE + to_chat(user, "Вы подползаете к [target] и начинаете искать [genderize_ru(target.gender,"его","её","его","их" )] слуховой проход...") - return - else - to_chat(src, "They are no longer in range!") - return - -/mob/living/simple_animal/borer/proc/perform_infestation(mob/living/carbon/M) - if(!M) + if(!do_mob(user, target, 5 SECONDS)) + to_chat(user, "Как только [target] отходит, вы срываетесь и падаете на пол.") + infesting = FALSE return - if(M.has_brain_worms()) - to_chat(src, "[M] is already infested!") + if(target.has_brain_worms()) + to_chat(user, span_warning("[target] уже заражён!")) + infesting = FALSE return - host = M - add_attack_logs(src, host, "Infested as borer") - M.borer = src - forceMove(M) - - host.status_flags |= PASSEMOTES + infesting = FALSE + user.host = target + add_attack_logs(user, user.host, "Infested as borer") + target.borer = user + user.forceMove(target) + user.host.status_flags |= PASSEMOTES - RemoveBorerActions() - GrantInfestActions() + user.RemoveBorerActions() + user.RemoveBorerSpells() + user.GrantInfestActions() - to_chat(src, span_boldnotice("You can analyze your host health by using Left-click.")) + to_chat(user, span_boldnotice("Вы можете анализировать здоровье носителя при помощи Left-click.")) /mob/living/simple_animal/borer/verb/secrete_chemicals() set category = "Borer" @@ -398,14 +372,15 @@ set desc = "Push some chemicals into your host's bloodstream." if(!host) - to_chat(src, "You are not inside a host body.") + to_chat(src, "Вы не находитесь в теле носителя.") return if(stat) - to_chat(src, "You cannot secrete chemicals in your current state.") + to_chat(src, "Вы не можете производить химикаты в вашем нынешнем состоянии.") + return if(docile) - to_chat(src, " You are feeling far too docile to do that.") + to_chat(src, "Вы слишком обессилели для этого.") return var/content = "" @@ -451,10 +426,10 @@ return var/datum/reagent/R = GLOB.chemical_reagents_list[C.chemname] if(chemicals < C.chemuse) - to_chat(src, "You need [C.chemuse] chemicals stored to secrete [R.name]!") + to_chat(src, span_boldnotice("Вам нужно [C.chemuse] химикатов для выделения [R.name]!")) return - to_chat(src, "You squirt a measure of [R.name] from your reservoirs into [host]'s bloodstream.") + to_chat(src, span_userdanger("Вы впрыскиваете [R.name] из своих резервуаров в кровь [host].")) host.reagents.add_reagent(C.chemname, C.quantity) chemicals -= C.chemuse add_attack_logs(src, host, "injected [R.name]") @@ -470,7 +445,7 @@ set desc = "Become invisible to the common eye." if(host) - to_chat(usr, "You cannot do this while you're inside a host.") + to_chat(usr, span_warning("Вы не можете сделать этого, находясь внутри носителя.")) return if(stat != CONSCIOUS) @@ -478,123 +453,100 @@ if(!hiding) layer = TURF_LAYER+0.2 - to_chat(src, "You are now hiding.") + to_chat(src, span_notice("Вы прячетесь.")) hiding = TRUE else layer = MOB_LAYER - to_chat(src, "You stop hiding.") + to_chat(src, span_notice("Вы перестали прятаться.")) hiding = FALSE -/mob/living/simple_animal/borer/verb/dominate_victim() - set category = "Borer" - set name = "Dominate Victim" - set desc = "Freeze the limbs of a potential host with supernatural fear." - - if(world.time - used_dominate < 150) - to_chat(src, "You cannot use that ability again so soon.") - return - - if(host) - to_chat(src, "You cannot do that from within a host body.") - return - - if(stat) - to_chat(src, "You cannot do that in your current state.") - return - - if(attempting_to_dominate) - to_chat(src, "You're already targeting someone!") - return - - var/list/choices = list() - for(var/mob/living/carbon/C in view(3,src)) - if(C.stat != DEAD) - choices += C - - if(world.time - used_dominate < 300) - to_chat(src, "You cannot use that ability again so soon.") - return - - attempting_to_dominate = TRUE - - var/mob/living/carbon/M = tgui_input_list(src,"Who do you wish to dominate?", "Dominate", choices) - - if(!M) - attempting_to_dominate = FALSE - return +/obj/effect/proc_holder/spell/borer_dominate + name = "Dominate Victim" + desc = "Freeze the limbs of a potential host with supernatural fear." + base_cooldown = 30 SECONDS + clothes_req = FALSE + action_icon_state = "genetic_cryo" + action_background_icon_state = "bg_alien" + selection_activated_message = span_notice("Вы приготовились поразить жертву. Left-click чтобы применить способность!") + selection_deactivated_message = span_notice("Вы решили дать своей жертве шанс. Пока что.") + need_active_overlay = TRUE + human_req = FALSE + +/obj/effect/proc_holder/spell/borer_dominate/create_new_targeting() + var/datum/spell_targeting/click/T = new() + T.range = 3 + T.click_radius = -1 + return T + +/obj/effect/proc_holder/spell/borer_dominate/can_cast(mob/living/user, charge_check = TRUE, show_message = FALSE) + + if (is_ventcrawling(user) || !src || user.stat) + return FALSE + . = ..() - if(!src) //different statement to avoid a runtime since if the source is deleted then attempting_to_dominate would also be deleted - return +/obj/effect/proc_holder/spell/borer_dominate/valid_target(mob/living/carbon/human/target, user) + return istype(target) && target.stat != DEAD - if(M.has_brain_worms()) - to_chat(src, "You cannot dominate someone who is already infested!") - attempting_to_dominate = FALSE - return +/obj/effect/proc_holder/spell/borer_dominate/cast(list/targets, mob/living/simple_animal/borer/user) + var/mob/living/carbon/human/target = targets[1] - if(incapacitated()) - attempting_to_dominate = FALSE + if(target.has_brain_worms()) + to_chat(user, span_warning("Вы не можете позволить себе сделать это с тем, кто уже заражён..")) return - if(get_dist(src, M) > 7) //to avoid people remotely doing from across the map etc, 7 is the default view range - to_chat(src, "You're too far away!") - attempting_to_dominate = FALSE - return - - to_chat(src, "You focus your psychic lance on [M] and freeze [M.p_their()] limbs with a wave of terrible dread.") - to_chat(M, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.") - M.Weaken(6 SECONDS) - - used_dominate = world.time - attempting_to_dominate = FALSE + to_chat(user, span_warning("Вы пронзили разум [target] пси-потоком, парализуя [genderize_ru(target.gender,"его","её","его","их" )] конечности волной первородного ужаса!")) + to_chat(target, span_warning("Вы чувствуете, как на вас наваливается жуткое чувство страха, леденящее конечности и заставляющее сердце бешено колотиться.")) + target.Weaken(6 SECONDS) /mob/living/simple_animal/borer/verb/release_host() set category = "Borer" set name = "Release Host" set desc = "Slither out of your host." + if(!host) - to_chat(src, "You are not inside a host body.") + to_chat(src, "Вы не находитесь в теле носителя.") return if(stat) - to_chat(src, "You cannot leave your host in your current state.") + to_chat(src, "Вы не можете покинуть носителя в вашем текущем состоянии.") return if(docile) - to_chat(src, "You are feeling far too docile to do that.") + to_chat(src, span_notice("Вы слишком обессилели для этого.")) return if(!host || !src) return - if(leaving) - leaving = FALSE - to_chat(src, "You decide against leaving your host.") - return - - to_chat(src, "You begin disconnecting from [host]'s synapses and prodding at [host.p_their()] internal ear canal.") - - leaving = TRUE - - addtimer(CALLBACK(src, PROC_REF(let_go)), 200) + leaving = !leaving + let_go() + leaving = FALSE /mob/living/simple_animal/borer/proc/let_go() - if(!host || !src || QDELETED(host) || QDELETED(src)) - return - if(!leaving) - return - if(controlling) + if(!host || !src || QDELETED(host) || QDELETED(src) || controlling) return if(stat) - to_chat(src, "You cannot release a target in your current state.") + to_chat(src, "Вы не можете освободить цель в вашем текущем состоянии.") return + if(leaving) + to_chat(src, "Вы начинаете отсоединяться от синапсов носителя и пробираться наружу через его слуховой проход.") + else + to_chat(src, span_danger("Вы решили остаться в носителе.")) - to_chat(src, "You wiggle out of [host]'s ear and plop to the ground.") + // If we cast the spell a second time, it will be canceled + if(!do_mob(src, host, 20 SECONDS, only_use_extra_checks = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(borer_leaving), src)))) + return - leaving = FALSE + to_chat(src, "Вы выкручиваетесь из уха носителя и падаете на пол.") leave_host() +/mob/living/simple_animal/borer/proc/borer_leaving() //Returning "TRUE" breaks the loop, "FALSE" - continue + if(!leaving || docile || bonding) + return TRUE + return FALSE + /mob/living/simple_animal/borer/proc/leave_host() if(!host) @@ -602,6 +554,7 @@ if(controlling) detach() GrantBorerActions() + GrantBorerSpells() RemoveInfestActions() forceMove(get_turf(host)) machine = null @@ -623,47 +576,54 @@ set desc = "Fully connect to the brain of your host." if(!host) - to_chat(src, "You are not inside a host body.") + to_chat(src, "Вы не находитесь в теле носителя.") return if(host.stat == DEAD) - to_chat(src, "This host is in no condition to be controlled.") + to_chat(src, "Носитель не может быть взят под контроль в его текущем состоянии.") return if(stat) - to_chat(src, "You cannot do that in your current state.") + to_chat(src, "Вы не можете сделать этого в вашем нынешнем состоянии.") return if(docile) - to_chat(src, "You are feeling far too docile to do that.") + to_chat(src, span_notice("Вы слишком обессилели для этого.")) return - if(bonding) - bonding = FALSE - to_chat(src, "You stop attempting to take control of your host.") + if(QDELETED(src) || QDELETED(host)) return - to_chat(src, "You begin delicately adjusting your connection to the host brain...") + bonding = !bonding - if(QDELETED(src) || QDELETED(host)) + if(bonding) + to_chat(src, "Вы начинаете деликатно настраивать связь с мозгом носителя...") + else + to_chat(src, span_danger("Вы прекращаете свои попытки взять носителя под полный контроль.")) + + var/delay = 300+(host.getBrainLoss()*5) + + // If we cast the spell a second time, it will be canceled + if(!do_mob(src, host, delay, only_use_extra_checks = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(borer_assuming), src)))) + bonding = FALSE return - bonding = TRUE + assume_control() + bonding = FALSE - var/delay = 300+(host.getBrainLoss()*5) - addtimer(CALLBACK(src, PROC_REF(assume_control)), delay) +/mob/living/simple_animal/borer/proc/borer_assuming() //Returning "TRUE" breaks the loop, "FALSE" - continue + if(!bonding || docile || leaving) + return TRUE + return FALSE /mob/living/simple_animal/borer/proc/assume_control() + if(!host || !src || controlling) return - if(!bonding) - return - if(docile) - to_chat(src,"You are feeling far too docile to do that.") - return + else - to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with [host.p_their()] nervous system.") - to_chat(host, "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.") + to_chat(src, span_userdanger("Вы погружаете свои хоботки глубоко в кору головного мозга носителя, напрямую взаимодействуя с его нервной системой.")) + to_chat(host, span_userdanger("Вы чувствуете странное смещение за глазами, прежде чем постороннее сознание вытесняет ваше.")) var/borer_key = src.key add_attack_logs(src, host, "Assumed control of (borer)") // host -> brain @@ -699,7 +659,6 @@ if(!host.lastKnownIP) host.lastKnownIP = s2h_ip - bonding = FALSE controlling = TRUE host.verbs += /mob/living/carbon/proc/release_control @@ -727,8 +686,8 @@ return if(B.host_brain) - to_chat(src, "You send a punishing spike of psychic agony lancing into your host's brain.") - to_chat(B.host_brain, "Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!") + to_chat(src, span_danger("Вы посылаете карающий всплеск психической агонии в мозг своего носителя.")) + to_chat(B.host_brain, span_danger("Ужасная, жгучая агония пронзает вас насквозь, вырывая беззвучный крик из глубин вашего запертого разума!")) //Brain slug proc for voluntary removal of control. /mob/living/carbon/proc/release_control() @@ -740,7 +699,7 @@ var/mob/living/simple_animal/borer/B = has_brain_worms() if(B && B.host_brain) - to_chat(src, "You withdraw your probosci, releasing control of [B.host_brain]") + to_chat(src, span_danger("Вы убираете свои хоботки, освобождая [B.host_brain].")) B.detach() @@ -769,15 +728,15 @@ return if(B.chemicals >= 100) - to_chat(src, "Your host twitches and quivers as you rapidly excrete several larvae from your sluglike body.") - visible_message("[src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") + to_chat(src, span_danger("Ваш хозяин дёргается и вздрагивает, когда вы быстро выводите личинку из своего слизнеподобного тела.")) + visible_message(span_danger("[src] яростно блюёт, изрыгая рвотные массы вместе с извивающимся, похожим на слизня существом!")) B.chemicals -= 100 var/turf/T = get_turf(src) T.add_vomit_floor() new /mob/living/simple_animal/borer(T, B.generation + 1) else - to_chat(src, "You need 100 chemicals to reproduce!") + to_chat(src, "Вам требуется 100 химикатов для размножения!") return /mob/living/simple_animal/borer/proc/detach() @@ -786,7 +745,6 @@ return controlling = FALSE - reset_perspective(null) machine = null @@ -848,11 +806,13 @@ candidate.mob = src ckey = candidate.ckey var/list/messages = list() - messages.Add("You are a cortical borer!") - messages.Add("You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.") - messages.Add("Sugar nullifies your abilities, avoid it at all costs!") - messages.Add("You can speak to your fellow borers by prefixing your messages with ':bo'. Check out your Borer tab to see your abilities.") + messages.Add(span_notice("Вы - Мозговой Червь!")) + messages.Add("Забирайтесь в голову своей жертвы, используйте скрытность, убеждение и свои способности к управлению разумом, чтобы сохранить себя, своё потомство и своего носителя в безопасности и тепле.") + messages.Add("Сахар сводит на нет ваши способности, избегайте его любой ценой!") + messages.Add("Вы можете разговаривать со своими коллегами-борерами, используя ':bo'.") to_chat(src, chat_box_purple(messages.Join("
"))) + GrantBorerSpells() + hide_borer() /proc/create_borer_mind(key) var/datum/mind/M = new /datum/mind(key) @@ -861,14 +821,19 @@ return M /mob/living/simple_animal/borer/proc/GrantBorerActions() - infest_host_action.Grant(src) toggle_hide_action.Grant(src) - freeze_victim_action.Grant(src) + /mob/living/simple_animal/borer/proc/RemoveBorerActions() - infest_host_action.Remove(src) toggle_hide_action.Remove(src) - freeze_victim_action.Remove(src) + +/mob/living/simple_animal/borer/proc/GrantBorerSpells() + mind?.AddSpell(new /obj/effect/proc_holder/spell/borer_infest) + mind?.AddSpell(new /obj/effect/proc_holder/spell/borer_dominate) + +/mob/living/simple_animal/borer/proc/RemoveBorerSpells() + mind?.RemoveSpell(/obj/effect/proc_holder/spell/borer_infest) + mind?.RemoveSpell(/obj/effect/proc_holder/spell/borer_dominate) /mob/living/simple_animal/borer/proc/GrantInfestActions() talk_to_host_action.Grant(src) @@ -906,15 +871,6 @@ var/mob/living/simple_animal/borer/B = owner B.Communicate() -/datum/action/innate/borer/infest_host - name = "Infest" - desc = "Infest a suitable humanoid host." - button_icon_state = "infest" - -/datum/action/innate/borer/infest_host/Activate() - var/mob/living/simple_animal/borer/B = owner - B.infest() - /datum/action/innate/borer/toggle_hide name = "Toggle Hide" desc = "Become invisible to the common eye. Toggled on or off." @@ -977,8 +933,7 @@ /datum/action/innate/borer/make_chems name = "Secrete Chemicals" desc = "Push some chemicals into your host's bloodstream." - icon_icon = 'icons/obj/chemical.dmi' - button_icon_state = "minidispenser" + button_icon_state = "fleshmend" /datum/action/innate/borer/make_chems/Activate() var/mob/living/simple_animal/borer/B = owner @@ -994,15 +949,6 @@ B.host = owner B.host.spawn_larvae() -/datum/action/innate/borer/freeze_victim - name = "Dominate Victim" - desc = "Freeze the limbs of a potential host with supernatural fear." - button_icon_state = "genetic_cryo" - -/datum/action/innate/borer/freeze_victim/Activate() - var/mob/living/simple_animal/borer/B = owner - B.dominate_victim() - /datum/action/innate/borer/torment name = "Torment Host" desc = "Punish your host with agony." diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 45196f0632e..0b97571fa65 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -116,7 +116,7 @@ /mob/living/simple_animal/hostile/swarmer/New() ..() - add_language("Swarmer", 1) + add_language(LANGUAGE_HIVE_SWARMER, 1) verbs -= /mob/living/verb/pulled for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) diag_hud.add_to_hud(src) @@ -646,7 +646,7 @@ max_integrity = 10 density = FALSE -/obj/structure/swarmer/trap/Crossed(var/atom/movable/AM, oldloc) +/obj/structure/swarmer/trap/Crossed(atom/movable/AM, oldloc) if(isliving(AM)) var/mob/living/L = AM if(!istype(L, /mob/living/simple_animal/hostile/swarmer)) diff --git a/code/game/gamemodes/miniantags/demons/demon.dm b/code/game/gamemodes/miniantags/demons/demon.dm index 180f31325a5..17d191847db 100644 --- a/code/game/gamemodes/miniantags/demons/demon.dm +++ b/code/game/gamemodes/miniantags/demons/demon.dm @@ -96,7 +96,7 @@ origin_tech = "combat=5;biotech=7" -/obj/item/organ/internal/heart/demon/update_icon() +/obj/item/organ/internal/heart/demon/update_icon_state() return //always beating visually diff --git a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm index 62590d81389..5742dd6768f 100644 --- a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm +++ b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm @@ -27,6 +27,7 @@ crawl.phased = TRUE RegisterSignal(loc, COMSIG_MOVABLE_MOVED, TYPE_PROC_REF(/mob/living/simple_animal/demon/shadow, check_darkness)) RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(check_darkness)) + add_overlay(emissive_appearance(icon, "shadow_demon_eye_glow_overlay")) /mob/living/simple_animal/demon/shadow/Life(seconds, times_fired) @@ -183,7 +184,7 @@ fireball_type = /obj/item/projectile/magic/shadow_hand -/obj/effect/proc_holder/spell/fireball/shadow_grapple/update_icon() +/obj/effect/proc_holder/spell/fireball/shadow_grapple/update_icon_state() return diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 019162d024e..d24b032b99a 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -430,7 +430,7 @@ /obj/item/paper/guardian name = "Справочник по голопаразитам" - icon_state = "paper" + icon_state = "paper_words" info = {"Cписок видов голопаразитов

@@ -453,7 +453,7 @@ Защитник: При нарушении дальности связи хозяин призывается к нему, а не наоборот. Имеет два режима: низкая атака с высокой защитой, и режим ультра-защиты, практически полностью нивелирующий входящий и исходящий урон. В режиме ультра-защиты способен пережить даже взрыв бомбы, лишь слегка ранив хозяина. Может ставить силовые барьеры, через которые могут пройти только вы и ваш подопечный.
"} -/obj/item/paper/guardian/update_icon() +/obj/item/paper/guardian/update_icon_state() return diff --git a/code/game/gamemodes/miniantags/guardian/types/bomb_components/guardian_mine.dm b/code/game/gamemodes/miniantags/guardian/types/bomb_components/guardian_mine.dm index 0abfe850e58..26dea446d90 100644 --- a/code/game/gamemodes/miniantags/guardian/types/bomb_components/guardian_mine.dm +++ b/code/game/gamemodes/miniantags/guardian/types/bomb_components/guardian_mine.dm @@ -1,7 +1,7 @@ /** * Guardian's mines. Can be attached to anything to do explosive stuff on a victim. */ -#define MINE_LIFE_TIME 60 SECONDS +#define MINE_LIFE_TIME (60 SECONDS) ///Datum specialized for guardian(holoparasite)-bomber. /datum/component/guardian_mine diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 45604bd52e9..2eda2e1f448 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -74,7 +74,7 @@ unstun_time = 0 notransform = 0 to_chat(src, "You can move again!") - update_spooky_icon() + update_icon(UPDATE_ICON_STATE) /mob/living/simple_animal/revenant/ex_act(severity) return 1 //Immune to the effects of explosions. @@ -217,7 +217,7 @@ invisibility = 0 playsound(src, 'sound/effects/screech.ogg', 100, 1) visible_message("[src] lets out a waning screech as violet mist swirls around its dissolving body!") - icon_state = "revenant_draining" + update_icon(UPDATE_ICON_STATE) for(var/i = alpha, i > 0, i -= 10) sleep(0.1) alpha = i @@ -285,7 +285,7 @@ else to_chat(src, "You have been revealed!") unreveal_time = unreveal_time + time - update_spooky_icon() + update_icon(UPDATE_ICON_STATE) /mob/living/simple_animal/revenant/proc/stun(time) if(!src) @@ -299,9 +299,9 @@ else to_chat(src, "You cannot move!") unstun_time = unstun_time + time - update_spooky_icon() + update_icon(UPDATE_ICON_STATE) -/mob/living/simple_animal/revenant/proc/update_spooky_icon() +/mob/living/simple_animal/revenant/update_icon_state() if(revealed) if(notransform) if(draining) diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index e4cbb83c190..f455d085dbe 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -74,7 +74,6 @@ to_chat(src, "You begin siphoning essence from [target]'s soul.") if(target.stat != DEAD) to_chat(target, "You feel a horribly unpleasant draining sensation as your grip on life weakens...") - icon_state = "revenant_draining" reveal(27) stun(27) target.visible_message("[target] suddenly rises slightly into the air, [target.p_their()] skin turning an ashy gray.") @@ -252,7 +251,7 @@ sleep(2 SECONDS) if(!L.on) //wait, wait, don't shock me return - flick("[L.base_state]2", L) + flick("[L.base_icon_state]2", L) for(var/mob/living/M in view(shock_range, L)) if(M == user) continue diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index bb69b9dfbe3..52f177e536c 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -27,6 +27,10 @@ var/obj/item/disk/nuclear/the_disk = null var/obj/machinery/nuclearbomb/the_bomb = null var/obj/machinery/nuclearbomb/syndicate/the_s_bomb = null // used by syndicate pinpointers. + var/atom/target = null + var/turf/target_turf = null + var/turf/source_turf = null + var/prev_dist var/cur_index = 1 // Which index the current mode is var/mode = MODE_OFF // On which mode the pointer is at var/modes = list(MODE_DISK, MODE_NUKE) // Which modes are there @@ -39,39 +43,55 @@ var/icon_medium = "pinonmedium" var/icon_far = "pinonfar" -/obj/item/pinpointer/New() - ..() + +/obj/item/pinpointer/Initialize(mapload) + . = ..() GLOB.pinpointer_list += src + /obj/item/pinpointer/Destroy() STOP_PROCESSING(SSfastprocess, src) GLOB.pinpointer_list -= src mode = MODE_OFF the_disk = null + the_bomb = null + the_s_bomb = null + target = null + target_turf = null + source_turf = null return ..() + /obj/item/pinpointer/process() - if(mode == MODE_DISK) - workdisk() - else if(mode == MODE_NUKE) - workbomb() + switch(mode) + if(MODE_DISK) + workdisk() + if(MODE_NUKE) + workbomb() + /obj/item/pinpointer/attack_self(mob/user) cycle(user) -/obj/item/pinpointer/proc/cycle(mob/user) + +/obj/item/pinpointer/proc/cycle(mob/user, silent = FALSE) if(cur_index > length(modes)) mode = MODE_OFF - to_chat(user, "Вы отключили [src.name].") + prev_dist = null + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSfastprocess, src) - icon_state = icon_off cur_index = 1 + if(!silent) + to_chat(user, span_notice("You turn off [name].")) return if(cur_index == 1) START_PROCESSING(SSfastprocess, src) mode = modes[cur_index++] - activate_mode(mode, user) - to_chat(user, "[get_mode_text(mode)]") + if(!target) + update_icon(UPDATE_ICON_STATE) // we need to update icon only without target, since processing will do it for us + if(!silent) + to_chat(user, span_notice("[get_mode_text(mode)]")) + /obj/item/pinpointer/proc/get_mode_text(mode) switch(mode) @@ -93,166 +113,204 @@ return "High energy scanner active." -/obj/item/pinpointer/proc/activate_mode(mode, mob/user) //for crew pinpointer - return - /obj/item/pinpointer/proc/scandisk() if(!the_disk) - the_disk = locate() + the_disk = locate() in GLOB.poi_list + /obj/item/pinpointer/proc/scanbomb() - if(!syndicate) - if(!the_bomb) - the_bomb = locate() - else - if(!the_s_bomb) - the_s_bomb = locate() + if(syndicate && !the_s_bomb) + the_s_bomb = locate() in GLOB.poi_list + return + if(!syndicate && !the_bomb) + the_bomb = locate() in GLOB.poi_list + + +/obj/item/pinpointer/update_icon_state() + if(mode == MODE_OFF) + icon_state = icon_off + return -/obj/item/pinpointer/proc/pinpoint_at(atom/target) if(!target) icon_state = icon_null return - var/turf/T = get_turf(target) - var/turf/L = get_turf(src) + switch(prev_dist) + if(-1) + icon_state = icon_direct + if(1 to 8) + icon_state = icon_close + if(9 to 16) + icon_state = icon_medium + if(16 to INFINITY) + icon_state = icon_far + + +/obj/item/pinpointer/proc/pinpoint_at(atom/pin_target) + if(!pin_target) + nullify_targets() + return + + target = pin_target + if(!target_turf) + target_turf = get_turf(pin_target) + if(!source_turf) + source_turf = get_turf(src) + + if(!(target_turf && source_turf) || (target_turf.z != source_turf.z)) + nullify_targets() + return + + dir = get_dir(source_turf, target_turf) + var/new_dist = get_dist(source_turf, target_turf) + if(new_dist != prev_dist) + prev_dist = new_dist + update_icon(UPDATE_ICON_STATE) + + target_turf = null + source_turf = null + + +/obj/item/pinpointer/proc/nullify_targets(stop_icon_update = FALSE) + var/should_update = target + target = null + target_turf = null + source_turf = null + prev_dist = null + if(!stop_icon_update && should_update) + update_icon(UPDATE_ICON_STATE) - if(!(T && L) || (T.z != L.z)) - icon_state = icon_null - else - dir = get_dir(L, T) - switch(get_dist(L, T)) - if(-1) - icon_state = icon_direct - if(1 to 8) - icon_state = icon_close - if(9 to 16) - icon_state = icon_medium - if(16 to INFINITY) - icon_state = icon_far /obj/item/pinpointer/proc/workdisk() scandisk() pinpoint_at(the_disk) + /obj/item/pinpointer/proc/workbomb() - if(!syndicate) - scanbomb() - pinpoint_at(the_bomb) - else - scanbomb() - pinpoint_at(the_s_bomb) + scanbomb() + pinpoint_at(syndicate ? the_s_bomb : the_bomb) + /obj/item/pinpointer/examine(mob/user) . = ..() if(shows_nuke_timer) - for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines) + for(var/obj/machinery/nuclearbomb/bomb in GLOB.poi_list) if(bomb.timing) - . += "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]" + . += span_warning("Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]") /obj/item/pinpointer/advpinpointer name = "advanced pinpointer" desc = "A larger version of the normal pinpointer, this unit features a helpful quantum entanglement detection system to locate various objects that do not broadcast a locator signal." modes = list(MODE_ADV) var/modelocked = FALSE // If true, user cannot change mode. - var/turf/location = null - var/obj/target = null - var/setting = 0 + var/setting = NONE + + +/obj/item/pinpointer/advpinpointer/examine(mob/user) + . = ..() + if(Adjacent(user)) + . += span_info("You can Alt-Click to choose tracking target.") + /obj/item/pinpointer/advpinpointer/process() switch(setting) if(SETTING_DISK) workdisk() - if(SETTING_LOCATION) - pinpoint_at(location) - if(SETTING_OBJECT) + if(SETTING_LOCATION, SETTING_OBJECT) pinpoint_at(target) -/obj/item/pinpointer/advpinpointer/workdisk() //since mode works diffrently for advpinpointer - scandisk() - pinpoint_at(the_disk) /obj/item/pinpointer/advpinpointer/AltClick(mob/user) - . = ..() - toggle_mode(user) + if(Adjacent(user)) + toggle_mode(user) + return + ..() + -/obj/item/pinpointer/advpinpointer/verb/toggle_mode(mob/user) +/obj/item/pinpointer/advpinpointer/verb/toggle_mode_verb() set category = "Object" set name = "Toggle Pinpointer Mode" set src in usr - if(user.stat || user.restrained()) + toggle_mode(usr) + + +/obj/item/pinpointer/advpinpointer/proc/toggle_mode(mob/user) + if(!iscarbon(user) || user.incapacitated()) return if(modelocked) - to_chat(user, "[src] is locked. It can only track one specific target.") + to_chat(user, span_warning("[src] is locked. It can only track one specific target.")) return - mode = MODE_OFF - icon_state = icon_off - target = null - location = null - switch(alert("Please select the mode you want to put the pinpointer in.", "Pinpointer Mode Select", "Location", "Disk Recovery", "Other Signature")) if("Location") setting = SETTING_LOCATION - var/locationx = input(user, "Введите X координату для поиска.", "Локация?" , "") as num - if(!locationx || !(user in view(1,src))) + var/locationx = input(user, "Enter X coordinate to search.", "Location X Define" , "") as null|num + if(isnull(locationx) || !(user in view(1,src))) return - var/locationy = input(user, "Введите Y координату для поиска.", "Локация?" , "") as num - if(!locationy || !(user in view(1,src))) + var/locationy = input(user, "Enter Y coordinate to search.", "Location Y Define" , "") as null|num + if(isnull(locationy) || !(user in view(1,src))) return - var/turf/Z = get_turf(src) - - location = locate(locationx,locationy,Z.z) - - to_chat(user, "Вы переключили пинпоинтер для обнаружения [locationx],[locationy]") - - - return attack_self(user) + source_turf = get_turf(src) + locationx = clamp(locationx, 1, 255) + locationy = clamp(locationy, 1, 255) + target = locate(locationx, locationy, source_turf.z) + to_chat(user, span_notice("You point the pinpointer to coordinates: [locationx], [locationy].")) if("Disk Recovery") setting = SETTING_DISK - return attack_self(user) + to_chat(user, span_notice("You point the pinpointer to Nuclear Authentication Disk.")) if("Other Signature") setting = SETTING_OBJECT switch(alert("Search for item signature or DNA fragment?" , "Signature Mode Select" , "Item" , "DNA")) if("Item") - var/list/item_names[0] - var/list/item_paths[0] - for(var/objective in GLOB.potential_theft_objectives) - var/datum/theft_objective/T = objective - var/name = initial(T.name) + var/list/item_names = list() + var/list/item_paths = list() + for(var/datum/theft_objective/objective as anything in GLOB.potential_theft_objectives) + var/name = initial(objective.name) item_names += name - item_paths[name] = initial(T.typepath) - var/targetitem = tgui_input_list(user, "Select item to search for.", "Select Item", item_names) + item_paths[name] = initial(objective.typepath) + var/targetitem = tgui_input_list(user, "Select item to serach for.", "Item Mode Select", item_names) if(!targetitem) return + target = null var/list/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE) for(var/obj/item/candidate in target_candidates) if(!is_admin_level((get_turf(candidate)).z)) target = candidate + to_chat(user, span_notice("You point the pinpointer to [target].")) break if(!target) - to_chat(user, "Failed to locate [targetitem]!") - return - to_chat(user, "Вы переключили пинпоинтер для обнаружения [targetitem].") + nullify_targets(stop_icon_update = TRUE) + to_chat(user, span_warning("Could not find [targetitem] signature!")) + if("DNA") - var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "") + var/DNAstring = input("Input DNA string to search for." , "Please Enter String" , "") if(!DNAstring) return - for(var/mob/living/carbon/C in GLOB.mob_list) - if(!C.dna) + + target = null + for(var/mob/living/carbon/human/check as anything in GLOB.human_list) + if(!check.dna) continue - if(C.dna.unique_enzymes == DNAstring) - target = C + if(check.dna.unique_enzymes == DNAstring) + target = check + to_chat(user, span_notice("You point the pinpointer to [check.real_name].")) break - return attack_self(user) + if(!target) + nullify_targets(stop_icon_update = TRUE) + to_chat(user, span_warning("Failed to detect humanoid with DNA: [DNAstring]!")) + + if(mode == MODE_OFF) + cycle(user, silent = TRUE) + /////////////////////// //nuke op pinpointers// @@ -263,6 +321,7 @@ syndicate = TRUE modes = list(MODE_DISK, MODE_NUKE) + /obj/item/pinpointer/nukeop/process() switch(mode) if(MODE_DISK) @@ -272,42 +331,40 @@ if(MODE_SHIP) worklocation() + /obj/item/pinpointer/nukeop/workdisk() if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle mode = MODE_SHIP //Ensures worklocation() continues to work modes = list(MODE_SHIP) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep - visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed + playsound(loc, 'sound/machines/twobeep.ogg', 50, TRUE) //Plays a beep + visible_message(span_notice("Shuttle Locator mode actived.")) //Lets the mob holding it know that the mode has changed return //Get outta here scandisk() pinpoint_at(the_disk) + /obj/item/pinpointer/nukeop/workbomb() if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle mode = MODE_SHIP //Ensures worklocation() continues to work modes = list(MODE_SHIP) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep - visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed + playsound(loc, 'sound/machines/twobeep.ogg', 50, TRUE) //Plays a beep + visible_message(span_notice("Shuttle Locator mode actived.")) //Lets the mob holding it know that the mode has changed return //Get outta here scanbomb() pinpoint_at(the_s_bomb) + /obj/item/pinpointer/nukeop/proc/worklocation() if(!GLOB.bomb_set) mode = MODE_DISK modes = list(MODE_DISK, MODE_NUKE) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) - visible_message("Authentication Disk Locator mode actived.") + playsound(loc, 'sound/machines/twobeep.ogg', 50, TRUE) + visible_message(span_notice("Authentication Disk Locator mode actived.")) return if(!home) home = SSshuttle.getShuttle("syndicate") - if(!home) - icon_state = icon_null - return - if(loc.z != home.z) //If you are on a different z-level from the shuttle - icon_state = icon_null - else - pinpoint_at(home) + pinpoint_at(home) + /obj/item/pinpointer/operative name = "operative pinpointer" @@ -319,71 +376,80 @@ icon_close = "pinonclose_contractor" icon_medium = "pinonmedium_contractor" icon_far = "pinonfar_contractor" - var/mob/living/carbon/nearest_op = null modes = list(MODE_OPERATIVE) + /obj/item/pinpointer/operative/process() if(mode == MODE_OPERATIVE) - workop() - else - icon_state = icon_off + scan_for_ops() + pinpoint_at(target) + /obj/item/pinpointer/operative/proc/scan_for_ops() - if(mode == MODE_OPERATIVE) - nearest_op = null //Resets nearest_op every time it scans - var/closest_distance = 1000 - for(var/mob/living/carbon/M in GLOB.mob_list) - if(M.mind && (M.mind in SSticker.mode.syndicates)) - if(get_dist(M, get_turf(src)) < closest_distance) //Actually points toward the nearest op, instead of a random one like it used to - nearest_op = M - -/obj/item/pinpointer/operative/proc/workop() - if(mode == MODE_OPERATIVE) - scan_for_ops() - pinpoint_at(nearest_op, FALSE) - else - return FALSE + target = null // Resets nearest_op every time it scans + var/closest_distance = 1000 + source_turf = get_turf(src) + if(!source_turf) + return + var/mob/living/carbon/human/holder = get(loc, /mob/living/carbon/human) + for(var/mob/living/carbon/human/operative as anything in (GLOB.human_list - holder)) + if(operative.mind && (operative.mind in SSticker.mode.syndicates)) + target_turf = get_turf(operative) + if(!target_turf) + continue + var/new_dist = get_dist(source_turf, target_turf) + if(source_turf.z == target_turf.z && new_dist < closest_distance) //Actually points toward the nearest op, instead of a random one like it used to + target = operative + closest_distance = new_dist + /obj/item/pinpointer/operative/examine(mob/user) . = ..() - if(mode == MODE_OPERATIVE) - if(nearest_op) - . += "Nearest operative detected is [nearest_op.real_name]." - else - . += "No operatives detected within scanning range." + if(target) + var/mob/living/carbon/human/operative = target + . += span_notice("Nearest operative detected is [operative.real_name].") + else + . += span_notice("No operatives detected within scanning range.") + /obj/item/pinpointer/ninja name = "spider clan pinpointer" desc = "A pinpointer that leads to the first Spider Clan assassin detected." - var/mob/living/carbon/nearest_ninja = null modes = list(MODE_NINJA) + /obj/item/pinpointer/ninja/process() if(mode == MODE_NINJA) - workninja() - else - icon_state = icon_off + scan_for_ninja() + pinpoint_at(target) + /obj/item/pinpointer/ninja/proc/scan_for_ninja() - if(mode == MODE_NINJA) - nearest_ninja = null //Resets nearest_ninja every time it scans - var/closest_distance = 1000 - for(var/mob/living/carbon/potential_ninja in GLOB.mob_list) - if(isninja(potential_ninja)) - if(get_dist(potential_ninja, get_turf(src)) < closest_distance) - nearest_ninja = potential_ninja + target = null //Resets nearest_ninja every time it scans + var/closest_distance = 1000 + source_turf = get_turf(src) + if(!source_turf) + return + var/mob/living/carbon/human/holder = get(loc, /mob/living/carbon/human) + for(var/mob/living/carbon/human/potential_ninja as anything in (GLOB.human_list - holder)) + if(isninja(potential_ninja)) + target_turf = get_turf(potential_ninja) + if(!target_turf) + continue + var/new_dist = get_dist(source_turf, target_turf) + if(source_turf.z == target_turf.z && new_dist < closest_distance) + target = potential_ninja + closest_distance = new_dist -/obj/item/pinpointer/ninja/proc/workninja() - scan_for_ninja() - pinpoint_at(nearest_ninja, FALSE) /obj/item/pinpointer/ninja/examine(mob/user) . = ..() - if(mode == MODE_NINJA) - if(nearest_ninja) - . += "Nearest ninja detected is [nearest_ninja.real_name]." - else - . += "No ninjas detected within scanning range." + if(target) + var/mob/living/carbon/human/ninja = target + . += span_notice("Nearest ninja detected is [ninja.real_name].") + else + . += span_notice("No ninjas detected within scanning range.") + /obj/item/pinpointer/crew name = "crew pinpointer" @@ -397,72 +463,108 @@ icon_medium = "pinonmedium_crew" icon_far = "pinonfar_crew" modes = list(MODE_CREW) - var/target = null //for targeting in processing - var/target_set = FALSE //have we set a target at any point? -/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H) - if(H && istype(H.w_uniform, /obj/item/clothing/under)) - var/turf/here = get_turf(src) - var/obj/item/clothing/under/U = H.w_uniform + +/obj/item/pinpointer/crew/examine(mob/user) + . = ..() + if(Adjacent(user)) + . += span_info("You can Alt-Click to choose whom to track.") + + +/obj/item/pinpointer/crew/proc/is_trackable(mob/living/carbon/human/pin_target) + if(pin_target && istype(pin_target.w_uniform, /obj/item/clothing/under)) + source_turf = get_turf(src) + if(!source_turf) + return FALSE + var/obj/item/clothing/under/uniform = pin_target.w_uniform // Suit sensors must be on maximum. - if(!U.has_sensor || U.sensor_mode < 3) + if(!uniform.has_sensor || uniform.sensor_mode < 3) return FALSE - var/turf/there = get_turf(U) - return istype(there) && there.z == here.z + target_turf = get_turf(pin_target) + return target_turf && source_turf.z == target_turf.z return FALSE + /obj/item/pinpointer/crew/process() - if(mode == MODE_CREW && target_set) + if(mode == MODE_CREW) pinpoint_at(target) -/obj/item/pinpointer/crew/pinpoint_at(atom/target) - if(!target || !trackable(target)) - icon_state = icon_null + +/obj/item/pinpointer/crew/pinpoint_at(atom/pin_target) + if(!is_trackable(pin_target)) + nullify_targets() return + ..() + + +/obj/item/pinpointer/crew/AltClick(mob/user) + if(Adjacent(user)) + choose_signal(user) + return + ..() + + +/obj/item/pinpointer/crew/verb/choose_signal_verb() + set category = "Object" + set name = "Track Signals" + set src in usr + + choose_signal(usr) - ..(target) -/obj/item/pinpointer/crew/activate_mode(mode, mob/user) +/obj/item/pinpointer/crew/proc/choose_signal(mob/living/carbon/user) + if(!iscarbon(user) || user.incapacitated()) + return + var/list/name_counts = list() var/list/names = list() - for(var/thing in GLOB.human_list) - var/mob/living/carbon/human/H = thing - if(!trackable(H)) + for(var/mob/living/carbon/human/human as anything in GLOB.human_list) + if(!is_trackable(human)) continue - var/name = "Unknown" - if(H.wear_id) - var/obj/item/card/id/I = H.wear_id.GetID() - if(I) - name = I.registered_name - - while(name in name_counts) - name_counts[name]++ - name = text("[] ([])", name, name_counts[name]) - names[name] = H - name_counts[name] = 1 - - if(!names.len) - user.visible_message("[user]'s pinpointer fails to detect a signal.", "Your pinpointer fails to detect a signal.") + var/human_name = "Unknown" + if(human.wear_id) + var/obj/item/card/id/card = human.wear_id.GetID() + if(card) + human_name = card.registered_name + + while(human_name in name_counts) + name_counts[human_name]++ + human_name = "[human_name] ([name_counts[human_name]])" + names[human_name] = human + name_counts[human_name] = 1 + + if(!length(names)) + user.visible_message( + span_notice("[user]'s pinpointer fails to detect any signals."), + span_notice("Your pinpointer fails to detect any signals."), + ) return - var/A = tgui_input_list(user, "Person to track", "Pinpoint", names) - if(!src || !user || (user.get_active_hand() != src) || user.incapacitated() || !A) + var/choice = tgui_input_list(user, "Person to track", "Pinpoint", names) + if(!choice || !src || !user || (user.get_active_hand() != src) || user.incapacitated()) return - target = names[A] - target_set = TRUE - user.visible_message("[user] activates [user.p_their()] pinpointer.", "You activate your pinpointer.") + target = names[choice] + user.visible_message( + span_notice("[user] activates [user.p_their()] pinpointer."), + span_notice("You start tracking [choice]."), + ) + + if(mode == MODE_OFF) + cycle(user, silent = TRUE) + /obj/item/pinpointer/crew/centcom name = "centcom pinpointer" desc = "A handheld tracking device that tracks crew based on remote centcom sensors." -/obj/item/pinpointer/crew/centcom/trackable(mob/living/carbon/human/H) - var/turf/here = get_turf(src) - var/turf/there = get_turf(H) - return istype(there) && istype(here) && there.z == here.z + +/obj/item/pinpointer/crew/centcom/is_trackable(mob/living/carbon/human/pin_target) + source_turf = get_turf(src) + target_turf = get_turf(pin_target) + return source_turf && target_turf && source_turf.z == target_turf.z /////////////////////// @@ -480,73 +582,76 @@ icon_close = "pinonclose_crew" icon_medium = "pinonmedium_crew" icon_far = "pinonfar_crew" - var/turf/location = null - var/obj/target = null var/setting = NONE var/list/current_targets var/targets_index = 1 +/obj/item/pinpointer/thief/examine(mob/user) + . = ..() + if(Adjacent(user)) + . += span_info("Нажмите Alt-Click для выбора режима отслеживания.") + + /obj/item/pinpointer/thief/process() - switch(setting) - if(SETTING_LOCATION) - pinpoint_at(location) - if(SETTING_OBJECT) - pinpoint_at(target) + if(setting == SETTING_LOCATION || setting == SETTING_OBJECT) + pinpoint_at(target) -/obj/item/pinpointer/thief/cycle(mob/user) +/obj/item/pinpointer/thief/cycle(mob/user, silent = TRUE) . = ..() switch(setting) if(SETTING_LOCATION) - if(!location) - to_chat(user, "Определите координаты локации у пинпоинтера.") + if(!target) + to_chat(user, span_notice("Определите координаты локации у пинпоинтера.")) if(SETTING_OBJECT) if(!target) - to_chat(user, "Определите цель пинпоинтера.") + to_chat(user, span_notice("Определите цель пинпоинтера.")) else - to_chat(user, "Режим пинпоинтера не определен.") + to_chat(user, span_notice("Режим пинпоинтера не определен.")) /obj/item/pinpointer/thief/AltClick(mob/user) - . = ..() - toggle_mode(user) + if(Adjacent(user)) + toggle_mode(user) + return + ..() -/obj/item/pinpointer/thief/verb/toggle_mode(mob/user) +/obj/item/pinpointer/thief/verb/toggle_mode_verb() set category = "Object" set name = "Переключить Режим Пинпоинтера" set src in usr - if(user.stat || user.restrained()) - return + toggle_mode(usr) - mode = MODE_OFF - icon_state = icon_off - target = null - location = null + +/obj/item/pinpointer/thief/proc/toggle_mode(mob/user) + if(!iscarbon(user) || user.incapacitated()) + return switch(alert("Выберите режим пинпоинтера.", "Выбор режима пинпоинтера", "Локация", "Сигнатура Объекта", "Цели")) if("Локация") setting = SETTING_LOCATION - var/locationx = input(user, "Введите X координату для поиска.", "Локация?" , "") as num - if(!locationx || !(user in view(1,src))) + var/locationx = input(user, "Введите X координату для поиска.", "Локация?" , "") as null|num + if(isnull(locationx) || !(user in view(1,src))) return - var/locationy = input(user, "Введите Y координату для поиска.", "Локация?" , "") as num - if(!locationy || !(user in view(1,src))) + var/locationy = input(user, "Введите Y координату для поиска.", "Локация?" , "") as null|num + if(isnull(locationy) || !(user in view(1,src))) return - var/turf/Z = get_turf(src) - location = locate(locationx,locationy,Z.z) - to_chat(user, span_notice("Вы переключили пинпоинтер для обнаружения [locationx],[locationy]")) - return attack_self(user) + source_turf = get_turf(src) + locationx = clamp(locationx, 1, 255) + locationy = clamp(locationy, 1, 255) + target = locate(locationx, locationy, source_turf.z) + to_chat(user, span_notice("Вы переключили пинпоинтер на координаты: [locationx], [locationy].")) if("Сигнатура Объекта") setting = SETTING_OBJECT var/list/targets_list = list() - var/list/target_names[0] - var/list/target_paths[0] + var/list/target_names = list() + var/list/target_paths = list() var/input_ask = "Выберите сигнатуру" var/input_tittle = "Режим выбора" @@ -561,25 +666,22 @@ input_subtype = alert("Какой тип доступности предмета?" , "Определение Доступности Предмета" , "Сложнодоступен" , "Доступен" , "Коллекционный") switch(input_subtype) if("Сложнодоступен") - for(var/element in (GLOB.potential_theft_objectives_hard | GLOB.potential_theft_objectives)) - var/datum/theft_objective/theft = element - targets_list |= initial(theft.typepath) + for(var/datum/theft_objective/theft as anything in (GLOB.potential_theft_objectives_hard|GLOB.potential_theft_objectives)) + targets_list += initial(theft.typepath) if("Доступен") - for(var/element in GLOB.potential_theft_objectives_medium) - var/datum/theft_objective/theft = element - targets_list |= initial(theft.typepath) + for(var/datum/theft_objective/theft as anything in GLOB.potential_theft_objectives_medium) + targets_list += initial(theft.typepath) if("Коллекционный") - for(var/element in GLOB.potential_theft_objectives_collect) - var/datum/theft_objective/collect/theft = element + for(var/datum/theft_objective/collect/theft as anything in GLOB.potential_theft_objectives_collect) var/typepath_datum = initial(theft.typepath) if(typepath_datum) - targets_list |= typepath_datum + targets_list += typepath_datum continue var/subtype_datum = initial(theft.subtype) var/list/type_list = subtype_datum ? subtypesof(subtype_datum) : initial(theft.type_list) - targets_list |= type_list + targets_list += type_list if(!input_subtype) return @@ -589,20 +691,17 @@ return if("Структура") - for(var/element in GLOB.potential_theft_objectives_structure) - var/datum/theft_objective/structure/theft = element - targets_list |= initial(theft.typepath) + for(var/datum/theft_objective/structure/theft as anything in GLOB.potential_theft_objectives_structure) + targets_list += initial(theft.typepath) if("Питомец") - for(var/element in GLOB.potential_theft_objectives_animal) - var/datum/theft_objective/animal/theft = element - targets_list |= initial(theft.typepath) + for(var/datum/theft_objective/animal/theft as anything in GLOB.potential_theft_objectives_animal) + targets_list += initial(theft.typepath) - for(var/typepath in targets_list) - var/atom/temp_target = typepath - var/thief_name = initial(temp_target.name) - target_names |= thief_name - target_paths[thief_name] = temp_target + for(var/atom/theft_typepath as anything in targets_list) + var/theft_name = initial(theft_typepath.name) + target_names += theft_name + target_paths[theft_name] = theft_typepath var/choosen_target = tgui_input_list(user, "[input_ask], типа \"[input_type][input_subtype]\"", "[input_tittle]: [input_type][input_subtype]", target_names) if(!choosen_target) @@ -616,7 +715,6 @@ targets_index = 1 target = current_targets[targets_index] to_chat(user, span_notice("Вы переключили пинпоинтер для обнаружения [choosen_target]. Найдено целей: [length(current_targets)].")) - return attack_self(user) if("Цели") var/input_type = alert("Какую операцию стоит произвести?", "Выбор Операции", "Показать Цели", "Следующая Цель") @@ -626,8 +724,8 @@ var/list/all_objectives = user.mind.get_all_objectives() if(length(all_objectives) && user.mind.has_antag_datum(/datum/antagonist/thief)) var/list/targets_list = list() - var/list/target_names[0] - var/list/target_paths[0] + var/list/target_names = list() + var/list/target_paths = list() for(var/datum/objective/steal/objective in all_objectives) if(istype(objective, /datum/objective/steal/collect)) @@ -641,11 +739,10 @@ if(wanted_type) targets_list |= wanted_type - for(var/typepath in targets_list) - var/atom/temp_target = typepath - var/thief_name = initial(temp_target.name) - target_names |= thief_name - target_paths[thief_name] = temp_target + for(var/atom/theft_typepath as anything in targets_list) + var/theft_name = initial(theft_typepath.name) + target_names += theft_name + target_paths[theft_name] = theft_typepath var/choosen_target = tgui_input_list(user, "Выберите интересующую вас цель:", "Режим Выбора Цели", target_names) if(!choosen_target) @@ -662,8 +759,7 @@ else to_chat(user, span_warning("Не удалось обнаружить интересные цели для #REDACTED#! Если вы не член #REDACTED#, верните устройство владельцу или обратитесь по зашифрованному номеру на обратной стороне пинпоинтера.")) - - return attack_self(user) + return if("Следующая Цель") if(!length(current_targets)) @@ -682,6 +778,9 @@ target = current_targets[targets_index] + if(mode == MODE_OFF) + cycle(user, silent = TRUE) + /obj/item/pinpointer/tendril name = "ancient scanning unit" @@ -694,31 +793,29 @@ icon_medium = "pinonmedium_ancient" icon_far = "pinonfar_ancient" modes = list(MODE_TENDRIL) - var/obj/structure/spawner/lavaland/target -/obj/item/pinpointer/tendril/process() - if(mode == MODE_TENDRIL) - find_tendril() - pinpoint_at(target, FALSE) - else - icon_state = icon_off -/obj/item/pinpointer/tendril/proc/find_tendril() +/obj/item/pinpointer/tendril/process() if(mode == MODE_TENDRIL) scan_for_tendrils() pinpoint_at(target) - else - return FALSE + /obj/item/pinpointer/tendril/proc/scan_for_tendrils() - if(mode == MODE_TENDRIL) - target = null //Resets nearest_op every time it scans - var/closest_distance = 1000 - for(var/obj/structure/spawner/lavaland/T as anything in GLOB.tendrils) - var/temp_distance = get_dist(T, get_turf(src)) - if(temp_distance < closest_distance) - target = T - closest_distance = temp_distance + target = null //Resets nearest_op every time it scans + var/closest_distance = 1000 + source_turf = get_turf(src) + if(!source_turf) + return + for(var/obj/structure/spawner/lavaland/tendril as anything in GLOB.tendrils) + target_turf = get_turf(tendril) + if(!target_turf) + continue + var/new_dist = get_dist(source_turf, target_turf) + if(source_turf.z == target_turf.z && new_dist < closest_distance) + target = tendril + closest_distance = new_dist + /obj/item/pinpointer/tendril/examine(mob/user) . = ..() @@ -726,7 +823,6 @@ . += "Number of high energy signatures remaining: [length(GLOB.tendrils)]" - #undef MODE_OFF #undef MODE_DISK #undef MODE_NUKE @@ -740,3 +836,4 @@ #undef SETTING_DISK #undef SETTING_LOCATION #undef SETTING_OBJECT + diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 1067cedb557..0e6f72b8d96 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -484,6 +484,11 @@ GLOBAL_LIST_EMPTY(admin_objective_list) damage_explain = "токсинов" return damage_explain +/datum/objective/pain_hunter/check_completion() + if(start_of_completing && target && ishuman(target.current) && target.current.stat != DEAD) + return TRUE + else + return completed /datum/objective/protect //The opposite of killing a dude. name = "Protect" diff --git a/code/game/gamemodes/shadowling/ascendant_shadowling.dm b/code/game/gamemodes/shadowling/ascendant_shadowling.dm index c903a5ed1a3..0c0149bb622 100644 --- a/code/game/gamemodes/shadowling/ascendant_shadowling.dm +++ b/code/game/gamemodes/shadowling/ascendant_shadowling.dm @@ -33,14 +33,14 @@ faction = list("faithless") -/mob/living/simple_animal/ascendant_shadowling/New() - ..() +/mob/living/simple_animal/ascendant_shadowling/Initialize(mapload) + . = ..() if(prob(35)) icon_state = "NurnKal" icon_living = "NurnKal" - update_icons() + update_icon(UPDATE_OVERLAYS) -/mob/living/simple_animal/ascendant_shadowling/Process_Spacemove(var/movement_dir = 0) +/mob/living/simple_animal/ascendant_shadowling/Process_Spacemove(movement_dir = 0) return 1 //copypasta from carp code /mob/living/simple_animal/ascendant_shadowling/ex_act(severity) @@ -49,11 +49,13 @@ /mob/living/simple_animal/ascendant_shadowling/singularity_act() return 0 //Well hi, fellow god! How are you today? -/mob/living/simple_animal/ascendant_shadowling/update_icons() - overlays.Cut() - overlays += mutable_appearance(icon = 'icons/mob/mob.dmi', icon_state = "shadowling_ascended_ms") -/mob/living/simple_animal/ascendant_shadowling/proc/announce(var/text, var/size = 4, var/new_sound = null) +/mob/living/simple_animal/ascendant_shadowling/update_overlays() + . = ..() + . += "shadowling_ascended_ms" + + +/mob/living/simple_animal/ascendant_shadowling/proc/announce(text, size = 4, new_sound = null) var/message = "\"[text]\"
" for(var/mob/M in GLOB.player_list) if(!isnewplayer(M) && M.client) diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index f6c877338e7..398ee971a71 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -147,7 +147,7 @@ Made by Xhuis var/mob/living/carbon/human/S = shadow_mind.current shadow_mind.AddSpell(new /obj/effect/proc_holder/spell/shadowling_hatch(null)) spawn(0) - shadow_mind.current.add_language("Shadowling Hivemind") + shadow_mind.current.add_language(LANGUAGE_HIVE_SHADOWLING) update_shadow_icons_added(shadow_mind) if(shadow_mind.assigned_role == "Clown") to_chat(S, "Your alien nature has allowed you to overcome your clownishness.") @@ -161,7 +161,7 @@ Made by Xhuis new_thrall_mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL update_shadow_icons_added(new_thrall_mind) add_conversion_logs(new_thrall_mind.current, "Became a Shadow thrall") - new_thrall_mind.current.add_language("Shadowling Hivemind") + new_thrall_mind.current.add_language(LANGUAGE_HIVE_SHADOWLING) //If you add spells to thrall, be sure to remove them on dethrallize new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/shadowling_guise(null)) new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/shadowling_vision/thrall(null)) @@ -191,7 +191,7 @@ Made by Xhuis //If you add spells to thrall, be sure to remove them on dethrallize thrall_mind.RemoveSpell(/obj/effect/proc_holder/spell/shadowling_guise) thrall_mind.RemoveSpell(/obj/effect/proc_holder/spell/shadowling_vision/thrall) - thrall_mind.current.remove_language("Shadowling Hivemind") + thrall_mind.current.remove_language(LANGUAGE_HIVE_SHADOWLING) if(kill && ishuman(thrall_mind.current)) //If dethrallization surgery fails, kill the mob as well as dethralling them var/mob/living/carbon/human/H = thrall_mind.current H.visible_message("[H] jerks violently and falls still.", \ diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 8acf0b2d8fe..1f21b499f66 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -644,7 +644,7 @@ to_chat(user, "You sent the APC's power to the void while overloading all it's lights!") target_apc.cell?.charge = 0 //Sent to the shadow realm target_apc.chargemode = FALSE //Won't recharge either until an someone hits the button - target_apc.charging = FALSE + target_apc.charging = APC_NOT_CHARGING target_apc.null_charge() target_apc.update_icon() @@ -935,7 +935,7 @@ to_chat(target, "An agonizing spike of pain drives into your mind, and--") SSticker.mode.add_thrall(target.mind) target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL - target.add_language("Shadowling Hivemind") + target.add_language(LANGUAGE_HIVE_SHADOWLING) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 38e95cd9904..5ba00f56936 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -282,7 +282,7 @@ GLOBAL_LIST_INIT(possibleShadowlingNames, list("U'ruan", "Y`shej", "Nex", "Hel-u undershirt = "None" socks = "None" faction |= "faithless" - add_language("Shadowling Hivemind") + add_language(LANGUAGE_HIVE_SHADOWLING) set_species(/datum/species/shadow/ling) equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(src), slot_w_uniform) diff --git a/code/game/gamemodes/wizard/apprentice.dm b/code/game/gamemodes/wizard/apprentice.dm index b8b5867fade..5090f762be6 100644 --- a/code/game/gamemodes/wizard/apprentice.dm +++ b/code/game/gamemodes/wizard/apprentice.dm @@ -195,6 +195,7 @@ new /datum/magick_school.singulo, new /datum/magick_school.blood, new /datum/magick_school.necromantic, + new /datum/magick_school/lavaland, ) @@ -219,33 +220,8 @@ owner.mind.AddSpell(new /obj/effect/proc_holder/spell/forcewall(null)) owner.equip_or_collect(new /obj/item/gun/magic/staff/healing(owner), slot_r_hand) - //Нацепляем белый балахон - var/obj/item/clothing/suit/storage/mercy_hoodie/suit = new (owner) - suit.magical = TRUE - suit.name = "Роба целителя" - suit.desc = "Магическая роба прислужника-целителя, оберегающая от проказы." - suit.gas_transfer_coefficient = 0.01 - suit.permeability_coefficient = 0.01 - suit.body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - suit.armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) - suit.allowed = list(/obj/item/teleportation_scroll) - suit.flags_inv = HIDEJUMPSUIT - suit.strip_delay = 50 - suit.put_on_delay = 50 - suit.resistance_flags = FIRE_PROOF | ACID_PROOF - owner.equip_or_collect(suit, slot_wear_suit) - var/obj/item/clothing/head/mercy_hood/head = new (owner) - head.magical = TRUE - head.name = "Капюшон целителя" - head.desc = "Магический капюшон робы прислужника-целителя, оберегающий от проказы." - head.gas_transfer_coefficient = 0.01 - head.permeability_coefficient = 0.01 - head.armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) - head.resistance_flags = FIRE_PROOF | ACID_PROOF - head.strip_delay = 50 - head.put_on_delay = 50 - owner.equip_or_collect(head, slot_head) - + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/healmage(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/healmage(owner), slot_head) /datum/magick_school/motion name = "Школа Пространства" @@ -333,9 +309,8 @@ owner.mind.AddSpell(new /obj/effect/proc_holder/spell/sacred_flame(null)) ADD_TRAIT(owner, RESISTHOT, MAGIC_TRAIT) //sacred_flame из-за не совсем верной выдачи, без этого, не выдает защиту от огня. - //Стандартный костюм мага-воителя, который есть в башне волшебника и так. - owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/magusred(owner), slot_wear_suit) - owner.equip_or_collect(new /obj/item/clothing/head/wizard/magus(owner), slot_head) + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/magusdefender(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/magusdefender(owner), slot_head) /datum/magick_school/fire @@ -372,30 +347,8 @@ owner.mind.AddSpell(new /obj/effect/proc_holder/spell/touch/flesh_to_stone(null)) owner.equip_or_collect(new /obj/item/gun/magic/staff/animate(owner), slot_r_hand) - //Костюм настоящего художника-скульптора. - var/obj/item/clothing/suit/chef/classic/suit = new - suit.magical = TRUE - suit.name = "Фартук скульптора-волшебника" - suit.desc = "Классический фартук последователей школы ваяния, хорошо защищает от разлетающейся глины." - suit.gas_transfer_coefficient = 0.01 - suit.permeability_coefficient = 0.01 - suit.armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) - suit.strip_delay = 50 - suit.put_on_delay = 50 - suit.resistance_flags = FIRE_PROOF | ACID_PROOF - owner.equip_or_collect(suit, slot_wear_suit) - var/obj/item/clothing/head/beret/ce/head = new - head.magical = TRUE - head.name = "Берет скульптора-волшебника" - head.desc = "Классический берет последователей школы ваяния, позволяет выглядеть как настоящий художник." - head.gas_transfer_coefficient = 0.01 - head.permeability_coefficient = 0.01 - head.armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) - head.resistance_flags = FIRE_PROOF | ACID_PROOF - head.strip_delay = 50 - head.put_on_delay = 50 - owner.equip_or_collect(head, slot_head) - + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/artmage(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/artmage(owner), slot_head) /datum/magick_school/stand name = "Школа Хранителей" @@ -406,6 +359,8 @@ owner.mind.AddSpell(new /obj/effect/proc_holder/spell/forcewall/greater(null)) owner.equip_or_collect(new /obj/item/guardiancreator(owner), slot_r_hand) + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/magusdefender(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/magusdefender(owner), slot_head) /datum/magick_school/instability name = "Школа Неустойчивости" @@ -457,6 +412,9 @@ owner.equip_or_collect(new /obj/item/necromantic_stone(owner), slot_l_store) owner.equip_or_collect(new /obj/item/necromantic_stone(owner), slot_r_store) + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/necromage(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/necromage(owner), slot_head) + /datum/magick_school/vision name = "Школа Прозрения" @@ -474,9 +432,8 @@ owner.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE to_chat(owner, "The walls suddenly disappear.") - //Нацепляем простой фиолетовый балахон - owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/psypurple(owner), slot_wear_suit) - owner.equip_or_collect(new /obj/item/clothing/head/wizard/amp(owner), slot_head) + owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/visionmage(owner), slot_wear_suit) + owner.equip_or_collect(new /obj/item/clothing/head/wizard/visionmage(owner), slot_head) /datum/magick_school/singulo @@ -534,3 +491,20 @@ owner.equip_or_collect(new /obj/item/clothing/suit/wizrobe/magusred(owner), slot_wear_suit) owner.equip_or_collect(new /obj/item/clothing/head/wizard/magus(owner), slot_head) +/datum/magick_school/lavaland + name = "Школа Лаваленда" + id = "lavaland" + desc = "Школа, использующая традиции магии пеплоходцев." + +/datum/magick_school/lavaland/kit() + owner.faction += "mining" + owner.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/legion_skulls) + owner.mind.AddSpell(new /obj/effect/proc_holder/spell/goliath_tentacles) + owner.mind.AddSpell(new /obj/effect/proc_holder/spell/goliath_dash) + owner.mind.AddSpell(new /obj/effect/proc_holder/spell/watchers_look) + owner.mind.AddSpell(new /obj/effect/proc_holder/spell/touch/healtouch) + + owner.equip_or_collect(new /obj/item/clothing/under/ash_walker(owner), slot_w_uniform) + owner.equip_or_collect(new /obj/item/clothing/gloves/color/black/goliath(owner), slot_gloves) + owner.equip_or_collect(new /obj/item/clothing/suit/hooded/goliath/wizard(owner), slot_wear_suit) + diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index a057c9e3385..de8beea2100 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -31,7 +31,7 @@ icon = 'icons/obj/biomass.dmi' icon_state = "rift" density = 1 - anchored = 1.0 + anchored = TRUE var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies var/spawn_amt_left = 20 diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 9ee9635e241..cfd99857dfc 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -66,6 +66,29 @@ A.death() return ..() + +/obj/item/soulstone/update_name(updates = ALL) + . = ..() + var/mob/living/simple_animal/shade/shade = locate() in src + if(shade) + name = "soulstone: [shade.name]" + else + name = initial(name) + + +/obj/item/soulstone/update_icon_state() + if(purified) + icon_state = "purified_soulstone" + icon_state_full = "purified_soulstone2" + else + icon_state = initial(icon_state) + icon_state_full = initial(icon_state_full) + + var/mob/living/simple_animal/shade/shade = locate() in src + if(shade) + icon_state = icon_state_full + + //////////////////////////////Capturing//////////////////////////////////////////////////////// /obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user) if(M == user) @@ -161,11 +184,9 @@ usability = TRUE purified = TRUE optional = TRUE - icon_state = "purified_soulstone" - icon_state_full = "purified_soulstone2" - for(var/mob/M in contents) + update_icon(UPDATE_ICON_STATE) + for(var/mob/M in src) if(M.mind) - icon_state = "purified_soulstone2" if(iscultist(M)) SSticker.mode.remove_cultist(M.mind, FALSE) to_chat(M, "An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] \ @@ -173,10 +194,10 @@ to_chat(M, "Assist [user], your saviour, and get vengeance on those who enslaved you!") else to_chat(M, "Your soulstone has been exorcised, and you are now bound to obey [user]. ") - - for(var/mob/living/simple_animal/shade/EX in src) - EX.holy = TRUE - EX.icon_state = "shade_angelic" + if(istype(M, /mob/living/simple_animal/shade)) + var/mob/living/simple_animal/shade/shade = M + shade.holy = TRUE + shade.update_icon(UPDATE_ICON_STATE) user.visible_message("[user] purifies [src]!", "You purify [src]!") else if(istype(O, /obj/item/melee/cultblade/dagger) && iscultist(user)) @@ -187,16 +208,15 @@ usability = FALSE purified = FALSE optional = FALSE - icon_state = "soulstone" - icon_state_full = "soulstone2" - for(var/mob/M in contents) + update_icon(UPDATE_ICON_STATE) + for(var/mob/M in src) if(M.mind) - icon_state = "soulstone2" SSticker.mode.add_cultist(M.mind) to_chat(M, "Your shard has been cleansed of holy magic, and you are now bound to the cult's will. Obey them and assist in their goals.") - for(var/mob/living/simple_animal/shade/EX in src) - EX.holy = FALSE - EX.icon_state = SSticker.cultdat?.shade_icon_state + if(istype(M, /mob/living/simple_animal/shade)) + var/mob/living/simple_animal/shade/shade = M + shade.holy = FALSE + shade.update_icon(UPDATE_ICON_STATE) to_chat(user, "You have cleansed [src] of holy magic.") else ..() @@ -218,11 +238,7 @@ for(var/mob/living/simple_animal/shade/A in src) A.forceMove(get_turf(user)) A.cancel_camera() - if(purified) - icon_state = "purified_soulstone" - else - icon_state = "soulstone" - name = initial(name) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) if(iscultist(A)) to_chat(A, "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.") else @@ -264,14 +280,30 @@ desc = "A holy machine used by those who are pure in soul and mind. It is inactive." var/defiled = FALSE + +/obj/structure/constructshell/holy/update_icon_state() + icon_state = defiled ? "construct-cult" : initial(icon_state) + + +/obj/structure/constructshell/holy/update_name(updates = ALL) + . = ..() + name = defiled ? "empty shell" : initial(name) + + +/obj/structure/constructshell/holy/update_desc(updates = ALL) + . = ..() + if(!defiled) + desc = initial(desc) + return + desc = "A wicked machine used by those skilled in magical arts. It is inactive." + + /obj/structure/constructshell/holy/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/storage/bible) && !iscultist(user) && user.mind.isholy) if(!defiled) return - name = initial(name) - icon_state = initial(icon_state) - desc = initial(desc) defiled = FALSE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) if(defiled) return ..() if(istype(I, /obj/item/soulstone)) @@ -285,10 +317,7 @@ if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user)) if(do_after(user, 4 SECONDS, target = src)) user.visible_message("[user] defile [src] with dark magic!!", "You sanctified [src]. Yes-yes. I need more acolytes!") - name = "empty shell" - icon_state = "construct-cult" - desc = "A wicked machine used by those skilled in magical arts. It is inactive." - defiled = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return return ..() @@ -337,10 +366,9 @@ to_chat(user, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else T.forceMove(src) // Put the shade into the stone. - T.canmove = 0 + T.canmove = FALSE T.health = T.maxHealth - icon_state = icon_state_full - name = "soulstone : [T.name]" + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") to_chat(user, "Capture successful! [T.name]'s has been recaptured and stored within the soul stone.") @@ -437,8 +465,7 @@ S.real_name = "Shade of [M.real_name]" S.key = M.key S.cancel_camera() - name = "soulstone: [S.name]" - icon_state = icon_state_full + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) log_game("[S.key] has become [S.name] with [purified ? "holy" : "corrupted"] essence.") if(user) S.faction |= "\ref[user]" //Add the master as a faction, allowing inter-mob cooperation diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index a6a116f4f56..a56e6d94a30 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -158,6 +158,30 @@ spell_type = /obj/effect/proc_holder/spell/infinite_guns category = "Offensive" +/datum/spellbook_entry/goliath_tentacles + name = "Summon Tentacles" + spell_type = /obj/effect/proc_holder/spell/goliath_tentacles + category = "Offensive" + cost = 1 + +/datum/spellbook_entry/legion_skulls + name = "Summon Skulls" + spell_type = /obj/effect/proc_holder/spell/aoe/conjure/legion_skulls + category = "Offensive" + cost = 1 + +/datum/spellbook_entry/goliath_dash + name = "Goliath Dash" + spell_type = /obj/effect/proc_holder/spell/goliath_dash + category = "Offensive" + cost = 1 + +/datum/spellbook_entry/watchers_look + name = "Watcher's Look" + spell_type = /obj/effect/proc_holder/spell/watchers_look + category = "Offensive" + cost = 1 + //Defensive /datum/spellbook_entry/disabletech name = "Disable Tech" @@ -293,6 +317,12 @@ spell_type = /obj/effect/proc_holder/spell/noclothes category = "Assistance" +/datum/spellbook_entry/healtouch + name = "Healing Touch" + spell_type = /obj/effect/proc_holder/spell/touch/healtouch + category = "Assistance" + cost = 1 + //Rituals /datum/spellbook_entry/summon name = "Summon Stuff" diff --git a/code/game/jobs/job/central.dm b/code/game/jobs/job/central.dm index d012c9f2df9..af56c0128ec 100644 --- a/code/game/jobs/job/central.dm +++ b/code/game/jobs/job/central.dm @@ -7,7 +7,7 @@ total_positions = 5 spawn_positions = 5 supervisors = "the admins" - selection_color = "#ffdddd" + selection_color = "#6865B3" access = list() minimal_access = list() admin_only = 1 @@ -70,7 +70,7 @@ total_positions = 5 spawn_positions = 5 supervisors = "the admins" - selection_color = "#ffdddd" + selection_color = "#6865B3" access = list() minimal_access = list() admin_only = 1 diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 6bf500f0bed..2e549ba702d 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -6,7 +6,7 @@ spawn_positions = -1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#e6e6e6" access = list() //See /datum/job/assistant/get_access() minimal_access = list() //See /datum/job/assistant/get_access() alt_titles = list("Tourist","Businessman","Trader","Assistant") diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 20e760dbc3f..f677cdca309 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -7,7 +7,7 @@ is_engineering = 1 supervisors = "the captain" department_head = list("Captain") - selection_color = "#ffeeaa" + selection_color = "#ffba4c" req_admin_notify = 1 access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_TELEPORTER, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ATMOSPHERICS, ACCESS_EMERGENCY_STORAGE, ACCESS_EVA, @@ -57,7 +57,7 @@ is_engineering = 1 supervisors = "the chief engineer" department_head = list("Chief Engineer") - selection_color = "#fff5cc" + selection_color = "#ffeaca" access = list(ACCESS_EVA, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_EVA, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM) alt_titles = list("Maintenance Technician","Engine Technician","Electrician") @@ -93,7 +93,7 @@ total_positions = 5 spawn_positions = 3 department_head = list("Chief Engineer", "Station Engineer") - selection_color = "#fff5cc" + selection_color = "#ffeaca" alt_titles = list("Engineer Assistant", "Technical Assistant", "Engineer Student", "Technical Student", "Technical Trainee") exp_requirements = 180 exp_type = EXP_TYPE_CREW @@ -142,7 +142,7 @@ is_engineering = 1 supervisors = "the chief engineer" department_head = list("Chief Engineer") - selection_color = "#fff5cc" + selection_color = "#ffeaca" access = list(ACCESS_EVA, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM, ACCESS_EMERGENCY_STORAGE) minimal_access = list(ACCESS_EVA, ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE) alt_titles = list("Atmospheric Technician") @@ -178,7 +178,7 @@ is_engineering = 1 supervisors = "the chief engineer" department_head = list("Chief Engineer") - selection_color = "#fff5cc" + selection_color = "#ffeaca" access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_MECHANIC, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_MINERAL_STOREROOM, ACCESS_EMERGENCY_STORAGE) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_EMERGENCY_STORAGE, ACCESS_MECHANIC, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_MINERAL_STOREROOM) exp_requirements = 900 diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 60cfa2f78b9..f0bbcfbf7c2 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -7,7 +7,7 @@ is_medical = 1 supervisors = "the captain" department_head = list("Captain") - selection_color = "#ffddf0" + selection_color = "#66c6ff" req_admin_notify = 1 access = list(ACCESS_EVA, ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_HEADS, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, @@ -53,7 +53,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY) alt_titles = list("Surgeon","Nurse") @@ -87,7 +87,7 @@ total_positions = 5 spawn_positions = 3 department_head = list("Chief Medical Officer", "Medical Doctor") - selection_color = "#ffeef0" + selection_color = "#d1eeff" alt_titles = list("Student Medical Doctor", "Medical Assistant") exp_requirements = 180 exp_type = EXP_TYPE_CREW @@ -134,7 +134,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE) minimal_player_age = 3 @@ -197,7 +197,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_CHEMISTRY, ACCESS_MINERAL_STOREROOM) alt_titles = list("Pharmacist","Pharmacologist") @@ -233,7 +233,7 @@ is_medical = 1 supervisors = "the chief medical officer and the research director" department_head = list("Chief Medical Officer", "Research Director") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_RESEARCH) minimal_player_age = 3 @@ -268,7 +268,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM) alt_titles = list("Pathologist","Microbiologist") @@ -305,7 +305,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_PSYCHIATRIST) minimal_access = list(ACCESS_MEDICAL, ACCESS_PSYCHIATRIST) alt_titles = list("Psychologist","Therapist") @@ -345,7 +345,7 @@ is_medical = 1 supervisors = "the chief medical officer" department_head = list("Chief Medical Officer") - selection_color = "#ffeef0" + selection_color = "#d1eeff" access = list(ACCESS_PARAMEDIC, ACCESS_MEDICAL, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_MORGUE, ACCESS_SURGERY) minimal_access=list(ACCESS_PARAMEDIC, ACCESS_MEDICAL, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_MORGUE, ACCESS_SURGERY) minimal_player_age = 3 diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 8918f067801..0eeeb918cc9 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -7,7 +7,7 @@ is_science = 1 supervisors = "the captain" department_head = list("Captain") - selection_color = "#ffddff" + selection_color = "#aa66cc" req_admin_notify = 1 access = list(ACCESS_EVA, ACCESS_RD, ACCESS_HEADS, ACCESS_TOX, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_TOX_STORAGE, ACCESS_TECH_STORAGE, ACCESS_TELEPORTER, ACCESS_SEC_DOORS, @@ -59,7 +59,7 @@ is_science = 1 supervisors = "the research director" department_head = list("Research Director") - selection_color = "#ffeeff" + selection_color = "#e6d1f0" access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_XENOARCH, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_XENOARCH, ACCESS_MINERAL_STOREROOM) alt_titles = list("Anomalist", "Plasma Researcher", "Xenobiologist", "Chemical Researcher") @@ -96,7 +96,7 @@ total_positions = 5 spawn_positions = 3 department_head = list("Research Director", "Scientist") - selection_color = "#ffeeff" + selection_color = "#e6d1f0" alt_titles = list("Scientist Assistant", "Scientist Pregraduate", "Scientist Graduate", "Scientist Postgraduate", "Student Robotist") exp_requirements = 180 exp_type = EXP_TYPE_CREW @@ -139,7 +139,7 @@ is_science = 1 supervisors = "the research director" department_head = list("Research Director") - selection_color = "#ffeeff" + selection_color = "#e6d1f0" access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) //As a job that handles so many corpses, it makes sense for them to have morgue access. minimal_access = list(ACCESS_ROBOTICS, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) //As a job that handles so many corpses, it makes sense for them to have morgue access. alt_titles = list("Biomechanical Engineer","Mechatronic Engineer") diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index ed9ea68d11b..6bd31a22500 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -7,7 +7,7 @@ is_security = 1 supervisors = "the captain" department_head = list("Captain") - selection_color = "#ffdddd" + selection_color = "#c25656" req_admin_notify = 1 access = list(ACCESS_EVA, ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_FORENSICS_LOCKERS, ACCESS_PILOT, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, @@ -65,7 +65,7 @@ is_security = 1 supervisors = "the head of security" department_head = list("Head of Security") - selection_color = "#ffeeee" + selection_color = "#edcdcd" access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS) alt_titles = list("Brig Sergeant") @@ -115,7 +115,7 @@ is_security = 1 supervisors = "the head of security" department_head = list("Head of Security") - selection_color = "#ffeeee" + selection_color = "#edcdcd" access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_WEAPONS) minimal_access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_WEAPONS) alt_titles = list("Forensic Technician") @@ -176,7 +176,7 @@ is_security = 1 supervisors = "the head of security" department_head = list("Head of Security") - selection_color = "#ffeeee" + selection_color = "#edcdcd" access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS) alt_titles = list("Security Trainer","Patrol Officer") @@ -241,7 +241,7 @@ is_security = 1 supervisors = "the head of security" department_head = list("Head of Security") - selection_color = "#ffeeee" + selection_color = "#edcdcd" access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS) alt_titles = list("Security Medic") @@ -278,7 +278,7 @@ is_security = 1 supervisors = "the head of security" department_head = list("Head of Security") - selection_color = "#ffeeee" + selection_color = "#edcdcd" access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_PILOT, ACCESS_EXTERNAL_AIRLOCKS) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS, ACCESS_PILOT, ACCESS_EXTERNAL_AIRLOCKS) minimal_player_age = 7 diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm index d941ca23253..30d8178b925 100644 --- a/code/game/jobs/job/silicon.dm +++ b/code/game/jobs/job/silicon.dm @@ -4,7 +4,7 @@ department_flag = JOBCAT_ENGSEC total_positions = -1 // Not used for AI, see is_position_available below and modules/mob/living/silicon/ai/latejoin.dm spawn_positions = 1 - selection_color = "#ccffcc" + selection_color = "#4c82bf" supervisors = "your laws" department_head = list("Captain") req_admin_notify = 1 @@ -28,7 +28,7 @@ spawn_positions = 2 supervisors = "your laws and the AI" //Nodrak department_head = list("AI") - selection_color = "#ddffdd" + selection_color = "#cadaec" minimal_player_age = 21 exp_requirements = 300 exp_type = EXP_TYPE_CREW diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 17e95e05456..f8cbc4828ee 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -7,7 +7,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca spawn_positions = 1 supervisors = "Nanotrasen officials" department_head = list("Nanotrasen Navy Officer") - selection_color = "#ccccff" + selection_color = "#6691ff" req_admin_notify = 1 is_command = 1 access = list() //See get_access() @@ -66,7 +66,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca spawn_positions = 1 supervisors = "the captain" department_head = list("Captain") - selection_color = "#ddddff" + selection_color = "#d1deff" req_admin_notify = 1 is_command = 1 minimal_player_age = 21 @@ -117,7 +117,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca spawn_positions = 1 supervisors = "the command staff" department_head = list("Captain") - selection_color = "#ddddff" + selection_color = "#d1deff" req_admin_notify = 1 is_command = 1 transfer_allowed = FALSE @@ -167,7 +167,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca spawn_positions = 1 supervisors = "the Nanotrasen representative" department_head = list("Captain") - selection_color = "#ddddff" + selection_color = "#d1deff" req_admin_notify = 1 is_command = 1 transfer_allowed = FALSE @@ -221,7 +221,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca spawn_positions = 1 supervisors = "the Nanotrasen Supreme Court" department_head = list("Captain") - selection_color = "#ddddff" + selection_color = "#edccd7" req_admin_notify = 1 is_legal = 1 transfer_allowed = FALSE @@ -274,7 +274,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca is_legal = 1 supervisors = "the magistrate" department_head = list("Captain") - selection_color = "#ddddff" + selection_color = "#edccd7" access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS, ACCESS_RESEARCH, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING) minimal_access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS, ACCESS_RESEARCH, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING) alt_titles = list("Human Resources Agent","Lawyer","Attorney") diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 3dd1f2942d2..81194e467c3 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -1,132 +1,3 @@ -//Food -/datum/job/bartender - title = "Bartender" - flag = JOB_BARTENDER - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - is_service = 1 - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) - minimal_access = list(ACCESS_BAR, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) - alt_titles = list("Barman","Barkeeper","Drink Artist") - money_factor = 2 - outfit = /datum/outfit/job/bartender - -/datum/outfit/job/bartender - name = "Bartender" - jobtype = /datum/job/bartender - - uniform = /obj/item/clothing/under/rank/bartender - suit = /obj/item/clothing/suit/armor/vest - belt = /obj/item/storage/belt/bandolier/full - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - glasses = /obj/item/clothing/glasses/sunglasses/reagent - pda = /obj/item/pda/bar - backpack_contents = list( - /obj/item/toy/russian_revolver = 1 - ) - -/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - H.dna.SetSEState(GLOB.soberblock,1) - genemutcheck(H, GLOB.soberblock, null, MUTCHK_FORCED) - H.dna.default_blocks.Add(GLOB.soberblock) - H.check_mutations = 1 - - - -/datum/job/chef - title = "Chef" - flag = JOB_CHEF - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - is_service = 1 - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE) - minimal_access = list(ACCESS_KITCHEN) - alt_titles = list("Cook","Culinary Artist","Butcher") - money_factor = 2 - outfit = /datum/outfit/job/chef - -/datum/outfit/job/chef - name = "Chef" - jobtype = /datum/job/chef - - uniform = /obj/item/clothing/under/rank/chef - suit = /obj/item/clothing/suit/chef - belt = /obj/item/storage/belt/chef - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/chefhat - l_ear = /obj/item/radio/headset/headset_service - pda = /obj/item/pda/chef - backpack_contents = list( - /obj/item/paper/chef=1,\ - /obj/item/book/manual/chef_recipes=1) - -/datum/outfit/job/chef/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - if(visualsOnly) - return - var/datum/martial_art/cqc/under_siege/justacook = new - justacook.teach(H) - -/datum/outfit/job/chef/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(H.mind && H.mind.role_alt_title) - switch(H.mind.role_alt_title) - if("Culinary Artist") - uniform = /obj/item/clothing/under/artist - belt = /obj/item/storage/belt/chef/artistred - head = /obj/item/clothing/head/chefcap - suit = /obj/item/clothing/suit/storage/chefbluza - - -/datum/job/hydro - title = "Botanist" - flag = JOB_BOTANIST - department_flag = JOBCAT_SUPPORT - total_positions = 2 - spawn_positions = 2 - is_service = 1 - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE) - minimal_access = list(ACCESS_HYDROPONICS, ACCESS_MORGUE) - alt_titles = list("Hydroponicist", "Botanical Researcher") - exp_requirements = 300 - exp_type = EXP_TYPE_CREW - money_factor = 2 - outfit = /datum/outfit/job/hydro - -/datum/outfit/job/hydro - name = "Botanist" - jobtype = /datum/job/hydro - - uniform = /obj/item/clothing/under/rank/hydroponics - suit = /obj/item/clothing/suit/apron - gloves = /obj/item/clothing/gloves/botanic_leather - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - suit_store = /obj/item/plant_analyzer - pda = /obj/item/pda/botanist - - backpack = /obj/item/storage/backpack/botany - satchel = /obj/item/storage/backpack/satchel_hyd - dufflebag = /obj/item/storage/backpack/duffel/hydro - - - //Cargo /datum/job/qm title = "Quartermaster" @@ -137,7 +8,7 @@ is_supply = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#9f8545" access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) min_age_allowed = 30 @@ -174,7 +45,7 @@ is_supply = 1 supervisors = "the quartermaster" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#e2dbc8" access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) money_factor = 2 @@ -201,7 +72,7 @@ is_supply = 1 supervisors = "the quartermaster" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#e2dbc8" access = list(ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MINING, ACCESS_MINT, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) alt_titles = list("Spelunker") @@ -254,6 +125,133 @@ suit = /obj/item/clothing/suit/space/hardsuit/mining mask = /obj/item/clothing/mask/breath +//Food +/datum/job/bartender + title = "Bartender" + flag = JOB_BARTENDER + department_flag = JOBCAT_SUPPORT + total_positions = 1 + spawn_positions = 1 + is_service = 1 + supervisors = "the head of personnel" + department_head = list("Head of Personnel") + selection_color = "#d1e8d3" + access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) + minimal_access = list(ACCESS_BAR, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) + alt_titles = list("Barman","Barkeeper","Drink Artist") + money_factor = 2 + outfit = /datum/outfit/job/bartender + +/datum/outfit/job/bartender + name = "Bartender" + jobtype = /datum/job/bartender + + uniform = /obj/item/clothing/under/rank/bartender + suit = /obj/item/clothing/suit/armor/vest + belt = /obj/item/storage/belt/bandolier/full + shoes = /obj/item/clothing/shoes/black + l_ear = /obj/item/radio/headset/headset_service + glasses = /obj/item/clothing/glasses/sunglasses/reagent + pda = /obj/item/pda/bar + backpack_contents = list( + /obj/item/toy/russian_revolver = 1 + ) + +/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + if(visualsOnly) + return + + H.dna.SetSEState(GLOB.soberblock,1) + genemutcheck(H, GLOB.soberblock, null, MUTCHK_FORCED) + H.dna.default_blocks.Add(GLOB.soberblock) + H.check_mutations = 1 + + + +/datum/job/chef + title = "Chef" + flag = JOB_CHEF + department_flag = JOBCAT_SUPPORT + total_positions = 1 + spawn_positions = 1 + is_service = 1 + supervisors = "the head of personnel" + department_head = list("Head of Personnel") + selection_color = "#d1e8d3" + access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE) + minimal_access = list(ACCESS_KITCHEN) + alt_titles = list("Cook","Culinary Artist","Butcher") + money_factor = 2 + outfit = /datum/outfit/job/chef + +/datum/outfit/job/chef + name = "Chef" + jobtype = /datum/job/chef + + uniform = /obj/item/clothing/under/rank/chef + suit = /obj/item/clothing/suit/chef + belt = /obj/item/storage/belt/chef + shoes = /obj/item/clothing/shoes/black + head = /obj/item/clothing/head/chefhat + l_ear = /obj/item/radio/headset/headset_service + pda = /obj/item/pda/chef + backpack_contents = list( + /obj/item/paper/chef=1,\ + /obj/item/book/manual/chef_recipes=1) + +/datum/outfit/job/chef/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + if(visualsOnly) + return + var/datum/martial_art/cqc/under_siege/justacook = new + justacook.teach(H) + +/datum/outfit/job/chef/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + if(H.mind && H.mind.role_alt_title) + switch(H.mind.role_alt_title) + if("Culinary Artist") + uniform = /obj/item/clothing/under/artist + belt = /obj/item/storage/belt/chef/artistred + head = /obj/item/clothing/head/chefcap + suit = /obj/item/clothing/suit/storage/chefbluza + + +/datum/job/hydro + title = "Botanist" + flag = JOB_BOTANIST + department_flag = JOBCAT_SUPPORT + total_positions = 2 + spawn_positions = 2 + is_service = 1 + supervisors = "the head of personnel" + department_head = list("Head of Personnel") + selection_color = "#d1e8d3" + access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE) + minimal_access = list(ACCESS_HYDROPONICS, ACCESS_MORGUE) + alt_titles = list("Hydroponicist", "Botanical Researcher") + exp_requirements = 300 + exp_type = EXP_TYPE_CREW + money_factor = 2 + outfit = /datum/outfit/job/hydro + +/datum/outfit/job/hydro + name = "Botanist" + jobtype = /datum/job/hydro + + uniform = /obj/item/clothing/under/rank/hydroponics + suit = /obj/item/clothing/suit/apron + gloves = /obj/item/clothing/gloves/botanic_leather + shoes = /obj/item/clothing/shoes/black + l_ear = /obj/item/radio/headset/headset_service + suit_store = /obj/item/plant_analyzer + pda = /obj/item/pda/botanist + + backpack = /obj/item/storage/backpack/botany + satchel = /obj/item/storage/backpack/satchel_hyd + dufflebag = /obj/item/storage/backpack/duffel/hydro + //Griff //BS12 EDIT /datum/job/clown @@ -265,7 +263,7 @@ is_service = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_CLOWN, ACCESS_THEATRE) minimal_access = list(ACCESS_CLOWN, ACCESS_THEATRE) alt_titles = list("Performance Artist","Comedian","Jester") @@ -324,7 +322,7 @@ genemutcheck(H, GLOB.comicblock, null, MUTCHK_FORCED) H.dna.default_blocks.Add(GLOB.comicblock) H.check_mutations = TRUE - H.add_language("Clownish") + H.add_language(LANGUAGE_CLOWN) //action given to antag clowns /datum/action/innate/toggle_clumsy @@ -356,7 +354,7 @@ is_service = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_MIME, ACCESS_THEATRE) minimal_access = list(ACCESS_MIME, ACCESS_THEATRE) alt_titles = list("Panthomimist") @@ -411,7 +409,7 @@ is_service = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_JANITOR, ACCESS_MAINT_TUNNELS) minimal_access = list(ACCESS_JANITOR, ACCESS_MAINT_TUNNELS) alt_titles = list("Custodial Technician","Sanitation Technician") @@ -438,7 +436,7 @@ is_service = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_LIBRARY) minimal_access = list(ACCESS_LIBRARY) alt_titles = list("Journalist") @@ -468,7 +466,7 @@ is_service = 1 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" alt_titles = list("Hair Stylist","Beautician") access = list() minimal_access = list() @@ -495,7 +493,7 @@ spawn_positions = 0 supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_MAINT_TUNNELS, ACCESS_GATEWAY, ACCESS_EVA, ACCESS_EXTERNAL_AIRLOCKS) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_GATEWAY, ACCESS_EVA, ACCESS_EXTERNAL_AIRLOCKS) outfit = /datum/outfit/job/explorer diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index 7a6b0295952..3a8b1128bb6 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -8,7 +8,7 @@ is_service = TRUE supervisors = "the head of personnel" department_head = list("Head of Personnel") - selection_color = "#dddddd" + selection_color = "#d1e8d3" access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_MAINT_TUNNELS) minimal_access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_MAINT_TUNNELS) alt_titles = list("Priest","Monk","Preacher","Reverend","Oracle","Nun","Imam","Exorcist") diff --git a/code/game/jobs/job/syndicate.dm b/code/game/jobs/job/syndicate.dm index ca71db768e5..cd3ad1a1add 100644 --- a/code/game/jobs/job/syndicate.dm +++ b/code/game/jobs/job/syndicate.dm @@ -5,7 +5,7 @@ total_positions = 5 spawn_positions = 5 supervisors = "the admins" - selection_color = "#ff0000" + selection_color = "#4c1e1e" access = list() minimal_access = list() admin_only = 1 diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 0eb62a7aadd..4b96dbef0da 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -7,7 +7,7 @@ layer = WIRE_LAYER plane = FLOOR_PLANE layer = 2.5 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 0 var/syndicate = 0 @@ -42,12 +42,12 @@ destroy_beacon() return ..() -/obj/machinery/bluespace_beacon/hide(var/intact) - invisibility = intact ? INVISIBILITY_ABSTRACT : 0 - update_icon() +/obj/machinery/bluespace_beacon/hide(intact) + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 + update_icon(UPDATE_ICON_STATE) // update the icon_state -/obj/machinery/bluespace_beacon/update_icon() +/obj/machinery/bluespace_beacon/update_icon_state() var/state="floor_beacon" if(invisibility) icon_state = "[state]f" @@ -61,11 +61,11 @@ Beacon.loc = loc else create_beacon() - update_icon() + update_icon(UPDATE_ICON_STATE) else if(Beacon) destroy_beacon() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/bluespace_beacon/syndicate diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index f4c5e63fcac..681b8ca57eb 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -4,7 +4,7 @@ icon_state = "freezer" density = 1 var/min_temperature = 0 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE active_power_usage = 5000 //cooling down massive amounts of air's not cheap. This is still very low considering everything power_channel = EQUIP @@ -69,7 +69,7 @@ if(default_deconstruction_screwdriver(user, "freezer-o", "freezer", I)) on = FALSE use_power = IDLE_POWER_USE - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE /obj/machinery/atmospherics/unary/cold_sink/freezer/wrench_act(mob/user, obj/item/I) @@ -91,14 +91,14 @@ build_network() update_icon() -/obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon() +/obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon_state() if(panel_open) icon_state = "freezer-o" - else if(src.on) + else if(on) icon_state = "freezer_1" else icon_state = "freezer" - return + /obj/machinery/atmospherics/unary/cold_sink/freezer/attack_ai(mob/user as mob) attack_hand(user) @@ -160,12 +160,13 @@ amount = text2num(amount) current_temperature = clamp(amount, T20C, min_temperature) -/obj/machinery/atmospherics/unary/cold_sink/freezer/power_change() - ..() +/obj/machinery/atmospherics/unary/cold_sink/freezer/power_change(forced = FALSE) + if(!..()) + return if(stat & NOPOWER) - on = 0 + on = FALSE use_power = IDLE_POWER_USE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/atmospherics/unary/heat_reservoir/heater/ name = "нагреватель" @@ -173,7 +174,7 @@ icon_state = "heater" density = 1 var/max_temperature = 0 - anchored = 1.0 + anchored = TRUE layer = 3 current_heat_capacity = 1000 active_power_usage = 5000 @@ -241,7 +242,7 @@ if(default_deconstruction_screwdriver(user, "heater-o", "heater", I)) on = 0 use_power = IDLE_POWER_USE - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE /obj/machinery/atmospherics/unary/heat_reservoir/heater/wrench_act(mob/user, obj/item/I) @@ -261,16 +262,17 @@ node = target break build_network() - update_icon() + update_icon(UPDATE_ICON_STATE) + -/obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon() +/obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon_state() if(panel_open) icon_state = "heater-o" - else if(src.on) + else if(on) icon_state = "heater_1" else icon_state = "heater" - return + /obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_ai(mob/user as mob) attack_hand(user) @@ -329,9 +331,12 @@ amount = text2num(amount) current_temperature = clamp(amount, T20C, T20C + max_temperature) -/obj/machinery/atmospherics/unary/heat_reservoir/heater/power_change() - ..() + +/obj/machinery/atmospherics/unary/heat_reservoir/heater/power_change(forced = FALSE) + if(!..()) + return if(stat & NOPOWER) - on = 0 + on = FALSE use_power = IDLE_POWER_USE - update_icon() + update_icon(UPDATE_ICON_STATE) + diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 1f88eb65aa8..50d4ec1e888 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "table2-idle" density = 1 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 1 active_power_usage = 5 @@ -39,7 +39,7 @@ else return FALSE -/obj/machinery/optable/MouseDrop_T(atom/movable/O, mob/user) +/obj/machinery/optable/MouseDrop_T(atom/movable/O, mob/user, params) if(!ishuman(user) && !isrobot(user)) //Only Humanoids and Cyborgs can put things on this table return if(!check_table()) //If the Operating Table is occupied, you cannot put someone else on it @@ -50,6 +50,7 @@ return add_fingerprint(user) take_patient(O, user) + return TRUE /** * Updates the `patient` var to be the mob occupying the table @@ -61,10 +62,12 @@ else patient = null if(!no_icon_updates) - if(patient && patient.pulse) - icon_state = "table2-active" - else - icon_state = "table2-idle" + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/optable/update_icon_state() + icon_state = "table2-[(patient && patient.pulse) ? "active" : "idle"]" + /obj/machinery/optable/Crossed(atom/movable/AM, oldloc) . = ..() diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index a4350e61887..b62893f59dd 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -3,8 +3,9 @@ desc = "A PDA painting machine. To use, simply insert your PDA and choose the desired preset paint scheme." icon = 'icons/obj/pda.dmi' icon_state = "pdapainter" + base_icon_state = "pdapainter" density = 1 - anchored = 1 + anchored = TRUE max_integrity = 200 var/obj/item/pda/storedpda = null var/list/colorlist = list() @@ -14,25 +15,9 @@ var/allowErasePda = TRUE -/obj/machinery/pdapainter/update_icon() - cut_overlays() - - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - return - - if(storedpda) - add_overlay("[initial(icon_state)]-closed") - - if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - - return - /obj/machinery/pdapainter/Initialize(mapload) . = ..() + var/blocked = list(/obj/item/pda/silicon, /obj/item/pda/silicon/ai, /obj/item/pda/silicon/robot, /obj/item/pda/silicon/pai, /obj/item/pda/heads, /obj/item/pda/clear, /obj/item/pda/syndicate, /obj/item/pda/chameleon, /obj/item/pda/chameleon/broken) @@ -51,6 +36,26 @@ QDEL_NULL(storedpda) return ..() + +/obj/machinery/pdapainter/update_icon_state() + if(stat & BROKEN) + icon_state = "[base_icon_state]-broken" + return + + if(powered()) + icon_state = base_icon_state + else + icon_state = "[base_icon_state]-off" + + +/obj/machinery/pdapainter/update_overlays() + . = ..() + if(stat & BROKEN) + return + if(storedpda) + . += "[base_icon_state]-closed" + + /obj/machinery/pdapainter/on_deconstruction() if(storedpda) storedpda.forceMove(loc) @@ -109,8 +114,10 @@ ui_interact(user) -/obj/machinery/pdapainter/power_change() - ..() + +/obj/machinery/pdapainter/power_change(forced = FALSE) + if(!..()) + return update_icon() diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 3e6bad4728b..5c58e704a48 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -10,9 +10,8 @@ icon_state = "sleeper-open" var/base_icon = "sleeper" density = 1 - anchored = 1 + anchored = TRUE dir = WEST - var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r" var/mob/living/carbon/human/occupant = null var/possible_chems = list("ephedrine", "salglu_solution", "salbutamol", "charcoal") var/emergency_chems = list("ephedrine") // Desnowflaking @@ -31,12 +30,6 @@ light_color = LIGHT_COLOR_CYAN -/obj/machinery/sleeper/power_change() - ..() - if(!(stat & (BROKEN|NOPOWER))) - set_light(2) - else - set_light(0) /obj/machinery/sleeper/New() ..() @@ -65,6 +58,22 @@ component_parts += new /obj/item/stack/cable_coil(null, 1) RefreshParts() + +/obj/machinery/sleeper/power_change(forced = FALSE) + ..() //we don't check parent return here because we also care about BROKEN + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) + + +/obj/machinery/sleeper/update_icon_state() + if(occupant) + icon_state = base_icon + else + icon_state = "[base_icon]-open" + + /obj/machinery/sleeper/RefreshParts() var/E for(var/obj/item/stock_parts/matter_bin/B in component_parts) @@ -336,7 +345,7 @@ var/mob/M = G.affecting M.forceMove(src) occupant = M - icon_state = "[base_icon]" + update_icon(UPDATE_ICON_STATE) to_chat(M, span_boldnotice("You feel cool air surround you. You go numb as your senses turn inward.")) add_fingerprint(user) qdel(G) @@ -357,6 +366,7 @@ if(default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", I)) return TRUE + /obj/machinery/sleeper/wrench_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -367,12 +377,9 @@ if(panel_open) to_chat(user, span_notice("Close the maintenance panel first.")) return - if(dir == EAST) - orient = "LEFT" - setDir(WEST) - else - orient = "RIGHT" - setDir(EAST) + + setDir(turn(dir, -90)) + /obj/machinery/sleeper/ex_act(severity) if(filtering) @@ -386,7 +393,7 @@ if(A == occupant) occupant = null updateUsrDialog() - update_icon() + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) if(A == beaker) beaker = null @@ -426,7 +433,7 @@ return occupant.forceMove(loc) occupant = null - icon_state = "[base_icon]-open" + update_icon(UPDATE_ICON_STATE) // eject trash the occupant dropped for(var/atom/movable/A in contents - component_parts - list(beaker)) A.forceMove(loc) @@ -463,10 +470,9 @@ if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other return - icon_state = "[base_icon]-open" go_out() add_fingerprint(usr) - return + /obj/machinery/sleeper/verb/remove_beaker() set name = "Remove Beaker" @@ -483,9 +489,9 @@ beaker = null SStgui.update_uis(src) add_fingerprint(usr) - return -/obj/machinery/sleeper/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) + +/obj/machinery/sleeper/MouseDrop_T(atom/movable/O, mob/user, params) if(O.loc == user) //no you can't pull things out of your ass return if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other @@ -504,41 +510,48 @@ return if(panel_open) to_chat(user, span_boldnotice("Close the maintenance panel first.")) - return + return TRUE if(occupant) to_chat(user, span_boldnotice("The sleeper is already occupied!")) - return + return TRUE var/mob/living/L = O if(!istype(L) || L.buckled) return if(L.abiotic()) to_chat(user, span_boldnotice("Subject cannot have abiotic items on.")) - return + return TRUE if(L.has_buckled_mobs()) //mob attached to us to_chat(user, span_warning("[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")) - return + return TRUE if(L == user) visible_message("[user] starts climbing into the sleeper.") else visible_message("[user] starts putting [L.name] into the sleeper.") + . = TRUE + INVOKE_ASYNC(src, PROC_REF(put_in), L, user) - if(do_after(user, 20, target = L)) - if(occupant) - to_chat(user, span_boldnotice("The sleeper is already occupied!")) - return - if(!L) return - L.forceMove(src) - occupant = L - icon_state = "[base_icon]" - to_chat(L, span_boldnotice("You feel cool air surround you. You go numb as your senses turn inward.")) - add_fingerprint(user) - if(user.pulling == L) - user.stop_pulling() - if(L.grabbed_by) - QDEL_LIST(L.grabbed_by) - SStgui.update_uis(src) + +/obj/machinery/sleeper/proc/put_in(mob/living/L, mob/user) + if(!do_after(user, 2 SECONDS, target = L)) return - return + + if(occupant) + to_chat(user, span_boldnotice("The sleeper is already occupied!")) + return + if(!L) + return + + L.forceMove(src) + occupant = L + update_icon(UPDATE_ICON_STATE) + to_chat(L, span_boldnotice("You feel cool air surround you. You go numb as your senses turn inward.")) + add_fingerprint(user) + if(user.pulling == L) + user.stop_pulling() + if(L.grabbed_by) + QDEL_LIST(L.grabbed_by) + SStgui.update_uis(src) + /obj/machinery/sleeper/AllowDrop() return FALSE @@ -561,21 +574,8 @@ to_chat(usr, span_warning("[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.")) return visible_message("[usr] starts climbing into the sleeper.") - if(do_after(usr, 20, target = usr)) - if(occupant) - to_chat(usr, span_boldnotice("The sleeper is already occupied!")) - return - usr.stop_pulling() - usr.forceMove(src) - occupant = usr - icon_state = "[base_icon]" - - for(var/obj/O in src) - qdel(O) - add_fingerprint(usr) - SStgui.update_uis(src) - return - return + put_in(usr, usr) + /obj/machinery/sleeper/syndie icon_state = "sleeper_s-open" diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 21a9ef8dc86..a096bacbde0 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -16,15 +16,35 @@ go_out() return ..() -/obj/machinery/bodyscanner/power_change() - ..() +/obj/machinery/bodyscanner/power_change(forced = FALSE) + if(!..()) + return if(!(stat & (BROKEN|NOPOWER))) set_light(2) else set_light(0) + +/obj/machinery/bodyscanner/examine(mob/user) + . = ..() + if(occupant) + if(occupant.is_dead()) + . += span_warning("You see [occupant.name] inside. [occupant.p_they(TRUE)] [occupant.p_are()] dead!>") + else + . += span_notice("You see [occupant.name] inside.") + if(Adjacent(user)) + . += span_info("You can Alt-Click to eject the current occupant. Click-drag someone to the scanner to place them inside.") + + +/obj/machinery/bodyscanner/update_icon_state() + if(occupant) + icon_state = "bodyscanner" + else + icon_state = "bodyscanner-open" + + /obj/machinery/bodyscanner/process() - for(var/mob/M as mob in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp + for(var/mob/M in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp if(M == occupant) continue else @@ -63,7 +83,7 @@ return M.forceMove(src) occupant = M - icon_state = "bodyscanner" + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) qdel(TYPECAST_YOUR_SHIT) SStgui.update_uis(src) @@ -79,6 +99,7 @@ if(default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", I)) return TRUE + /obj/machinery/bodyscanner/wrench_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -89,12 +110,11 @@ if(panel_open) to_chat(user, span_notice("Close the maintenance panel first.")) return - if(dir == EAST) - setDir(WEST) - else - setDir(EAST) -/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/H, mob/user) + setDir(turn(dir, -90)) + + +/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/H, mob/user, params) if(!istype(H)) return FALSE //not human if(user.incapacitated()) @@ -107,18 +127,18 @@ return FALSE //not a borg or human if(panel_open) to_chat(user, span_notice("Close the maintenance panel first.")) - return FALSE //panel open + return TRUE //panel open if(occupant) to_chat(user, span_notice("[src] is already occupied.")) - return FALSE //occupied + return TRUE //occupied if(H.buckled) return FALSE if(H.abiotic()) to_chat(user, span_notice("Subject cannot have abiotic items on.")) - return FALSE + return TRUE if(H.has_buckled_mobs()) //mob attached to us to_chat(user, span_warning("[H] will not fit into [src] because [H.p_they()] [H.p_have()] a slime latched onto [H.p_their()] head.")) - return + return TRUE if(H == user) visible_message("[user] climbs into [src].") @@ -128,9 +148,10 @@ add_fingerprint(user) H.forceMove(src) occupant = H - icon_state = "bodyscanner" + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) SStgui.update_uis(src) + return TRUE /obj/machinery/bodyscanner/attack_ai(user) return attack_hand(user) @@ -175,7 +196,7 @@ return occupant.forceMove(loc) occupant = null - icon_state = "bodyscanner-open" + update_icon(UPDATE_ICON_STATE) // eject trash the occupant dropped for(var/atom/movable/A in contents - component_parts) A.forceMove(loc) @@ -194,7 +215,7 @@ if(A == occupant) occupant = null updateUsrDialog() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/bodyscanner/narsie_act() go_out() diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 990903e626c..4b02439c75c 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -4,84 +4,96 @@ icon_state = "liquid_dispenser" layer = 3 plane = FLOOR_PLANE - anchored = 1.0 + anchored = TRUE max_integrity = 200 armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) var/uses = 20 var/disabled = TRUE - var/lethal = 0 var/locked = TRUE - var/cooldown_time = 0 - var/cooldown_timeleft = 0 + var/cooldown_time = 10 SECONDS var/cooldown_on = FALSE req_access = list(ACCESS_AI_UPLOAD) + +/obj/machinery/ai_slipper/examine(mob/user) + . = ..() + . += span_notice("A small counter shows it has: [uses] use\s remaining.") + + /obj/machinery/ai_slipper/power_change() - if(stat & BROKEN) - update_icon() - else - if( powered() ) - stat &= ~NOPOWER - else - stat |= NOPOWER - disabled = TRUE - update_icon() - -/obj/machinery/ai_slipper/proc/setState(var/enabled, var/uses) - disabled = disabled - uses = uses - power_change() + ..() //we don't check return here because we also care about the BROKEN flag + if(stat & NOPOWER) + disabled = TRUE + update_icon(UPDATE_ICON_STATE) + /obj/machinery/ai_slipper/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) if(stat & (NOPOWER|BROKEN)) - add_fingerprint(user) return - if(istype(user, /mob/living/silicon)) + if(issilicon(user)) return attack_hand(user) - if(allowed(usr)) // trying to unlock the interface - add_fingerprint(user) - locked = !locked - to_chat(user, "You [locked ? "lock" : "unlock"] the device.") - if(locked) - if(user.machine == src) - user.unset_machine() - user << browse(null, "window=ai_slipper") - else - if(user.machine == src) - attack_hand(usr) - return - return ..() + if(!allowed(user)) // trying to unlock the interface + to_chat(user, span_warning("Access denied.")) + return ..() + + locked = !locked + to_chat(user, span_notice("You [locked ? "lock" : "unlock"] the device.")) + if(locked) + if(user.machine == src) + user.unset_machine() + user << browse(null, "window=ai_slipper") + else + if(user.machine == src) + attack_hand(user) + /obj/machinery/ai_slipper/proc/ToggleOn() if(stat & (NOPOWER|BROKEN)) return disabled = !disabled - update_icon() + update_icon(UPDATE_ICON_STATE) + -/obj/machinery/ai_slipper/proc/Activate() +/obj/machinery/ai_slipper/proc/Activate(mob/user) if(stat & (NOPOWER|BROKEN)) return - if(cooldown_on || disabled) + if(!uses) + to_chat(user, span_warning("[src] is empty!")) return - else - new /obj/effect/particle_effect/foam(loc) - uses-- - cooldown_on = TRUE - cooldown_time = world.timeofday + 100 - slip_process() - -/obj/machinery/ai_slipper/update_icon() - if(stat & (NOPOWER|BROKEN) || disabled) + if(cooldown_on) + to_chat(user, span_warning("[src] is still recharging!")) + return + + new /obj/effect/particle_effect/foam(loc) + uses-- + cooldown_on = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(recharge)), cooldown_time) + + +/obj/machinery/ai_slipper/proc/recharge() + if(!uses) + return + cooldown_on = FALSE + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/ai_slipper/update_icon_state() + if((stat & (NOPOWER|BROKEN)) || disabled || cooldown_on || !uses) icon_state = "liquid_dispenser" else icon_state = "liquid_dispenser_on" + /obj/machinery/ai_slipper/attack_ai(mob/user) return attack_hand(user) + /obj/machinery/ai_slipper/attack_ghost(mob/user) return attack_hand(user) + /obj/machinery/ai_slipper/attack_hand(mob/user) if(stat & (NOPOWER|BROKEN)) return @@ -106,6 +118,7 @@ user << browse(t, "window=computer;size=575x450") onclose(user, "computer") + /obj/machinery/ai_slipper/Topic(href, href_list) if(..()) return 1 @@ -118,22 +131,7 @@ ToggleOn() if(href_list["toggleUse"]) - Activate() + Activate(usr) attack_hand(usr) -/obj/machinery/ai_slipper/proc/slip_process() - while(cooldown_time - world.timeofday > 0) - var/ticksleft = cooldown_time - world.timeofday - - if(ticksleft > 1e5) - cooldown_time = world.timeofday + 10 // midnight rollover - - - cooldown_timeleft = (ticksleft / 10) - sleep(5) - if(uses <= 0) - return - if(uses >= 0) - cooldown_on = FALSE - power_change() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 22ed3d826e7..330b7b00b7b 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -72,7 +72,7 @@ name = "alarm" icon = 'icons/obj/machines/monitors.dmi' icon_state = "alarm0" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 4 active_power_usage = 8 @@ -92,7 +92,7 @@ var/rcon_time = 0 var/locked = 1 var/datum/wires/alarm/wires = null - var/wiresexposed = 0 // If it's been screwdrivered open. + var/wiresexposed = FALSE // If it's been screwdrivered open. var/aidisabled = 0 var/AAlarmwires = 31 var/shorted = 0 @@ -204,8 +204,8 @@ if(dir) setDir(direction) - buildstage = 0 - wiresexposed = 1 + buildstage = AIR_ALARM_FRAME + wiresexposed = TRUE set_pixel_offsets_from_dir(-24, 24, -24, 24) update_icon() return @@ -262,7 +262,7 @@ return 0 /obj/machinery/alarm/process() - if((stat & (NOPOWER|BROKEN)) || shorted || buildstage != 2) + if((stat & (NOPOWER|BROKEN)) || shorted || buildstage != AIR_ALARM_READY) return var/turf/simulated/location = loc @@ -356,29 +356,43 @@ environment.merge(gas) -/obj/machinery/alarm/update_icon() + +/obj/machinery/alarm/update_icon_state() if(wiresexposed) - icon_state = "alarmx" - set_light(0) + switch(buildstage) + if(AIR_ALARM_FRAME) + icon_state = "alarm_b1" + if(AIR_ALARM_BUILDING) + icon_state = "alarm_b2" + if(AIR_ALARM_READY) + icon_state = "alarmx" return + if((stat & (NOPOWER|BROKEN)) || shorted) icon_state = "alarmp" - set_light(0) return - var/new_color = null - switch(max(danger_level, alarm_area.atmosalm-1)) + if(!alarm_area) // We wont have our alarm_area if we aint initialised + return + + switch(max(danger_level, alarm_area.atmosalm - 1)) if(ATMOS_ALARM_NONE) icon_state = "alarm0" - new_color = COLOR_GREEN if(ATMOS_ALARM_WARNING) icon_state = "alarm2" //yes, alarm2 is yellow alarm - new_color = COLOR_YELLOW if(ATMOS_ALARM_DANGER) icon_state = "alarm1" - new_color = COLOR_RED - set_light(1, 1, new_color) + +/obj/machinery/alarm/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER || buildstage != AIR_ALARM_READY || wiresexposed || shorted) + return + + underlays += emissive_appearance(icon, "alarm_lightmask") + /obj/machinery/alarm/proc/register_env_machine(m_id, device_type) var/new_name @@ -574,7 +588,7 @@ /////////////// /obj/machinery/alarm/attack_ai(mob/user) - if(buildstage != 2) + if(buildstage != AIR_ALARM_READY) return add_hiddenprint(user) @@ -590,7 +604,7 @@ return interact(user) /obj/machinery/alarm/interact(mob/user) - if(buildstage != 2) + if(buildstage != AIR_ALARM_READY) return if(wiresexposed) @@ -801,7 +815,7 @@ return !locked /obj/machinery/alarm/ui_status(mob/user, datum/ui_state/state) - if(buildstage != 2) + if(buildstage != AIR_ALARM_READY) return STATUS_CLOSE if(aidisabled && (isAI(user) || isrobot(user))) @@ -949,47 +963,46 @@ /obj/machinery/alarm/attackby(obj/item/I, mob/user, params) switch(buildstage) - if(2) + if(AIR_ALARM_READY) if(I.GetID() || ispda(I)) // trying to unlock the interface if(stat & (NOPOWER|BROKEN)) - to_chat(user, "It does nothing") + to_chat(user, span_warning("It does nothing!")) return + + if(allowed(user) && !wires.is_cut(WIRE_IDSCAN)) + add_fingerprint(user) + locked = !locked + to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] the Air Alarm interface.")) + SStgui.update_uis(src) else - if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) - add_fingerprint(user) - locked = !locked - to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] the Air Alarm interface.")) - SStgui.update_uis(src) - else - to_chat(user, span_warning("Access denied.")) + to_chat(user, span_warning("Access denied.")) return - if(1) + if(AIR_ALARM_BUILDING) if(iscoil(I)) var/obj/item/stack/cable_coil/coil = I if(coil.get_amount() < 5) - to_chat(user, "You need more cable for this!") + to_chat(user, span_notice("You need more cable for this!")) return add_fingerprint(user) to_chat(user, "You wire \the [src]!") - playsound(get_turf(src), coil.usesound, 50, 1) + playsound(get_turf(src), coil.usesound, 50, TRUE) coil.use(5) - if(!coil.amount) - qdel(coil) - - buildstage = 2 + buildstage = AIR_ALARM_READY + wiresexposed = TRUE update_icon() first_run() return - if(0) + + if(AIR_ALARM_FRAME) if(istype(I, /obj/item/airalarm_electronics)) add_fingerprint(user) - to_chat(user, "You insert the circuit!") + to_chat(user, span_notice("You insert the circuit!")) playsound(get_turf(src), I.usesound, 50, 1) qdel(I) - buildstage = 1 - update_icon() + buildstage = AIR_ALARM_BUILDING + update_icon(UPDATE_ICON_STATE) return return ..() @@ -999,15 +1012,15 @@ . = TRUE if(!I.tool_start_check(src, user, 0)) return - to_chat(user, "You start prying out the circuit.") + CROWBAR_ATTEMPT_PRY_CIRCUIT_MESSAGE if(!I.use_tool(src, user, 20, volume = I.tool_volume)) return if(buildstage != AIR_ALARM_BUILDING) return - to_chat(user, "You pry out the circuit!") + CROWBAR_PRY_CIRCUIT_SUCCESS_MESSAGE new /obj/item/airalarm_electronics(user.drop_location()) buildstage = AIR_ALARM_FRAME - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/alarm/multitool_act(mob/user, obj/item/I) if(buildstage != AIR_ALARM_READY) @@ -1040,7 +1053,7 @@ if(wires.is_all_cut()) // all wires cut new /obj/item/stack/cable_coil(user.drop_location(), 5) buildstage = AIR_ALARM_BUILDING - update_icon() + update_icon(UPDATE_ICON_STATE) if(wiresexposed) wires.Interact(user) @@ -1054,13 +1067,15 @@ WRENCH_UNANCHOR_WALL_MESSAGE qdel(src) -/obj/machinery/alarm/power_change() - if(powered(power_channel)) - stat &= ~NOPOWER + +/obj/machinery/alarm/power_change(forced = FALSE) + ..() //we don't check return here because we also care about the BROKEN flag + if(stat & NOPOWER) + set_light(0) else - stat |= NOPOWER - spawn(rand(0,15)) - update_icon() + set_light(1, LIGHTING_MINIMUM_POWER) + update_icon() + /obj/machinery/alarm/obj_break(damage_flag) ..() @@ -1075,12 +1090,18 @@ new /obj/item/stack/cable_coil(loc, 3) qdel(src) + /obj/machinery/alarm/examine(mob/user) . = ..() - if(buildstage < 2) - . += span_notice("It is not wired.") - if(buildstage < 1) - . += span_notice("The circuit is missing.") + switch(buildstage) + if(AIR_ALARM_FRAME) + . += span_notice("Its circuit is missing and the bolts are exposed.") + if(AIR_ALARM_BUILDING) + . += span_notice("The frame is missing wires and the control circuit can be pried out.") + if(AIR_ALARM_READY) + if(wiresexposed) + . += span_notice("The wiring could be cut and removed or panel could screwed closed.") + /obj/machinery/alarm/proc/unshort_callback() if(shorted) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index e55f1320421..28191123cc3 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -1,19 +1,29 @@ +GLOBAL_LIST_EMPTY(gas_sensors) + +#define SENSOR_PRESSURE 1 +#define SENSOR_TEMPERATURE 2 +#define SENSOR_O2 4 +#define SENSOR_PLASMA 8 +#define SENSOR_N2 16 +#define SENSOR_CO2 32 + + /obj/machinery/atmospherics/air_sensor icon = 'icons/obj/stationobjs.dmi' icon_state = "gsensor1" resistance_flags = FIRE_PROOF name = "gas sensor" - anchored = 1 - var/state = 0 - var/bolts = 1 + anchored = TRUE + var/state = NONE + var/bolts = TRUE var/id_tag frequency = ATMOS_TANKS_FREQ - var/on = 1 - var/output = 3 - //Flags: + on = TRUE + var/output = SENSOR_PRESSURE|SENSOR_TEMPERATURE + //Flags: (see lines 3-9) // 1 for pressure // 2 for temperature // Output >= 4 includes gas composition @@ -22,17 +32,20 @@ // 16 for nitrogen concentration // 32 for carbon dioxide concentration -/obj/machinery/atmospherics/air_sensor/update_icon() + +/obj/machinery/atmospherics/air_sensor/update_icon_state() icon_state = "gsensor[on]" + /obj/machinery/atmospherics/air_sensor/proc/toggle_out_flag(bitflag_value) - if(!(bitflag_value in list(1, 2, 4, 8, 16, 32))) - return 0 + if(!(bitflag_value in list(SENSOR_PRESSURE, SENSOR_TEMPERATURE, SENSOR_O2, SENSOR_PLASMA, SENSOR_N2, SENSOR_CO2))) + return if(output & bitflag_value) output &= ~bitflag_value else output |= bitflag_value + /obj/machinery/atmospherics/air_sensor/proc/toggle_bolts() bolts = !bolts if(bolts) @@ -99,10 +112,12 @@ /obj/machinery/atmospherics/air_sensor/Initialize() . = ..() + GLOB.gas_sensors += src SSair.atmos_machinery += src set_frequency(frequency) /obj/machinery/atmospherics/air_sensor/Destroy() + GLOB.gas_sensors -= src SSair.atmos_machinery -= src if(SSradio) SSradio.remove_object(src, frequency) diff --git a/code/game/machinery/atmoalter/area_atmos_computer.dm b/code/game/machinery/atmoalter/area_atmos_computer.dm index 8b0bd2e1e91..87e31ffda70 100644 --- a/code/game/machinery/atmoalter/area_atmos_computer.dm +++ b/code/game/machinery/atmoalter/area_atmos_computer.dm @@ -15,11 +15,12 @@ //Simple variable to prevent me from doing attack_hand in both this and the child computer var/zone = "This computer is working on a wireless range, the range is currently limited to 25 meters." -/obj/machinery/computer/area_atmos/New() - ..() + +/obj/machinery/computer/area_atmos/Initialize(mapload) + . = ..() //So the scrubbers have time to spawn - spawn(10) - scanscrubbers() + addtimer(CALLBACK(src, PROC_REF(scanscrubbers)), 1 SECONDS) + /obj/machinery/computer/area_atmos/attack_ai(mob/user as mob) src.add_hiddenprint(user) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 627c3d99cfc..647f4879cfa 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -43,42 +43,48 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) name = "canister" icon = 'icons/obj/pipes_and_stuff/atmospherics/atmos.dmi' icon_state = "yellow" - density = 1 + density = TRUE flags = CONDUCT - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 80, ACID = 50) max_integrity = 250 integrity_failure = 100 - var/valve_open = 0 + var/valve_open = FALSE var/release_pressure = ONE_ATMOSPHERE - var/list/canister_color //variable that stores colours - var/list/color_index // list which stores tgui color indexes for the recoloring options, to enable previously-set colors to show up right + /// Variable that stores colours + var/list/canister_color + /// List which stores tgui color indexes for the recoloring options, to enable previously-set colors to show up right + var/list/color_index - //lists for check_change() - var/list/oldcolor + /// Lists for check_change() + var/list/old_color - //passed to the ui to render the color lists + /// Passed to the ui to render the color lists var/list/colorcontainer - var/can_label = 1 + var/can_label = TRUE var/filled = 0.5 pressure_resistance = 7 * ONE_ATMOSPHERE var/temperature_resistance = 1000 + T0C volume = 1000 use_power = NO_POWER_USE - interact_offline = 1 - var/update_flag = 0 + interact_offline = TRUE + var/update_flag = NONE + + +/obj/machinery/portable_atmospherics/canister/Initialize(mapload) + . = ..() -/obj/machinery/portable_atmospherics/canister/New() - ..() canister_color = list( "prim" = "yellow", "sec" = "none", "ter" = "none", - "quart" = "none" + "quart" = "none", ) - oldcolor = new /list() + + old_color = list() + colorcontainer = list( "prim" = list( "options" = GLOB.canister_icon_container.possiblemaincolor, @@ -97,84 +103,98 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) "name" = "Quaternary color", ) ) + color_index = list() update_icon() + +#define HOLDING_TANK 1 +#define CONNECTED_PORT 2 +#define LOW_PRESSURE 4 +#define NORMAL_PRESSURE 8 +#define HIGH_PRESSURE 16 +#define EXTREME_PRESSURE 32 +#define NEW_COLOR 64 +#define RESET 68 + /obj/machinery/portable_atmospherics/canister/proc/check_change() var/old_flag = update_flag - update_flag = 0 + + update_flag = NONE if(holding) - update_flag |= 1 + update_flag |= HOLDING_TANK if(connected_port) - update_flag |= 2 + update_flag |= CONNECTED_PORT var/tank_pressure = air_contents.return_pressure() if(tank_pressure < 10) - update_flag |= 4 + update_flag |= LOW_PRESSURE else if(tank_pressure < ONE_ATMOSPHERE) - update_flag |= 8 + update_flag |= NORMAL_PRESSURE else if(tank_pressure < 15*ONE_ATMOSPHERE) - update_flag |= 16 + update_flag |= HIGH_PRESSURE else - update_flag |= 32 + update_flag |= EXTREME_PRESSURE - if(list2params(oldcolor) != list2params(canister_color)) - update_flag |= 64 - oldcolor = canister_color.Copy() + if(list2params(old_color) != list2params(canister_color)) + update_flag |= NEW_COLOR + old_color = canister_color.Copy() - if(update_flag == old_flag) - return 1 - else - return 0 + return update_flag != old_flag -/obj/machinery/portable_atmospherics/canister/update_icon() + +/obj/machinery/portable_atmospherics/canister/update_icon_state() /* -update_flag -1 = holding -2 = connected_port -4 = tank_pressure < 10 -8 = tank_pressure < ONE_ATMOS -16 = tank_pressure < 15*ONE_ATMOS -32 = tank_pressure go boom. -64 = colors (note: colors has to be applied every icon update) */ - if(stat & BROKEN) - overlays = 0 - icon_state = text("[]-1", canister_color["prim"])//yes, I KNOW the colours don't reflect when the can's borked, whatever. + icon_state = "[canister_color["prim"]]-1"//yes, I KNOW the colours don't reflect when the can's borked, whatever. return if(icon_state != canister_color["prim"]) icon_state = canister_color["prim"] - if(check_change()) //Returns 1 if no change needed to icons. + +/obj/machinery/portable_atmospherics/canister/update_overlays() + . = ..() + + if(stat & BROKEN) return - overlays.Cut() + if(!check_change()) //Returns FALSE if no change needed to icons. + return for(var/C in canister_color) if(C == "prim") continue if(canister_color[C] == "none") continue - overlays.Add(canister_color[C]) - - if(update_flag & 1) - overlays += "can-open" - if(update_flag & 2) - overlays += "can-connector" - if(update_flag & 4) - overlays += "can-o0" - if(update_flag & 8) - overlays += "can-o1" - else if(update_flag & 16) - overlays += "can-o2" - else if(update_flag & 32) - overlays += "can-o3" - - update_flag &= ~68 //the flag 64 represents change, not states. As such, we have to reset them to be able to detect a change on the next go. - return + . += canister_color[C] + + if(update_flag & HOLDING_TANK) + . += "can-open" + if(update_flag & CONNECTED_PORT) + . += "can-connector" + if(update_flag & LOW_PRESSURE) + . += "can-o0" + if(update_flag & NORMAL_PRESSURE) + . += "can-o1" + else if(update_flag & HIGH_PRESSURE) + . += "can-o2" + else if(update_flag & EXTREME_PRESSURE) + . += "can-o3" + + update_flag &= ~RESET //the flag NEW_COLOR represents change, not states. As such, we have to reset them to be able to detect a change on the next go. + +#undef HOLDING_TANK +#undef CONNECTED_PORT +#undef LOW_PRESSURE +#undef NORMAL_PRESSURE +#undef HIGH_PRESSURE +#undef EXTREME_PRESSURE +#undef NEW_COLOR +#undef RESET + /obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() @@ -212,6 +232,7 @@ update_flag holding.forceMove(T) holding = null + /obj/machinery/portable_atmospherics/canister/process_atmos() if(stat & BROKEN) return @@ -245,9 +266,10 @@ update_flag if(air_contents.return_pressure() < 1) - can_label = 1 + can_label = TRUE else - can_label = 0 + can_label = FALSE + /obj/machinery/portable_atmospherics/canister/return_air() return air_contents @@ -274,6 +296,20 @@ update_flag else if(valve_open && holding) investigate_log("[key_name_log(user)] started a transfer into [holding].", INVESTIGATE_ATMOS) + +/obj/machinery/portable_atmospherics/canister/welder_act(mob/user, obj/item/I) + if(!(stat & BROKEN)) + return + . = TRUE + if(!I.tool_use_check(user, 0)) + return + WELDER_ATTEMPT_SLICING_MESSAGE + if(I.use_tool(src, user, 50, volume = I.tool_volume)) + to_chat(user, span_notice("You salvage whats left of [src]!")) + new /obj/item/stack/sheet/metal(drop_location(), 3) + qdel(src) + + /obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user) return attack_hand(user) @@ -385,105 +421,79 @@ update_flag /obj/machinery/portable_atmospherics/canister/toxins name = "Canister \[Toxin (Plasma)\]" - icon_state = "orange" //See New() - can_label = 0 + icon_state = "orange" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/oxygen name = "Canister: \[O2\]" - icon_state = "blue" //See New() - can_label = 0 + icon_state = "blue" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/sleeping_agent name = "Canister: \[N2O\]" - icon_state = "redws" //See New() - can_label = 0 + icon_state = "redws" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/nitrogen name = "Canister: \[N2\]" - icon_state = "red" //See New() - can_label = 0 + icon_state = "red" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/carbon_dioxide name = "Canister \[CO2\]" - icon_state = "black" //See New() - can_label = 0 + icon_state = "black" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/air name = "Canister \[Air\]" - icon_state = "grey" //See New() - can_label = 0 + icon_state = "grey" //See Initialize() + can_label = FALSE /obj/machinery/portable_atmospherics/canister/custom_mix name = "Canister \[Custom\]" - icon_state = "whiters" //See New() - can_label = 0 - + icon_state = "whiters" //See Initialize() + can_label = FALSE -/obj/machinery/portable_atmospherics/canister/toxins/New() - ..() +/obj/machinery/portable_atmospherics/canister/toxins/Initialize(mapload) + . = ..() canister_color["prim"] = "orange" air_contents.toxins = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/oxygen/New() - ..() +/obj/machinery/portable_atmospherics/canister/oxygen/Initialize(mapload) + . = ..() canister_color["prim"] = "blue" air_contents.oxygen = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/sleeping_agent/New() - ..() +/obj/machinery/portable_atmospherics/canister/sleeping_agent/Initialize(mapload) + . = ..() canister_color["prim"] = "redws" air_contents.sleeping_agent = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/nitrogen/New() - ..() +/obj/machinery/portable_atmospherics/canister/nitrogen/Initialize(mapload) + . = ..() canister_color["prim"] = "red" air_contents.nitrogen = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/carbon_dioxide/New() - ..() +/obj/machinery/portable_atmospherics/canister/carbon_dioxide/Initialize(mapload) + . = ..() canister_color["prim"] = "black" air_contents.carbon_dioxide = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/air/New() - ..() - +/obj/machinery/portable_atmospherics/canister/air/Initialize(mapload) + . = ..() canister_color["prim"] = "grey" air_contents.oxygen = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) air_contents.nitrogen = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - update_icon() - return 1 -/obj/machinery/portable_atmospherics/canister/custom_mix/New() - ..() +/obj/machinery/portable_atmospherics/canister/custom_mix/Initialize(mapload) + . = ..() canister_color["prim"] = "whiters" update_icon() // Otherwise new canisters do not have their icon updated with the pressure light, likely want to add this to the canister class constructor, avoiding at current time to refrain from screwing up code for other canisters. --DZD - return 1 -/obj/machinery/portable_atmospherics/canister/welder_act(mob/user, obj/item/I) - if(!(stat & BROKEN)) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - to_chat(user, span_notice("You salvage whats left of [src]!")) - new /obj/item/stack/sheet/metal(drop_location(), 3) - qdel(src) diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index da0c9fb5a24..a2546559ba3 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -31,19 +31,20 @@ target = null return ..() -/obj/machinery/atmospherics/meter/process_atmos() + +/obj/machinery/atmospherics/meter/update_icon_state() if(!target) icon_state = "meterX" - return 0 + return if(stat & (BROKEN|NOPOWER)) icon_state = "meter0" - return 0 + return var/datum/gas_mixture/environment = target.return_air() if(!environment) icon_state = "meterX" - return 0 + return var/env_pressure = environment.return_pressure() if(env_pressure <= 0.15*ONE_ATMOSPHERE) @@ -60,21 +61,37 @@ else icon_state = "meter4" - if(frequency) - var/datum/radio_frequency/radio_connection = SSradio.return_frequency(frequency) - - if(!radio_connection) return - - var/datum/signal/signal = new - signal.source = src - signal.transmission_method = 1 - signal.data = list( - "tag" = id_tag, - "device" = "AM", - "pressure" = round(env_pressure), - "sigtype" = "status" - ) - radio_connection.post_signal(src, signal) + +/obj/machinery/atmospherics/meter/process_atmos() + if(!target || (stat & (BROKEN|NOPOWER))) + update_icon(UPDATE_ICON_STATE) + return + + var/datum/gas_mixture/environment = target.return_air() + if(!environment) + update_icon(UPDATE_ICON_STATE) + return + + update_icon(UPDATE_ICON_STATE) + + if(!frequency) + return + + var/datum/radio_frequency/radio_connection = SSradio.return_frequency(frequency) + if(!radio_connection) + return + + var/datum/signal/signal = new + signal.source = src + signal.transmission_method = 1 + signal.data = list( + "tag" = id_tag, + "device" = "AM", + "pressure" = round(environment.return_pressure()), + "sigtype" = "status", + ) + radio_connection.post_signal(src, signal) + /obj/machinery/atmospherics/meter/proc/status() var/t = "" diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index ad658db1ced..ed430b6175b 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -7,34 +7,40 @@ var/obj/machinery/atmospherics/unary/portables_connector/connected_port var/obj/item/tank/holding - var/volume = 0 - var/maximum_pressure = 90*ONE_ATMOSPHERE -/obj/machinery/portable_atmospherics/New() - ..() + +/obj/machinery/portable_atmospherics/Initialize(mapload) + . = ..() SSair.atmos_machinery += src air_contents.volume = volume air_contents.temperature = T20C - return 1 + if(mapload) + return INITIALIZE_HINT_LATELOAD + + check_for_port() + + +// Late init this otherwise it shares with the port and it tries to div temperature by 0 +/obj/machinery/portable_atmospherics/LateInitialize() + check_for_port() + + +/obj/machinery/portable_atmospherics/proc/check_for_port() + var/obj/machinery/atmospherics/unary/portables_connector/port = locate() in loc + if(port) + connect(port) -/obj/machinery/portable_atmospherics/Initialize() - . = ..() - spawn() - var/obj/machinery/atmospherics/unary/portables_connector/port = locate() in loc - if(port) - connect(port) - update_icon() /obj/machinery/portable_atmospherics/process_atmos() if(!connected_port) //only react when pipe_network will ont it do it for you //Allow for reactions air_contents.react() - else - update_icon() + return + update_icon() /obj/machinery/portable_atmospherics/Destroy() SSair.atmos_machinery -= src @@ -43,17 +49,20 @@ QDEL_NULL(holding) return ..() -/obj/machinery/portable_atmospherics/update_icon() - return null +/obj/machinery/portable_atmospherics/update_icon_state() + return + +/obj/machinery/portable_atmospherics/update_overlays() + . = list() /obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/unary/portables_connector/new_port) //Make sure not already connected to something else if(connected_port || !new_port || new_port.connected_device) - return 0 + return FALSE //Make sure are close enough for a valid connection if(new_port.loc != loc) - return 0 + return FALSE //Perform the connection connected_port = new_port @@ -64,20 +73,20 @@ connected_port.build_network() connected_port.parent.reconcile_air() - anchored = 1 //Prevent movement + anchored = TRUE //Prevent movement - return 1 + return TRUE /obj/machinery/portable_atmospherics/proc/disconnect() if(!connected_port) - return 0 + return FALSE - anchored = 0 + anchored = FALSE connected_port.connected_device = null connected_port = null - return 1 + return TRUE /obj/machinery/portable_atmospherics/portableConnectorReturnAir() return air_contents @@ -121,10 +130,10 @@ if(!user.drop_transfer_item_to_loc(T, src)) return add_fingerprint(user) - if(src.holding) + if(holding) to_chat(user, span_notice("[holding ? "In one smooth motion you pop [holding] out of [src]'s connector and replace it with [T]" : "You insert [T] into [src]"].")) replace_tank(user, FALSE) - src.holding = T + holding = T update_icon() return return ..() diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index e5987d8076f..c86161bb714 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -19,21 +19,18 @@ /// The desired pressure the pump should be outputting, either into the atmosphere, or into a holding tank. var/target_pressure = 101.325 -/obj/machinery/portable_atmospherics/pump/update_icon() - overlays = 0 - if(on) - icon_state = "psiphon:1" - else - icon_state = "psiphon:0" +/obj/machinery/portable_atmospherics/pump/update_icon_state() + icon_state = "psiphon:[on]" - if(holding) - overlays += "siphon-open" +/obj/machinery/portable_atmospherics/pump/update_overlays() + . = ..() + if(holding) + . += "siphon-open" if(connected_port) - overlays += "siphon-connector" + . += "siphon-connector" - return /obj/machinery/portable_atmospherics/pump/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 5d1b6f5a3ee..7d1d95a0ec7 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -25,21 +25,18 @@ ..(severity) -/obj/machinery/portable_atmospherics/scrubber/update_icon() - overlays = 0 - if(on) - icon_state = "pscrubber:1" - else - icon_state = "pscrubber:0" +/obj/machinery/portable_atmospherics/scrubber/update_icon_state() + icon_state = "pscrubbe:[on]" - if(holding) - overlays += "scrubber-open" +/obj/machinery/portable_atmospherics/scrubber/update_overlays() + . = ..() + if(holding) + . += "scrubber-open" if(connected_port) - overlays += "scrubber-connector" + . += "scrubber-connector" - return /obj/machinery/portable_atmospherics/scrubber/process_atmos() ..() @@ -164,7 +161,7 @@ /obj/machinery/portable_atmospherics/scrubber/huge name = "Huge Air Scrubber" icon_state = "scrubber:0" - anchored = 1 + anchored = TRUE volume = 50000 volume_rate = 5000 widenet = 1 @@ -183,13 +180,14 @@ /obj/machinery/portable_atmospherics/scrubber/huge/attack_hand(mob/user) to_chat(usr, span_warning("You can't directly interact with this machine. Use the area atmos computer.")) -/obj/machinery/portable_atmospherics/scrubber/huge/update_icon() - overlays = 0 - if(on) - icon_state = "scrubber:1" - else - icon_state = "scrubber:0" +/obj/machinery/portable_atmospherics/scrubber/huge/update_icon_state() + icon_state = "pscrubbe:[on]" + + +/obj/machinery/portable_atmospherics/scrubber/update_overlays() + . = list() + /obj/machinery/portable_atmospherics/scrubber/huge/wrench_act(mob/user, obj/item/I) . = TRUE diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm index a135833b903..162fe45fe22 100644 --- a/code/game/machinery/atmoalter/zvent.dm +++ b/code/game/machinery/atmoalter/zvent.dm @@ -9,8 +9,8 @@ var/on = 0 var/volume_rate = 800 -/obj/machinery/zvent/New() - ..() +/obj/machinery/zvent/Initialize(mapload) + . = ..() SSair.atmos_machinery += src /obj/machinery/zvent/Destroy() diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 6001a1d638e..1e9319154d8 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -12,7 +12,7 @@ var/list/queue = list() var/queue_max_len = 12 var/turf/BuildTurf - anchored = 1.0 + anchored = TRUE var/list/L = list() var/list/LL = list() var/hacked = 0 @@ -376,8 +376,7 @@ if(can_build(D, multiplier)) being_built = list(D, multiplier) use_power(power) - icon_state = "autolathe" - flick("autolathe_n",src) + flick("autolathe_n", src) if(is_stack) var/list/materials_used = list(MAT_METAL=metal_cost*multiplier, MAT_GLASS=glass_cost*multiplier) materials.use_amount(materials_used) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 8802037979c..54e28a7c775 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -9,8 +9,8 @@ icon_state = "launcherbtt" desc = "A remote control switch for a mass driver." var/id_tag = "default" - var/active = 0 - anchored = 1.0 + var/active = FALSE + anchored = TRUE armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100, fire = 90, acid = 70) use_power = IDLE_POWER_USE idle_power_usage = 2 @@ -57,6 +57,10 @@ return ..() +/obj/machinery/driver_button/update_icon_state() + icon_state = active ? "launcheract" : "launcherbtt" + + /obj/machinery/driver_button/attack_ai(mob/user as mob) return attack_hand(user) @@ -96,8 +100,8 @@ launch_sequence() /obj/machinery/driver_button/proc/launch_sequence() - active = 1 - icon_state = "launcheract" + active = TRUE + update_icon(UPDATE_ICON_STATE) if(logic_connect) if(!radio_connection) //can't output without this @@ -145,8 +149,8 @@ rearm() /obj/machinery/driver_button/proc/rearm() - icon_state = "launcherbtt" active = FALSE + update_icon(UPDATE_ICON_STATE) ////////////////////////////////////// // Ignition Switch // @@ -158,8 +162,8 @@ icon_state = "launcherbtt" desc = "A remote control switch for a mounted igniter." var/id = null - var/active = 0 - anchored = 1.0 + var/active = FALSE + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 4 @@ -181,8 +185,8 @@ use_power(5) - active = 1 - icon_state = "launcheract" + active = TRUE + update_icon(UPDATE_ICON_STATE) for(var/obj/machinery/sparker/M in GLOB.machines) if(M.id == id) @@ -197,5 +201,10 @@ sleep(50) - icon_state = "launcherbtt" - active = 0 + active = FALSE + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/ignition_switch/update_icon_state() + icon_state = active ? "launcheract" : "launcherbtt" + diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 6a7416df3f5..ecf1df39b62 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -2,6 +2,7 @@ name = "security camera" desc = "It's used to monitor rooms." icon = 'icons/obj/machines/monitors.dmi' + blocks_emissive = EMISSIVE_BLOCK_GENERIC icon_state = "camera" use_power = ACTIVE_POWER_USE idle_power_usage = 5 @@ -39,8 +40,8 @@ wires = new(src) assembly = new(src) assembly.state = 4 - assembly.anchored = 1 - assembly.update_icon() + assembly.anchored = TRUE + assembly.update_icon(UPDATE_ICON_STATE) GLOB.cameranet.cameras += src if(networks) @@ -82,15 +83,14 @@ return if(!isEmpProof()) if(prob(150/severity)) - update_icon() stat |= EMPED set_light(0) - update_icon() + update_icon(UPDATE_ICON_STATE) GLOB.cameranet.removeCamera(src) - addtimer(CALLBACK(src, PROC_REF(triggerCameraAlarm)), 10 SECONDS, TIMER_UNIQUE | TIMER_DELETE_ME) - addtimer(CALLBACK(src, PROC_REF(restore_from_emp)), 90 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) + addtimer(CALLBACK(src, PROC_REF(triggerCameraAlarm)), 10 SECONDS, TIMER_UNIQUE|TIMER_DELETE_ME) + addtimer(CALLBACK(src, PROC_REF(restore_from_emp)), 90 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_DELETE_ME) for(var/mob/M in GLOB.player_list) if(M.client && M.client.eye == src) @@ -102,7 +102,7 @@ /obj/machinery/camera/proc/restore_from_emp() stat &= ~EMPED - update_icon() + update_icon(UPDATE_ICON_STATE) if(can_use()) GLOB.cameranet.addCamera(src) @@ -254,7 +254,7 @@ assembly.forceMove(drop_location()) assembly.state = 1 assembly.setDir(dir) - assembly.update_icon() + assembly.update_icon(UPDATE_ICON_STATE) assembly = null else var/obj/item/I = new /obj/item/camera_assembly(loc) @@ -262,7 +262,8 @@ new /obj/item/stack/cable_coil(loc, 2) qdel(src) -/obj/machinery/camera/update_icon() + +/obj/machinery/camera/update_icon_state() if(!status) icon_state = "[initial(icon_state)]1" else if(stat & EMPED) @@ -270,6 +271,7 @@ else icon_state = "[initial(icon_state)]" + /obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) status = !status if(can_use()) @@ -299,7 +301,7 @@ visible_message(span_danger("\The [src] [change_msg]!")) playsound(loc, toggle_sound, 100, 1) - update_icon() + update_icon(UPDATE_ICON_STATE) // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. @@ -423,8 +425,8 @@ /obj/machinery/camera/portable/Initialize(mapload) . = ..() assembly.state = 0 //These cameras are portable, and so shall be in the portable state if removed. - assembly.anchored = 0 - assembly.update_icon() + assembly.anchored = FALSE + assembly.update_icon(UPDATE_ICON_STATE) /obj/machinery/camera/portable/process() //Updates whenever the camera is moved. if(GLOB.cameranet && get_turf(src) != prev_turf) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 6370aa4351c..9ef6ebd632c 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -119,12 +119,12 @@ WRENCH_ANCHOR_TO_WALL_MESSAGE anchored = TRUE state = ASSEMBLY_WRENCHED - update_icon() + update_icon(UPDATE_ICON_STATE) auto_turn() else if(state == ASSEMBLY_WRENCHED) WRENCH_UNANCHOR_WALL_MESSAGE anchored = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) state = ASSEMBLY_UNBUILT else to_chat(user, span_warning("[src] can't fit here!")) @@ -147,7 +147,7 @@ to_chat(user, span_notice("You unweld [src] from its place.")) state = ASSEMBLY_WRENCHED -/obj/item/camera_assembly/update_icon() +/obj/item/camera_assembly/update_icon_state() if(anchored) icon_state = "camera1" else diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 1ce7b76d783..d47de7afbb2 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -3,7 +3,7 @@ desc = "It charges power cells." icon = 'icons/obj/engines_and_power/power.dmi' icon_state = "ccharger0" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 60 @@ -21,20 +21,19 @@ QDEL_NULL(charging) return ..() -/obj/machinery/cell_charger/proc/updateicon() + +/obj/machinery/cell_charger/update_icon_state() icon_state = "ccharger[charging ? 1 : 0]" - if(charging && !(stat & (BROKEN|NOPOWER))) - var/newlevel = round(charging.percent() * 4 / 100) - if(chargelevel != newlevel) - chargelevel = newlevel +/obj/machinery/cell_charger/update_overlays() + . = ..() + if(!charging || (stat & (BROKEN|NOPOWER))) + return - overlays.Cut() - overlays += "ccharger-o[newlevel]" + var/newlevel = round(charging.percent() * 4 / 100) + . += "ccharger-o[newlevel]" - else - overlays.Cut() /obj/machinery/cell_charger/examine(mob/user) . = ..() @@ -67,8 +66,8 @@ charging = I user.visible_message("[user] inserts a cell into the charger.", span_notice("You insert a cell into the charger.")) - chargelevel = -1 - updateicon() + check_level() + update_icon() else return ..() @@ -90,7 +89,7 @@ charging.update_icon() charging = null chargelevel = -1 - updateicon() + update_icon() /obj/machinery/cell_charger/attack_hand(mob/user) if(!charging) @@ -137,4 +136,13 @@ use_power(200) //this used to use CELLRATE, but CELLRATE is fucking awful. feel free to fix this properly! charging.give(175) //inefficiency. - updateicon() + if(check_level()) + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/cell_charger/proc/check_level() + var/newlevel = round(charging.percent() * 4 / 100) + if(chargelevel != newlevel) + chargelevel = newlevel + return TRUE + diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 1324085660a..d1412461175 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -53,13 +53,15 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ light_color = LIGHT_COLOR_PURE_GREEN -/obj/machinery/clonepod/power_change() - ..() + +/obj/machinery/clonepod/power_change(forced = FALSE) + ..() //we don't check return here because we also care about the BROKEN flag if(!(stat & (BROKEN|NOPOWER))) set_light(2) else set_light(0) + /obj/machinery/clonepod/biomass biomass = CLONE_BIOMASS @@ -460,7 +462,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ . = TRUE // These icon states don't really matter since we need to call update_icon() to handle panel open/closed overlays anyway. default_deconstruction_screwdriver(user, null, null, I) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/clonepod/wrench_act(mob/user, obj/item/I) . = TRUE @@ -596,13 +598,8 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ mess = TRUE update_icon() -/obj/machinery/clonepod/update_icon() - ..() - cut_overlays() - - if(panel_open) - add_overlay("panel_open") +/obj/machinery/clonepod/update_icon_state() if(occupant && !(stat & NOPOWER)) icon_state = "pod_cloning" else if(mess) @@ -610,6 +607,13 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ else icon_state = "pod_idle" + +/obj/machinery/clonepod/update_overlays() + . = ..() + if(panel_open) + . += "panel_open" + + /obj/machinery/clonepod/relaymove(mob/user) if(user.stat == CONSCIOUS) go_out() diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index b578fef4d6f..cf44d50900b 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -332,13 +332,11 @@ icon_state = "grass1" floor_tile = /obj/item/stack/tile/grass -/turf/simulated/floor/holofloor/grass/New() - ..() - spawn(1) - update_icon() +/turf/simulated/floor/holofloor/grass/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_ICON_STATE), 0.1 SECONDS) -/turf/simulated/floor/holofloor/grass/update_icon() - ..() +/turf/simulated/floor/holofloor/grass/update_icon_state() if(!(icon_state in list("grass1", "grass2", "grass3", "grass4", "sand"))) icon_state = "grass[pick("1","2","3","4")]" @@ -400,7 +398,7 @@ density = 1 layer = 3.2//Just above doors pressure_resistance = 4*ONE_ATMOSPHERE - anchored = 1.0 + anchored = TRUE flags = ON_BORDER /obj/structure/rack/holorack/has_prints() @@ -463,18 +461,22 @@ ..() item_color = pick("red","blue","green","purple") + +/obj/item/holo/esword/update_icon_state() + icon_state = active ? "sword[item_color]" : "sword0" + + /obj/item/holo/esword/attack_self(mob/living/user as mob) active = !active + update_icon(UPDATE_ICON_STATE) if(active) force = 30 - icon_state = "sword[item_color]" hitsound = "sound/weapons/blade1.ogg" w_class = WEIGHT_CLASS_BULKY playsound(user, 'sound/weapons/saberon.ogg', 20, 1) to_chat(user, span_notice("[src] is now active.")) else force = 3 - icon_state = "sword0" hitsound = "swing_hit" w_class = WEIGHT_CLASS_SMALL playsound(user, 'sound/weapons/saberoff.ogg', 20, 1) @@ -506,7 +508,7 @@ desc = "Boom, Shakalaka!" icon = 'icons/obj/basketball.dmi' icon_state = "hoop" - anchored = 1 + anchored = TRUE density = 1 pass_flags = LETPASSTHROW @@ -564,7 +566,7 @@ var/area/currentarea = null var/eventstarted = 0 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 @@ -594,7 +596,7 @@ add_fingerprint(user) ready = !ready - update_icon() + update_icon(UPDATE_ICON_STATE) var/numbuttons = 0 var/numready = 0 @@ -606,11 +608,9 @@ if(numbuttons == numready) begin_event() -/obj/machinery/readybutton/update_icon() - if(ready) - icon_state = "auth_on" - else - icon_state = "auth_off" +/obj/machinery/readybutton/update_icon_state() + icon_state = ready ? "auth_on" : "auth_off" + /obj/machinery/readybutton/proc/begin_event() eventstarted = 1 diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 0b250ef8c9d..00b06ad8c3e 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -3,7 +3,7 @@ /obj/machinery/computer/operating name = "operating computer" density = 1 - anchored = 1.0 + anchored = TRUE icon_keyboard = "med_key" icon_screen = "crew" circuit = /obj/item/circuitboard/operating diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 461383e8026..d698ed8119c 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -1,6 +1,6 @@ /obj/structure/AIcore density = 1 - anchored = 0 + anchored = FALSE name = "AI core" icon = 'icons/mob/ai.dmi' icon_state = "0" @@ -25,7 +25,7 @@ add_fingerprint(user) playsound(loc, P.usesound, 50, 1) to_chat(user, span_notice("You place the circuit board inside the frame.")) - update_icon() + update_icon(UPDATE_ICON_STATE) state = CIRCUIT_CORE circuit = P return @@ -39,7 +39,7 @@ add_fingerprint(user) to_chat(user, span_notice("You add cables to the frame.")) state = CABLED_CORE - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(user, span_warning("You need five lengths of cable to wire the AI core!")) return @@ -53,7 +53,7 @@ add_fingerprint(user) to_chat(user, span_notice("You put in the glass panel.")) state = GLASS_CORE - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(user, span_warning("You need two sheets of reinforced glass to insert them into the AI core!")) return @@ -115,7 +115,7 @@ add_fingerprint(user) brain = M to_chat(user, span_notice("You add [M.name] to the frame.")) - update_icon() + update_icon(UPDATE_ICON_STATE) return return ..() @@ -143,7 +143,7 @@ to_chat(user, span_notice("You remove the brain.")) brain.forceMove(loc) brain = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/AIcore/screwdriver_act(mob/living/user, obj/item/I) if(!(state in list(SCREWED_CORE, CIRCUIT_CORE, GLASS_CORE, AI_READY_CORE))) @@ -182,7 +182,7 @@ if(AI_READY_CORE) to_chat(user, span_notice("You disconnect the monitor.")) state = GLASS_CORE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/AIcore/wirecutter_act(mob/living/user, obj/item/I) @@ -205,7 +205,7 @@ return default_unfasten_wrench(user, I, 20) -/obj/structure/AIcore/update_icon() +/obj/structure/AIcore/update_icon_state() switch(state) if(EMPTY_CORE) icon_state = "0" diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 9b5bbe4902d..749de03db75 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -63,6 +63,9 @@ return switch(action) if("fix") + if(occupant.suiciding) + to_chat(usr, span_warning("Memory corruption detected in recovery partition, likely due to a sudden self-induced shutdown. AI is unrecoverable.")) + return if(active) // Prevent from starting a fix while fixing. to_chat(usr, span_warning("You are already fixing this AI!")) return @@ -93,22 +96,23 @@ sleep(10) active = FALSE -/obj/machinery/computer/aifixer/update_icon() - ..() + +/obj/machinery/computer/aifixer/update_overlays() + . = ..() if(stat & (NOPOWER|BROKEN)) return + + if(active) + . += "ai-fixer-on" + if(occupant) + switch(occupant.stat) + if(CONSCIOUS) + . += "ai-fixer-full" + if(DEAD) + . += "ai-fixer-404" else - var/overlay_layer = LIGHTING_LAYER+0.2 // +0.1 from the default computer overlays - if(active) - overlays += image(icon,"ai-fixer-on",overlay_layer) - if(occupant) - switch(occupant.stat) - if(0) - overlays += image(icon,"ai-fixer-full",overlay_layer) - if(2) - overlays += image(icon,"ai-fixer-404",overlay_layer) - else - overlays += image(icon,"ai-fixer-empty",overlay_layer) + . += "ai-fixer-empty" + /obj/machinery/computer/aifixer/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/aicard/card) if(!..()) diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 52e81a8e665..214415f01a0 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -83,11 +83,12 @@ minor_alarms += zone update_icon() -/obj/machinery/computer/atmos_alert/update_icon() + +/obj/machinery/computer/atmos_alert/update_icon_state() if(length(priority_alarms)) icon_screen = "alert:2" else if(length(minor_alarms)) icon_screen = "alert:1" else icon_screen = "alert:0" - ..() + diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 72da90aa7b2..ca7c63935e6 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -475,7 +475,7 @@ playsound(src, 'sound/effects/pop.ogg', 50) /obj/item/circuitboard/rdconsole/attackby(obj/item/I, mob/user, params) - if(I.GetID()) + if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) if(allowed(user)) user.visible_message(span_notice("\the [user] waves [user.p_their()] ID past the [src]'s access protocol scanner."), span_notice("You swipe your ID past the [src]'s access protocol scanner.")) var/console_choice = tgui_input_list(user, "What do you want to configure the access to?", "Access Modification", access_types) @@ -522,11 +522,43 @@ var/state = STATE_EMPTY var/obj/item/circuitboard/circuit = null + +/obj/structure/computerframe/examine(mob/user) + . = ..() + . += span_notice("It is [anchored ? "bolted to the floor" : "unbolted"].") + switch(state) + if(STATE_EMPTY) + . += span_notice("The frame is welded together, but it is missing a circuit board.") + if(STATE_CIRCUIT) + . += span_notice("A circuit board is firmly connected, but the cover is unscrewed and open.") + if(STATE_NOWIRES) + . += span_notice("The cover is screwed shut, but the frame is missing wiring.") + if(STATE_WIRES) + . += span_notice("The frame is wired, but the glass is missing.") + if(STATE_GLASS) + . += span_notice("The glass is loosely connected and needs to be screwed into place.") + if(!anchored) + . += span_notice("Alt-Click to rotate it.") + + /obj/structure/computerframe/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) drop_computer_parts() return ..() // will qdel the frame + +/obj/structure/computerframe/AltClick(mob/user) + if(user.incapacitated()) + to_chat(user, span_warning("You can't do that right now!")) + return + if(!Adjacent(user)) + return + if(anchored) + to_chat(user, span_warning("The frame is anchored to the floor!")) + return + setDir(turn(dir, 90)) + + /obj/structure/computerframe/obj_break(damage_flag) deconstruct() @@ -541,8 +573,7 @@ if(state == STATE_GLASS) new /obj/item/stack/sheet/glass(location, 2) -/obj/structure/computerframe/update_icon() - . = ..() +/obj/structure/computerframe/update_icon_state() icon_state = "comp_frame_[state]" /obj/structure/computerframe/welder_act(mob/user, obj/item/I) @@ -588,7 +619,7 @@ return I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/computerframe/screwdriver_act(mob/living/user, obj/item/I) . = TRUE @@ -600,12 +631,12 @@ to_chat(user, span_notice("You screw the circuit board into place.")) state = STATE_NOWIRES I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) if(STATE_NOWIRES) to_chat(user, span_notice("You unfasten the circuit board.")) state = STATE_CIRCUIT I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) if(STATE_GLASS) to_chat(user, span_notice("You connect the monitor.")) I.play_tool_sound(src) @@ -616,6 +647,7 @@ SC.can_order_contraband = C.contraband_enabled qdel(src) + /obj/structure/computerframe/wirecutter_act(mob/living/user, obj/item/I) . = TRUE if(!I.use_tool(src, user)) @@ -626,7 +658,8 @@ new /obj/item/stack/cable_coil(drop_location(), 5) state = STATE_NOWIRES I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/structure/computerframe/attackby(obj/item/I, mob/user, params) switch(state) @@ -648,7 +681,7 @@ state = STATE_CIRCUIT user.drop_transfer_item_to_loc(B, src) circuit = B - update_icon() + update_icon(UPDATE_ICON_STATE) return if(STATE_NOWIRES) @@ -670,7 +703,7 @@ to_chat(user, span_notice("You add cables to the frame.")) state = STATE_WIRES - update_icon() + update_icon(UPDATE_ICON_STATE) return if(STATE_WIRES) @@ -692,11 +725,11 @@ to_chat(user, span_notice("You put in the glass panel.")) state = STATE_GLASS - update_icon() + update_icon(UPDATE_ICON_STATE) return - return ..() + /obj/structure/computerframe/HONKputer name = "Bananium Computer-frame" icon = 'icons/obj/machines/HONKputer.dmi' @@ -711,10 +744,11 @@ /obj/structure/computerframe/abductor icon_state = "comp_frame_alien1" -/obj/structure/computerframe/abductor/update_icon() - . = ..() + +/obj/structure/computerframe/abductor/update_icon_state() icon_state = "comp_frame_alien[state]" + /obj/structure/computerframe/abductor/screwdriver_act(mob/living/user, obj/item/I) . = TRUE if(!I.use_tool(src, user)) @@ -725,26 +759,25 @@ to_chat(user, span_notice("You screw the circuit board into place.")) state = STATE_NOWIRES I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) if(STATE_NOWIRES) to_chat(user, span_notice("You unfasten the circuit board.")) state = STATE_CIRCUIT I.play_tool_sound(src) - update_icon() + update_icon(UPDATE_ICON_STATE) if(STATE_GLASS) to_chat(user, span_notice("You connect the monitor.")) I.play_tool_sound(src) - var/obj/machinery/computer/B = new circuit.build_path(loc) - B.abductor = TRUE - B.max_integrity = 400 - B.obj_integrity = 400 - if(B.icon_state == "computer") - B.icon_state = "aliencomputer" - B.update_icon() + var/obj/machinery/computer/computer = new circuit.build_path(loc) + computer.abductor = TRUE + computer.update_icon() + computer.max_integrity = 400 + computer.obj_integrity = 400 + computer.update_icon() if(istype(circuit, /obj/item/circuitboard/supplycomp)) - var/obj/machinery/computer/supplycomp/SC = B - var/obj/item/circuitboard/supplycomp/C = circuit - SC.can_order_contraband = C.contraband_enabled + var/obj/machinery/computer/supplycomp/supply_comp = computer + var/obj/item/circuitboard/supplycomp/supply_circuit = circuit + supply_comp.can_order_contraband = supply_circuit.contraband_enabled qdel(src) /obj/structure/computerframe/abductor/drop_computer_parts() diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index d87ca65f39f..c1887478d23 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -194,6 +194,19 @@ cam_background.icon_state = "scanline2" cam_background.fill_rect(1, 1, default_map_size, default_map_size) + + +// Other computer monitors. +/obj/machinery/computer/security/telescreen + name = "telescreen" + desc = "Used for watching camera networks." + icon_state = "telescreen_console" + icon_screen = "telescreen" + icon_keyboard = null + density = FALSE + circuit = /obj/item/circuitboard/camera/telescreen + + /obj/machinery/computer/security/telescreen/multitool_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -213,28 +226,27 @@ if("West") pixel_x = -32 -// Other computer monitors. -/obj/machinery/computer/security/telescreen - name = "telescreen" - desc = "Used for watching camera networks." - icon_state = "telescreen_console" - icon_screen = "telescreen" - icon_keyboard = null - light_range_on = 0 - density = 0 - circuit = /obj/item/circuitboard/camera/telescreen /obj/machinery/computer/security/telescreen/entertainment name = "entertainment monitor" desc = "Damn, they better have Paradise TV on these things." icon_state = "entertainment_console" - icon_screen = "entertainment" + icon_screen = "entertainment_off" light_color = "#FFEEDB" - light_range_on = 0 + light_power_on = LIGHTING_MINIMUM_POWER network = list("news") - luminosity = 0 layer = 4 //becouse of plasma glass with layer = 3 circuit = /obj/item/circuitboard/camera/telescreen/entertainment + /// Icon utilised when feeds_on is true + var/icon_screen_on = "entertainment" + /// Used to detect how many video cameras are active + var/feeds_on = 0 + + +/obj/machinery/computer/security/telescreen/entertainment/update_overlays() + icon_screen = feeds_on ? icon_screen_on : initial(icon_screen) + return ..() + /obj/machinery/computer/security/telescreen/singularity name = "Singularity Engine Telescreen" diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 19cd3110b46..8da496e8a52 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -109,6 +109,7 @@ var/eye_initialized = 0 var/visible_icon = 0 var/image/user_image = null + ai_detector_visible = FALSE // Abductors dont trigger the Ai Detector /mob/camera/aiEye/remote/Destroy() eye_user = null diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 9007b353a23..5585d22f58b 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -157,7 +157,7 @@ return call_shuttle_proc(usr, input) if(SSshuttle.emergency.timer) - post_status("shuttle") + post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) setMenuState(usr, COMM_SCREEN_MAIN) if("cancelshuttle") @@ -168,7 +168,7 @@ if(response == "Yes") cancel_call_proc(usr) if(SSshuttle.emergency.timer) - post_status("shuttle") + post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) setMenuState(usr, COMM_SCREEN_MAIN) if("messagelist") @@ -204,13 +204,13 @@ switch(display_type) if("message") display_icon = null - post_status("message", stat_msg1, stat_msg2, usr) + post_status(STATUS_DISPLAY_MESSAGE, stat_msg1, stat_msg2) if("alert") display_icon = params["alert"] - post_status("alert", params["alert"], user = usr) + post_status(STATUS_DISPLAY_ALERT, params["alert"]) else display_icon = null - post_status(params["statdisp"], user = usr) + post_status(display_type) setMenuState(usr, COMM_SCREEN_STAT) if("setmsg1") @@ -481,27 +481,23 @@ add_game_logs("has tried and failed to recall the shuttle.", user) message_admins("[ADMIN_LOOKUPFLW(user)] has tried and failed to recall the shuttle.") -/proc/post_status(command, data1, data2, mob/user = null) - var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) +/proc/post_status(mode, data1, data2) + if(usr && mode == STATUS_DISPLAY_MESSAGE) + log_and_message_admins("set status screen message: [data1] [data2]") - if(!frequency) return + for(var/obj/machinery/status_display/display as anything in GLOB.status_displays) + if(display.is_supply) + continue - var/datum/signal/status_signal = new - status_signal.transmission_method = 1 - status_signal.data["command"] = command + display.set_mode(mode) + switch(mode) + if(STATUS_DISPLAY_MESSAGE) + display.set_message(data1, data2) + if(STATUS_DISPLAY_ALERT) + display.set_picture(data1) - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - add_misc_logs(user, "STATUS: [key_name_log(user)] set status screen message: [data1] [data2]") - //message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") - if("alert") - status_signal.data["picture_state"] = data1 - - spawn(0) - frequency.post_signal(null, status_signal) + display.update() /obj/machinery/computer/communications/Destroy() diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 3451e9d0014..25871f0310a 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -2,8 +2,8 @@ name = "computer" icon = 'icons/obj/machines/computer.dmi' icon_state = "computer" - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 300 active_power_usage = 300 @@ -11,24 +11,19 @@ integrity_failure = 100 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 20) var/obj/item/circuitboard/circuit = null //if circuit==null, computer can't disassembly - var/processing = 0 var/icon_keyboard = "generic_key" var/icon_screen = "generic" - var/light_range_on = 2 - var/light_power_on = 1 - var/overlay_layer + var/light_range_on = 1 + var/light_power_on = 0.7 var/abductor = FALSE /// Are we in the middle of a flicker event? var/flickering = FALSE /// Are we forcing the icon to be represented in a no-power state? var/force_no_power_icon_state = FALSE -/obj/machinery/computer/New() - overlay_layer = layer - ..() -/obj/machinery/computer/Initialize() - ..() +/obj/machinery/computer/Initialize(mapload) + . = ..() power_change() update_icon() @@ -75,33 +70,46 @@ update_icon() flickering = FALSE -/obj/machinery/computer/update_icon() - overlays.Cut() + +/obj/machinery/computer/update_icon_state() + icon_state = abductor ? "aliencomputer" : initial(icon_state) + + +/obj/machinery/computer/update_overlays() + . = ..() + underlays.Cut() + if((stat & NOPOWER) || force_no_power_icon_state) if(icon_keyboard && abductor) - overlays += image(icon,"alien_key_off",overlay_layer) + . += "alien_key_off" else if(icon_keyboard) - overlays += image(icon,"[icon_keyboard]_off",overlay_layer) + . += "[icon_keyboard]_off" return if(stat & BROKEN) - overlays += image(icon,"[icon_state]_broken",overlay_layer) + . += "[icon_state]_broken" else - overlays += image(icon,icon_screen,overlay_layer) + . += "[icon_screen]" + if(light) + underlays += emissive_appearance(icon, "[icon_state]_lightmask") if(icon_keyboard && abductor) - overlays += image(icon, "alien_key" ,overlay_layer) + . += "alien_key" + underlays += emissive_appearance(icon, "alien_key_lightmask") else if(icon_keyboard) - overlays += image(icon, icon_keyboard ,overlay_layer) + . += "[icon_keyboard]" + underlays += emissive_appearance(icon, "[icon_keyboard]_lightmask") -/obj/machinery/computer/power_change() - ..() - update_icon() +/obj/machinery/computer/power_change(forced = FALSE) + . = ..() //we don't check parent return due to this also being contigent on the BROKEN stat flag if((stat & (BROKEN|NOPOWER))) set_light(0) else set_light(light_range_on, light_power_on) + if(.) + update_icon() + /obj/machinery/computer/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/machinery/computer/depot.dm b/code/game/machinery/computer/depot.dm index cd3c4065136..0d7f73bcf6f 100644 --- a/code/game/machinery/computer/depot.dm +++ b/code/game/machinery/computer/depot.dm @@ -378,8 +378,9 @@ Enjoy your stay. "}) -/obj/machinery/computer/syndicate_depot/syndiecomms/power_change() - . = ..() +/obj/machinery/computer/syndicate_depot/syndiecomms/power_change(forced = FALSE) + if(!..()) + return if(!security_lockout && (stat & NOPOWER)) security_lockout = TRUE raise_alert("[src] lost power.") diff --git a/code/game/machinery/computer/honkputer.dm b/code/game/machinery/computer/honkputer.dm index 57e6bd17543..026214d380a 100644 --- a/code/game/machinery/computer/honkputer.dm +++ b/code/game/machinery/computer/honkputer.dm @@ -89,29 +89,3 @@ dat += "
\[ [(src.state != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]" user << browse(dat, "window=honkputer;size=400x500") onclose(user, "honkputer") - - -/obj/machinery/computer/HONKputer/attackby(obj/I, mob/user, params) - if(istype(I, /obj/item/screwdriver) && circuit) - var/obj/item/screwdriver/S = I - playsound(src.loc, S.usesound, 50, 1) - if(do_after(user, 20 * S.toolspeed * gettoolspeedmod(user), target = src)) - var/obj/structure/computerframe/HONKputer/A = new /obj/structure/computerframe/HONKputer( src.loc ) - var/obj/item/circuitboard/M = new circuit( A ) - A.circuit = M - A.anchored = 1 - A.add_fingerprint(user) - for(var/obj/C in src) - C.loc = src.loc - if(src.stat & BROKEN) - to_chat(user, span_notice("The broken glass falls out.")) - new /obj/item/shard( src.loc ) - A.state = 4 - A.icon_state = "comp_frame_4" - else - to_chat(user, span_notice("You disconnect the monitor.")) - A.state = 5 - A.icon_state = "comp_frame_5" - qdel(src) - else - return ..() diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index bb4d5eaf9ed..2a5d7a7b3cf 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -63,14 +63,15 @@ else if(user) to_chat(user, span_notice("A no server error appears on the screen.")) -/obj/machinery/computer/message_monitor/update_icon() + +/obj/machinery/computer/message_monitor/update_icon_state() if(emag || hacking) icon_screen = hack_icon else icon_screen = normal_icon - ..() + /obj/machinery/computer/message_monitor/Initialize() ..() //Is the server isn't linked to a server, and there's a server available, default it to the first one in the list. @@ -488,22 +489,21 @@ /obj/item/paper/monitorkey - //..() name = "Monitor Decryption Key" - var/obj/machinery/message_server/server = null -/obj/item/paper/monitorkey/New() + +/obj/item/paper/monitorkey/Initialize(mapload) ..() - spawn(10) - if(GLOB.message_servers) - for(var/obj/machinery/message_server/server in GLOB.message_servers) - if(!isnull(server)) - if(!isnull(server.decryptkey)) - info = "

Daily Key Reset

\n\t
The new message monitor key is '[server.decryptkey]'.
Please keep this a secret and away from the clown.
If necessary, change the password to a more secure one." - info_links = info - overlays += "paper_words" - break + return INITIALIZE_HINT_LATELOAD + +/obj/item/paper/monitorkey/LateInitialize() + for(var/obj/machinery/message_server/server as anything in GLOB.message_servers) + if(!isnull(server.decryptkey)) + info = "

Daily Key Reset

\n\t
The new message monitor key is '[server.decryptkey]'.
Please keep this a secret and away from the clown.
If necessary, change the password to a more secure one." + info_links = info + update_icon() + break /obj/item/paper/rnd_logs_key name = "RnD logs Decryption Key" @@ -519,4 +519,5 @@ var/decryption_key = located_server.logs_decryption_key info = "

RnD logs Access key

\n\t
The new RnD logs access key is \"[decryption_key]\"." info_links = info - overlays += "paper_words" + update_icon() + diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index de9496dba94..934e2ad24f1 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -4,29 +4,40 @@ icon_screen = "mass_driver" light_color = "#555555" circuit = /obj/item/circuitboard/pod - var/list/id_tags = list() - var/list/door_only_tags = list() - var/list/synced = list() - var/list/timings = list() - var/list/times = list() - var/list/maxtimes = list() - var/list/powers = list() - var/list/loopings = list() + var/initial_set = FALSE + var/list/id_tags + var/list/door_only_tags + var/list/synced + var/list/timings + var/list/times + var/list/maxtimes + var/list/powers + var/list/loopings + var/static/list/deathsquad_teles -/obj/machinery/computer/pod/New() - ..() - spawn(5) - driver_sync() + +/obj/machinery/computer/pod/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, PROC_REF(driver_sync)), 0.5 SECONDS) /obj/machinery/computer/pod/proc/driver_sync() + initial_set = TRUE + id_tags = list() + door_only_tags = list() + synced = list() timings = list() times = list() - synced = list() - for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue + maxtimes = list() + powers = list() + loopings = list() + deathsquad_teles = list() + for(var/obj/machinery/mass_driver/driver in GLOB.machines) + if(driver.z != src.z) + continue + for(var/ident_tag in id_tags) - if((M.id_tag == ident_tag) && !(ident_tag in synced)) + if((driver.id_tag == ident_tag) && !(ident_tag in synced)) synced += ident_tag timings += ident_tag timings[ident_tag] = 0.0 @@ -39,19 +50,21 @@ loopings += ident_tag loopings[ident_tag] = 0 break - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue + + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue for(var/ident_tag in id_tags) - if((M.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags)) + if((poddoor.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags)) door_only_tags += ident_tag break - return -/obj/machinery/computer/pod/proc/solo_sync(var/ident_tag) - for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue - if((M.id_tag == ident_tag) && !(ident_tag in synced)) +/obj/machinery/computer/pod/proc/solo_sync(ident_tag) + for(var/obj/machinery/mass_driver/driver in GLOB.machines) + if(driver.z != src.z) + continue + if((driver.id_tag == ident_tag) && !(ident_tag in synced)) synced += ident_tag timings += ident_tag timings[ident_tag] = 0.0 @@ -64,48 +77,50 @@ loopings += ident_tag loopings[ident_tag] = 0 break + if(!(ident_tag in synced)) - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if((M.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags)) + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if((poddoor.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags)) door_only_tags += ident_tag break - return - -/obj/machinery/computer/pod/proc/launch_sequence(var/ident_tag) +/obj/machinery/computer/pod/proc/launch_sequence(ident_tag) if(stat & (NOPOWER|BROKEN)) return - var/anydriver = 0 + + var/anydriver = FALSE for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue + if(M.z != src.z) + continue if(M.id_tag == ident_tag) - anydriver = 1 + anydriver = TRUE + if(!anydriver) visible_message("Cannot locate any mass driver of that ID. Cancelling firing sequence!") return - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - spawn() - M.open() - sleep(20) + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if(poddoor.id_tag == ident_tag) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, open)) + sleep(2 SECONDS) + for(var/obj/machinery/mass_driver/driver in GLOB.machines) + if(driver.z != src.z) + continue + if(driver.id_tag == ident_tag) + driver.drive() - for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - M.drive() - - sleep(50) - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - spawn() - M.close() - return + sleep(5 SECONDS) + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if(poddoor.id_tag == ident_tag) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, close)) /obj/machinery/computer/pod/attack_ai(var/mob/user as mob) @@ -161,15 +176,14 @@ return /obj/machinery/computer/pod/process() - if(!..()) + if(!..() || !initial_set) return for(var/ident_tag in id_tags) if(timings[ident_tag]) if(times[ident_tag] > 0) times[ident_tag] = round(times[ident_tag]) - 1 else - spawn() - launch_sequence(ident_tag) + INVOKE_ASYNC(src, PROC_REF(launch_sequence), ident_tag) if(loopings[ident_tag]) times[ident_tag] = maxtimes[ident_tag] else @@ -178,7 +192,6 @@ else times[ident_tag] = maxtimes[ident_tag] updateDialog() - return /obj/machinery/computer/pod/Topic(href, href_list) @@ -213,8 +226,7 @@ if(href_list["massfire"]) for(var/ident_tag in synced) - spawn() - launch_sequence(ident_tag) + INVOKE_ASYNC(src, PROC_REF(launch_sequence), ident_tag) if(href_list["power"]) var/ident_tag = href_list["driver"] var/t = text2num(href_list["power"]) @@ -240,14 +252,14 @@ maxtimes[ident_tag] = min(max(round(maxtimes[ident_tag]), 0), 120) if(href_list["door"]) var/ident_tag = href_list["driver"] - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - spawn() - if(M.density) - M.open() - else - M.close() + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if(poddoor.id_tag == ident_tag) + if(poddoor.density) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, open)) + else + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, close)) if(href_list["rename"]) var/new_title = input("Enter a new title", "[name]", "[name]") if(new_title) @@ -291,77 +303,105 @@ var/teleporter_dest = 0 circuit = /obj/item/circuitboard/pod/deathsquad -/obj/machinery/computer/pod/deathsquad/launch_sequence(var/ident_tag) + +/obj/machinery/computer/pod/deathsquad/launch_sequence(ident_tag) if(stat & (NOPOWER|BROKEN)) return - var/anydriver = 0 + + var/anydriver = FALSE for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue + if(M.z != src.z) + continue if(M.id_tag == ident_tag) - anydriver = 1 + anydriver = TRUE + if(!anydriver) visible_message("Cannot locate any mass driver of that ID. Cancelling firing sequence!") return - var/spawn_marauder[] = new() - for(var/thing in GLOB.landmarks_list) - var/obj/effect/landmark/L = thing - if(L.name == "Marauder Entry") - spawn_marauder.Add(L) - for(var/thing in GLOB.landmarks_list) - var/obj/effect/landmark/L = thing - if(L.name == "Marauder Exit") - var/obj/effect/portal/P = new(L.loc, pick(spawn_marauder)) - P.invisibility = INVISIBILITY_ABSTRACT//So it is not seen by anyone. - P.failchance = 0//So it has no fail chance when teleporting. - P.can_mecha_pass = TRUE - spawn_marauder.Remove(P.target) - - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - spawn() - M.open() - sleep(20) - - for(var/obj/machinery/mass_driver/M in GLOB.machines) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - M.drive() - - sleep(50) - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(M.z != src.z) continue - if(M.id_tag == ident_tag) - spawn() - M.close() - - for(var/obj/structure/deathsquad_tele/D in world) - if(D.z != src.z) continue - if(D.id_tag == ident_tag) - D.icon_state = "tele0" - D.density = 0 - - return + var/list/spawn_marauder = list() + for(var/obj/effect/landmark/landmark as anything in GLOB.landmarks_list) + if(landmark.name == "Marauder Entry") + spawn_marauder.Add(landmark) + + for(var/obj/effect/landmark/landmark as anything in GLOB.landmarks_list) + if(landmark.name == "Marauder Exit") + var/obj/effect/landmark/target_landmark = pick_n_take(spawn_marauder) + var/obj/effect/portal/portal = new(landmark.loc, target_landmark.loc) + portal.invisibility = INVISIBILITY_ABSTRACT //So it is not seen by anyone. + portal.failchance = 0 //So it has no fail chance when teleporting. + portal.can_mecha_pass = TRUE + + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if(poddoor.id_tag == ident_tag) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, open)) + + sleep(2 SECONDS) + for(var/obj/machinery/mass_driver/driver in GLOB.machines) + if(driver.z != src.z) + continue + if(driver.id_tag == ident_tag) + driver.drive() + + sleep(5 SECONDS) + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(poddoor.z != src.z) + continue + if(poddoor.id_tag == ident_tag) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, close)) + + for(var/obj/structure/deathsquad_tele/tele in GLOB.deathsquad_teles) + if(tele.z != src.z) + continue + if(tele.id_tag == ident_tag) + tele.working = TRUE + tele.update_icon(UPDATE_ICON_STATE) + + +GLOBAL_LIST_EMPTY(deathsquad_teles) /obj/structure/deathsquad_tele name = "Mech Teleporter" - density = 0 - anchored = 1 + density = TRUE + anchored = TRUE icon = 'icons/obj/stationobjs.dmi' icon_state = "tele0" var/ztarget = 0 var/id_tag = "" + var/working = FALSE + + +/obj/structure/deathsquad_tele/Initialize(mapload) + . = ..() + GLOB.deathsquad_teles += src + + +/obj/structure/deathsquad_tele/Destroy() + GLOB.deathsquad_teles -= src + return ..() + + +/obj/structure/deathsquad_tele/update_icon_state() + icon_state = "tele[working]" /obj/structure/deathsquad_tele/Bumped(atom/movable/moving_atom) - if(!ztarget) return ..() - var/y = moving_atom.y - spawn() - moving_atom.z = ztarget - moving_atom.y = y - moving_atom.x = world.maxx - TRANSITIONEDGE - 2 - moving_atom.dir = 8 - var/atom/target = get_edge_target_turf(moving_atom, moving_atom.dir) - moving_atom.throw_at(target, 50, 1) - return + if(!ztarget || !working) + return ..() + + INVOKE_ASYNC(src, PROC_REF(async_bump_effect), moving_atom) + + +/obj/structure/deathsquad_tele/proc/async_bump_effect(atom/movable/moving_atom) + if(QDELETED(moving_atom)) + return + + moving_atom.z = ztarget + moving_atom.y = moving_atom.y + moving_atom.x = world.maxx - TRANSITIONEDGE - 2 + moving_atom.dir = 8 + var/atom/target = get_edge_target_turf(moving_atom, moving_atom.dir) + moving_atom.throw_at(target, 50, 1) + diff --git a/code/game/machinery/computer/power.dm b/code/game/machinery/computer/power.dm index c8e7dae6b74..b0b6b761c9f 100644 --- a/code/game/machinery/computer/power.dm +++ b/code/game/machinery/computer/power.dm @@ -47,8 +47,8 @@ QDEL_NULL(power_monitor) return ..() -/obj/machinery/computer/monitor/power_change() - ..() +/obj/machinery/computer/monitor/power_change(forced = FALSE) + . = ..() if(is_secret_monitor) return if(!(stat & (NOPOWER|BROKEN))) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 82241309b82..073bd226ea2 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -76,7 +76,7 @@ return update_icon() -/obj/machinery/computer/station_alert/update_icon() +/obj/machinery/computer/station_alert/update_icon_state() var/active_alarms = FALSE var/list/list/temp_alarm_list = SSalarm.alarms.Copy() for(var/cat in temp_alarm_list) diff --git a/code/game/machinery/computer/syndie_cargo.dm b/code/game/machinery/computer/syndie_cargo.dm index 68a3dcc753d..99b8a1e3fe0 100644 --- a/code/game/machinery/computer/syndie_cargo.dm +++ b/code/game/machinery/computer/syndie_cargo.dm @@ -109,11 +109,11 @@ GLOBAL_LIST_INIT(data_storages, list()) //list of all cargo console data storage if(istype(crate, /obj/structure/closet/crate)) var/obj/structure/closet/crate/CR = crate CR.manifest = slip - CR.update_icon() + CR.update_icon(UPDATE_OVERLAYS) if(istype(crate, /obj/structure/largecrate)) var/obj/structure/largecrate/LC = crate LC.manifest = slip - LC.update_icon() + LC.update_icon(UPDATE_OVERLAYS) /*************************** diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 4583134eab8..c0d9b637c5d 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -1,20 +1,23 @@ +// Construction | Deconstruction +#define STATE_EMPTY 1 // Add wires | Wrench to destroy +#define STATE_WIRED 2 // Add cicuit / Wrench to unchor/unanchor | Remove wires with wirecutters +#define STATE_COMPONENTS 3 // Add components / Wrench to unchor/unanchor | Remove circuit/components with crowbar + /obj/machinery/constructable_frame //Made into a seperate type to make future revisions easier. name = "machine frame" icon = 'icons/obj/stock_parts.dmi' icon_state = "box_0" - density = 1 + density = TRUE anchored = TRUE use_power = NO_POWER_USE max_integrity = 250 - var/obj/item/circuitboard/circuit = null - var/list/components = null - var/list/req_components = null - var/list/req_component_names = null // user-friendly names of components - var/state = 1 + var/obj/item/circuitboard/circuit + var/list/components + var/list/req_components + /// User-friendly names of components + var/list/req_component_names + var/state = STATE_EMPTY - // For pods - var/list/connected_parts = list() - var/pattern_idx=0 /obj/machinery/constructable_frame/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) @@ -26,21 +29,18 @@ circuit = null return ..() + /obj/machinery/constructable_frame/obj_break(damage_flag) deconstruct() -// unfortunately, we have to instance the objects really quickly to get the names -// fortunately, this is only called once when the board is added and the items are immediately GC'd -// and none of the parts do much in their constructors -/obj/machinery/constructable_frame/proc/update_namelist() - if(!req_components) - return - req_component_names = new() - for(var/tname in req_components) - var/path = tname - var/obj/O = new path() - req_component_names[tname] = O.name +/obj/machinery/constructable_frame/proc/update_lists(list/circuit_components) + req_components = circuit_components.Copy() + components = list() + req_component_names = list() + for(var/atom/path as anything in req_components) + req_component_names[path] = initial(path.name) + /obj/machinery/constructable_frame/proc/get_req_components_amt() var/amt = 0 @@ -48,145 +48,212 @@ amt += req_components[path] return amt -// update description of required components remaining -/obj/machinery/constructable_frame/proc/update_req_desc() + +/obj/machinery/constructable_frame/proc/get_req_desc() + . = "" + if(!req_components || !req_component_names) return - var/hasContent = 0 - desc = "Requires" - for(var/i = 1 to req_components.len) + var/hasContent = FALSE + var/components_len = length(req_components) + . = "Required components:" + for(var/i = 1 to components_len) var/tname = req_components[i] var/amt = req_components[tname] - if(amt == 0) + if(!amt) continue - var/use_and = i == req_components.len - desc += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" - hasContent = 1 + var/use_and = (i == components_len) + . += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" + hasContent = TRUE - if(!hasContent) - desc = "Does not require any more components." + if(hasContent) + . += "." else - desc += "." + . = span_notice("Does not require any more components.") -/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/P, mob/user, params) + +/obj/machinery/constructable_frame/machine_frame/examine(mob/user) + . = ..() + . += span_notice("It is [anchored ? "bolted to the floor" : "unbolted"].") switch(state) - if(1) - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = P - if(C.get_amount() >= 5) - playsound(src.loc, C.usesound, 50, 1) - to_chat(user, span_notice("You start to add cables to the frame.")) - if(do_after(user, 20 * C.toolspeed * gettoolspeedmod(user), target = src)) - if(state == 1 && C.use(5)) - add_fingerprint(user) - to_chat(user, span_notice("You add cables to the frame.")) - state = 2 - icon_state = "box_1" - else - to_chat(user, span_warning("At some point during construction you lost some cable. Make sure you have five lengths before trying again.")) - return - else - to_chat(user, span_warning("You need five lengths of cable to wire the frame.")) - return + if(STATE_EMPTY) + . += span_notice("The frame is constructed, but it is missing a wiring.") + if(STATE_WIRED) + . += span_notice("The frame is wired, but it is missing a circuit board") + if(STATE_COMPONENTS) + var/required = get_req_desc() + if(required) + . += required - if(istype(P, /obj/item/wrench)) - playsound(src.loc, P.usesound, 75, 1) - to_chat(user, span_notice("You dismantle the frame.")) - deconstruct(TRUE) - return - if(2) - if(istype(P, /obj/item/circuitboard)) - var/obj/item/circuitboard/B = P - if(B.board_type == "machine") - add_fingerprint(user) - playsound(src.loc, B.usesound, 50, 1) - to_chat(user, span_notice("You add the circuit board to the frame.")) - circuit = P - user.drop_transfer_item_to_loc(P, src) - name += " ([B.board_name])" - icon_state = "box_2" - state = 3 - components = list() - req_components = circuit.req_components.Copy() - update_namelist() - update_req_desc() - else - to_chat(user, span_danger("This frame does not accept circuit boards of this type!")) - return - if(istype(P, /obj/item/wirecutters)) - add_fingerprint(user) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, span_notice("You remove the cables.")) - state = 1 - icon_state = "box_0" - new /obj/item/stack/cable_coil(src.loc, 5) + +/obj/machinery/constructable_frame/machine_frame/update_icon_state() + switch(state) + if(STATE_EMPTY) + icon_state = "box_0" + if(STATE_WIRED) + icon_state = "box_1" + if(STATE_COMPONENTS) + icon_state = "box_2" + + +/obj/machinery/constructable_frame/machine_frame/wrench_act(mob/living/user, obj/item/I) + . = TRUE + add_fingerprint(user) + if(!I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume)) + return . + + if(state == STATE_EMPTY) + deconstruct(TRUE) + to_chat(user, span_notice("You dismantle the frame.")) + return . + + if(anchored) + anchored = FALSE + WRENCH_UNANCHOR_MESSAGE + return . + + if(isinspace()) + to_chat(user, span_warning("You cannot tightens the bolts in space!")) + return . + + anchored = TRUE + WRENCH_ANCHOR_MESSAGE + + +/obj/machinery/constructable_frame/machine_frame/wirecutter_act(mob/living/user, obj/item/I) + . = TRUE + add_fingerprint(user) + if(state != STATE_WIRED) + return . + + if(!I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume)) + return . + + state = STATE_EMPTY + WIRECUTTER_SNIP_MESSAGE + update_icon(UPDATE_ICON_STATE) + new /obj/item/stack/cable_coil(loc, 5) + + +/obj/machinery/constructable_frame/machine_frame/crowbar_act(mob/living/user, obj/item/I) + . = TRUE + add_fingerprint(user) + if(state != STATE_COMPONENTS) + return . + + if(!I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume)) + return . + + state = STATE_WIRED + circuit.forceMove(loc) + circuit = null + + if(length(components)) + to_chat(user, span_notice("You remove the circuit board and other components.")) + for(var/obj/item/component in components) + component.forceMove(loc) + else + to_chat(user, span_notice("You remove the circuit board.")) + + name = initial(name) + desc = initial(desc) + req_components = null + components = null + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/constructable_frame/machine_frame/screwdriver_act(mob/living/user, obj/item/I) + . = TRUE + add_fingerprint(user) + if(state != STATE_COMPONENTS) + return . + + var/component_check = TRUE + for(var/component in req_components) + if(req_components[component] > 0) + component_check = FALSE + break + + if(!component_check) + to_chat(user, span_warning("Machine frame requires more components!")) + return . + + if(!I.use_tool(src, user, 5 SECONDS, volume = I.tool_volume)) + return . + + to_chat(user, span_notice("You finish the construction.")) + var/obj/machinery/new_machine = new circuit.build_path(loc) + new_machine.on_construction() + for(var/obj/component in new_machine.component_parts) + qdel(component) + new_machine.component_parts = list() + for(var/obj/component in src) + component.loc = null + new_machine.component_parts += component + circuit.loc = null + new_machine.RefreshParts() + transfer_fingerprints_to(new_machine) + qdel(src) + + +/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/I, mob/user, params) + if(user.a_intent == INTENT_HARM) + return ..() + + add_fingerprint(user) + + switch(state) + if(STATE_EMPTY) + if(!iscoil(I)) + return ..() + + var/obj/item/stack/cable_coil/coil = I + if(coil.get_amount() < 5) + to_chat(user, span_warning("You need five lengths of cable to wire the frame.")) return - if(istype(P, /obj/item/wrench)) - add_fingerprint(user) - playsound(src.loc, P.usesound, 75, 1) - if(!anchored && !isinspace()) - anchored = TRUE - WRENCH_ANCHOR_MESSAGE - else if(anchored) - anchored = FALSE - WRENCH_UNANCHOR_MESSAGE + + playsound(loc, coil.usesound, 50, TRUE) + to_chat(user, span_notice("You start to add cables to the frame.")) + if(!do_after(user, 2 SECONDS * coil.toolspeed * gettoolspeedmod(user), target = src) || state != STATE_EMPTY) return - if(3) - if(istype(P, /obj/item/crowbar)) - add_fingerprint(user) - playsound(src.loc, P.usesound, 50, 1) - state = 2 - circuit.loc = src.loc - circuit = null - if(components.len == 0) - to_chat(user, span_notice("You remove the circuit board.")) - else - to_chat(user, span_notice("You remove the circuit board and other components.")) - for(var/obj/item/I in components) - I.loc = src.loc - name = initial(name) - desc = initial(desc) - req_components = null - components = null - icon_state = "box_1" + + if(!coil.use(5)) + to_chat(user, span_warning("At some point during construction you lost some cable. Make sure you have five lengths before trying again.")) return - if(istype(P, /obj/item/wrench)) - add_fingerprint(user) - playsound(src.loc, P.usesound, 75, 1) - if(!anchored && !isinspace()) - anchored = TRUE - WRENCH_ANCHOR_MESSAGE - else if(anchored) - anchored = FALSE - WRENCH_UNANCHOR_MESSAGE + state = STATE_WIRED + update_icon(UPDATE_ICON_STATE) + to_chat(user, span_notice("You add cables to the frame.")) + + if(STATE_WIRED) + if(!istype(I, /obj/item/circuitboard)) + return ..() + + var/obj/item/circuitboard/new_circuit = I + if(new_circuit.board_type != "machine") + to_chat(user, span_warning("This frame does not accept circuit boards of this type!")) return - if(istype(P, /obj/item/screwdriver)) - var/component_check = 1 - for(var/R in req_components) - if(req_components[R] > 0) - component_check = 0 - break - if(component_check) - playsound(src.loc, P.usesound, 50, 1) - var/obj/machinery/new_machine = new src.circuit.build_path(src.loc) - new_machine.on_construction() - for(var/obj/O in new_machine.component_parts) - qdel(O) - new_machine.component_parts = list() - for(var/obj/O in src) - O.loc = null - new_machine.component_parts += O - circuit.loc = null - new_machine.RefreshParts() - transfer_fingerprints_to(new_machine) - qdel(src) + if(!user.drop_transfer_item_to_loc(new_circuit, src)) + to_chat(user, span_warning("[new_circuit] is stuck to you and cannot be placed into [src]!")) return - if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) - var/obj/item/storage/part_replacer/replacer = P + state = STATE_COMPONENTS + circuit = new_circuit + name += " ([new_circuit.board_name])" + if(length(circuit.req_components)) + update_lists(circuit.req_components) + else + stack_trace("Circuit without req_components list, placed in [src].") + playsound(loc, new_circuit.usesound, 50, TRUE) + to_chat(user, span_notice("You add the circuit board to the frame.")) + update_icon(UPDATE_ICON_STATE) + + if(STATE_COMPONENTS) + + if(istype(I, /obj/item/storage/part_replacer) && length(I.contents) && get_req_components_amt()) + var/obj/item/storage/part_replacer/replacer = I var/list/added_components = list() var/list/part_list = list() @@ -206,42 +273,40 @@ components += part to_chat(user, span_notice("[part.name] applied.")) replacer.play_rped_sound() - - update_req_desc() return - if(istype(P, /obj/item)) - var/success - for(var/I in req_components) - if(istype(P, I) && (req_components[I] > 0) && (!(P.flags & NODROP) || istype(P, /obj/item/stack))) - add_fingerprint(user) - success=1 - playsound(src.loc, P.usesound, 50, 1) - if(istype(P, /obj/item/stack)) - var/obj/item/stack/S = P - var/camt = min(S.get_amount(), req_components[I]) - var/obj/item/stack/NS - if (S.is_cyborg && S.cyborg_construction_stack) - NS = new S.cyborg_construction_stack(src, camt) + if(isitem(I)) + var/success = FALSE + for(var/path in req_components) + var/is_stack = isstack(I) + if(istype(I, path) && (req_components[path] > 0) && (!(I.flags & NODROP) || is_stack)) + success = TRUE + playsound(loc, I.usesound, 50, TRUE) + if(is_stack) + var/obj/item/stack/stack = I + var/camt = min(stack.get_amount(), req_components[path]) + var/obj/item/stack/new_stack + if(stack.is_cyborg && stack.cyborg_construction_stack) + new_stack = new stack.cyborg_construction_stack(src, camt) else - NS = new P.type(src, camt) - NS.update_icon() - S.use(camt) - components += NS - req_components[I] -= camt - update_req_desc() + new_stack = new stack.type(src, camt) + new_stack.update_icon() + stack.use(camt) + components += new_stack + req_components[path] -= camt break - user.drop_transfer_item_to_loc(P, src) - components += P - req_components[I]-- - update_req_desc() - return 1 + user.drop_transfer_item_to_loc(I, src) + components += I + req_components[path]-- + break + if(!success) - to_chat(user, span_danger("You cannot add that to the machine!")) - return 0 - return - if(user.a_intent == INTENT_HARM) - return ..() + to_chat(user, span_warning("You cannot add that to the machine!")) + + +#undef STATE_EMPTY +#undef STATE_WIRED +#undef STATE_COMPONENTS //Machine Frame Circuit Boards @@ -376,7 +441,7 @@ to destroy them and players will be able to make replacements. /obj/item/stack/sheet/glass = 1) /obj/item/circuitboard/thermomachine/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) if(build_path == /obj/machinery/atmospherics/unary/cold_sink/freezer) build_path = /obj/machinery/atmospherics/unary/heat_reservoir/heater board_name = "Heater" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index f5c148e8dc0..e351c09ee86 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -1,5 +1,7 @@ #define AUTO_EJECT_DEAD (1<<0) #define AUTO_EJECT_HEALTHY (1<<1) +#define OCCUPANT_PIXEL_BOUNCE_HIGH 28 +#define OCCUPANT_PIXEL_BOUNCE_LOW 22 /obj/machinery/atmospherics/unary/cryo_cell name = "криокапсула" @@ -7,19 +9,21 @@ icon = 'icons/obj/machines/cryogenics.dmi' icon_state = "pod0" density = 1 - anchored = 1.0 + anchored = TRUE layer = ABOVE_WINDOW_LAYER plane = GAME_PLANE resistance_flags = null interact_offline = 1 max_integrity = 350 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30) - var/on = FALSE + on = FALSE var/temperature_archived - var/mob/living/carbon/occupant = null - var/obj/item/reagent_containers/glass/beaker = null + var/mob/living/carbon/occupant + /// A separate effect for the occupant, as you can't animate overlays reliably and constantly removing and adding overlays is spamming the subsystem. + var/obj/effect/occupant_overlay + var/obj/item/reagent_containers/glass/beaker //if you don't want to dupe reagents - var/list/reagents_blacklist = list( + var/static/list/reagents_blacklist = list( "stimulants" ) /// Holds two bitflags, AUTO_EJECT_DEAD and AUTO_EJECT_HEALTHY. Used to determine if the cryo cell will auto-eject dead and/or completely health patients. @@ -34,12 +38,26 @@ light_color = LIGHT_COLOR_WHITE -/obj/machinery/atmospherics/unary/cryo_cell/power_change() + +/obj/machinery/atmospherics/unary/cryo_cell/power_change(forced = FALSE) ..() - if(!(stat & (BROKEN|NOPOWER))) - set_light(2) - else + if(stat & (BROKEN|NOPOWER)) set_light(0) + else + set_light(2) + + +/obj/machinery/atmospherics/unary/cryo_cell/examine(mob/user) + . = ..() + if(occupant) + if(occupant.is_dead()) + . += span_warning("You see [occupant.name] inside. [occupant.p_they(TRUE)] [occupant.p_are()] dead!") + else + . += span_notice("You see [occupant.name] inside.") + . += span_notice("The Cryogenic cell chamber is effective at treating those with genetic damage, but all other damage types at a moderate rate.") + . += span_notice("Mostly using cryogenic chemicals, such as cryoxadone for it's medical purposes, requires that the inside of the cell be kept cool at all times. Hooking up a freezer and cooling the pipeline will do this nicely.") + . += span_info("Click-drag someone to a cell to place them in it, Alt-Click it to remove it.") + /obj/machinery/atmospherics/unary/cryo_cell/New() ..() @@ -110,7 +128,7 @@ beaker.forceMove(drop_location()) beaker = null -/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(atom/movable/O, mob/living/user) +/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(atom/movable/O, mob/living/user, params) if(O.loc == user) //no you can't pull things out of your ass return if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other @@ -129,16 +147,17 @@ return if(occupant) to_chat(user, span_boldnotice("Криокапсула уже занята!")) - return + return TRUE var/mob/living/L = O if(!istype(L) || L.buckled) return if(L.abiotic()) to_chat(user, span_danger("Субъект не должен держать в руках абиотические предметы.")) - return + return TRUE if(L.has_buckled_mobs()) //mob attached to us to_chat(user, span_warning("[L] нельзя поместить в [src], поскольку к [genderize_ru(L.gender,"его","её","его","их")] голове прилеплен слайм.")) - return + return TRUE + . = TRUE if(put_mob(L)) add_fingerprint(user) if(L == user) @@ -338,59 +357,40 @@ if(default_deconstruction_screwdriver(user, "pod0-o", "pod0", I)) return TRUE -/obj/machinery/atmospherics/unary/cryo_cell/update_icon() - handle_update_icon() -/obj/machinery/atmospherics/unary/cryo_cell/proc/handle_update_icon() //making another proc to avoid spam in update_icon - overlays.Cut() //empty the overlay proc, just in case +/obj/machinery/atmospherics/unary/cryo_cell/update_icon_state() icon_state = "pod[on]" //set the icon properly every time - if(!src.occupant) - overlays += "lid[on]" //if no occupant, just put the lid overlay on, and ignore the rest - return - - if(occupant) - var/mutable_appearance/pickle = mutable_appearance(occupant.icon, occupant.icon_state) - pickle.overlays = occupant.overlays - pickle.pixel_y = 22 - overlays += pickle - overlays += "lid[on]" - if(src.on && !running_bob_animation) //no bobbing if off - var/up = 0 //used to see if we are going up or down, 1 is down, 2 is up - spawn(0) // Without this, the icon update will block. The new thread will die once the occupant leaves. - running_bob_animation = 1 - while(occupant) - overlays -= "lid[on]" //have to remove the overlays first, to force an update- remove cloning pod overlay - overlays -= pickle //remove mob overlay +/obj/machinery/atmospherics/unary/cryo_cell/update_overlays() + . = ..() - switch(pickle.pixel_y) //this looks messy as fuck but it works, switch won't call itself twice + if(occupant_overlay) + QDEL_NULL(occupant_overlay) - if(23) //inbetween state, for smoothness - switch(up) //this is set later in the switch, to keep track of where the mob is supposed to go - if(2) //2 is up - pickle.pixel_y = 24 //set to highest - - if(1) //1 is down - pickle.pixel_y = 22 //set to lowest + if(!occupant) + . += "lid[on]" //if no occupant, just put the lid overlay on, and ignore the rest + return - if(22) //mob is at it's lowest - pickle.pixel_y = 23 //set to inbetween - up = 2 //have to go up + if(occupant) + occupant_overlay = new(get_turf(src)) + occupant_overlay.icon = occupant.icon + occupant_overlay.icon_state = occupant.icon_state + occupant_overlay.overlays = occupant.overlays + occupant_overlay.pixel_y = OCCUPANT_PIXEL_BOUNCE_LOW + occupant_overlay.layer = layer + 0.01 - if(24) //mob is at it's highest - pickle.pixel_y = 23 //set to inbetween - up = 1 //have to go down + if(on) + animate(occupant_overlay, time = 3 SECONDS, loop = -1, easing = QUAD_EASING, pixel_y = OCCUPANT_PIXEL_BOUNCE_HIGH) + animate(time = 3 SECONDS, loop = -1, easing = QUAD_EASING, pixel_y = OCCUPANT_PIXEL_BOUNCE_LOW) - overlays += pickle //re-add the mob to the icon - overlays += "lid[on]" //re-add the overlay of the pod, they are inside it, not floating + . += mutable_appearance(icon = icon, icon_state = "lid[on]", layer = occupant_overlay.layer + 0.01) - sleep(7) //don't want to jiggle violently, just slowly bob - running_bob_animation = 0 /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles() < 10) return + if(occupant) if(occupant.bodytemperature < T0C) var/stun_time = (max(5 / efficiency, (1 / occupant.bodytemperature) * 2000/efficiency)) STATUS_EFFECT_CONSTANT @@ -416,6 +416,7 @@ if(next_trans == 17) next_trans = 0 + /obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents() if(!occupant) return @@ -442,7 +443,7 @@ if(occupant.bodytemperature < 261 && occupant.bodytemperature >= 70) //Patch by Aranclanos to stop people from taking burn damage after being ejected occupant.bodytemperature = 261 occupant = null - update_icon() + update_icon(UPDATE_OVERLAYS) // eject trash the occupant dropped for(var/atom/movable/A in contents - component_parts - list(beaker)) A.forceMove(get_step(loc, SOUTH)) @@ -479,11 +480,18 @@ if(M.health > -100 && (M.health < 0 || M.IsSleeping())) to_chat(M, span_boldnotice("Вас окружает холодная жидкость. Кожа начинает замерзать.")) occupant = M -// M.metabslow = 1 add_fingerprint(usr) - update_icon() + update_icon(UPDATE_OVERLAYS) M.ExtinguishMob() - return 1 + return TRUE + + +/obj/machinery/atmospherics/unary/cryo_cell/AltClick(mob/living/carbon/user) + if(user && (!iscarbon(user) || user.incapacitated() || user.restrained() || !Adjacent(user))) + return + go_out() + add_fingerprint(user) + /obj/machinery/atmospherics/unary/cryo_cell/verb/move_eject() set name = "Извлечь пациента" @@ -562,3 +570,6 @@ #undef AUTO_EJECT_HEALTHY #undef AUTO_EJECT_DEAD +#undef OCCUPANT_PIXEL_BOUNCE_HIGH +#undef OCCUPANT_PIXEL_BOUNCE_LOW + diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 348dbf2a6b2..87ed2ff2b0f 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -177,20 +177,23 @@ desc = "A bewildering tangle of machinery and pipes." icon = 'icons/obj/machines/cryogenic2.dmi' icon_state = "cryo_rear" - anchored = 1 + anchored = TRUE + var/orient_right = FALSE //Flips the sprite. - var/orient_right = null //Flips the sprite. /obj/structure/cryofeed/right - orient_right = 1 + orient_right = TRUE icon_state = "cryo_rear-r" + /obj/structure/cryofeed/Initialize(mapload) . = ..() - if(orient_right) - icon_state = "cryo_rear-r" - else - icon_state = "cryo_rear" + update_icon(UPDATE_ICON_STATE) + + +/obj/structure/cryofeed/update_icon_state() + icon_state = "cryo_rear[orient_right ? "-r" : ""]" + //Cryopods themselves. /obj/machinery/cryopod @@ -210,9 +213,7 @@ var/allow_occupant_types = list(/mob/living/carbon/human) var/disallow_occupant_types = list() var/syndicate = FALSE - var/mob/living/occupant = null // Person waiting to be despawned. - var/orient_right = null // Flips the sprite. // 15 minutes-ish safe period before being despawned. var/time_till_despawn = 9000 // This is reduced by 90% if a player manually enters cryo var/willing_time_divisor = 10 @@ -262,23 +263,22 @@ icon_state = "cryo_s" base_icon_state = "cryo_s-open" occupied_icon_state = "cryo_s" - dir = 8 + dir = WEST syndicate = TRUE -/obj/machinery/cryopod/New() + +/obj/machinery/cryopod/Initialize(mapload) + . = ..() announce = new /obj/item/radio/intercom(src) + announce.follow_target = src + icon_state = base_icon_state + set_light(1, 1, COLOR_LIGHT_GREEN) + find_control_computer() - if(orient_right) - icon_state = "[base_icon_state]-r" - else - icon_state = base_icon_state - ..() +/obj/machinery/cryopod/update_icon_state() + icon_state = occupant ? occupied_icon_state : base_icon_state -/obj/machinery/cryopod/Initialize() - ..() - set_light(1, 1, COLOR_LIGHT_GREEN) - find_control_computer() /obj/machinery/cryopod/proc/find_control_computer(urgent=0) var/area/A = get_area(src) @@ -434,10 +434,6 @@ announce_rank = G.fields["rank"] qdel(G) - if(orient_right) - icon_state = "[base_icon_state]-r" - else - icon_state = base_icon_state //Make an announcement and log the person entering storage + their rank var/list/crew_member = list() @@ -476,6 +472,7 @@ else occupant.ghostize(1) QDEL_NULL(occupant) + update_icon(UPDATE_ICON_STATE) name = initial(name) @@ -528,10 +525,6 @@ to_chat(user, span_notice("You stop putting [M] into the cryopod.")) return - if(orient_right) - icon_state = "[occupied_icon_state]-r" - else - icon_state = occupied_icon_state to_chat(M, span_notice("[on_enter_occupant_message]")) to_chat(M, span_boldnotice("If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")) @@ -541,7 +534,7 @@ return ..() -/obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) +/obj/machinery/cryopod/MouseDrop_T(atom/movable/O, mob/user, params) if(O.loc == user) //no you can't pull things out of your ass return @@ -561,8 +554,7 @@ return if(occupant) to_chat(user, span_boldnotice("The cryo pod is already occupied!")) - return - + return TRUE var/mob/living/L = O if(!istype(L) || L.buckled) @@ -570,30 +562,32 @@ if(L.stat == DEAD) to_chat(user, span_notice("Dead people can not be put into cryo.")) - return + return TRUE if(!L.mind) to_chat(user, span_notice("Catatonic people are not allowed into cryo.")) - return + return TRUE if(L.has_buckled_mobs()) //mob attached to us to_chat(user, span_warning("[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")) - return + return TRUE + + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/cryopod, put_in), user, L) + return TRUE +/obj/machinery/cryopod/proc/put_in(mob/user, mob/living/L) // need this proc to use INVOKE_ASYNC in other proc. You're not recommended to use that one var/willing = null //We don't want to allow people to be forced into despawning. time_till_despawn = initial(time_till_despawn) if(L.client) if(alert(L,"Would you like to enter cryosleep?",,"Yes","No") == "Yes") - if(!L) return + if(!L) + return willing = willing_time_divisor else willing = 1 - if(istype(L.loc, /obj/machinery/cryopod)) - return - if(willing) if(!Adjacent(L) && !Adjacent(user)) to_chat(user, span_boldnotice("You're not close enough to [src].")) @@ -602,18 +596,17 @@ visible_message("[user] starts climbing into the cryo pod.") else visible_message("[user] starts putting [L] into the cryo pod.") - - if(do_after(user, 20, target = L)) - if(!L) return - + if(do_after(user, 2 SECONDS, target = L)) + if(!L) + return if(occupant) - to_chat(user, span_boldnotice("\The [src] is in use.")) + to_chat(user, span_boldnotice("[src] is in use.")) return - add_fingerprint(user) take_occupant(L, willing) else to_chat(user, span_notice("You stop [L == user ? "climbing into the cryo pod." : "putting [L] into the cryo pod."]")) + /obj/machinery/cryopod/proc/take_occupant(var/mob/living/carbon/E, var/willing_factor = 1) if(occupant) return @@ -621,13 +614,10 @@ return E.forceMove(src) time_till_despawn = initial(time_till_despawn) / willing_factor - if(orient_right) - icon_state = "[occupied_icon_state]-r" - else - icon_state = occupied_icon_state to_chat(E, span_notice("[on_enter_occupant_message]")) to_chat(E, span_boldnotice("If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")) occupant = E + update_icon(UPDATE_ICON_STATE) name = "[name] ([occupant.name])" time_entered = world.time if(findtext("[E.key]","@",1,2)) @@ -653,15 +643,12 @@ to_chat(usr, "The cryopod is in use and locked!") return - if(orient_right) - icon_state = "[base_icon_state]-r" - else - icon_state = base_icon_state - //Eject any items that aren't meant to be in the pod. var/list/items = contents - if(occupant) items -= occupant - if(announce) items -= announce + if(occupant) + items -= occupant + if(announce) + items -= announce for(var/obj/item/I in items) I.forceMove(get_turf(src)) @@ -704,11 +691,6 @@ occupant = usr time_till_despawn = initial(time_till_despawn) / willing_time_divisor - if(orient_right) - icon_state = "[occupied_icon_state]-r" - else - icon_state = occupied_icon_state - to_chat(usr, span_notice("[on_enter_occupant_message]")) to_chat(usr, span_boldnotice("If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")) occupant = usr @@ -717,7 +699,6 @@ add_fingerprint(usr) name = "[name] ([usr.name])" - return /obj/machinery/cryopod/proc/go_out() if(!occupant) @@ -725,15 +706,9 @@ occupant.forceMove(get_turf(src)) occupant = null - - if(orient_right) - icon_state = "[base_icon_state]-r" - else - icon_state = base_icon_state - + update_icon(UPDATE_ICON_STATE) name = initial(name) - return //Attacks/effects. @@ -764,13 +739,11 @@ allow_occupant_types = list(/mob/living/silicon/robot) disallow_occupant_types = list() -/obj/machinery/cryopod/robot/right - orient_right = 1 - icon_state = "pod_0-r" /obj/machinery/cryopod/robot/despawn_occupant() var/mob/living/silicon/robot/R = occupant - if(!istype(R)) return ..() + if(!istype(R)) + return ..() R.contents -= R.mmi qdel(R.mmi) @@ -806,7 +779,7 @@ target_cryopod = safepick(free_cryopods) if(target_cryopod.check_occupant_allowed(person_to_cryo)) var/turf/T = get_turf(person_to_cryo) - var/obj/effect/portal/SP = new /obj/effect/portal(T, null, null, 40) + var/obj/effect/portal/SP = new /obj/effect/portal(T, null, null, 4 SECONDS, create_sparks = FALSE) SP.name = "NT SSD Teleportation Portal" target_cryopod.take_occupant(person_to_cryo, 1) return 1 diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index c8917f01419..ead58469c2c 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -71,12 +71,20 @@ WRENCH_UNANCHOR_MESSAGE playsound(src, 'sound/items/deconstruct.ogg', 50, 1) -/obj/machinery/disco/update_icon() + +/obj/machinery/disco/update_icon_state() if(active) icon_state = "disco1" else icon_state = "disco0" - ..() + + +/obj/machinery/disco/update_overlays() + . = ..() + underlays.Cut() + + if(active) + underlays += emissive_appearance(icon, "disco_lightmask") /obj/machinery/disco/attack_hand(mob/user) @@ -129,6 +137,7 @@ return active = TRUE update_icon() + set_light(1, LIGHTING_MINIMUM_POWER) //for emmisive appearance dance_setup() START_PROCESSING(SSobj, src) lights_spin() @@ -481,7 +490,8 @@ STOP_PROCESSING(SSobj, src) dance_over() playsound(src,'sound/machines/terminal_off.ogg',50,1) - icon_state = "disco0" + update_icon() + set_light(0) stop = world.time + 100 diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm index 07c3b8fdb97..f2f56ef4cac 100644 --- a/code/game/machinery/defib_mount.dm +++ b/code/game/machinery/defib_mount.dm @@ -34,10 +34,10 @@ if(building) set_pixel_offsets_from_dir(30, -30, 30, -30) -/obj/machinery/defibrillator_mount/loaded/New() //loaded subtype for mapping use - ..() +/obj/machinery/defibrillator_mount/loaded/Initialize(mapload) //loaded subtype for mapping use + . = ..() defib = new/obj/item/defibrillator/loaded(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/defibrillator_mount/Destroy() QDEL_NULL(defib) @@ -46,7 +46,7 @@ /obj/machinery/defibrillator_mount/examine(mob/user) . = ..() if(defib) - . += span_notice("There is a defib unit hooked up. Alt-click to remove it.") + . += span_info("There is a defib unit hooked up. Alt-Click to remove it.") if(GLOB.security_level >= SEC_LEVEL_RED) . += span_notice("Due to a security situation, its locking clamps can be toggled by swiping any ID.") else @@ -58,47 +58,36 @@ if(defib && defib.cell && defib.cell.charge < defib.cell.maxcharge && is_operational()) use_power(200) defib.cell.give(180) //90% efficiency, slightly better than the cell charger's 87.5% - update_icon() + update_icon(UPDATE_OVERLAYS) + -/obj/machinery/defibrillator_mount/update_icon() - cut_overlays() +/obj/machinery/defibrillator_mount/update_overlays() + . = ..() if(defib) - add_overlay("defib") + . += "defib" if(defib.powered) - add_overlay(defib.safety ? "online" : "emagged") + . += "[defib.safety ? "online" : "emagged"]" var/ratio = defib.cell.charge / defib.cell.maxcharge ratio = CEILING(ratio * 4, 1) * 25 - add_overlay("charge[ratio]") + . += "charge[ratio]" if(clamps_locked) - add_overlay("clamps") + . += "clamps" + //defib interaction -/obj/machinery/defibrillator_mount/attack_hand(mob/living/carbon/) - var/mob/living/carbon/human/user = usr +/obj/machinery/defibrillator_mount/attack_hand(mob/living/carbon/human/user = usr) if(!defib) to_chat(user, span_warning("There's no defibrillator unit loaded!")) return - var/obj/item/organ/external/temp2 = user.bodyparts_by_name[BODY_ZONE_PRECISE_R_HAND] - var/obj/item/organ/external/temp = user.bodyparts_by_name[BODY_ZONE_PRECISE_L_HAND] - - if(!temp || !temp.is_usable() && !temp2 || !temp2.is_usable()) - to_chat(user, span_warning("You can't use your hand to take out the paddles!")) - return - - if(defib.paddles.loc != defib) - to_chat(user, span_warning("[defib.paddles.loc == user ? "You are already" : "Someone else is"] holding [defib]'s paddles!")) - return - - defib.paddles.forceMove_turf() - if(!user.put_in_hands(defib.paddles, ignore_anim = FALSE)) - defib.paddles.forceMove(defib) - to_chat(user, span_warning("You need a free hand to hold the paddles!")) + if(!defib.paddles_on_defib) + to_chat(user, span_warning("[user.is_in_hands(defib.paddles) ? "You are already" : "Someone else is"] holding [defib]'s paddles!")) return + defib.dispence_paddles(user) add_fingerprint(user) - defib.paddles_on_defib = FALSE + /obj/machinery/defibrillator_mount/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/defibrillator)) @@ -109,16 +98,20 @@ to_chat(user, span_warning("[I] is stuck to your hand!")) return add_fingerprint(user) - user.visible_message(span_notice("[user] hooks up [I] to [src]!"), \ - span_notice("You press [I] into the mount, and it clicks into place.")) + user.visible_message( + span_notice("[user] hooks up [I] to [src]!"), + span_notice("You press [I] into the mount, and it clicks into place."), + ) playsound(src, 'sound/machines/click.ogg', 50, TRUE) defib = I - update_icon() + update_icon(UPDATE_OVERLAYS) return - else if(defib && I == defib.paddles) + + if(defib && I == defib.paddles) add_fingerprint(user) - user.drop_from_active_hand() + user.drop_item_ground(I) return + var/obj/item/card/id = I.GetID() if(id) if(check_access(id) || GLOB.security_level >= SEC_LEVEL_RED) //anyone can toggle the clamps in red alert! @@ -128,12 +121,14 @@ add_fingerprint(user) clamps_locked = !clamps_locked to_chat(user, span_notice("Clamps [clamps_locked ? "" : "dis"]engaged.")) - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, span_warning("Insufficient access.")) return + return ..() + /obj/machinery/defibrillator_mount/wrench_act(mob/user, obj/item/I) . = TRUE if(defib) @@ -145,18 +140,19 @@ new /obj/item/mounted/frame/defib_mount(get_turf(user)) qdel(src) + /obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/human/user) + if(!Adjacent(user)) + return if(!istype(user) || user.incapacitated()) to_chat(user, span_warning("You can't do that right now!")) return - var/obj/item/organ/external/temp2 = user.bodyparts_by_name[BODY_ZONE_PRECISE_R_HAND] - var/obj/item/organ/external/temp = user.bodyparts_by_name[BODY_ZONE_PRECISE_L_HAND] - if(!Adjacent(user)) - return if(!defib) to_chat(user, span_warning("It'd be hard to remove a defib unit from a mount that has none.")) return - if(!temp || !temp.is_usable() && !temp2 || !temp2.is_usable()) + var/obj/item/organ/external/hand_right = user.get_organ(BODY_ZONE_PRECISE_R_HAND) + var/obj/item/organ/external/hand_left = user.get_organ(BODY_ZONE_PRECISE_L_HAND) + if((!hand_right || !hand_right.is_usable()) && (!hand_left || !hand_left.is_usable())) to_chat(user, span_warning("You can't use your hand to take out the defibrillator!")) return if(clamps_locked) @@ -168,7 +164,8 @@ span_notice("You slide out [defib] from [src] and unhook the charging cables.")) playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) defib = null - update_icon() + update_icon(UPDATE_OVERLAYS) + //wallframe, for attaching the mounts easily /obj/item/mounted/frame/defib_mount diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 323af03b398..f5ea968b96b 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -3,6 +3,7 @@ desc = "A remote control-switch for a door." icon = 'icons/obj/stationobjs.dmi' icon_state = "doorctrl" + base_icon_state = "doorctrl" power_channel = ENVIRON var/id = null var/safety_z_check = TRUE @@ -20,11 +21,18 @@ var/exposedwires = FALSE var/ai_control = TRUE + var/is_animating = FALSE anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 4 + +/obj/machinery/door_control/Initialize(mapload) + . = ..() + power_change(forced = TRUE) + + /obj/machinery/door_control/attack_ai(mob/user) if(ai_control) return attack_hand(user) @@ -48,50 +56,46 @@ /obj/machinery/door_control/Initialize(mapload) . = ..() - if(!istype(id, /list)) + if(!islist(id)) id = list(id) /obj/machinery/door_control/proc/do_main_action(mob/user) if(normaldoorcontrol) - for(var/obj/machinery/door/airlock/D in GLOB.airlocks) - if(safety_z_check && D.z != z || !(D.id_tag in id)) + for(var/obj/machinery/door/airlock/airlock in GLOB.airlocks) + if(safety_z_check && airlock.z != z || !(airlock.id_tag in id)) continue if(specialfunctions & OPEN) - if(D.density) - spawn(0) - D.open() + if(airlock.density) + INVOKE_ASYNC(airlock, TYPE_PROC_REF(/obj/machinery/door, open)) else - spawn(0) - D.close() + INVOKE_ASYNC(airlock, TYPE_PROC_REF(/obj/machinery/door, close)) if(desiredstate) if(specialfunctions & IDSCAN) - D.aiDisabledIdScanner = TRUE + airlock.aiDisabledIdScanner = TRUE if(specialfunctions & BOLTS) - D.lock() + airlock.lock() if(specialfunctions & SHOCK) - D.electrify(-1) + airlock.electrify(-1) if(specialfunctions & SAFE) - D.safe = FALSE + airlock.safe = FALSE else if(specialfunctions & IDSCAN) - D.aiDisabledIdScanner = FALSE + airlock.aiDisabledIdScanner = FALSE if(specialfunctions & BOLTS) - D.unlock() + airlock.unlock() if(specialfunctions & SHOCK) - D.electrify(0) + airlock.electrify(0) if(specialfunctions & SAFE) - D.safe = TRUE + airlock.safe = TRUE else - for(var/obj/machinery/door/poddoor/M in GLOB.airlocks) - if(safety_z_check && M.z != z || !(M.id_tag in id)) + for(var/obj/machinery/door/poddoor/poddoor in GLOB.airlocks) + if(safety_z_check && poddoor.z != z || !(poddoor.id_tag in id)) continue - if(M.density) - spawn(0) - M.open() + if(poddoor.density) + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, open)) else - spawn(0) - M.close() + INVOKE_ASYNC(poddoor, TYPE_PROC_REF(/obj/machinery/door, close)) desiredstate = !desiredstate @@ -102,46 +106,86 @@ if(!allowed(user) && !user.can_advanced_admin_interact()) to_chat(user, span_warning("Access Denied.")) - flick("[initial(icon_state)]-denied",src) + flick("[base_icon_state]-denied",src) playsound(src, pick('sound/machines/button.ogg', 'sound/machines/button_alternate.ogg', 'sound/machines/button_meloboom.ogg'), 20) return use_power(5) - animate_activation() - do_main_action(user) + /obj/machinery/door_control/proc/animate_activation() - icon_state = "[initial(icon_state)]-inuse" - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 15) + if(is_animating) + return + is_animating = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(finish_animation)), 1.5 SECONDS) -/obj/machinery/door_control/power_change() - ..() - update_icon() -/obj/machinery/door_control/update_icon() +/obj/machinery/door_control/proc/finish_animation() + is_animating = FALSE + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/door_control/power_change(forced = FALSE) + if(!..()) + return if(stat & NOPOWER) - icon_state = "[initial(icon_state)]-p" + set_light(0) else - icon_state = initial(icon_state) + set_light(1, LIGHTING_MINIMUM_POWER) + update_icon() + + +/obj/machinery/door_control/update_icon_state() + if(stat & NOPOWER) + icon_state = "[base_icon_state]-p" + return + icon_state = is_animating ? "[base_icon_state]-inuse" : base_icon_state + + +/obj/machinery/door_control/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER) + return + + underlays += emissive_appearance(icon, "[base_icon_state]_lightmask") + /obj/machinery/door_control/secure //Use icon_state = "altdoorctrl" if you just want cool icon for your button on map. This button is created for Admin-zones. icon_state = "altdoorctrl" + base_icon_state = "altdoorctrl" ai_control = FALSE /obj/machinery/door_control/secure/emag_act(user) if(user) to_chat(user, span_notice("The electronic systems in this device are far too advanced for your primitive hacking peripherals.")) -// hidden mimic button +// hidden mimic button /obj/machinery/door_control/mimic icon = 'icons/obj/lighting.dmi' icon_state = "lantern" + /obj/machinery/door_control/mimic/animate_activation() - audible_message("Something clicked.", ,1) + audible_message("Something clicked.", hearing_distance = 1) + -/obj/machinery/door_control/mimic/update_icon() +/obj/machinery/door_control/mimic/update_icon_state() return + + +/obj/machinery/door_control/mimic/update_overlays() + . = list() + + +/obj/machinery/door_control/mimic/power_change(forced = FALSE) + if(powered(power_channel)) + stat &= ~NOPOWER + else + stat |= NOPOWER + diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c40549255f0..eb69b600a35 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -44,6 +44,7 @@ GLOBAL_LIST_EMPTY(airlock_overlays) +GLOBAL_LIST_EMPTY(airlock_emissive_underlays) /obj/machinery/door/airlock name = "airlock" @@ -86,14 +87,10 @@ GLOBAL_LIST_EMPTY(airlock_overlays) var/paintable = TRUE // If the airlock type can be painted with an airlock painter var/id //ID for tint controlle - var/image/old_frame_overlay //keep those in order to prevent unnecessary updating - var/image/old_filling_overlay - var/image/old_lights_overlay - var/image/old_panel_overlay - var/image/old_weld_overlay - var/image/old_sparks_overlay - var/image/old_dam_overlay - var/image/old_note_overlay + var/mutable_appearance/old_buttons_underlay + var/mutable_appearance/old_lights_underlay + var/mutable_appearance/old_damag_underlay + var/mutable_appearance/old_sparks_underlay var/doorOpen = 'sound/machines/airlock_open.ogg' var/doorClose = 'sound/machines/airlock_close.ogg' @@ -134,8 +131,8 @@ About the new airlock wires panel: /obj/machinery/door/airlock/Initialize() . = ..() - if(closeOtherId != null) - addtimer(CALLBACK(src, PROC_REF(update_other_id)), 5) + if(closeOtherId) + addtimer(CALLBACK(src, PROC_REF(update_other_id)), 0.5 SECONDS) if(glass) airlock_material = "glass" if(security_level > AIRLOCK_SECURITY_METAL) @@ -155,9 +152,9 @@ About the new airlock wires panel: damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_N /obj/machinery/door/airlock/proc/update_other_id() - for(var/obj/machinery/door/airlock/A in GLOB.airlocks) - if(A.closeOtherId == closeOtherId && A != src) - closeOther = A + for(var/obj/machinery/door/airlock/airlock in GLOB.airlocks) + if(airlock.closeOtherId == closeOtherId && airlock != src) + closeOther = airlock break /obj/machinery/door/airlock/Destroy() @@ -200,8 +197,6 @@ About the new airlock wires panel: return ..(user) -/obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user) - ..(user) /obj/machinery/door/airlock/proc/isElectrified() if(electrified_until != 0) @@ -314,22 +309,30 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/shock_user(mob/user, prob) return (!issilicon(user) && isElectrified() && shock(user, prob)) -/obj/machinery/door/airlock/update_icon(state=0, override=0) + +/obj/machinery/door/airlock/update_icon(state = NONE, override = FALSE) if(operating && !override) return - check_unres() + icon_state = density ? "closed" : "open" switch(state) - if(0) + if(NONE) if(density) state = AIRLOCK_CLOSED else state = AIRLOCK_OPEN - if(AIRLOCK_OPEN, AIRLOCK_CLOSED) if(AIRLOCK_DENY, AIRLOCK_OPENING, AIRLOCK_CLOSING, AIRLOCK_EMAG) icon_state = "nonexistenticonstate" //MADNESS + + . = ..(UPDATE_ICON_STATE) // Sent after the icon_state is changed + set_airlock_overlays(state) + +/obj/machinery/door/airlock/update_icon_state() + return + + /obj/machinery/door/airlock/proc/set_airlock_overlays(state) var/image/frame_overlay var/image/filling_overlay @@ -340,14 +343,20 @@ About the new airlock wires panel: var/image/sparks_overlay var/image/note_overlay var/notetype = note_type() + var/mutable_appearance/buttons_underlay + var/mutable_appearance/lights_underlay + var/mutable_appearance/damag_underlay + var/mutable_appearance/sparks_underlay switch(state) if(AIRLOCK_CLOSED) frame_overlay = get_airlock_overlay("closed", icon) + buttons_underlay = get_airlock_emissive_underlay("closed_lightmask", overlays_file) if(airlock_material) filling_overlay = get_airlock_overlay("[airlock_material]_closed", overlays_file) else filling_overlay = get_airlock_overlay("fill_closed", icon) if(panel_open) + buttons_underlay = null if(security_level) panel_overlay = get_airlock_overlay("panel_closed_protected", overlays_file) else @@ -356,15 +365,20 @@ About the new airlock wires panel: weld_overlay = get_airlock_overlay("welded", overlays_file) if(obj_integrity electrified_until) electrify(duration) + /obj/machinery/door/airlock/attack_alien(mob/living/carbon/alien/humanoid/user) add_fingerprint(user) if(isElectrified()) @@ -1399,7 +1437,7 @@ About the new airlock wires panel: to_chat(user, span_warning("Despite your efforts, [src] managed to resist your attempts!")) -/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason +/obj/machinery/door/airlock/power_change(forced = FALSE) //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason ..() if(stat & NOPOWER) // If we lost power, disable electrification @@ -1476,7 +1514,7 @@ About the new airlock wires panel: else ae = new/obj/item/airlock_electronics(loc) check_access() - ae.selected_accesses = req_access + ae.selected_accesses = length(req_access) ? req_access : list() ae.one_access = check_one_access else ae = electronics @@ -1490,9 +1528,13 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/note_type() //Returns a string representing the type of note pinned to this airlock if(!note) return - else if(istype(note, /obj/item/paper)) - return "note" - else if(istype(note, /obj/item/photo)) + if(istype(note, /obj/item/paper)) + var/obj/item/paper/pinned_paper = note + if(pinned_paper.info) + return "note_words" + else + return "note" + if(istype(note, /obj/item/photo)) return "photo" //Removes the current note on the door if any. Returns if a note is removed diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 65c30d7e2de..80a738c38d6 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -134,8 +134,6 @@ if(frequency) set_frequency(frequency) - update_icon() - /obj/machinery/door/airlock/New() ..() @@ -147,7 +145,7 @@ icon = 'icons/obj/machines/airlock_machines.dmi' icon_state = "airlock_sensor_off" name = "airlock sensor" - anchored = 1 + anchored = TRUE resistance_flags = FIRE_PROOF power_channel = ENVIRON @@ -160,7 +158,7 @@ var/alert = 0 var/previousPressure -/obj/machinery/airlock_sensor/update_icon() +/obj/machinery/airlock_sensor/update_icon_state() if(on) if(alert) icon_state = "airlock_sensor_alert" @@ -197,7 +195,7 @@ alert = (pressure < ONE_ATMOSPHERE*0.8) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/airlock_sensor/set_frequency(new_frequency) SSradio.remove_object(src, frequency) @@ -229,7 +227,7 @@ icon = 'icons/obj/machines/airlock_machines.dmi' icon_state = "access_button_standby" name = "access button" - anchored = 1 + anchored = TRUE power_channel = ENVIRON var/master_tag @@ -242,13 +240,13 @@ 2=Network Access */ -/obj/machinery/access_button/update_icon() +/obj/machinery/access_button/update_icon_state() if(on) icon_state = "access_button_standby" else icon_state = "access_button_off" -/obj/machinery/access_button/attack_ai(mob/user as mob) +/obj/machinery/access_button/attack_ai(mob/user) if(wires & 2) return ..(user) else diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 8a3cfcb8771..81a838fbe25 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -1,7 +1,3 @@ -#define CHARS_PER_LINE 5 -#define FONT_SIZE "5pt" -#define FONT_COLOR "#09f" -#define FONT_STYLE "Small Fonts" #define CELL_NONE "None" #define PERMABRIG_TIME 60 //MINUTES @@ -19,7 +15,7 @@ icon_state = "frame" desc = "A remote control for a door." req_access = list(ACCESS_BRIG) - anchored = 1 // can't pick it up + anchored = TRUE // can't pick it up density = 0 // can walk through it. var/id = null // id of door it controls. var/releasetime = 0 // when world.timeofday reaches it - release the prisoner @@ -43,13 +39,54 @@ var/prisoner_hasrecord = FALSE var/prisoner_time_add -/obj/machinery/door_timer/New() - GLOB.celltimers_list += src - return ..() + +/obj/machinery/door_timer/Initialize(mapload) + . = ..() + GLOB.celltimers_list += src + + Radio = new /obj/item/radio(src) + Radio.listening = 0 + Radio.config(list("Security" = 0)) + Radio.follow_target = src + + set_pixel_offsets_from_dir(32, -32, 32, -32) + + addtimer(CALLBACK(src, PROC_REF(delayed_update)), 2 SECONDS, TIMER_DELETE_ME) + /obj/machinery/door_timer/Destroy() - GLOB.celltimers_list -= src - return ..() + GLOB.celltimers_list -= src + QDEL_NULL(Radio) + targets.Cut() + prisoner = null + return ..() + + +/obj/machinery/door_timer/proc/delayed_update() + for(var/obj/machinery/door/window/brigdoor/brigdoor in GLOB.airlocks) + if(brigdoor.id == id) + targets += brigdoor + INVOKE_ASYNC(brigdoor, TYPE_PROC_REF(/obj/machinery/door, open)) + + for(var/obj/machinery/machine in GLOB.machines) + if(istype(machine, /obj/machinery/flasher)) + var/obj/machinery/flasher/flasher = machine + if(flasher.id == id) + targets += flasher + + if(istype(machine, /obj/machinery/treadmill_monitor)) + var/obj/machinery/treadmill_monitor/monitor = machine + if(monitor.id == id) + targets += monitor + + for(var/obj/structure/closet/secure_closet/brig/brig_closet in GLOB.closets) + if(brig_closet.id == id) + targets += brig_closet + + if(!length(targets)) + stat |= BROKEN + update_icon(UPDATE_OVERLAYS) + /obj/machinery/door_timer/proc/print_report() if(occupant == CELL_NONE || crimes == CELL_NONE) @@ -119,65 +156,57 @@ return atom_say("[src] beeps, \"[occupant]: [notifytext]\"") -/obj/machinery/door_timer/Initialize() - ..() - - Radio = new /obj/item/radio(src) - Radio.listening = 0 - Radio.config(list("Security" = 0)) - Radio.follow_target = src - - set_pixel_offsets_from_dir(32, -32, 32, -32) - - spawn(20) - for(var/obj/machinery/door/window/brigdoor/M in GLOB.airlocks) - if(M.id == id) - targets += M - - for(var/obj/machinery/flasher/F in GLOB.machines) - if(F.id == id) - targets += F - - for(var/obj/structure/closet/secure_closet/brig/C in world) - if(C.id == id) - targets += C - - for(var/obj/machinery/treadmill_monitor/T in GLOB.machines) - if(T.id == id) - targets += T - - if(targets.len==0) - stat |= BROKEN - update_icon() - -/obj/machinery/door_timer/Destroy() - QDEL_NULL(Radio) - targets.Cut() - prisoner = null - return ..() //Main door timer loop, if it's timing and time is >0 reduce time by 1. // if it's less than 0, open door, reset timer // update the door_timer window and the icon /obj/machinery/door_timer/process() - if(stat & (NOPOWER|BROKEN)) - return + if((stat & (NOPOWER|BROKEN))) + update_display() + return PROCESS_KILL if(timing) + if(emagged) + timer_end() + return PROCESS_KILL if(timeleft() <= 0) Radio.autosay("Timer has expired. Releasing prisoner.", name, "Security", list(z)) occupant = CELL_NONE timer_end() // open doors, reset timer, clear status screen - timing = 0 - . = PROCESS_KILL - update_icon() + return PROCESS_KILL + update_display() else timer_end() return PROCESS_KILL + +//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display +// Stolen from status_display +/obj/machinery/door_timer/proc/update_display() + update_icon(UPDATE_OVERLAYS) + + if(stat & (NOPOWER|BROKEN)) + if(maptext) + maptext = "" + return + + if(timing) + var/disp1 = id + var/timeleft = timeleft() + var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" + if(length(disp2) > DISPLAY_CHARS_PER_LINE) + disp2 = "Error" + var/new_text = {"
[uppertext(disp1)]
[uppertext(disp2)]
"} + if(maptext != new_text) + maptext = new_text + else if(maptext) + maptext = "" + + // has the door power situation changed, if so update icon. -/obj/machinery/door_timer/power_change() - ..() - update_icon() +/obj/machinery/door_timer/power_change(forced = FALSE) + if(!..()) + return + update_display() // open/closedoor checks if door_timer has power, if so it checks if the @@ -185,14 +214,16 @@ // Closes and locks doors, power check /obj/machinery/door_timer/proc/timer_start() + timing = TRUE + update_display() if(stat & (NOPOWER|BROKEN)) - return 0 + timing = FALSE + return FALSE - if(!printed) - if(!print_report()) - timing = FALSE - return FALSE + if(!printed && !print_report()) + timing = FALSE + return FALSE // Set releasetime releasetime = world.timeofday + timetoset @@ -201,28 +232,30 @@ for(var/obj/machinery/door/window/brigdoor/door in targets) if(door.density) continue - spawn(0) - door.close() + INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door, close)) - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) + for(var/obj/structure/closet/secure_closet/brig/closet in targets) + if(closet.broken) continue - if(C.opened && !C.close()) + if(closet.opened && !closet.close()) continue - C.locked = 1 - C.update_icon() + closet.locked = TRUE + closet.update_icon() - for(var/obj/machinery/treadmill_monitor/T in targets) - T.total_joules = 0 - T.on = 1 + for(var/obj/machinery/treadmill_monitor/monitor in targets) + monitor.total_joules = 0 + monitor.on = TRUE - return 1 + return TRUE // Opens and unlocks doors, power check /obj/machinery/door_timer/proc/timer_end() + timing = FALSE + update_display() + if(stat & (NOPOWER|BROKEN)) - return 0 + return FALSE // Reset vars occupant = CELL_NONE @@ -231,7 +264,7 @@ timetoset = 0 officer = CELL_NONE releasetime = 0 - printed = 0 + printed = FALSE if(prisoner) prisoner.fields["criminal"] = SEC_RECORD_STATUS_RELEASED update_all_mob_security_hud() @@ -242,20 +275,20 @@ continue INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door/window/brigdoor, open)) - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) + for(var/obj/structure/closet/secure_closet/brig/closet in targets) + if(closet.broken) continue - if(C.opened) + if(closet.opened) continue - C.locked = 0 - C.update_icon() + closet.locked = FALSE + closet.update_icon() - for(var/obj/machinery/treadmill_monitor/T in targets) - if(!T.stat) - T.redeem() - T.on = 0 + for(var/obj/machinery/treadmill_monitor/monitor in targets) + if(!monitor.stat) + monitor.redeem() + monitor.on = FALSE - return 1 + return TRUE // Check for releasetime timeleft @@ -282,6 +315,22 @@ /obj/machinery/door_timer/attack_ghost(mob/user) ui_interact(user) + +/obj/machinery/door_timer/emp_act(severity) + if((stat & (BROKEN|NOPOWER)) || emagged) + ..(severity) + return + if(timing && prob(100 / severity)) + emagged = TRUE + ..(severity) + + +/obj/machinery/door_timer/emag_act() + if((stat & (BROKEN|NOPOWER)) || emagged || !timing) + return + emagged = TRUE + + //Allows humans to use door_timer //Opens dialog window when someone clicks on door timer // Allows altering timer and the timing boolean. @@ -360,9 +409,7 @@ prisoner_name = null prisoner_charge = null prisoner_time = null - timing = TRUE timer_start() - update_icon() if("add_timer") if(timing) var/add_reason = sanitize(copytext(input(usr, "Reason:", name, "") as text|null, 1, MAX_MESSAGE_LEN)) @@ -412,74 +459,19 @@ else . = FALSE if("flash") - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - to_chat(usr, span_warning("Flash still charging.")) + for(var/obj/machinery/flasher/flasher in targets) + if(flasher.last_flash && (flasher.last_flash + 15 SECONDS) > world.time) + to_chat(usr, span_warning("Flash is still recharging.")) else - F.flash() + flasher.flash() else . = FALSE -//icon update function -// if NOPOWER, display blank -// if BROKEN, display blue screen of death icon AI uses -// if timing=true, run update display function -/obj/machinery/door_timer/update_icon() - if(stat & (NOPOWER)) - icon_state = "frame" - return - if(stat & (BROKEN)) - set_picture("ai_bsod") - return - if(timing) - var/disp1 = id - var/timeleft = timeleft() - var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" - if(length(disp2) > CHARS_PER_LINE) - disp2 = "Error" - update_display(disp1, disp2) - else - if(maptext) maptext = "" - - -// Adds an icon in case the screen is broken/off, stolen from status_display.dm -/obj/machinery/door_timer/proc/set_picture(state) - picture_state = state - overlays.Cut() - overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) - -/obj/machinery/door_timer/proc/return_time_input() - var/mins = input(usr, "Minutes", "Enter number of minutes", 0) as num - var/seconds = input(usr, "Seconds", "Enter number of seconds", 0) as num - var/totaltime = (seconds + (mins * 60)) - return totaltime - -//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display -// Stolen from status_display -/obj/machinery/door_timer/proc/update_display(line1, line2) - line1 = uppertext(line1) - line2 = uppertext(line2) - var/new_text = {"
[line1]
[line2]
"} - if(maptext != new_text) - maptext = new_text - - -//Actual string input to icon display for loop, with 5 pixel x offsets for each letter. -//Stolen from status_display -/obj/machinery/door_timer/proc/texticon(tn, px = 0, py = 0) - var/image/I = image('icons/obj/status_display.dmi', "blank") - var/len = length(tn) - - for(var/d = 1 to len) - var/char = copytext(tn, len-d+1, len-d+2) - if(char == " ") - continue - var/image/ID = image('icons/obj/status_display.dmi', icon_state=char) - ID.pixel_x = -(d-1)*5 + px - ID.pixel_y = py - I.overlays += ID - return I +/obj/machinery/door_timer/update_overlays() + . = ..() + if(!(stat & NOPOWER) && ((stat & BROKEN) || emagged)) + . += "ai_bsod" /obj/machinery/door_timer/cell_1 @@ -531,8 +523,3 @@ name = "Cell 8" id = "Cell 8" -#undef FONT_SIZE -#undef FONT_COLOR -#undef FONT_STYLE -#undef CHARS_PER_LINE -#undef CELL_NONE diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 742b85e7d2c..df810481825 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -15,7 +15,7 @@ var/closingLayer = CLOSED_DOOR_LAYER var/visible = 1 /// Is it currently in the process of opening or closing. - var/operating = FALSE + var/operating = NONE var/autoclose = 0 /// Whether the door detects things and mobs in its way and reopen or crushes them. var/safe = TRUE @@ -65,9 +65,12 @@ ..() update_dir() -/obj/machinery/door/power_change() - ..() - update_icon() + +/obj/machinery/door/power_change(forced = FALSE) + . = ..() + if(.) + update_icon() + /obj/machinery/door/proc/update_dir() if(width > 1) @@ -228,7 +231,7 @@ return if(requiresID() && (allowed(user) || user.can_advanced_admin_interact())) if(density) - if(HAS_TRAIT(src, TRAIT_CMAGGED) && !user.can_advanced_admin_interact()) + if(HAS_TRAIT(src, TRAIT_CMAGGED) && !user.can_advanced_admin_interact()) //cmag should not prevent admin intervention cmag_switch(FALSE, user) return open() @@ -236,7 +239,7 @@ if(HAS_TRAIT(src, TRAIT_CMAGGED) && !user.can_advanced_admin_interact()) return close() - return + return TRUE if(HAS_TRAIT(src, TRAIT_CMAGGED)) cmag_switch(TRUE, user) return @@ -369,11 +372,10 @@ sound_ready = FALSE addtimer(VARSET_CALLBACK(src, sound_ready, TRUE), sound_cooldown) -/obj/machinery/door/update_icon() - if(density) - icon_state = "door1" - else - icon_state = "door0" + +/obj/machinery/door/update_icon_state() + icon_state = "door[density]" + /obj/machinery/door/proc/do_animate(animation) switch(animation) @@ -395,23 +397,23 @@ if(!density) return TRUE if(operating) - return - operating = TRUE + return FALSE + operating = DOOR_OPENING do_animate("opening") - set_opacity(0) - sleep(5) + set_opacity(FALSE) + sleep(0.5 SECONDS) density = FALSE - sleep(5) + sleep(0.5 SECONDS) layer = initial(layer) update_icon() - set_opacity(0) - operating = FALSE - air_update_turf(1) + operating = NONE + air_update_turf(TRUE) update_freelook_sight() if(autoclose) autoclose_in(normalspeed ? auto_close_time : auto_close_time_dangerous) return TRUE + /obj/machinery/door/proc/close() if(density) return TRUE @@ -422,21 +424,21 @@ for(var/atom/movable/M in turf) if(M.density && M != src) //something is blocking the door if(autoclose) - autoclose_in(60) + autoclose_in(6 SECONDS) return - operating = TRUE + operating = DOOR_CLOSING do_animate("closing") layer = closingLayer - sleep(5) + sleep(0.5 SECONDS) density = TRUE - sleep(5) + sleep(0.5 SECONDS) update_icon() if(visible && !glass) - set_opacity(1) - operating = FALSE - air_update_turf(1) + set_opacity(TRUE) + operating = NONE + air_update_turf(TRUE) update_freelook_sight() if(safe) CheckForMobs() @@ -444,6 +446,7 @@ crush() return TRUE + /obj/machinery/door/proc/CheckForMobs() if(locate(/mob/living) in get_turf(src)) sleep(1) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index bc9eb38a6ad..e7fd99032e5 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -19,6 +19,7 @@ safe = FALSE layer = BELOW_OPEN_DOOR_LAYER closingLayer = CLOSED_FIREDOOR_LAYER + blocks_emissive = EMISSIVE_BLOCK_GENERIC auto_close_time = 5 SECONDS assemblytype = /obj/structure/firelock_frame armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) @@ -79,14 +80,31 @@ return ..() return 0 -/obj/machinery/door/firedoor/power_change() - if(powered(power_channel)) - stat &= ~NOPOWER - latetoggle() + +/obj/machinery/door/firedoor/proc/adjust_light() + if(stat & (NOPOWER|BROKEN)) + set_light(0) + return + if(active_alarm) + set_light(1, 0.5, COLOR_RED_LIGHT) else - stat |= NOPOWER + set_light(1, LIGHTING_MINIMUM_POWER) + +/obj/machinery/door/firedoor/extinguish_light(force = FALSE) + set_light(0) + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/door/firedoor/power_change(forced = FALSE) + . = ..() + if(!(stat & NOPOWER)) + latetoggle() + if(!.) + return + adjust_light() update_icon() + /obj/machinery/door/firedoor/attack_hand(mob/user) if(user.a_intent == INTENT_HARM && ishuman(user) && user.dna.species.obj_damage) add_fingerprint(user) @@ -166,7 +184,7 @@ return WELDER_WELD_SUCCESS_MESSAGE welded = !welded - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/door/firedoor/try_to_crowbar(obj/item/I, mob/user) if(welded || operating) @@ -204,25 +222,31 @@ flick("door_closing", src) playsound(src, 'sound/machines/firedoor.ogg', 60, 1) -/obj/machinery/door/firedoor/update_icon() - overlays.Cut() + +/obj/machinery/door/firedoor/update_icon_state() + icon_state = "door_[density ? "closed" : "open"]" + + +/obj/machinery/door/firedoor/update_overlays() + . = ..() + if(welded) + . += "welded[density ? "" : "_open"]" if(active_alarm && hasPower()) - overlays += image('icons/obj/doors/doorfire.dmi', "alarmlights") - if(density) - icon_state = "door_closed" - if(welded) - overlays += "welded" - else - icon_state = "door_open" - if(welded) - overlays += "welded_open" + if(light) + . += emissive_appearance('icons/obj/doors/doorfire.dmi', "alarmlights_lightmask") + . += image('icons/obj/doors/doorfire.dmi', "alarmlights") + /obj/machinery/door/firedoor/proc/activate_alarm() active_alarm = TRUE + adjust_light() update_icon() /obj/machinery/door/firedoor/proc/deactivate_alarm() active_alarm = FALSE + if(!density) + layer = initial(layer) + adjust_light() update_icon() /obj/machinery/door/firedoor/open(auto_close = TRUE) @@ -230,7 +254,8 @@ return . = ..() latetoggle(auto_close) - + if(active_alarm) + layer = closingLayer // Active firedoors take precedence and remain visible over closed airlocks. if(auto_close) autoclose = TRUE @@ -245,13 +270,11 @@ /obj/machinery/door/firedoor/proc/latetoggle(auto_close = TRUE) if(operating || !hasPower() || !nextstate) return - switch(nextstate) - if(FD_OPEN) - nextstate = null - open(auto_close) - if(FD_CLOSED) - nextstate = null - close() + if(nextstate == FD_OPEN) + INVOKE_ASYNC(src, PROC_REF(open), auto_close) + if(nextstate == FD_CLOSED) + INVOKE_ASYNC(src, PROC_REF(close)) + nextstate = null /obj/machinery/door/firedoor/proc/forcetoggle(magic = FALSE, auto_close = TRUE) if(!magic && (operating || !hasPower())) @@ -269,7 +292,7 @@ else F.constructionStep = CONSTRUCTION_WIRES_EXPOSED F.obj_integrity = F.max_integrity * 0.5 - F.update_icon() + F.update_icon(UPDATE_ICON_STATE) qdel(src) /obj/machinery/door/firedoor/border_only @@ -366,8 +389,7 @@ if(CONSTRUCTION_NOCIRCUIT) . += span_notice("There are no firelock electronics in the frame. The frame could be cut apart.") -/obj/structure/firelock_frame/update_icon() - ..() +/obj/structure/firelock_frame/update_icon_state() icon_state = "frame[constructionStep]" /obj/structure/firelock_frame/attackby(obj/item/C, mob/user) @@ -412,7 +434,7 @@ playsound(get_turf(src), B.usesound, 50, 1) B.use(5) constructionStep = CONSTRUCTION_WIRES_EXPOSED - update_icon() + update_icon(UPDATE_ICON_STATE) return if(CONSTRUCTION_NOCIRCUIT) if(istype(C, /obj/item/firelock_electronics)) @@ -430,7 +452,7 @@ span_notice("You insert and secure [C].")) playsound(get_turf(src), C.usesound, 50, 1) constructionStep = CONSTRUCTION_GUTTED - update_icon() + update_icon(UPDATE_ICON_STATE) return return ..() @@ -471,7 +493,7 @@ span_notice("You remove the circuit board from [src].")) new /obj/item/firelock_electronics(get_turf(src)) constructionStep = CONSTRUCTION_NOCIRCUIT - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/firelock_frame/wirecutter_act(mob/user, obj/item/I) if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) @@ -490,7 +512,7 @@ span_notice("You remove the wiring from [src], exposing the circuit board.")) new /obj/item/stack/cable_coil(drop_location(), 5) constructionStep = CONSTRUCTION_GUTTED - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/firelock_frame/wrench_act(mob/user, obj/item/I) if(constructionStep != CONSTRUCTION_PANEL_OPEN) @@ -516,9 +538,6 @@ qdel(src) - - - /obj/structure/firelock_frame/welder_act(mob/user, obj/item/I) if(constructionStep != CONSTRUCTION_NOCIRCUIT) return diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index ae064f4adc8..5c4c4358578 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -53,11 +53,9 @@ flick("closing", src) playsound(src, 'sound/machines/blastdoor.ogg', 30, 1) -/obj/machinery/door/poddoor/update_icon() - if(density) - icon_state = "closed" - else - icon_state = "open" +/obj/machinery/door/poddoor/update_icon_state() + icon_state = density ? "closed" : "open" + /obj/machinery/door/poddoor/try_to_activate_door(mob/user) return diff --git a/code/game/machinery/doors/spacepod.dm b/code/game/machinery/doors/spacepod.dm index a69de0ee0d2..ee4f842324f 100644 --- a/code/game/machinery/doors/spacepod.dm +++ b/code/game/machinery/doors/spacepod.dm @@ -4,7 +4,7 @@ icon = 'icons/effects/beam.dmi' icon_state = "n_beam" density = 0 - anchored = 1 + anchored = TRUE var/id = 1.0 /obj/structure/spacepoddoor/Initialize() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index faa3966c041..35190479d5c 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -46,11 +46,6 @@ QDEL_NULL(electronics) return ..() -/obj/machinery/door/window/update_icon() - if(density) - icon_state = base_state - else - icon_state = "[base_state]open" /obj/machinery/door/window/examine(mob/user) . = ..() @@ -148,54 +143,62 @@ else return 1 + +/obj/machinery/door/window/update_icon_state() + switch(operating) + if(DOOR_OPENING) + icon_state = "[base_state]open" + if(DOOR_CLOSING) + icon_state = base_state + else + icon_state = base_state + + /obj/machinery/door/window/open(forced=0) if(operating) //doors can still open when emag-disabled - return 0 - if(!forced) - if(!hasPower()) - return 0 - if(forced < 2) - if(emagged) - return 0 + return FALSE + if(!forced && !hasPower()) + return FALSE + if(forced < 2 && emagged) + return FALSE if(!operating) //in case of emag - operating = TRUE + operating = DOOR_OPENING do_animate("opening") + set_opacity(FALSE) playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1) - icon_state ="[base_state]open" - sleep(10) + update_icon() + sleep(1 SECONDS) density = FALSE -// sd_set_opacity(0) //TODO: why is this here? Opaque windoors? ~Carn - air_update_turf(1) + + air_update_turf(TRUE) update_freelook_sight() if(operating) //emag again - operating = FALSE - return 1 + operating = NONE + return TRUE + -/obj/machinery/door/window/close(forced=0) +/obj/machinery/door/window/close(forced = 0) if(operating) - return 0 - if(!forced) - if(!hasPower()) - return 0 - if(forced < 2) - if(emagged) - return 0 - operating = TRUE + return FALSE + if(!forced && !hasPower()) + return FALSE + if(forced < 2 && emagged) + return FALSE + operating = DOOR_CLOSING do_animate("closing") - playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1) - icon_state = base_state + playsound(loc, 'sound/machines/windowdoor.ogg', 100, TRUE) - density = 1 -// if(visible) -// set_opacity(1) //TODO: why is this here? Opaque windoors? ~Carn - air_update_turf(1) + density = TRUE + update_icon() + air_update_turf(TRUE) update_freelook_sight() - sleep(10) + sleep(1 SECONDS) + + operating = NONE + return TRUE - operating = 0 - return 1 /obj/machinery/door/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index b8dcbf75845..c5ecaca8749 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -5,8 +5,9 @@ GLOBAL_LIST_EMPTY(doppler_arrays) desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array." icon = 'icons/obj/machines/research.dmi' icon_state = "tdoppler" + base_icon_state = "tdoppler" density = 1 - anchored = 1 + anchored = TRUE atom_say_verb = "states coldly" var/list/logged_explosions = list() var/explosion_target @@ -46,17 +47,13 @@ GLOBAL_LIST_EMPTY(doppler_arrays) return return ..() + /obj/machinery/doppler_array/wrench_act(mob/user, obj/item/I) . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + if(!default_unfasten_wrench(user, I, 0)) return - if(!anchored && !isinspace()) - anchored = TRUE - WRENCH_ANCHOR_MESSAGE - else if(anchored) - anchored = FALSE - WRENCH_UNANCHOR_MESSAGE - power_change() + update_icon(UPDATE_ICON_STATE) + /obj/machinery/doppler_array/attack_hand(mob/user) if(..()) @@ -70,11 +67,15 @@ GLOBAL_LIST_EMPTY(doppler_arrays) /obj/machinery/doppler_array/AltClick(mob/user) rotate(user) -/obj/machinery/doppler_array/verb/rotate(mob/user) + +/obj/machinery/doppler_array/verb/rotate_verb() set name = "Rotate Tachyon-doppler Dish" set category = "Object" set src in oview(1) + rotate(usr) + +/obj/machinery/doppler_array/proc/rotate(mob/user) if(user.incapacitated()) return if(!Adjacent(user)) @@ -164,16 +165,21 @@ GLOBAL_LIST_EMPTY(doppler_arrays) for(var/message in messages) atom_say(message) -/obj/machinery/doppler_array/power_change() + +/obj/machinery/doppler_array/update_icon_state() if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" + icon_state = "[base_icon_state]-broken" else - if(powered() && anchored) - icon_state = initial(icon_state) - stat &= ~NOPOWER - else - icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER + icon_state = (!(stat & NOPOWER) && anchored) ? base_icon_state : "[base_icon_state]-off" + + +/obj/machinery/doppler_array/power_change(forced = FALSE) // overrides base power_change to check to make sure machine is anchored + if(powered(power_channel) && anchored) + stat &= ~NOPOWER + else + stat |= NOPOWER + update_icon(UPDATE_ICON_STATE) + /obj/machinery/doppler_array/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) diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm index 8b22c0aab12..ac043595d88 100644 --- a/code/game/machinery/dye_generator.dm +++ b/code/game/machinery/dye_generator.dm @@ -1,36 +1,60 @@ /obj/machinery/dye_generator name = "Dye Generator" icon = 'icons/obj/machines/vending.dmi' - icon_state = "barbervend" - density = 1 - anchored = 1 + icon_state = "barbervend_off" + base_icon_state = "barbervend" + density = TRUE + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 40 var/dye_color = "#FFFFFF" -/obj/machinery/dye_generator/Initialize() - ..() - power_change() -/obj/machinery/dye_generator/power_change() +/obj/machinery/dye_generator/Initialize(mapload) + . = ..() + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/dye_generator/update_overlays() + . = ..() + + underlays.Cut() + + if(panel_open) + . += "[base_icon_state]_panel" + + if(stat & NOPOWER) + if(stat & BROKEN) + . += "[base_icon_state]_broken" + return + if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" + . += "[base_icon_state]_broken" + underlays += emissive_appearance(icon, "[base_icon_state]_broken_lightmask") + else + . += "[base_icon_state]" + underlays += emissive_appearance(icon, "[base_icon_state]_lightmask") + + +/obj/machinery/dye_generator/obj_break(damage_flag) + ..() + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/dye_generator/power_change(forced = FALSE) + . = ..() + if(stat & NOPOWER) set_light(0) else - if(powered()) - icon_state = initial(icon_state) - stat &= ~NOPOWER - set_light(2, l_color = dye_color) - else - spawn(rand(0, 15)) - src.icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER - set_light(0) + set_light(1, LIGHTING_MINIMUM_POWER, dye_color) + if(.) + update_icon(UPDATE_OVERLAYS) /obj/machinery/dye_generator/extinguish_light(force = FALSE) - set_light(0) - underlays.Cut() + if(light) + set_light(0) + underlays.Cut() /obj/machinery/dye_generator/attack_hand(mob/user) @@ -39,7 +63,8 @@ return var/temp = input(usr, "Choose a dye color", "Dye Color") as color dye_color = temp - set_light(2, l_color = temp) + set_light(1, LIGHTING_MINIMUM_POWER, temp) + /obj/machinery/dye_generator/attackby(obj/item/I, mob/user, params) @@ -52,12 +77,12 @@ var/obj/item/hair_dye_bottle/HD = I user.visible_message(span_notice("[user] fills the [HD] up with some dye."),span_notice("You fill the [HD] up with some hair dye.")) HD.dye_color = dye_color - HD.update_dye_overlay() + HD.update_icon(UPDATE_OVERLAYS) return return ..() -//Hair Dye Bottle +//Hair Dye Bottle /obj/item/hair_dye_bottle name = "Hair Dye Bottle" desc = "A refillable bottle used for holding hair dyes of all sorts of colors." @@ -70,15 +95,16 @@ w_class = WEIGHT_CLASS_TINY var/dye_color = "#FFFFFF" -/obj/item/hair_dye_bottle/New() - ..() - update_dye_overlay() -/obj/item/hair_dye_bottle/proc/update_dye_overlay() - overlays.Cut() - var/image/I = new('icons/obj/items.dmi', "hairdyebottle-overlay") - I.color = dye_color - overlays += I +/obj/item/hair_dye_bottle/Initialize(mapload) + . = ..() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/hair_dye_bottle/update_overlays() + . = ..() + . += mutable_appearance(icon, icon_state = "hairdyebottle-overlay", color = dye_color) + /obj/item/hair_dye_bottle/attack(mob/living/carbon/M, mob/user) if(user.a_intent != INTENT_HELP) diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 8288cefd09b..900043238f7 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -74,7 +74,7 @@ name = "Access Controller" tag_secure = 1 -/obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon() +/obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon_state() if(on && program) if(program.memory["processing"]) icon_state = "access_control_process" diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 6a52cc19dfc..bd3005fad59 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -2,7 +2,7 @@ var/datum/computer/file/embedded_program/program //the currently executing program name = "Embedded Controller" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 @@ -23,8 +23,8 @@ if(program) program.process() - update_icon() - src.updateDialog() + update_icon(UPDATE_ICON_STATE) + updateDialog() /obj/machinery/embedded_controller/attack_ghost(mob/user as mob) ui_interact(user) @@ -61,7 +61,7 @@ radio_connection = null return ..() -/obj/machinery/embedded_controller/radio/update_icon() +/obj/machinery/embedded_controller/radio/update_icon_state() if(on && program) if(program.memory["processing"]) icon_state = "airlock_control_process" diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 1d64aeb3b0d..2a82f6a4101 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -2,6 +2,8 @@ FIRE ALARM */ +GLOBAL_LIST_EMPTY(firealarms) + #define FIRE_ALARM_FRAME 0 #define FIRE_ALARM_UNWIRED 1 #define FIRE_ALARM_READY 2 @@ -10,13 +12,8 @@ FIRE ALARM name = "fire alarm" desc = "\"Pull this in case of emergency\". Thus, keep pulling it forever." icon = 'icons/obj/machines/monitors.dmi' - icon_state = "fire0" - var/detecting = 1.0 - var/working = 1.0 - var/time = 10.0 - var/timing = 0.0 - var/lockdownbyai = 0 - anchored = 1.0 + icon_state = "firealarm_on" + anchored = TRUE max_integrity = 250 integrity_failure = 100 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100, fire = 90, acid = 30) @@ -26,16 +23,44 @@ FIRE ALARM power_channel = ENVIRON resistance_flags = FIRE_PROOF - light_power = 0 - light_range = 5 - light_color = COLOR_RED_LIGHT + light_power = LIGHTING_MINIMUM_POWER + light_range = 7 + light_color = "#ff3232" + + var/buildstage = FIRE_ALARM_READY + var/wiresexposed = FALSE + var/detecting = TRUE + var/working = TRUE + /// Should triggered fire alarms also trigger an actual alarm? + var/report_fire_alarms = TRUE + /// Should fire alarms display the current alert level? + var/show_alert_level = TRUE + /// Used to prevent pulling spam by same persons + var/last_time_pulled + - var/wiresexposed = 0 - var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone +/obj/machinery/firealarm/New(location, direction, building) + . = ..() + + GLOB.firealarms += src + + if(building) + buildstage = FIRE_ALARM_FRAME + wiresexposed = TRUE + setDir(direction) + set_pixel_offsets_from_dir(26, -26, 26, -26) + + myArea = get_area(src) + LAZYADD(myArea.firealarms, src) + set_light(1, LIGHTING_MINIMUM_POWER) //for emissives + update_icon() + + +/obj/machinery/firealarm/Destroy() + GLOB.firealarms -= src + LAZYREMOVE(myArea.firealarms, src) + return ..() - var/report_fire_alarms = TRUE // Should triggered fire alarms also trigger an actual alarm? - var/show_alert_level = TRUE // Should fire alarms display the current alert level? - var/triggered = FALSE /obj/machinery/firealarm/no_alarm report_fire_alarms = FALSE @@ -48,34 +73,44 @@ FIRE ALARM report_fire_alarms = TRUE show_alert_level = FALSE -/obj/machinery/firealarm/update_icon() +/obj/machinery/firealarm/update_icon_state() if(wiresexposed) - switch(buildstage) - if(2) - icon_state="fire_b2" - if(1) - icon_state="fire_b1" - if(0) - icon_state="fire_b0" - set_light(0) + icon_state = "firealarm_b[buildstage]" return - if(stat & BROKEN) - icon_state = "firex" - set_light(0) - else if(stat & NOPOWER) - icon_state = "firep" - set_light(0) - else if(!detecting) - icon_state = "fire1" - set_light(2, 1, COLOR_RED) - else if(triggered) - set_light(5, 0.8, COLOR_RED_LIGHT) + icon_state = "firealarm_broken" + return + if(stat & NOPOWER) + icon_state = "firealarm_off" + return + + var/area/area = get_area(src) + if(area.fire) + icon_state = "firealarm_alarming" + return + if(!detecting) + icon_state = "firealarm_detect" + return else - icon_state = "fire0" - if(is_station_contact(z)) - set_light(get_security_level_l_range(), get_security_level_l_power(), get_security_level_l_color()) + icon_state = "firealarm_on" + + +/obj/machinery/firealarm/update_overlays() + . = ..() + underlays.Cut() + + if(stat & (NOPOWER|BROKEN)) + return + + if(is_station_contact(z) && show_alert_level) + + . += "overlay_[get_security_level()]" + underlays += emissive_appearance(icon, "firealarm_overlay_lightmask") + + if(!wiresexposed) + underlays += emissive_appearance(icon, "firealarm_lightmask") + /obj/machinery/firealarm/emag_act(mob/user) if(!emagged) @@ -149,6 +184,7 @@ FIRE ALARM if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return detecting = !detecting + update_icon() if(detecting) user.visible_message(span_warning("[user] has reconnected [src]'s detecting unit!"), "You have reconnected [src]'s detecting unit.") else @@ -179,6 +215,7 @@ FIRE ALARM WIRECUTTER_SNIP_MESSAGE new /obj/item/stack/cable_coil(drop_location(), 5) buildstage = FIRE_ALARM_UNWIRED + update_icon() /obj/machinery/firealarm/wrench_act(mob/user, obj/item/I) @@ -220,26 +257,41 @@ FIRE ALARM qdel(src) /obj/machinery/firealarm/proc/update_fire_light(fire) - triggered = fire - update_icon() + if(stat & NOPOWER) + set_light(0) + return + else if(GLOB.security_level == SEC_LEVEL_EPSILON) + set_light(2, 1, COLOR_WHITE) + return + else if(fire == !!light_power || fire == !!(light_power - 0.1)) + return // do nothing if we're already active -/obj/machinery/firealarm/power_change() - if(powered(ENVIRON)) - stat &= ~NOPOWER - update_icon() + if(fire) + set_light(l_power = 0.8) else - spawn(rand(0,15)) - stat |= NOPOWER - update_icon() + set_light(l_power = LIGHTING_MINIMUM_POWER) + + +/obj/machinery/firealarm/power_change() + if(!..()) + return + update_fire_light() + update_icon() + /obj/machinery/firealarm/attack_hand(mob/user) if(stat & (NOPOWER|BROKEN) || buildstage != 2) - return 1 + return TRUE if(user.incapacitated()) - return 1 + return TRUE + + . = FALSE + + if(fingerprintslast == user.ckey && world.time < last_time_pulled + 5 SECONDS) //no spamming >:C + to_chat(user, span_warning("[src] is still processing your earlier command.")) + return . - add_fingerprint(user) toggle_alarm(user) @@ -247,50 +299,39 @@ FIRE ALARM var/area/A = get_area(src) if(istype(A)) add_fingerprint(user) + last_time_pulled = world.time if(A.fire) reset() else alarm() + /obj/machinery/firealarm/examine(mob/user) . = ..() - . += span_notice("Текущий уровень угрозы: [capitalize(get_security_level_ru())].") + switch(buildstage) + if(FIRE_ALARM_FRAME) + . += "It's missing a circuit board and the bolts are exposed." + if(FIRE_ALARM_UNWIRED) + . += "The control board needs wiring and can be pried out." + if(FIRE_ALARM_READY) + if(wiresexposed) + . += "The fire alarm's wires are exposed by the unscrewed panel." + . += "The detection circuitry can be turned [detecting ? "off" : "on"] by pulsing the board." + + . += "It shows the alert level as: [capitalize(get_security_level())]." + /obj/machinery/firealarm/proc/reset() if(!working || !report_fire_alarms) return - var/area/A = get_area(src) - A.firereset(src) + myArea?.firereset(src) + /obj/machinery/firealarm/proc/alarm() if(!working || !report_fire_alarms) return - var/area/A = get_area(src) - A.firealert(src) // Manually trigger alarms if the alarm isn't reported - update_icon() - -/obj/machinery/firealarm/New(location, direction, building) - . = ..() + myArea?.firealert(src) - if(building) - buildstage = 0 - wiresexposed = TRUE - setDir(direction) - set_pixel_offsets_from_dir(26, -26, 26, -26) - - if(is_station_contact(z) && show_alert_level) - if(GLOB.security_level) - overlays += image('icons/obj/machines/monitors.dmi', "overlay_[get_security_level()]") - else - overlays += image('icons/obj/machines/monitors.dmi', "overlay_green") - - myArea = get_area(src) - LAZYADD(myArea.firealarms, src) - update_icon() - -/obj/machinery/firealarm/Destroy() - LAZYREMOVE(myArea.firealarms, src) - return ..() /* FIRE ALARM CIRCUIT @@ -307,6 +348,8 @@ Just a object used in constructing fire alarms toolspeed = 1 usesound = 'sound/items/deconstruct.ogg' + #undef FIRE_ALARM_FRAME #undef FIRE_ALARM_UNWIRED #undef FIRE_ALARM_READY + diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index b308bdac883..d75ddabaec0 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -147,7 +147,7 @@ icon_state = "launcherbtt" var/id = null var/active = 0 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 4 diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 9950b3f61de..fce57b61fa9 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -26,132 +26,151 @@ QDEL_NULL(cell) return ..() -/obj/machinery/floodlight/proc/updateicon() + +/obj/machinery/floodlight/proc/mapVarInit() + if(on) + if(!cell) + return + if(cell.charge <= 0) + return + set_light(brightness_on) + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/floodlight/examine(mob/user) + . = ..() + if(!unlocked) + . += span_notice("The panel is screwed shut.") + else + if(open) + . += span_notice("The panel is pried open, looks like you could fit a cell in there.") + else + . += span_notice("The panel looks like it could be pried open, or screwed shut.") + + +/obj/machinery/floodlight/update_icon_state() icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]" + /obj/machinery/floodlight/process() - if(!cell && on) + if(!on) + return + + if(cell && !cell.use(use)) on = FALSE - visible_message(span_warning("[src] shuts down due to lack of power!")) - update_icon() + update_icon(UPDATE_ICON_STATE) set_light(0) - if(on) - cell.charge -= use - if(cell.charge <= 0) - on = FALSE - updateicon() - set_light(0) - visible_message(span_warning("[src] shuts down due to lack of power!")) + visible_message(span_warning("[src] shuts down due to lack of power!")) + /obj/machinery/floodlight/attack_ai() return -/obj/machinery/floodlight/attack_hand(mob/user as mob) +/obj/machinery/floodlight/attack_hand(mob/user) + add_fingerprint(user) if(open && cell) - if(ishuman(user)) - if(!user.get_active_hand()) - cell.forceMove_turf() - user.put_in_hands(cell, ignore_anim = FALSE) - else - cell.loc = loc - - add_fingerprint(user) + if(user.get_active_hand()) + to_chat(user, span_warning("Your hand is occupied!")) + return + cell.forceMove_turf() cell.add_fingerprint(user) - cell.update_icon() - + cell.update_icon(UPDATE_OVERLAYS) + user.put_in_hands(cell, ignore_anim = FALSE) cell = null - to_chat(user, "You remove the power cell.") + to_chat(user, span_notice("You remove the power cell.")) if(on) on = FALSE visible_message(span_warning("[src] shuts down due to lack of power!")) set_light(0) - updateicon() + update_icon(UPDATE_ICON_STATE) return if(on) - add_fingerprint(user) on = FALSE to_chat(user, span_notice("You turn off the light.")) set_light(0) else if(!cell) + to_chat(user, span_warning("You try to turn on [src] but nothing happens! Seems like it lacks a power cell.")) return if(cell.charge <= 0) + to_chat(user, span_warning("[src] hardly glows at all! Seems like the power cell is empty.")) + return + if(!anchored) + to_chat(user, span_warning("[src] must be anchored first!")) return - add_fingerprint(user) on = TRUE to_chat(user, span_notice("You turn on the light.")) set_light(brightness_on) + update_icon(UPDATE_ICON_STATE) - updateicon() -/obj/machinery/floodlight/proc/mapVarInit() - if(on) - if(!cell) - return - if(cell.charge <= 0) - return - set_light(brightness_on) - updateicon() - -/obj/machinery/floodlight/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wrench)) - add_fingerprint(user) - if(!anchored && !isinspace()) - playsound(loc, W.usesound, 50, 1) - user.visible_message( \ - "[user] tightens \the [src]'s casters.", \ - span_notice(" You have tightened \the [src]'s casters."), \ - "You hear ratchet.") - anchored = TRUE - else if(anchored) - playsound(loc, W.usesound, 50, 1) - user.visible_message( \ - "[user] loosens \the [src]'s casters.", \ - span_notice(" You have loosened \the [src]'s casters."), \ - "You hear ratchet.") - anchored = FALSE - updateicon() - return - if(istype(W, /obj/item/screwdriver)) - add_fingerprint(user) - if(!open) - if(unlocked) - unlocked = FALSE - to_chat(user, "You screw the battery panel in place.") - else - unlocked = TRUE - to_chat(user, "You unscrew the battery panel.") - updateicon() - return - if(istype(W, /obj/item/crowbar)) - add_fingerprint(user) - if(unlocked) - if(open) - open = FALSE - overlays = null - to_chat(user, "You crowbar the battery panel in place.") - else - if(unlocked) - open = TRUE - to_chat(user, "You remove the battery panel.") - updateicon() - return - if(istype(W, /obj/item/stock_parts/cell)) +/obj/machinery/floodlight/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stock_parts/cell)) if(open) if(cell) - to_chat(user, "There is a power cell already installed.") + to_chat(user, span_warning("There is a power cell already installed.")) else add_fingerprint(user) - user.drop_transfer_item_to_loc(W, src) - cell = W - to_chat(user, "You insert the power cell.") - updateicon() + user.drop_transfer_item_to_loc(I, src) + cell = I + to_chat(user, span_notice("You insert the power cell.")) + update_icon(UPDATE_ICON_STATE) return return ..() + +/obj/machinery/floodlight/crowbar_act(mob/living/user, obj/item/I) + add_fingerprint(user) + if(!unlocked) + to_chat(user, span_warning("The cover is screwed tightly down.")) + return TRUE + + if(!I.use_tool(src, user, volume = I.tool_volume)) + return + + if(open) + to_chat(user, span_notice("You pry the panel closed.")) + else + to_chat(user, span_notice("You pry the panel open.")) + open = !open + update_icon(UPDATE_ICON_STATE) + return TRUE + + +/obj/machinery/floodlight/screwdriver_act(mob/living/user, obj/item/I) + add_fingerprint(user) + if(open) + to_chat(user, span_warning("The screws can't reach while its open.")) + return TRUE + + if(!I.use_tool(src, user, volume = I.tool_volume)) + return + + if(open) + return + + if(unlocked) + to_chat(user, span_notice("You screw the battery panel in place.")) + else + to_chat(user, span_notice("You unscrew the battery panel.")) + unlocked = !unlocked + update_icon(UPDATE_ICON_STATE) + return TRUE + + +/obj/machinery/floodlight/wrench_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.tool_use_check(user, 0)) + return + if(anchored) + extinguish_light() + default_unfasten_wrench(user, I) + + /obj/machinery/floodlight/extinguish_light(force = FALSE) if(on) on = FALSE set_light(0) - update_icon() + update_icon(UPDATE_ICON_STATE) + diff --git a/code/game/machinery/gameboard.dm b/code/game/machinery/gameboard.dm index b67be897ba5..56c39b8212a 100644 --- a/code/game/machinery/gameboard.dm +++ b/code/game/machinery/gameboard.dm @@ -4,7 +4,7 @@ icon_state = "gboard_on" desc = "A holographic table allowing the crew to have fun(TM) on boring shifts! One player per board." density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE var/cooling_down = 0 light_color = LIGHT_COLOR_LIGHTBLUE @@ -25,15 +25,17 @@ if(get_dist(src, p) > 1 && !istype(p, /mob/living/silicon)) close_game(p) -/obj/machinery/gameboard/power_change() - . = ..() - update_icon() +/obj/machinery/gameboard/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) if(stat & NOPOWER) set_light(0) else set_light(3, 3) -/obj/machinery/gameboard/update_icon() + +/obj/machinery/gameboard/update_icon_state() if(stat & NOPOWER) icon_state = "gboard_off" else diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index ac2ef018553..483e4b84355 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_EMPTY(holopads) name = "holopad" desc = "It's a floor-mounted device for projecting holographic images." icon_state = "holopad0" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 100 @@ -398,7 +398,7 @@ GLOBAL_LIST_EMPTY(holopads) hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - hologram.anchored = 1//So space wind cannot drag it. + hologram.anchored = TRUE//So space wind cannot drag it. hologram.name = "[user.name] (hologram)"//If someone decides to right click. hologram.set_light(2) //hologram lighting move_hologram() diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index c221a941426..1914a694664 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/holosign.dmi' icon_state = "sign_off" layer = 4 - anchored = 1 - var/lit = 0 + anchored = TRUE + var/lit = FALSE var/id = null var/on_icon = "sign_on" @@ -14,18 +14,17 @@ if(stat & (BROKEN|NOPOWER)) return lit = !lit - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/machinery/holosign/update_icon() - if(!lit) - icon_state = "sign_off" - else - icon_state = on_icon +/obj/machinery/holosign/update_icon_state() + icon_state = lit ? on_icon : "sign_off" -/obj/machinery/holosign/power_change() +/obj/machinery/holosign/power_change(forced = FALSE) + if(!..()) + return if(stat & NOPOWER) - lit = 0 - update_icon() + lit = FALSE + update_icon(UPDATE_ICON_STATE) /obj/machinery/holosign/surgery name = "surgery holosign" @@ -40,7 +39,7 @@ desc = "A remote control switch for holosign." var/id = null var/active = 0 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 4 @@ -62,10 +61,7 @@ use_power(5) active = !active - if(active) - icon_state = "light1" - else - icon_state = "light0" + update_icon(UPDATE_ICON_STATE) for(var/obj/machinery/holosign/M in GLOB.machines) if(M.id == src.id) @@ -73,4 +69,7 @@ M.toggle() return - return + +/obj/machinery/holosign_switch/update_icon_state() + icon_state = "light[active]" + diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index bff3fe9b282..537c149c465 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -7,18 +7,27 @@ max_integrity = 300 armor = list(melee = 50, bullet = 30, laser = 70, energy = 50, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF - var/id = null - var/on = FALSE anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 4 + /// Are we on? + var/on = FALSE + /// ID to hook buttons into + var/id = null + /obj/machinery/igniter/on on = TRUE + +/obj/machinery/igniter/Initialize(mapload) + . = ..() + update_icon() + + /obj/machinery/igniter/attack_ai(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/igniter/attack_hand(mob/user as mob) @@ -27,26 +36,44 @@ add_fingerprint(user) use_power(50) - src.on = !( src.on ) - src.icon_state = text("igniter[]", src.on) - return + on = !on + update_icon() -/obj/machinery/igniter/process() //ugh why is this even in process()? - if(src.on && !(stat & NOPOWER) ) - var/turf/location = src.loc - if(isturf(location)) - location.hotspot_expose(1000,500,1) - return 1 + if(on) + set_light(1, 1, "#ff821c") + else + set_light(0) -/obj/machinery/igniter/New() - ..() - icon_state = "igniter[on]" -/obj/machinery/igniter/power_change() - if(!( stat & NOPOWER) ) - icon_state = "igniter[src.on]" - else +/obj/machinery/igniter/update_icon_state() + if(stat & (NOPOWER|BROKEN)) icon_state = "igniter0" + return + icon_state = "igniter[on]" + + +/obj/machinery/igniter/update_overlays() + . = ..() + underlays.Cut() + if(on) + underlays += emissive_appearance(icon, "igniter_lightmask") + + +/obj/machinery/igniter/process() //ugh why is this even in process()? // AA 2022-08-02 - I guess it cant go anywhere else? + if(on && !(stat & NOPOWER)) + var/turf/location = get_turf(src) + if(isturf(location)) + location.hotspot_expose(1000, 500, 1) + return TRUE + + +/obj/machinery/igniter/power_change(forced = FALSE) + if(!..()) + return + if(stat & NOPOWER) + on = FALSE + update_icon() + // Wall mounted remote-control igniter. @@ -60,63 +87,65 @@ var/disable = FALSE var/last_spark = FALSE var/base_state = "migniter" - anchored = 1 + anchored = TRUE -/obj/machinery/sparker/New() - ..() -/obj/machinery/sparker/power_change() - if( powered() && disable == 0 ) - stat &= ~NOPOWER +/obj/machinery/sparker/update_icon_state() + if(disable) + icon_state = "[base_state]-d" + else if(powered()) icon_state = "[base_state]" -// src.sd_set_light(2) else - stat |= ~NOPOWER icon_state = "[base_state]-p" -// src.sd_set_light(0) + + +/obj/machinery/sparker/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) + /obj/machinery/sparker/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/detective_scanner)) return return ..() + /obj/machinery/sparker/screwdriver_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return disable = !disable - if(disable) - user.visible_message(span_warning("[user] has disabled [src]!"), span_warning("You disable the connection to [src].")) - icon_state = "[base_state]-d" - if(!disable) - user.visible_message(span_warning("[user] has reconnected [src]!"), span_warning("You fix the connection to [src].")) - if(powered()) - icon_state = "[base_state]" - else - icon_state = "[base_state]-p" + user.visible_message( + span_warning("[user] has [disable ? "disabled" : "reconnected"] [src]!"), + span_warning("You [disable ? "disable" : "fix"] the connection to [src]."), + ) + update_icon(UPDATE_ICON_STATE) + /obj/machinery/sparker/attack_ai() - if(src.anchored) - return src.spark() - else - return + if(anchored) + return spark() + /obj/machinery/sparker/proc/spark() - if(!(powered())) + if(!powered()) return - if((src.disable) || (src.last_spark && world.time < src.last_spark + 50)) + if(disable || (last_spark && world.time < last_spark + 5 SECONDS)) return - flick("[base_state]-spark", src) do_sparks(2, 1, src) - src.last_spark = world.time + last_spark = world.time use_power(1000) - var/turf/location = src.loc + + var/turf/location = get_turf(src) if(isturf(location)) - location.hotspot_expose(1000,500,1) - return 1 + location.hotspot_expose(1000, 500, 1) + + return TRUE + /obj/machinery/sparker/emp_act(severity) if(stat & (BROKEN|NOPOWER)) @@ -124,3 +153,4 @@ return spark() ..(severity) + diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index c3698353eec..5a7281ff110 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -11,40 +11,41 @@ /obj/machinery/iv_drip/process() if(istype(bag) && bag.injection_target) - update_icon() + update_icon(UPDATE_OVERLAYS) return return PROCESS_KILL -/obj/machinery/iv_drip/update_icon() - cut_overlays() +/obj/machinery/iv_drip/update_overlays() + . = ..() if(bag) - add_overlay("hangingbag") + . += "hangingbag" if(bag.reagents.total_volume) var/image/filling = image('icons/goonstation/objects/iv.dmi', src, "hangingbag-fluid") filling.icon += mix_color_from_reagents(bag.reagents.reagent_list) - add_overlay(filling) + . += filling -/obj/machinery/iv_drip/MouseDrop(mob/living/target) - if(usr.incapacitated()) - return - if(!ishuman(usr) || !iscarbon(target)) - return +/obj/machinery/iv_drip/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(usr.incapacitated() || !ishuman(usr) || !ishuman(over_object) || !Adjacent(over_object) || !usr.Adjacent(over_object)) + return FALSE + + add_fingerprint(usr) + if(!bag) + to_chat(usr, span_warning("There's no IV bag connected to [src]!")) + return FALSE + bag.afterattack(over_object, usr, TRUE) + START_PROCESSING(SSmachines, src) - if(Adjacent(target) && usr.Adjacent(target)) - add_fingerprint(usr) - bag.afterattack(target, usr, TRUE) - START_PROCESSING(SSmachines, src) /obj/machinery/iv_drip/attack_hand(mob/user) if(bag) add_fingerprint(user) bag.forceMove_turf() user.put_in_hands(bag, ignore_anim = FALSE) - bag.update_icon() + bag.update_icon(UPDATE_OVERLAYS) bag = null - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/iv_drip/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/reagent_containers/iv_bag)) @@ -57,13 +58,13 @@ add_fingerprint(user) bag = I to_chat(user, span_notice("You attach [I] to [src].")) - update_icon() + update_icon(UPDATE_OVERLAYS) START_PROCESSING(SSmachines, src) else if (bag && istype(I, /obj/item/reagent_containers)) add_fingerprint(user) bag.attackby(I) I.afterattack(bag, usr, TRUE) - update_icon() + update_icon(UPDATE_OVERLAYS) else return ..() diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 80e4efe8f4b..9e0d3387ee5 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -6,17 +6,17 @@ desc = "It turns lights on and off. What are you, simple?" icon = 'icons/obj/engines_and_power/power.dmi' icon_state = "light1" - anchored = 1.0 - var/on = 1 + anchored = TRUE + var/on = TRUE var/area/area = null var/otherarea = null // luminosity = 1 - var/light_connect = 1 //Allows the switch to control lights in its associated areas. When set to 0, using the switch won't affect the lights. + var/light_connect = TRUE //Allows the switch to control lights in its associated areas. When set to 0, using the switch won't affect the lights. var/logic_id_tag = "default" //Defines the ID tag to send logic signals to. var/logic_connect = 0 //Set this to allow the switch to send out logic signals. -/obj/machinery/light_switch/New(turf/loc, var/w_dir=null) +/obj/machinery/light_switch/New(turf/loc, w_dir) ..() switch(w_dir) if(NORTH) @@ -27,29 +27,30 @@ pixel_x = 25 if(WEST) pixel_x = -25 - if(SSradio) - set_frequency(frequency) - spawn(5) - src.area = get_area(src) - if(otherarea) - src.area = locate(text2path("/area/[otherarea]")) - if(!name) - name = "light switch([area.name])" +/obj/machinery/light_switch/Initialize(mapload) + . = ..() + set_frequency(frequency) + + if(otherarea) + area = locate(text2path("/area/[otherarea]")) + else + area = get_area(src) + + if(!name) + name = "light switch([area.name])" - src.on = src.area.lightswitch - updateicon() + on = area.lightswitch + light_switch_light() + update_icon() -/obj/machinery/light_switch/Initialize() - ..() - set_frequency(frequency) /obj/machinery/light_switch/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency radio_connection = SSradio.add_object(src, frequency, RADIO_LOGIC) - return + /obj/machinery/light_switch/Destroy() if(SSradio) @@ -57,43 +58,62 @@ radio_connection = null return ..() -/obj/machinery/light_switch/proc/updateicon() + +/obj/machinery/light_switch/proc/light_switch_light() if(stat & (NOPOWER|BROKEN)) - icon_state = "light-p" set_light(0) - else - if(on) - icon_state = "light1" - else - icon_state = "light0" - set_light(2, 0.3, on ? COLOR_APC_GREEN : COLOR_APC_RED) + return + set_light(1, LIGHTING_MINIMUM_POWER, on ? COLOR_APC_GREEN : COLOR_APC_RED) + + +/obj/machinery/light_switch/update_icon_state() + if(stat & NOPOWER) + icon_state = "light-p" + return + icon_state = "light[on]" + + +/obj/machinery/light_switch/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER) + return + underlays += emissive_appearance(icon, "light_lightmask") + /obj/machinery/light_switch/examine(mob/user) . = ..() . += span_notice("A light switch. It is [on? "on" : "off"].") + /obj/machinery/light_switch/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) + /obj/machinery/light_switch/attack_hand(mob/user) + playsound(src, 'sound/machines/lightswitch.ogg', 10, TRUE) add_fingerprint(user) on = !on - updateicon() + light_switch_light() + update_icon() - if(light_connect) + + if(light_connect && area) area.lightswitch = on - area.updateicon() + area.update_icon(UPDATE_ICON_STATE) if(logic_connect && powered(LIGHT)) //Don't bother sending a signal if we aren't set to send them or we have no power to send with. handle_output() if(light_connect) - for(var/obj/machinery/light_switch/L in area.machinery_cache) - L.on = on - L.updateicon() + for(var/obj/machinery/light_switch/light_switch in area.machinery_cache) + light_switch.on = on + light_switch.light_switch_light() + light_switch.update_icon() + area?.power_change() - area.power_change() /obj/machinery/light_switch/proc/handle_output() if(!radio_connection) //can't output without this @@ -124,14 +144,14 @@ if(on) use_power(5, LIGHT) //Use a tiny bit of power every time we send an ON signal. Draws from the local APC's lighting circuit, since this is a LIGHT switch. -/obj/machinery/light_switch/power_change() - if(!otherarea) - if(powered(LIGHT)) - stat &= ~NOPOWER - else - stat |= NOPOWER - updateicon() +/obj/machinery/light_switch/power_change(forced = FALSE) + if(!..() || !otherarea) + return + + light_switch_light() + update_icon() + /obj/machinery/light_switch/emp_act(severity) if(stat & (BROKEN|NOPOWER)) @@ -144,7 +164,7 @@ if(logic_connect && powered(LIGHT)) //We won't send signals while unpowered, but the last signal will remain valid for anything that received it before we went dark handle_output() -/obj/machinery/light_switch/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/machinery/light_switch/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/detective_scanner)) return return ..() @@ -154,7 +174,6 @@ if(!I.tool_use_check(user, 0)) return user.visible_message(span_notice("[user] starts unwrenching [src] from the wall..."), span_notice("You are unwrenching [src] from the wall..."), span_warning("You hear ratcheting.")) - . = TRUE if(!I.use_tool(src, user, 30, volume = I.tool_volume)) return WRENCH_UNANCHOR_WALL_MESSAGE diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index cd4329fbde6..d9e404216a9 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -143,6 +143,7 @@ Class Procs: /obj/machinery/proc/flicker() return FALSE + /obj/machinery/Initialize(mapload) if(!armor) armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) @@ -151,7 +152,7 @@ Class Procs: myArea = get_area(src) if(myArea) - RegisterSignal(myArea, COMSIG_AREA_EXITED, PROC_REF(onAreaExited)) + RegisterSignal(src, COMSIG_ATOM_EXITED_AREA, PROC_REF(onAreaExited)) LAZYADD(myArea.machinery_cache, src) if(!speed_process) @@ -163,16 +164,17 @@ Class Procs: init_multitool_menu() + /obj/machinery/proc/onAreaExited() + SIGNAL_HANDLER if(myArea == get_area(src)) return - LAZYREMOVE(myArea.machinery_cache, src) - UnregisterSignal(myArea, COMSIG_AREA_EXITED) //message_admins("[src] exited [myArea]") Uncomment for debugging myArea = get_area(src) - RegisterSignal(myArea, COMSIG_AREA_EXITED, PROC_REF(onAreaExited)) - LAZYADDOR(myArea.machinery_cache, src) + if(!myArea) + return + LAZYADD(myArea.machinery_cache, src) //message_admins("[src] entered [myArea]") power_change() @@ -199,6 +201,7 @@ Class Procs: if(myArea) LAZYREMOVE(myArea.machinery_cache, src) myArea = null + UnregisterSignal(src, COMSIG_ATOM_EXITED_AREA) GLOB.machines.Remove(src) if(!speed_process) STOP_PROCESSING(SSmachines, src) @@ -289,7 +292,7 @@ Class Procs: else return attack_hand(user) -/obj/machinery/attack_hand(mob/user as mob) +/obj/machinery/attack_hand(mob/user) if(istype(user, /mob/dead/observer)) return FALSE @@ -351,8 +354,8 @@ Class Procs: if(!disassembled) M.obj_integrity = M.max_integrity * 0.5 //the frame is already half broken transfer_fingerprints_to(M) - M.state = 2 - M.icon_state = "box_1" + M.state = 2 // STATE_WIRED + M.update_icon(UPDATE_ICON_STATE) /obj/machinery/obj_break(damage_flag) if(!(flags & NODECONSTRUCT)) @@ -376,14 +379,18 @@ Class Procs: if(!I.use_tool(src, user, 0, volume = 0)) return FALSE if(!(flags & NODECONSTRUCT)) + var/prev_icon_state = icon_state if(!panel_open) - panel_open = 1 + panel_open = TRUE icon_state = icon_state_open to_chat(user, span_notice("You open the maintenance hatch of [src].")) else - panel_open = 0 + panel_open = FALSE icon_state = icon_state_closed to_chat(user, span_notice("You close the maintenance hatch of [src].")) + if(prev_icon_state != icon_state) + SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON_STATE) + SEND_SIGNAL(src, COMSIG_ATOM_UPDATED_ICON, UPDATE_ICON_STATE) I.play_tool_sound(user, I.tool_volume) return 1 return 0 diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 01995956d64..8bd5e7dc1f2 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -1,3 +1,12 @@ +#define MIN_CONTROLLER_SPEED 1 +#define MAX_CONTROLLER_SPEED 10 +#define MIN_ELECTRICITY_LEVEL 1 +#define MAX_ELECTRICITY_LEVEL 12 +#define MIN_MAGNETIC_FIELD 1 +#define MAX_MAGNETIC_FIELD 4 +#define MAX_PATH_LENGTH 50 + + // Magnetic attractor, creates variable magnetic fields and attraction. // Can also be used to emit electron/proton beams to create a center of magnetism on another tile @@ -5,62 +14,59 @@ // This was created for firing ranges, but I suppose this could have other applications - Doohl /obj/machinery/magnetic_module - icon = 'icons/obj/objects.dmi' icon_state = "floor_magnet-f" name = "Electromagnetic Generator" desc = "A device that uses station power to create points of magnetic energy." level = 1 // underfloor layer = WIRE_LAYER+0.001 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 50 - - var/freq = AIRLOCK_FREQ // radio frequency - var/electricity_level = 1 // intensity of the magnetic pull - var/magnetic_field = 1 // the range of magnetic attraction - var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something - var/turf/center // the center of magnetic attraction - var/on = 0 - var/magpulling = 0 + /// Radio frequency + var/freq = AIRLOCK_FREQ + /// Intensity of the magnetic pull + var/electricity_level = MIN_ELECTRICITY_LEVEL + /// The range of magnetic attraction + var/magnetic_field = MIN_MAGNETIC_FIELD + /// Frequency code, they should be different unless you have a group of magnets working together or something + var/code = 0 + /// The center of magnetic attraction + var/turf/center + var/on = FALSE + var/magpulling = FALSE // x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down var/center_x = 0 var/center_y = 0 - var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer + /// absolute value of center_x,y cannot exceed this integer + var/max_dist = 20 + -/obj/machinery/magnetic_module/New() +/obj/machinery/magnetic_module/Initialize(mapload) ..() var/turf/T = loc if(!T.transparent_floor) hide(T.intact) - hide(T.intact) center = T - spawn(10) // must wait for map loading to finish - if(SSradio) - SSradio.add_object(src, freq, RADIO_MAGNETS) + SSradio.add_object(src, freq, RADIO_MAGNETS) + + INVOKE_ASYNC(src, PROC_REF(magnetic_process)) - spawn() - magnetic_process() // update the invisibility and icon /obj/machinery/magnetic_module/hide(intact) - invisibility = intact ? INVISIBILITY_ABSTRACT : 0 - updateicon() + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 + update_icon(UPDATE_ICON_STATE) + // update the icon_state -/obj/machinery/magnetic_module/proc/updateicon() - var/state="floor_magnet" - var/onstate="" - if(!on) - onstate="0" - - if(invisibility) - icon_state = "[state][onstate]-f" // if invisible, set icon to faded version - // in case of being revealed by T-scanner - else - icon_state = "[state][onstate]" +/obj/machinery/magnetic_module/update_icon_state() + // if invisible, set icon to faded version + // in case of being revealed by T-scanner + icon_state = "floor_magnet[on ? "" : "0"][invisibility ? "-f" : ""]" + /obj/machinery/magnetic_module/receive_signal(datum/signal/signal) var/command = signal.data["command"] @@ -70,36 +76,38 @@ Cmd(command, modifier) - -/obj/machinery/magnetic_module/proc/Cmd(var/command, var/modifier) +/obj/machinery/magnetic_module/proc/Cmd(command, modifier) if(command) switch(command) if("set-electriclevel") - if(modifier) electricity_level = modifier + if(modifier) + electricity_level = modifier if("set-magneticfield") - if(modifier) magnetic_field = modifier - + if(modifier) + magnetic_field = modifier if("add-elec") electricity_level++ - if(electricity_level > 12) - electricity_level = 12 + if(electricity_level > MAX_ELECTRICITY_LEVEL) + electricity_level = MAX_ELECTRICITY_LEVEL if("sub-elec") electricity_level-- - if(electricity_level <= 0) - electricity_level = 1 + if(electricity_level < MIN_ELECTRICITY_LEVEL) + electricity_level = MIN_ELECTRICITY_LEVEL if("add-mag") magnetic_field++ - if(magnetic_field > 4) - magnetic_field = 4 + if(magnetic_field > MAX_MAGNETIC_FIELD) + magnetic_field = MAX_MAGNETIC_FIELD if("sub-mag") magnetic_field-- - if(magnetic_field <= 0) - magnetic_field = 1 + if(magnetic_field < MIN_MAGNETIC_FIELD) + magnetic_field = MIN_MAGNETIC_FIELD if("set-x") - if(modifier) center_x = modifier + if(modifier) + center_x = modifier if("set-y") - if(modifier) center_y = modifier + if(modifier) + center_y = modifier if("N") // NORTH center_y++ @@ -120,100 +128,112 @@ if(modifier) code = modifier if("toggle-power") on = !on - if(on) - spawn() - magnetic_process() + INVOKE_ASYNC(src, PROC_REF(magnetic_process)) + /obj/machinery/magnetic_module/process() if(stat & NOPOWER) - on = 0 + on = FALSE // Sanity checks: - if(electricity_level <= 0) - electricity_level = 1 - if(magnetic_field <= 0) - magnetic_field = 1 - + if(electricity_level < MIN_ELECTRICITY_LEVEL) + electricity_level = MIN_ELECTRICITY_LEVEL + if(magnetic_field < MIN_MAGNETIC_FIELD) + magnetic_field = MIN_MAGNETIC_FIELD // Limitations: if(abs(center_x) > max_dist) center_x = max_dist if(abs(center_y) > max_dist) center_y = max_dist - if(magnetic_field > 4) - magnetic_field = 4 - if(electricity_level > 12) - electricity_level = 12 + if(magnetic_field > MAX_MAGNETIC_FIELD) + magnetic_field = MAX_MAGNETIC_FIELD + if(electricity_level > MAX_ELECTRICITY_LEVEL) + electricity_level = MAX_ELECTRICITY_LEVEL // Update power usage: if(on) - use_power = 2 - active_power_usage = electricity_level*15 + use_power = ACTIVE_POWER_USE + active_power_usage = electricity_level * 15 else - use_power = 0 - updateicon() + use_power = NO_POWER_USE + update_icon(UPDATE_ICON_STATE) -/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the pulling - if(magpulling) return - while(on) +// proc that actually does the pulling +/obj/machinery/magnetic_module/proc/magnetic_process() + if(magpulling) + return - magpulling = 1 + while(on) + magpulling = TRUE center = locate(x+center_x, y+center_y, z) if(center) - for(var/obj/M in orange(magnetic_field, center)) - if(!M.anchored && (M.flags & CONDUCT)) - step_towards(M, center) + for(var/obj/object in orange(magnetic_field, center)) + if(!object.anchored && (object.flags & CONDUCT)) + step_towards(object, center) - for(var/mob/living/silicon/S in orange(magnetic_field, center)) - if(istype(S, /mob/living/silicon/ai)) continue - step_towards(S, center) + for(var/mob/living/silicon/silicon in orange(magnetic_field, center)) + if(isAI(silicon)) + continue + step_towards(silicon, center) use_power(electricity_level * 5) - sleep(13 - electricity_level) + sleep(1.3 SECONDS - electricity_level) + + magpulling = FALSE - magpulling = 0 /obj/machinery/magnetic_controller name = "Magnetic Control Console" icon = 'icons/obj/machines/airlock_machines.dmi' // uses an airlock machine icon, THINK GREEN HELP THE ENVIRONMENT - RECYCLING! icon_state = "airlock_control_standby" - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 45 frequency = AIRLOCK_FREQ var/code = 0 var/list/magnets = list() var/title = "Magnetic Control Console" - var/autolink = 0 // if set to 1, can't probe for other magnets! + /// If set to TRUE, can't probe for other magnets! + var/autolink = FALSE + var/probing = FALSE - var/pathpos = 1 // position in the path - var/path = "NULL" // text path of the magnet - var/speed = 1 // lowest = 1, highest = 10 - var/list/rpath = list() // real path of the magnet, used in iterator + /// Position in the path + var/pathpos = 1 + /// Text path of the magnet + var/path = "NULL" + var/speed = MIN_CONTROLLER_SPEED + /// Real path of the magnet, used in iterator + var/list/rpath = list() + var/static/list/valid_paths = list("n", "s", "e", "w", "c", "r") - var/moving = 0 // 1 if scheduled to loop - var/looping = 0 // 1 if looping + /// TRUE if scheduled to loop + var/moving = FALSE + /// TRUE if looping + var/looping = FALSE -/obj/machinery/magnetic_controller/New() - ..() +/obj/machinery/magnetic_controller/Initialize(mapload) + . = ..() - if(autolink) - for(var/obj/machinery/magnetic_module/M in GLOB.machines) - if(M.freq == frequency && M.code == code) - magnets.Add(M) + radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) + if(path) // check for default path + filter_path() // renders rpath - spawn(45) // must wait for map loading to finish - if(SSradio) - radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) + if(autolink) + return INITIALIZE_HINT_LATELOAD - if(path) // check for default path - filter_path() // renders rpath +/obj/machinery/magnetic_controller/LateInitialize() + ..() + if(autolink) + // GLOB.machines is populated in /machinery/Initialize + // so linkage gets delayed until that one finished. + link_magnets() /obj/machinery/magnetic_controller/Destroy() @@ -222,15 +242,30 @@ radio_connection = null return ..() + +/obj/machinery/magnetic_controller/proc/link_magnets() + magnets = list() + for(var/obj/machinery/magnetic_module/module in GLOB.machines) + if(module.freq == frequency && module.code == code) + magnets += module + RegisterSignal(module, COMSIG_PARENT_QDELETING, PROC_REF(on_magnet_del), TRUE) + + +/obj/machinery/magnetic_controller/proc/on_magnet_del(magnet) + SIGNAL_HANDLER + magnets -= magnet + + /obj/machinery/magnetic_controller/process() - if(magnets.len == 0 && autolink) - for(var/obj/machinery/magnetic_module/M in GLOB.machines) - if(M.freq == frequency && M.code == code) - magnets.Add(M) + if(!length(magnets) && autolink) + for(var/obj/machinery/magnetic_module/module in GLOB.machines) + if(module.freq == frequency && module.code == code) + magnets += module /obj/machinery/magnetic_controller/attack_ai(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) + /obj/machinery/magnetic_controller/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) @@ -244,13 +279,13 @@ Probe Generators
"} - if(magnets.len >= 1) + if(length(magnets)) dat += "Magnets confirmed:
" var/i = 0 - for(var/obj/machinery/magnetic_module/M in magnets) + for(var/obj/machinery/magnetic_module/module as anything in magnets) i++ - dat += "     < \[[i]\] ([M.on ? "On":"Off"]) | Electricity level: - [M.electricity_level] +; Magnetic field: - [M.magnetic_field] +
" + dat += "     < \[[i]\] ([module.on ? "On":"Off"]) | Electricity level: - [module.electricity_level] +; Magnetic field: - [module.magnetic_field] +
" add_fingerprint(user) dat += "
Speed: - [speed] +
" @@ -261,6 +296,7 @@ user << browse(dat, "window=magnet;size=400x500") onclose(user, "magnet") + /obj/machinery/magnetic_controller/Topic(href, href_list) if(stat & (BROKEN|NOPOWER)) return @@ -295,9 +331,7 @@ // Broadcast the signal radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) - - spawn(1) - updateUsrDialog() // pretty sure this increases responsiveness + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj, updateUsrDialog)), 0.1 SECONDS) // pretty sure this increases responsiveness if(href_list["operation"]) switch(href_list["operation"]) @@ -312,7 +346,7 @@ if("setpath") var/newpath = sanitize(copytext_char(input(usr, "Please define a new path!",,path) as text|null,1,MAX_MESSAGE_LEN)) if(newpath && newpath != "") - moving = 0 // stop moving + moving = FALSE // stop moving path = newpath pathpos = 1 // reset position filter_path() // renders rpath @@ -320,20 +354,21 @@ if("togglemoving") moving = !moving if(moving) - spawn() MagnetMove() - + INVOKE_ASYNC(src, PROC_REF(MagnetMove)) updateUsrDialog() + /obj/machinery/magnetic_controller/proc/MagnetMove() - if(looping) return + if(looping) + return - while(moving && rpath.len >= 1) + while(moving && length(rpath) >= 1) if(stat & (BROKEN|NOPOWER)) break - looping = 1 + looping = TRUE // Prepare the radio signal var/datum/signal/signal = new @@ -342,7 +377,7 @@ signal.frequency = frequency signal.data["code"] = code - if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list! + if(pathpos > length(rpath)) // if the position is greater than the length, we just loop through the list! pathpos = 1 var/nextmove = uppertext(rpath[pathpos]) // makes it un-case-sensitive @@ -356,26 +391,24 @@ signal.data["command"] = nextmove - pathpos++ // increase iterator // Broadcast the signal - spawn() - radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + INVOKE_ASYNC(radio_connection, TYPE_PROC_REF(/datum/radio_frequency, post_signal), src, signal, RADIO_MAGNETS) if(speed == 10) sleep(1) else sleep(12-speed) - looping = 0 + looping = FALSE /obj/machinery/magnetic_controller/proc/filter_path() // Generates the rpath variable using the path string, think of this as "string2list" // Doesn't use params2list() because of the akward way it stacks entities rpath = list() // clear rpath - var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length + var/maximum_character = min(MAX_PATH_LENGTH, length(path) ) // chooses the maximum length of the iterator. 50 max length for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path @@ -385,3 +418,13 @@ rpath += copytext(path, i, i+1) // else, add to list // there doesn't HAVE to be separators but it makes paths syntatically visible + + +#undef MIN_CONTROLLER_SPEED +#undef MAX_CONTROLLER_SPEED +#undef MIN_ELECTRICITY_LEVEL +#undef MAX_ELECTRICITY_LEVEL +#undef MIN_MAGNETIC_FIELD +#undef MAX_MAGNETIC_FIELD +#undef MAX_PATH_LENGTH + diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 22405f41daf..6dd86395959 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -3,7 +3,7 @@ desc = "Shoots things into space." icon = 'icons/obj/objects.dmi' icon_state = "mass_driver" - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 50 @@ -27,7 +27,7 @@ if(do_after(user, 30 * I.toolspeed * gettoolspeedmod(user), target = src)) var/obj/machinery/mass_driver_frame/F = new(get_turf(src)) F.dir = dir - F.anchored = 1 + F.anchored = TRUE F.build = 4 F.update_icon() qdel(src) @@ -90,30 +90,30 @@ icon = 'icons/obj/objects.dmi' icon_state = "mass_driver_frame" density = 0 - anchored = 0 + anchored = FALSE var/build = 0 /obj/machinery/mass_driver_frame/attackby(var/obj/item/W as obj, var/mob/user as mob) switch(build) if(0) // Loose frame - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) to_chat(user, "You begin to anchor \the [src] on the floor.") playsound(get_turf(src), W.usesound, 50, 1) if(do_after(user, 10 * W.toolspeed * gettoolspeedmod(user), target = src) && (build == 0)) add_fingerprint(user) to_chat(user, span_notice("You anchor \the [src]!")) - anchored = 1 + anchored = TRUE build++ return 1 return if(1) // Fixed to the floor - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) to_chat(user, "You begin to de-anchor \the [src] from the floor.") playsound(get_turf(src), W.usesound, 50, 1) if(do_after(user, 10 * W.toolspeed * gettoolspeedmod(user), target = src) && (build == 1)) add_fingerprint(user) build-- - anchored = 0 + anchored = FALSE to_chat(user, span_notice("You de-anchored \the [src]!")) return 1 if(2) // Welded to the floor @@ -128,7 +128,7 @@ build++ return if(3) // Wired - if(istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour == TOOL_WIRECUTTER) to_chat(user, "You begin to remove the wiring from \the [src].") if(do_after(user, 10 * W.toolspeed * gettoolspeedmod(user), target = src) && (build == 3)) add_fingerprint(user) @@ -149,7 +149,7 @@ return 1 return if(4) // Grille in place - if(istype(W, /obj/item/crowbar)) + if(W.tool_behaviour == TOOL_CROWBAR) to_chat(user, "You begin to pry off the grille from \the [src]...") playsound(get_turf(src), W.usesound, 50, 1) if(do_after(user, 30 * W.toolspeed * gettoolspeedmod(user), target = src) && (build == 4)) @@ -157,7 +157,7 @@ new /obj/item/stack/rods(loc,2) build-- return 1 - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) add_fingerprint(user) to_chat(user, "You finalize the Mass Driver...") playsound(get_turf(src), W.usesound, 50, 1) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 881acfeae39..dc247487346 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -10,7 +10,7 @@ level = 1 // underfloor layer = WIRE_LAYER plane = FLOOR_PLANE - anchored = 1 + anchored = TRUE max_integrity = 500 armor = list(melee = 70, bullet = 70, laser = 70, energy = 70, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 80) var/open = 0 // true if cover is open @@ -76,32 +76,22 @@ // hide the object if turf is intact /obj/machinery/navbeacon/hide(intact) invisibility = intact ? INVISIBILITY_MAXIMUM : 0 - updateicon() + update_icon(UPDATE_ICON_STATE) + // update the icon_state -/obj/machinery/navbeacon/proc/updateicon() - var/state="navbeacon[open]" +/obj/machinery/navbeacon/update_icon_state() + // if invisible, set icon to faded version + // in case revealed by T-scanner + icon_state = "navbeacon[open][invisibility ? "-f" : ""]" - if(invisibility) - icon_state = "[state]-f" // if invisible, set icon to faded version - // in case revealed by T-scanner - else - icon_state = "[state]" /obj/machinery/navbeacon/attackby(obj/item/I, mob/user, params) var/turf/T = loc if(T.intact) return // prevent intraction when T-scanner revealed - if(istype(I, /obj/item/screwdriver)) - add_fingerprint(user) - open = !open - - user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", span_notice("You [open ? "open" : "close"] the beacon's cover.")) - - updateicon() - - else if(I.GetID()) + if(I.GetID()) if(open) if(allowed(user)) add_fingerprint(user) @@ -115,6 +105,20 @@ else return ..() + +/obj/machinery/navbeacon/screwdriver_act(mob/living/user, obj/item/I) + var/turf/T = get_turf(src) + if(T.intact) + return FALSE + open = !open + user.visible_message( + "[user] [open ? "opens" : "closes"] the beacon's cover.", + span_notice("You [open ? "open" : "close"] the beacon's cover."), + ) + update_icon(UPDATE_ICON_STATE) + return TRUE + + /obj/machinery/navbeacon/attack_ai(mob/user) interact(user, 1) @@ -123,7 +127,7 @@ interact(user, 0) /obj/machinery/navbeacon/interact(mob/user, ai = 0) - var/turf/T = loc + var/turf/T = get_turf(src) if(T.intact) return // prevent intraction when T-scanner revealed @@ -220,8 +224,8 @@ Transponder Codes:
    "} /obj/machinery/navbeacon/invisible - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT /obj/machinery/navbeacon/invisible/hide(intact) - invisibility = INVISIBILITY_MAXIMUM - updateicon() + invisibility = INVISIBILITY_ABSTRACT + update_icon(UPDATE_ICON_STATE) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index e5c4a71290d..7e842e4225c 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -522,7 +522,7 @@ w_class = WEIGHT_CLASS_BULKY /obj/item/pipe_meter/attackby(var/obj/item/W as obj, var/mob/user as mob, params) - if(!istype(W, /obj/item/wrench)) + if(W.tool_behaviour != TOOL_WRENCH) return ..() if(!locate(/obj/machinery/atmospherics/pipe, src.loc)) to_chat(user, span_warning("You need to fasten it to a pipe")) @@ -548,7 +548,7 @@ w_class = WEIGHT_CLASS_BULKY /obj/item/pipe_gsensor/attackby(var/obj/item/W as obj, var/mob/user as mob) - if(!istype(W, /obj/item/wrench)) + if(!W.tool_behaviour == TOOL_WRENCH) return ..() var/obj/machinery/atmospherics/air_sensor/sensor = new(loc) sensor.add_fingerprint(user) diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 14cf12c074f..b3231773dbb 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -102,7 +102,7 @@ user.drop_transfer_item_to_loc(W, src) qdel(W) return - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) if(unwrenched==0) playsound(loc, W.usesound, 50, 1) to_chat(user, span_notice("You begin to unfasten \the [src] from the floor...")) @@ -111,7 +111,7 @@ "[user] unfastens \the [src].", \ span_notice("You have unfastened \the [src]. Now it can be pulled somewhere else."), \ "You hear ratchet.") - anchored = 0 + anchored = FALSE stat |= MAINT unwrenched = 1 if(usr.machine==src) @@ -124,7 +124,7 @@ "[user] fastens \the [src].", \ span_notice("You have fastened \the [src]. Now it can dispense pipes."), \ "You hear ratchet.") - anchored = 1 + anchored = TRUE stat &= ~MAINT unwrenched = 0 power_change() @@ -138,17 +138,18 @@ icon_state = "pipe_d" //Allow you to drag-drop disposal pipes into it -/obj/machinery/pipedispenser/disposal/MouseDrop_T(var/obj/structure/disposalconstruct/pipe, mob/usr) - if(usr.incapacitated()) +/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/disposalconstruct/pipe, mob/user, params) + if(user.incapacitated()) return - if(!istype(pipe) || get_dist(usr, src) > 1 || get_dist(src, pipe) > 1 ) + if(!istype(pipe) || get_dist(user, src) > 1 || get_dist(src, pipe) > 1 ) return if(pipe.anchored) return qdel(pipe) + return TRUE /obj/machinery/pipedispenser/disposal/attack_hand(mob/user) if(..()) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index db8c24b2fbc..26fae76f1c3 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -9,7 +9,7 @@ desc = "A controller for the nearby pool." icon = 'icons/obj/machines/airlock_machines.dmi' icon_state = "airlock_control_standby" - anchored = 1 //this is what I get for assuming /obj/machinery has anchored set to 1 by default + anchored = TRUE //this is what I get for assuming /obj/machinery has anchored set to 1 by default var/list/linkedturfs = list() //List contains all of the linked pool turfs to this controller, assignment happens on New() var/mobinpool = list() //List contains all of the mob in the pool, to prevent looping through the entire area to find mobs inside.. var/decalinpool = list() // List containing all of the cleanable decals in pool @@ -20,7 +20,7 @@ var/deep_water = FALSE //set to 1 to drown even standing people /obj/machinery/poolcontroller/invisible - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT name = "Water Controller" desc = "An invisible water controller. Players shouldn't see this." diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm index 562db4074f3..4edc5fc4162 100644 --- a/code/game/machinery/portable_tag_turret.dm +++ b/code/game/machinery/portable_tag_turret.dm @@ -37,7 +37,7 @@ ) return data -/obj/machinery/porta_turret/tag/update_icon() +/obj/machinery/porta_turret/tag/update_icon_state() if(!anchored) icon_state = "turretCover" return diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index e2774ae3aef..18c3e40fb49 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -153,8 +153,10 @@ eprojectile = /obj/item/projectile/beam/pulse eshot_sound = 'sound/weapons/pulse.ogg' + GLOBAL_LIST_EMPTY(turret_icons) -/obj/machinery/porta_turret/update_icon() + +/obj/machinery/porta_turret/update_icon_state() if(!GLOB.turret_icons) GLOB.turret_icons = list() GLOB.turret_icons["open"] = image(icon, "openTurretCover") @@ -303,19 +305,16 @@ GLOBAL_LIST_EMPTY(turret_icons) req_access = list() check_one_access = !check_one_access -/obj/machinery/porta_turret/power_change() - if(powered() || !use_power) - stat &= ~NOPOWER - update_icon() - else - spawn(rand(0, 15)) - stat |= NOPOWER - update_icon() + +/obj/machinery/porta_turret/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) /obj/machinery/porta_turret/attackby(obj/item/I, mob/user) if((stat & BROKEN) && !syndicate) - if(istype(I, /obj/item/crowbar)) + if(I.tool_behaviour == TOOL_CROWBAR) //If the turret is destroyed, you can remove it with a crowbar to //try and salvage its components to_chat(user, span_notice("You begin prying the metal coverings off.")) @@ -334,7 +333,7 @@ GLOBAL_LIST_EMPTY(turret_icons) to_chat(user, span_notice("You remove the turret but did not manage to salvage anything.")) qdel(src) // qdel - else if((istype(I, /obj/item/wrench))) + else if(I.tool_behaviour == TOOL_WRENCH) if(enabled || raised) to_chat(user, span_warning("You cannot unsecure an active turret!")) return @@ -352,18 +351,12 @@ GLOBAL_LIST_EMPTY(turret_icons) wrenching = TRUE if(do_after(user, 50 * I.toolspeed * gettoolspeedmod(user), target = src)) - add_fingerprint(user) //This code handles moving the turret around. After all, it's a portable turret! - if(!anchored) - playsound(loc, I.usesound, 100, 1) - anchored = TRUE - update_icon() - to_chat(user, span_notice("You secure the exterior bolts on the turret.")) - else if(anchored) - playsound(loc, I.usesound, 100, 1) - anchored = FALSE - to_chat(user, span_notice("You unsecure the exterior bolts on the turret.")) - update_icon() + add_fingerprint(user) + playsound(loc, I.usesound, 100, TRUE) + anchored = !anchored + update_icon(UPDATE_ICON_STATE) + to_chat(user, "You [anchored ? "" : "un"]secure the exterior bolts on the turret.") wrenching = FALSE else if(I.GetID() || ispda(I)) @@ -490,7 +483,7 @@ GLOBAL_LIST_EMPTY(turret_icons) stat |= BROKEN //enables the BROKEN bit if(spark_system) spark_system.start() //creates some sparks because they look cool - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/porta_turret/process() //the main machinery process @@ -640,7 +633,7 @@ GLOBAL_LIST_EMPTY(turret_icons) return set_raised_raising(raised, TRUE) playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - update_icon() + update_icon(UPDATE_ICON_STATE) var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) flick_holder.layer = layer + 0.1 @@ -649,7 +642,7 @@ GLOBAL_LIST_EMPTY(turret_icons) qdel(flick_holder) set_raised_raising(TRUE, FALSE) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/porta_turret/proc/popDown() //pops the turret down last_target = null @@ -661,7 +654,7 @@ GLOBAL_LIST_EMPTY(turret_icons) return set_raised_raising(raised, TRUE) playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - update_icon() + update_icon(UPDATE_ICON_STATE) var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) flick_holder.layer = layer + 0.1 @@ -670,7 +663,7 @@ GLOBAL_LIST_EMPTY(turret_icons) qdel(flick_holder) set_raised_raising(FALSE, FALSE) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/porta_turret/on_assess_perp(mob/living/carbon/human/perp) if((check_access || attacked) && !allowed(perp)) @@ -709,7 +702,7 @@ GLOBAL_LIST_EMPTY(turret_icons) if(!istype(T) || !istype(U)) return - update_icon() + update_icon(UPDATE_ICON_STATE) var/obj/item/projectile/A if(emagged || lethal) if(eprojectile) @@ -807,7 +800,7 @@ GLOBAL_LIST_EMPTY(turret_icons) //this is a bit unwieldy but self-explanatory switch(build_step) if(0) //first step - if(istype(I, /obj/item/wrench) && !anchored) + if(I.tool_behaviour == TOOL_WRENCH && !anchored) add_fingerprint(user) playsound(loc, I.usesound, 100, 1) to_chat(user, span_notice("You secure the external bolts.")) @@ -815,7 +808,7 @@ GLOBAL_LIST_EMPTY(turret_icons) build_step = 1 return - else if(istype(I, /obj/item/crowbar) && !anchored) + else if(I.tool_behaviour == TOOL_CROWBAR && !anchored) playsound(loc, I.usesound, 75, 1) to_chat(user, span_notice("You dismantle the turret construction.")) new /obj/item/stack/sheet/metal( loc, 5) @@ -834,7 +827,7 @@ GLOBAL_LIST_EMPTY(turret_icons) to_chat(user, span_warning("You need two sheets of metal to continue construction.")) return - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) playsound(loc, I.usesound, 75, 1) to_chat(user, span_notice("You unfasten the external bolts.")) @@ -844,7 +837,7 @@ GLOBAL_LIST_EMPTY(turret_icons) if(2) - if(istype(I, /obj/item/wrench)) + if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) playsound(loc, I.usesound, 100, 1) to_chat(user, span_notice("You bolt the metal armor into place.")) @@ -876,7 +869,7 @@ GLOBAL_LIST_EMPTY(turret_icons) qdel(I) //delete the gun :( qdel return - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) playsound(loc, I.usesound, 100, 1) to_chat(user, span_notice("You remove the turret's metal armor bolts.")) @@ -897,7 +890,7 @@ GLOBAL_LIST_EMPTY(turret_icons) //attack_hand() removes the gun if(5) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) add_fingerprint(user) playsound(loc, I.usesound, 100, 1) build_step = 6 @@ -917,13 +910,13 @@ GLOBAL_LIST_EMPTY(turret_icons) to_chat(user, span_warning("You need two sheets of metal to continue construction.")) return - else if(istype(I, /obj/item/screwdriver)) + else if(I.tool_behaviour == TOOL_SCREWDRIVER) add_fingerprint(user) playsound(loc, I.usesound, 100, 1) build_step = 5 to_chat(user, span_notice("You open the internal access hatch.")) return - else if(istype(I, /obj/item/crowbar)) + else if(I.tool_behaviour == TOOL_CROWBAR) add_fingerprint(user) playsound(loc, I.usesound, 75, 1) to_chat(user, span_notice("You pry off the turret's exterior armor.")) @@ -1055,7 +1048,7 @@ GLOBAL_LIST_EMPTY(turret_icons) depotarea.declare_started() return ..(target) -/obj/machinery/porta_turret/syndicate/update_icon() +/obj/machinery/porta_turret/syndicate/update_icon_state() if(stat & BROKEN) icon_state = icon_state_destroyed else if(enabled) diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index a5a5476170e..bbe4830223c 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -3,7 +3,7 @@ desc = "A bluespace quantum-linked telepad used for teleporting objects to other quantum pads." icon = 'icons/obj/telescience.dmi' icon_state = "qpad-idle" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 200 active_power_usage = 5000 diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 7fd72aa7e93..6b729917c26 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "borgcharger0" density = 1 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 1000 @@ -26,7 +26,7 @@ component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/cell/high(null) RefreshParts() - build_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/recharge_station/ert/New() ..() @@ -86,7 +86,7 @@ if(A == occupant) occupant = null updateUsrDialog() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/recharge_station/narsie_act() go_out() @@ -124,15 +124,17 @@ go_out() ..(severity) -/obj/machinery/recharge_station/proc/build_icon() - if(NOPOWER|BROKEN) - if(src.occupant) - icon_state = "borgcharger1" + +/obj/machinery/recharge_station/update_icon_state() + if(occupant) + if(stat & (NOPOWER|BROKEN)) + icon_state = "borgcharger2" else - icon_state = "borgcharger0" + icon_state = "borgcharger1" else icon_state = "borgcharger0" + /obj/machinery/recharge_station/attackby(obj/item/I, mob/user, params) if(exchange_parts(user, I)) return @@ -167,14 +169,16 @@ if(repairs) H.heal_overall_damage(repairs, repairs, TRUE, 0, 1) -/obj/machinery/recharge_station/proc/go_out() +/obj/machinery/recharge_station/proc/go_out(mob/user = usr) if(!occupant) return + if(user?.incapacitated() || user?.restrained()) + return occupant.forceMove(loc) occupant = null - build_icon() + update_icon(UPDATE_ICON_STATE) use_power = IDLE_POWER_USE - return + /obj/machinery/recharge_station/proc/restock_modules() if(src.occupant) @@ -242,13 +246,16 @@ /obj/machinery/recharge_station/verb/move_eject() set category = "Object" set src in oview(1) - if(usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return + go_out(usr) + -/obj/machinery/recharge_station/verb/move_inside(var/mob/user = usr) +/obj/machinery/recharge_station/verb/move_inside_verb() + set category = "Object" + set src in oview(1) + move_inside(usr) + + +/obj/machinery/recharge_station/proc/move_inside(mob/user = usr) set category = "Object" set src in oview(1) if(!user || !usr) @@ -302,6 +309,6 @@ occupant = user add_fingerprint(user) - build_icon() + update_icon(UPDATE_ICON_STATE) update_use_power(1) - return + diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index edcc5ee16b4..590147d275c 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/machines/recycling.dmi' icon_state = "grinder-o0" layer = MOB_LAYER+1 // Overhead - anchored = 1 + anchored = TRUE density = 1 damage_deflection = 15 var/emergency_mode = FALSE // Temporarily stops machine if it detects a mob @@ -26,7 +26,7 @@ component_parts += new /obj/item/stock_parts/matter_bin(null) component_parts += new /obj/item/stock_parts/manipulator(null) RefreshParts() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/recycler/RefreshParts() var/amt_made = 0 @@ -46,9 +46,10 @@ . += "The operation light is [emergency_mode ? "off. [src] has detected a forbidden object with its sensors, and has shut down temporarily." : "on. [src] is active."]" . += "The safety sensor light is [emagged ? "off!" : "on."]" -/obj/machinery/recycler/power_change() - ..() - update_icon() +/obj/machinery/recycler/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) /obj/machinery/recycler/attackby(obj/item/I, mob/user, params) if(exchange_parts(user, I)) @@ -68,25 +69,25 @@ return TRUE - /obj/machinery/recycler/emag_act(mob/user) if(!emagged) emagged = 1 if(emergency_mode) emergency_mode = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(user) to_chat(user, span_notice("You use the cryptographic sequencer on the [name].")) add_attack_logs(user, src, "emagged") -/obj/machinery/recycler/update_icon() - ..() + +/obj/machinery/recycler/update_icon_state() var/is_powered = !(stat & (BROKEN|NOPOWER)) if(emergency_mode) - is_powered = 0 + is_powered = FALSE icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end + // This is purely for admin possession !FUN!. /obj/machinery/recycler/Bump(atom/movable/AM) ..() @@ -148,14 +149,14 @@ /obj/machinery/recycler/proc/emergency_stop(mob/living/L) playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) emergency_mode = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) L.loc = loc addtimer(CALLBACK(src, PROC_REF(reboot)), SAFETY_COOLDOWN) /obj/machinery/recycler/proc/reboot() playsound(loc, 'sound/machines/ping.ogg', 50, 0) emergency_mode = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/recycler/proc/crush_living(mob/living/L) @@ -176,7 +177,7 @@ if(!blood && !issilicon(L)) blood = 1 - update_icon() + update_icon(UPDATE_ICON_STATE) // Remove and recycle the equipped items if(eat_victim_items) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index fc41a8d709c..5ddf594e0a5 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -41,7 +41,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) desc = "A console intended to send requests to different departments on the station." anchored = TRUE icon = 'icons/obj/machines/terminals.dmi' - icon_state = "req_comp0" + icon_state = "req_comp_off" max_integrity = 300 armor = list("melee" = 70, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department @@ -62,7 +62,6 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) var/message = "" var/recipient = ""; //the department which will be receiving the message var/priority = -1 ; //Priority of the message being sent - light_range = 0 var/datum/announcement/announcement = new var/list/shipping_log = list() var/ship_tag_name = "" @@ -71,16 +70,6 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) var/obj/item/radio/Radio var/radiochannel = "" -/obj/machinery/requests_console/power_change() - ..() - update_icon() - -/obj/machinery/requests_console/update_icon() - if(stat & NOPOWER) - if(icon_state != "req_comp_off") - icon_state = "req_comp_off" - else - icon_state = "req_comp[newmessagepriority]" /obj/machinery/requests_console/Initialize(mapload) Radio = new /obj/item/radio(src) @@ -102,8 +91,8 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) if(departmentType & RC_INFO) GLOB.req_console_information |= department - // NOT BOOLEAN. DO NOT CONVERT. - set_light(1) + update_icon(UPDATE_OVERLAYS) + /obj/machinery/requests_console/Destroy() GLOB.allRequestConsoles -= src @@ -134,6 +123,28 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) ui_interact(user) + +/obj/machinery/requests_console/power_change(forced = FALSE) + if(!..()) + return + if(stat & NOPOWER) + set_light(0) + else + set_light(1, LIGHTING_MINIMUM_POWER) + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/requests_console/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER) + return + + . += "req_comp[newmessagepriority]" + underlays += emissive_appearance(icon, "req_comp_lightmask") + + /obj/machinery/requests_console/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) @@ -251,8 +262,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) for(var/obj/machinery/requests_console/Console in GLOB.allRequestConsoles) if(Console.department == department) Console.newmessagepriority = RQ_NONEW_MESSAGES - Console.icon_state = "req_comp0" - Console.set_light(1) + Console.update_icon(UPDATE_OVERLAYS) if(tempScreen == RCS_MAINMENU) reset_message() screen = tempScreen @@ -340,7 +350,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) capitalize(title) if(newmessagepriority < priority) newmessagepriority = priority - update_icon() + update_icon(UPDATE_OVERLAYS) if(!silent) playsound(loc, 'sound/machines/twobeep.ogg', 50, TRUE) atom_say(title) @@ -350,7 +360,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) write_to_message_log("Высокий приоритет - От: [linkedSender] - [message]") else // Normal write_to_message_log("От: [linkedSender] - [message]") - set_light(2) + /obj/machinery/requests_console/proc/write_to_message_log(message) message_log = list(message) + message_log diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 54cee71d5fe..543191364f7 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -90,7 +90,7 @@ /obj/machinery/shield/cult/barrier/Initialize() . = ..() - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT /obj/machinery/shield/cult/barrier/Destroy() if(parent_rune && !QDELETED(parent_rune)) @@ -121,7 +121,7 @@ visible = TRUE else // Currently visible density = FALSE // Turn invisible - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT visible = FALSE air_update_turf(1) @@ -134,7 +134,7 @@ icon_state = "shieldoff" density = 1 opacity = FALSE - anchored = 0 + anchored = FALSE pressure_resistance = 2*ONE_ATMOSPHERE req_access = list(ACCESS_ENGINE) var/const/max_health = 100 @@ -312,8 +312,8 @@ desc = "A shield generator." icon = 'icons/obj/stationobjs.dmi' icon_state = "shieldgen" - anchored = 0 - density = 1 + anchored = FALSE + density = TRUE req_access = list(ACCESS_TELEPORTER) var/active = 0 var/power = 0 @@ -469,7 +469,7 @@ /obj/machinery/shieldwallgen/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/wrench)) + if(I.tool_behaviour == TOOL_WRENCH) if(active) to_chat(user, "Turn off the field generator first.") return @@ -479,7 +479,7 @@ state = 1 playsound(loc, I.usesound, 75, 1) to_chat(user, "You secure the external reinforcing bolts to the floor.") - anchored = 1 + anchored = TRUE return else if(state == 1) @@ -487,7 +487,7 @@ state = 0 playsound(loc, I.usesound, 75, 1) to_chat(user, "You undo the external reinforcing bolts.") - anchored = 0 + anchored = FALSE return if(I.GetID() || ispda(I)) @@ -539,7 +539,7 @@ desc = "An energy shield." icon = 'icons/effects/effects.dmi' icon_state = "shieldwall" - anchored = 1 + anchored = TRUE density = 1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF light_range = 3 diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 8e6c6cfe05f..757dd285018 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -3,7 +3,7 @@ desc = "Gambling for the antisocial." icon = 'icons/obj/economy.dmi' icon_state = "slots-off" - anchored = 1 + anchored = TRUE density = 1 var/plays = 0 var/working = 0 @@ -15,6 +15,11 @@ add_fingerprint(user) ui_interact(user) + +/obj/machinery/slot_machine/update_icon_state() + icon_state = "slots-[working ? "on" : "off"]" + + /obj/machinery/slot_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, 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) @@ -48,7 +53,7 @@ return plays++ working = TRUE - icon_state = "slots-on" + update_icon(UPDATE_ICON_STATE) playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) addtimer(CALLBACK(src, PROC_REF(spin_slots), usr.name), 25) @@ -84,7 +89,7 @@ result = "No luck!" resultlvl = "orange" working = FALSE - icon_state = "slots-off" + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) // Push a UI update /obj/machinery/slot_machine/proc/win_money(amt, sound='sound/machines/ping.ogg') diff --git a/code/game/machinery/snow_machine.dm b/code/game/machinery/snow_machine.dm index 2a1ee2fc5ad..8574f2b608d 100644 --- a/code/game/machinery/snow_machine.dm +++ b/code/game/machinery/snow_machine.dm @@ -84,19 +84,22 @@ continue make_snowcloud(TF) -/obj/machinery/snow_machine/power_change() - ..() + +/obj/machinery/snow_machine/power_change(forced = FALSE) + if(!..()) + return if(!powered()) turn_on_or_off(FALSE, TRUE) - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/machinery/snow_machine/update_icon() - ..() + +/obj/machinery/snow_machine/update_icon_state() if(panel_open) icon_state = "snow_machine_openpanel" else icon_state = "snow_machine_[active ? "on" : "off"]" + /obj/machinery/snow_machine/proc/affect_turf_temperature(turf/T, modifier) if(!issimulatedturf(T) || T.density) return @@ -132,5 +135,5 @@ if(!active && give_message) visible_message(span_warning("[src] switches off!")) playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE) - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index a52caa410dc..d4d71d67ea1 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -1,5 +1,5 @@ /obj/machinery/space_heater - anchored = 0 + anchored = FALSE density = 1 icon = 'icons/obj/pipes_and_stuff/atmospherics/atmos.dmi' icon_state = "sheater0" @@ -26,12 +26,16 @@ QDEL_NULL(cell) return ..() -/obj/machinery/space_heater/update_icon() - overlays.Cut() + +/obj/machinery/space_heater/update_icon_state() icon_state = "sheater[on]" + + +/obj/machinery/space_heater/update_overlays() + . = ..() if(open) - overlays += "sheater-open" - return + . += "sheater-open" + /obj/machinery/space_heater/examine(mob/user) . = ..() diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 1232ef3c13f..0a6e153a28c 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -1,8 +1,4 @@ -#define FONT_SIZE "5pt" -#define FONT_COLOR "#09f" -#define WARNING_FONT_COLOR "#f90" -#define FONT_STYLE "Small Fonts" -#define SCROLL_SPEED 2 +GLOBAL_LIST_EMPTY(status_displays) GLOBAL_LIST_INIT(statdisp_picture_colors, list( "" = COLOR_GRAY, @@ -47,56 +43,75 @@ GLOBAL_LIST_INIT(statdisp_picture_colors, list( icon = 'icons/obj/status_display.dmi' icon_state = "frame" name = "дисплей статуса" - anchored = 1 - density = 0 + anchored = TRUE + density = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 - var/mode = 1 // 0 = Blank - // 1 = Shuttle timer - // 2 = Arbitrary message(s) - // 3 = alert picture - // 4 = Station time - - var/picture_state // icon_state of alert picture - var/message1 = "" // message line 1 - var/message2 = "" // message line 2 - var/index1 // display index for scrolling messages or 0 if non-scrolling - var/index2 - - frequency = DISPLAY_FREQ // radio frequency - - var/friendc = 0 // track if Friend Computer mode - var/ignore_friendc = 0 - maptext_height = 26 maptext_width = 32 maptext_y = -1 + /// Status display mode + VAR_PRIVATE/mode = STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME + /// Icon_state of alert picture + var/picture_state + /// Are we spooked? + var/spookymode = FALSE + /// Line 1 of a custom message, if any + var/message1 + /// Line 2 of a custom message, if any + var/message2 + /// Is this a supply display? + var/is_supply = FALSE + /// Track if Friend Computer mode + var/friendc = FALSE + /// Display indexes for scrolling messages, or 0 if non-scrolling + var/index1 + var/index2 + +/obj/machinery/status_display/Initialize() + . = ..() + GLOB.status_displays |= src + update_icon(UPDATE_OVERLAYS) /obj/machinery/status_display/Destroy() - if(SSradio) - SSradio.remove_object(src,frequency) + GLOB.status_displays -= src return ..() -// register for radio system -/obj/machinery/status_display/Initialize() - ..() - if(SSradio) - SSradio.add_object(src, frequency) -// timed process +/obj/machinery/status_display/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER) + return + + if(picture_state) + . += picture_state + + underlays += emissive_appearance(icon, "lightmask") + + +/obj/machinery/status_display/power_change(forced = FALSE) + if(!..()) + return + update_display_light() + update_icon(UPDATE_OVERLAYS) + + /obj/machinery/status_display/process() - if(stat & (BROKEN|NOPOWER)) + if(stat & NOPOWER) + remove_display() return - update() -/obj/machinery/status_display/power_change() - ..() - if(stat & (BROKEN|NOPOWER)) + if(spookymode) + spookymode = FALSE remove_display() - else if(picture_state) - set_picture(picture_state) + return + + update() + /obj/machinery/status_display/emp_act(severity) if(stat & (BROKEN|NOPOWER)) @@ -105,42 +120,48 @@ GLOBAL_LIST_INIT(statdisp_picture_colors, list( set_picture("ai_bsod") ..(severity) + /obj/machinery/status_display/flicker() if(stat & (NOPOWER | BROKEN)) return FALSE - mode = STATUS_DISPLAY_ALERT - remove_display() - set_picture("ai_tribunal_malf") + spookymode = TRUE return TRUE + // set what is displayed /obj/machinery/status_display/proc/update() - if(friendc && !ignore_friendc) + if(friendc) if(picture_state != "ai_friend") mode = STATUS_DISPLAY_ALERT set_picture("ai_friend") - return TRUE + return switch(mode) - if(STATUS_DISPLAY_BLANK) //blank + // Blank + if(STATUS_DISPLAY_BLANK) remove_display() - return TRUE - if(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) //emergency shuttle timer - var/use_warn = 0 + return + + // Emergency shuttle timer + if(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) + var/use_warn = FALSE + if(SSshuttle.emergency && SSshuttle.emergency.timer) - use_warn = 1 + use_warn = TRUE message1 = "-[SSshuttle.emergency.getModeStr()]-" message2 = SSshuttle.emergency.getTimerStr() if(length(message2) > DISPLAY_CHARS_PER_LINE) message2 = "Error!" + else message1 = "ВРЕМЯ" message2 = station_time_timestamp("hh:mm") update_display(message1, message2, use_warn) - return TRUE - if(STATUS_DISPLAY_MESSAGE) //custom messages + + // Custom messages + if(STATUS_DISPLAY_MESSAGE) var/line1 var/line2 @@ -149,26 +170,32 @@ GLOBAL_LIST_INIT(statdisp_picture_colors, list( else line1 = copytext_char(message1+"|"+message1, index1, index1+DISPLAY_CHARS_PER_LINE) var/message1_len = length_char(message1) - index1 += SCROLL_SPEED + + index1 += DISPLAY_SCROLL_SPEED + if(index1 > message1_len) index1 -= message1_len if(!index2) line2 = message2 + else line2 = copytext_char(message2+"|"+message2, index2, index2+DISPLAY_CHARS_PER_LINE) var/message2_len = length_char(message2) - index2 += SCROLL_SPEED + + index2 += DISPLAY_SCROLL_SPEED + if(index2 > message2_len) index2 -= message2_len + update_display(line1, line2) - return TRUE + + // Just time if(STATUS_DISPLAY_TIME) message1 = "ВРЕМЯ" message2 = station_time_timestamp("hh:mm") update_display(message1, message2) - return TRUE - return FALSE + /obj/machinery/status_display/examine(mob/user) . = ..() @@ -179,6 +206,7 @@ GLOBAL_LIST_INIT(statdisp_picture_colors, list( if(mode == STATUS_DISPLAY_ALERT) . += span_notice("Текущий уровень угрозы: [get_security_level_ru()]. ") + /obj/machinery/status_display/proc/set_message(m1, m2) if(m1) index1 = (length_char(m1) > DISPLAY_CHARS_PER_LINE) @@ -194,191 +222,179 @@ GLOBAL_LIST_INIT(statdisp_picture_colors, list( message2 = "" index2 = 0 + +// Always call update() after using this +/obj/machinery/status_display/proc/set_mode(newmode) + mode = newmode + if(mode == STATUS_DISPLAY_ALERT) + // Its an alert image, clear all text + set_message(null, null) + else + // Not an alert image, clear any leftover image + set_picture(null) + + /obj/machinery/status_display/proc/set_picture(state) + maptext = null picture_state = state - remove_display() - if(state == "outline") - mode = STATUS_DISPLAY_TIME - else - overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) - set_light(1.5, 2, GLOB.statdisp_picture_colors[picture_state]) + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/status_display/proc/remove_display() + picture_state = null + update_icon(UPDATE_OVERLAYS) + -/obj/machinery/status_display/proc/update_display(line1, line2, warning = 0) +/obj/machinery/status_display/proc/update_display(line1, line2, warning = FALSE) line1 = uppertext(line1) line2 = uppertext(line2) - var/new_text = {"
    [line1]
    [line2]
    "} + var/new_text = {"
    [line1]
    [line2]
    "} if(maptext != new_text) maptext = new_text - var/lum = 0.5 - if(line1) - lum += 0.5 - if(line2) - lum += 0.5 - set_light(1.5, lum, warning ? COLOR_SUN : COLOR_LIGHT_CYAN) + update_display_light() -/obj/machinery/status_display/proc/remove_display() - if(overlays.len) - overlays.Cut() - if(maptext) - maptext = "" - if(mode != STATUS_DISPLAY_ALERT && picture_state) - picture_state = "" + +/obj/machinery/status_display/proc/update_display_light() if(light) set_light(0) - -/obj/machinery/status_display/receive_signal(datum/signal/signal) - if(stat & (BROKEN|NOPOWER)) + if(stat & (NOPOWER|BROKEN)) return - switch(signal.data["command"]) - if("blank") - mode = STATUS_DISPLAY_BLANK - if("shuttle") - remove_display() - mode = STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME - - if("message") - remove_display() - mode = STATUS_DISPLAY_MESSAGE - set_message(signal.data["msg1"], signal.data["msg2"]) + if(mode == STATUS_DISPLAY_ALERT) + set_light(1, 1, GLOB.statdisp_picture_colors[picture_state]) + else + var/lum = 0.4 + if(index1) + lum += 0.4 + if(index2) + lum += 0.4 + set_light(1, lum, (SSshuttle.emergency && SSshuttle.emergency.timer) ? COLOR_SUN : COLOR_LIGHT_CYAN) - if("alert") - mode = STATUS_DISPLAY_ALERT - set_picture(signal.data["picture_state"]) - if("time") - remove_display() - mode = STATUS_DISPLAY_TIME +GLOBAL_LIST_EMPTY(ai_displays) /obj/machinery/ai_status_display icon = 'icons/obj/status_display.dmi' icon_state = "frame" name = "AI display" - anchored = 1 - density = 0 + anchored = TRUE + density = FALSE + /// Current mode + var/mode = AI_DISPLAY_MODE_BLANK + /// Target icon state + var/picture_state + /// Current emotion, used to calculate an icon state + var/emotion = "Neutral" + +/obj/machinery/ai_status_display/Initialize(mapload) + . = ..() + GLOB.ai_displays |= src - var/mode = 0 // 0 = Blank - // 1 = AI emoticon - // 2 = Blue screen of death - var/picture_state // icon_state of ai picture +/obj/machinery/ai_status_display/Destroy() + GLOB.ai_displays -= src + return ..() - var/emotion = "Neutral" /obj/machinery/ai_status_display/attack_ai(mob/living/silicon/ai/user) if(isAI(user)) user.ai_statuschange() -/obj/machinery/ai_status_display/process() - if(stat & (BROKEN|NOPOWER)) - return - update() - -/obj/machinery/ai_status_display/proc/remove_display() - if(light) - set_light(0) - if(!mode && picture_state) - picture_state = "" - if(overlays.len) - overlays.Cut() - -/obj/machinery/ai_status_display/power_change() - ..() - if(stat & (BROKEN|NOPOWER)) - remove_display() - else if(picture_state) - set_picture(picture_state) /obj/machinery/ai_status_display/emp_act(severity) if(stat & (BROKEN|NOPOWER)) ..(severity) return - set_picture("ai_bsod") + mode = AI_DISPLAY_MODE_BSOD + update_icon() ..(severity) + +/obj/machinery/ai_status_display/power_change(forced = FALSE) + if(!..()) + return + if(stat & NOPOWER) + set_light(0) + else + set_light(1, LIGHTING_MINIMUM_POWER, GLOB.statdisp_picture_colors[picture_state]) + + /obj/machinery/ai_status_display/flicker() - if(stat & (NOPOWER | BROKEN)) + if(stat & (NOPOWER|BROKEN)) return FALSE - remove_display() - set_picture("ai_tribunal_malf") + emotion = "Tribunal Malf" + update_icon() return TRUE -/obj/machinery/ai_status_display/proc/update() - if(mode==0) //Blank - remove_display() - return - if(mode==1) // AI emoticon - switch(emotion) - if("Very Happy") - set_picture("ai_veryhappy") - if("Happy") - set_picture("ai_happy") - if("Neutral") - set_picture("ai_neutral") - if("Unsure") - set_picture("ai_unsure") - if("Confused") - set_picture("ai_confused") - if("Sad") - set_picture("ai_sad") - if("Surprised") - set_picture("ai_surprised") - if("Upset") - set_picture("ai_upset") - if("Angry") - set_picture("ai_angry") - if("BSOD") - set_picture("ai_bsod") - if("Blank") - set_picture("ai_off") - if("Problems?") - set_picture("ai_trollface") - if("Awesome") - set_picture("ai_awesome") - if("Dorfy") - set_picture("ai_urist") - if("Facepalm") - set_picture("ai_facepalm") - if("Friend Computer") - set_picture("ai_friend") - if("Beer") - set_picture("ai_beer") - if("Dwarf") - set_picture("ai_dwarf") - if("Fish Tank") - set_picture("ai_fishtank") - if("Plump") - set_picture("ai_plump") - if("Tribunal") - set_picture("ai_tribunal") - if("Tribunal Malf") - set_picture("ai_tribunal_malf") - return +/obj/machinery/ai_status_display/update_overlays() + . = ..() - if(mode==2) // BSOD - set_picture("ai_bsod") - return + var/new_display + underlays.Cut() -/obj/machinery/ai_status_display/proc/set_picture(state) - if(picture_state == state) + if(stat & NOPOWER) return - picture_state = state - if(overlays.len) - overlays.Cut() - overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) - set_light(1.5, 2, GLOB.statdisp_picture_colors[picture_state]) - -#undef FONT_SIZE -#undef FONT_COLOR -#undef WARNING_FONT_COLOR -#undef FONT_STYLE -#undef SCROLL_SPEED - -#undef STATUS_DISPLAY_BLANK -#undef STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME -#undef STATUS_DISPLAY_MESSAGE -#undef STATUS_DISPLAY_ALERT -#undef STATUS_DISPLAY_TIME + + switch(mode) + // Blank + if(AI_DISPLAY_MODE_BLANK) + new_display = "ai_off" + + // AI emoticon + if(AI_DISPLAY_MODE_EMOTE) + switch(emotion) + if("Very Happy") + new_display = "ai_veryhappy" + if("Happy") + new_display = "ai_happy" + if("Neutral") + new_display = "ai_neutral" + if("Unsure") + new_display = "ai_unsure" + if("Confused") + new_display = "ai_confused" + if("Sad") + new_display = "ai_sad" + if("Surprised") + new_display = "ai_surprised" + if("Upset") + new_display = "ai_upset" + if("Angry") + new_display = "ai_angry" + if("BSOD") + new_display = "ai_bsod" + if("Blank") + new_display = "ai_off" + if("Problems?") + new_display = "ai_trollface" + if("Awesome") + new_display = "ai_awesome" + if("Dorfy") + new_display = "ai_urist" + if("Facepalm") + new_display = "ai_facepalm" + if("Friend Computer") + new_display = "ai_friend" + if("Beer") + new_display = "ai_beer" + if("Dwarf") + new_display = "ai_dwarf" + if("Fish Tank") + new_display = "ai_fishtank" + if("Plump") + new_display = "ai_plump" + if("Tribunal") + new_display = "ai_tribunal" + if("Tribunal Malf") + new_display = "ai_tribunal_malf" + + // BSOD + if(AI_DISPLAY_MODE_BSOD) + new_display = "ai_bsod" + + . += new_display + underlays += emissive_appearance(icon, "lightmask") + diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 136a4d1a5ef..3f58fa3101e 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -258,7 +258,7 @@ magboots = new magboots_type(src) if(storage_type) storage = new storage_type(src) - update_icon() + update_icon(UPDATE_OVERLAYS) //move this into machinery eventually... if(occupant_typecache) @@ -273,31 +273,33 @@ . = ..() . += " There's a warning label dangling from the control pad that reads:
    [span_danger("\"BIOLOGICAL SUBJECTS ARE STRICTLY PROHIBITED IN THE CONFINES OF THE UNIT.\"")]" -/obj/machinery/suit_storage_unit/update_icon() - cut_overlays() + +/obj/machinery/suit_storage_unit/update_overlays() + . = ..() if(uv) if(uv_super) - add_overlay("[icon_state]_super") + . += "[icon_state]_super" else if(occupant) - add_overlay("[icon_state]_uvhuman") + . += "[icon_state]_uvhuman" else - add_overlay("[icon_state]_uv") + . += "[icon_state]_uv" else if(state_open) if(stat & BROKEN) - add_overlay("[icon_state]_broken") + . += "[icon_state]_broken" else - add_overlay("[icon_state]_open") + . += "[icon_state]_open" if(suit) - add_overlay("[icon_state]_suit") + . += "[icon_state]_suit" if(helmet) - add_overlay("[icon_state]_helm") + . += "[icon_state]_helm" if(storage) - add_overlay("[icon_state]_storage") + . += "[icon_state]_storage" else if(occupant) - add_overlay("[icon_state]_human") + . += "[icon_state]_human" if(!locked) - add_overlay("[icon_state]_unlocked") + . += "[icon_state]_unlocked" + /obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) if(shocked) @@ -318,7 +320,7 @@ if(state_open) add_fingerprint(user) if(store_item(I, user)) - update_icon() + update_icon(UPDATE_OVERLAYS) SStgui.update_uis(src) to_chat(user, span_notice("You load the [I] into the storage compartment.")) else @@ -356,12 +358,12 @@ user.drop_transfer_item_to_loc(I, src) -/obj/machinery/suit_storage_unit/power_change() - ..() +/obj/machinery/suit_storage_unit/power_change(forced = FALSE) + ..() //we don't check parent return here because `is_operational` cares about other flags in stat if(!is_operational() && state_open) open_machine() dump_contents() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/suit_storage_unit/proc/dump_contents() @@ -380,9 +382,10 @@ new /obj/item/stack/sheet/metal (loc, 2) qdel(src) -/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) +/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user, params) if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) return + . = TRUE var/mob/living/target = A if(!state_open) to_chat(user, span_warning("The [src]'s doors are shut!")) @@ -399,15 +402,19 @@ else target.visible_message(span_warning("[user] starts shoving [target] into [src]!"), span_userdanger("[user] starts shoving you into [src]!")) - if(do_mob(user, target, 30)) - if(occupant || helmet || suit || storage) - return - if(target == user) - user.visible_message(span_warning("[user] slips into [src] and closes the door behind [user.p_them()]!"), span_notice("You slip into [src]'s cramped space and shut its door.")) - else - target.visible_message(span_warning("[user] pushes [target] into [src] and shuts its door!"), span_userdanger("[user] shoves you into [src] and shuts the door!")) - close_machine(target) - add_fingerprint(user) + if(!do_mob(user, target, 3 SECONDS)) + return + + if(occupant || helmet || suit || storage) + return + + if(target == user) + user.visible_message(span_warning("[user] slips into [src] and closes the door behind [user.p_them()]!"), span_notice("You slip into [src]'s cramped space and shut its door.")) + else + target.visible_message(span_warning("[user] pushes [target] into [src] and shuts its door!"), span_userdanger("[user] shoves you into [src] and shuts the door!")) + close_machine(target) + add_fingerprint(user) + /obj/machinery/suit_storage_unit/proc/cook() if(uv_cycles) @@ -447,7 +454,7 @@ playsound(src, 'sound/machines/airlock_close.ogg', 25, 1) if(occupant) dump_contents() - update_icon() + update_icon(UPDATE_OVERLAYS) SStgui.update_uis(src) /obj/machinery/suit_storage_unit/relaymove(mob/user) @@ -496,7 +503,7 @@ state_open = TRUE if(drop) dropContents() - update_icon() + update_icon(UPDATE_OVERLAYS) SStgui.update_uis(src) /obj/machinery/suit_storage_unit/dropContents() @@ -528,7 +535,7 @@ occupant = target target.forceMove(src) SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/suit_storage_unit/attack_hand(mob/user) if(..() || (stat & NOPOWER)) @@ -591,7 +598,7 @@ cook() if("eject_occupant") eject_occupant(usr) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/suit_storage_unit/proc/dispense_helmet() if(!helmet) @@ -677,7 +684,7 @@ occupant = null if(!state_open) state_open = TRUE - update_icon() + update_icon(UPDATE_OVERLAYS) return /obj/machinery/suit_storage_unit/force_eject_occupant(mob/target) @@ -693,7 +700,7 @@ eject_occupant(usr) add_fingerprint(usr) SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_OVERLAYS) return /obj/machinery/suit_storage_unit/verb/move_inside() @@ -720,7 +727,7 @@ usr.forceMove(src) occupant = usr state_open = FALSE //Close the thing after the guy gets inside - update_icon() + update_icon(UPDATE_OVERLAYS) add_fingerprint(usr) SStgui.update_uis(src) @@ -742,7 +749,7 @@ add_attack_logs(user, src, "emagged") locked = FALSE emagged = TRUE - update_icon() + update_icon(UPDATE_OVERLAYS) SStgui.update_uis(src) if(user) to_chat(user, span_warning("You burn the locking mechanism, unlocking it forever.")) diff --git a/code/game/machinery/supply_display.dm b/code/game/machinery/supply_display.dm index 5cddc4b09ce..21d95579cc9 100644 --- a/code/game/machinery/supply_display.dm +++ b/code/game/machinery/supply_display.dm @@ -1,29 +1,21 @@ /obj/machinery/status_display/supply_display name = "дисплей статуса доставки" - ignore_friendc = 1 + is_supply = TRUE + /obj/machinery/status_display/supply_display/update() - if(!..() && mode == STATUS_DISPLAY_CUSTOM) - if(SSshuttle.supply.mode == SHUTTLE_IDLE) - if(is_station_level(SSshuttle.supply.z)) - message1 = "ГРУЗ" - message2 = "ГОТОВ" - else - message1 = "ВРЕМЯ" - message2 = station_time_timestamp("hh:mm") - else + if(SSshuttle.supply.mode == SHUTTLE_IDLE) + if(is_station_level(SSshuttle.supply.z)) message1 = "ГРУЗ" - message2 = SSshuttle.supply.getTimerStr() - if(length(message2) > DISPLAY_CHARS_PER_LINE) - message2 = "Error" - - update_display(message1, message2) - return 1 - return 0 - -/obj/machinery/status_display/supply_display/receive_signal/(datum/signal/signal) - if(signal.data["command"] == "supply") - mode = STATUS_DISPLAY_CUSTOM + message2 = "ГОТОВ" + else + message1 = "ВРЕМЯ" + message2 = station_time_timestamp("hh:mm") else - return + message1 = "ГРУЗ" + message2 = SSshuttle.supply.getTimerStr() + if(length(message2) > DISPLAY_CHARS_PER_LINE) + message2 = "Error" + + update_display(message1, message2) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index c9c12651304..d230bb618f5 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -10,7 +10,7 @@ icon = 'icons/obj/device.dmi' icon_state = "syndbeacon" - anchored = 1 + anchored = TRUE density = 1 var/temptext = "" @@ -108,7 +108,7 @@ icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "beacon" - anchored = 0 + anchored = FALSE density = 1 layer = MOB_LAYER - 0.2 //so people can't hide it and it's REALLY OBVIOUS stat = 0 diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 24a33fc43b0..6a21f1fbabc 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -7,7 +7,7 @@ icon_state = "syndicate-bomb" desc = "A large and menacing device. Can be bolted down with a wrench." - anchored = 0 + anchored = FALSE density = 0 layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS resistance_flags = FIRE_PROOF | ACID_PROOF @@ -74,7 +74,7 @@ if(active && !defused && ((detonation_timer <= world.time) || explode_now)) active = FALSE timer_set = initial(timer_set) - update_icon() + update_icon(UPDATE_ICON_STATE) try_detonate(TRUE) //Counter terrorists win else if(defused) @@ -86,7 +86,7 @@ wires = new(src) if(payload) payload = new payload(src) - update_icon() + update_icon(UPDATE_ICON_STATE) countdown = new(src) ..() @@ -101,7 +101,7 @@ . = ..() . += span_warning("A digital display on it reads \"[seconds_remaining()]\".") -/obj/machinery/syndicatebomb/update_icon() +/obj/machinery/syndicatebomb/update_icon_state() icon_state = "[initial(icon_state)][active ? "-active" : "-inactive"][open_panel ? "-wires" : ""]" /obj/machinery/syndicatebomb/proc/seconds_remaining() @@ -153,7 +153,7 @@ if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return open_panel = !open_panel - update_icon() + update_icon(UPDATE_ICON_STATE) to_chat(user, span_notice("You [open_panel ? "open" : "close"] the wire panel.")) /obj/machinery/syndicatebomb/wirecutter_act(mob/user, obj/item/I) @@ -259,7 +259,7 @@ else loc.visible_message(span_danger("[bicon(src)] [timer_set] seconds until detonation, please clear the area.")) activate() - update_icon() + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) var/turf/bombturf = get_turf(src) @@ -381,7 +381,7 @@ holder.delayedbig = FALSE holder.delayedlittle = FALSE holder.explode_now = FALSE - holder.update_icon() + holder.update_icon(UPDATE_ICON_STATE) holder.updateDialog() /obj/item/bombcore/training/detonate() diff --git a/code/game/machinery/syndiepad.dm b/code/game/machinery/syndiepad.dm index 5e5eb97673d..9e2b3165e14 100644 --- a/code/game/machinery/syndiepad.dm +++ b/code/game/machinery/syndiepad.dm @@ -3,7 +3,7 @@ desc = "Syndicate redspace quantumpads! Can transport goods through galaxies and completely ignores bluespace interference!" icon = 'icons/obj/telescience.dmi' icon_state = "sqpad-idle" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 200 active_power_usage = 5000 diff --git a/code/game/machinery/tcomms/_base.dm b/code/game/machinery/tcomms/_base.dm index febdb9283d3..8dadfd7cad0 100644 --- a/code/game/machinery/tcomms/_base.dm +++ b/code/game/machinery/tcomms/_base.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) /obj/machinery/tcomms/Initialize(mapload) . = ..() GLOB.tcomms_machines += src - update_icon() + update_icon(UPDATE_ICON_STATE) if((!mapload) && (usr)) // To the person who asks "Hey affected, why are you using this massive operator when you can use AREACOORD?" Well, ill tell you // get_area_name is fucking broken and uses a for(x in world) search @@ -82,8 +82,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) * * Ensures that the icon updates properly based on if the machine is active or not. This removes the need for this check in many other places. */ -/obj/machinery/tcomms/update_icon() - . = ..() +/obj/machinery/tcomms/update_icon_state() // Show the off sprite if were inactive, ion'd or unpowered if(!active || (stat & NOPOWER) || ion) icon_state = "[initial(icon_state)]_off" @@ -116,7 +115,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) */ /obj/machinery/tcomms/proc/start_ion() ion = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) /** * End of Ion Anomaly Event @@ -125,7 +124,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) */ /obj/machinery/tcomms/proc/end_ion() ion = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) /** * Z-Level transit change helper @@ -138,7 +137,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) active = FALSE // This needs a timer because otherwise its on the shuttle Z and the message is missed addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, visible_message), span_warning("Radio equipment on [src] has been overloaded by heavy bluespace interference. Please restart the machine.")), 5) - update_icon() + update_icon(UPDATE_ICON_STATE) /** @@ -159,9 +158,10 @@ GLOBAL_LIST_EMPTY(tcomms_machines) * * Proc which ensures icons are updated when machines lose power */ -/obj/machinery/tcomms/power_change() - ..() - update_icon() +/obj/machinery/tcomms/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) /** * # Telecommunications Message @@ -451,7 +451,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines) if(C.network_id == "STATION-CORE") info = "

    Telecommunications Key

    \n\t
    The station core linkage password is '[C.link_password]'.
    Should this paper be misplaced or destroyed, fear not, as the password is visible under the core linkage section. Should you wish to modify this password, it can be modified from the core." info_links = info - update_icon() + update_icon(UPDATE_ICON_STATE) // Save time, even though there should only be one STATION-CORE in the world break return ..() diff --git a/code/game/machinery/tcomms/core.dm b/code/game/machinery/tcomms/core.dm index dd4dfc20237..5a7570a6d7e 100644 --- a/code/game/machinery/tcomms/core.dm +++ b/code/game/machinery/tcomms/core.dm @@ -41,7 +41,7 @@ active = TRUE else visible_message(span_warning("Error: Another core is already active in this sector. Power-up cancelled due to radio interference.")) - update_icon() + update_icon(UPDATE_ICON_STATE) /** * Destructor for the core. @@ -158,7 +158,7 @@ if(C.active) if(C.stat & NOPOWER) // If another core has no power but is supposed to be on, we shut it down so we can continue. C.active = FALSE // Since only one active core is allowed per z level, give priority to the one actually working. - C.update_icon() + C.update_icon(UPDATE_ICON_STATE) else return FALSE // If we got here there isnt an active core on this Z-level. So return true @@ -231,7 +231,7 @@ if("toggle_active") if(check_power_on()) active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(usr, span_warning("Error: Another core is already active in this sector. Power-up cancelled due to radio interference.")) @@ -265,7 +265,7 @@ if(!new_language) return if(new_language == "--DISABLE--") - nttc.setting_language = null + nttc.setting_language = LANGUAGE_NONE to_chat(usr, span_notice("Language conversion disabled.")) else nttc.setting_language = new_language diff --git a/code/game/machinery/tcomms/nttc.dm b/code/game/machinery/tcomms/nttc.dm index d1b519e827d..c069a0cfc77 100644 --- a/code/game/machinery/tcomms/nttc.dm +++ b/code/game/machinery/tcomms/nttc.dm @@ -107,7 +107,7 @@ var/toggle_command_bold = FALSE /* Strings */ - var/setting_language = null + var/setting_language = LANGUAGE_NONE var/job_indicator_type = null // This tells the datum what is safe to serialize and what's not. It also applies to deserialization. @@ -151,9 +151,9 @@ job_indicator_type = initial(job_indicator_type) /datum/nttc_configuration/proc/update_languages() - for(var/language in GLOB.all_languages) - var/datum/language/L = GLOB.all_languages[language] - if(L.flags & HIVEMIND) + for(var/language_name in GLOB.all_languages) + var/datum/language/language = GLOB.all_languages[language_name] + if(language.flags & (HIVEMIND|NONGLOBAL)) continue valid_languages[language] = TRUE @@ -260,18 +260,18 @@ var/datum/multilingual_say_piece/S = message_pieces[I] if(!S.message) continue - if(I == 1 && !istype(S.speaking, /datum/language/noise)) // Capitalise the first section only, unless it's an emote. + if(I == 1 && S.speaking != GLOB.all_languages[LANGUAGE_NOISE]) // Capitalise the first section only, unless it's an emote. S.message = "[capitalize(S.message)]" S.message = "[S.message]" // Make everything bolded // Language Conversion if(setting_language && valid_languages[setting_language]) if(setting_language == "--DISABLE--") - setting_language = null + setting_language = LANGUAGE_NONE else for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking != GLOB.all_languages["Noise"]) // check if they are emoting, these do not need to be translated - S.speaking = GLOB.all_languages[setting_language] + if(S.speaking != GLOB.all_languages[LANGUAGE_NOISE]) // check if they are emoting, these do not need to be translated + S.speaking = setting_language return tcm diff --git a/code/game/machinery/tcomms/relay.dm b/code/game/machinery/tcomms/relay.dm index 0b1b32c9889..04072589fe0 100644 --- a/code/game/machinery/tcomms/relay.dm +++ b/code/game/machinery/tcomms/relay.dm @@ -32,7 +32,7 @@ active = TRUE else visible_message(span_warning("Error: Another relay is already active in this sector. Power-up cancelled due to radio interference.")) - update_icon() + update_icon(UPDATE_ICON_STATE) if(mapload && autolink_id) return INITIALIZE_HINT_LATELOAD @@ -90,7 +90,7 @@ if(R.active) if(R.stat & NOPOWER) // If another relay has no power but is supposed to be on, we shut it down so we can continue. R.active = FALSE // Since only one active relay is allowed per z level, give priority to the one that's actually working. - R.update_icon() + R.update_icon(UPDATE_ICON_STATE) else return FALSE // If we got here there isnt an active relay on this Z-level. So return TRUE @@ -127,8 +127,9 @@ * * Proc which ensures the host core has its zlevels updated (icons are updated by parent call) */ -/obj/machinery/tcomms/relay/power_change() - ..() +/obj/machinery/tcomms/relay/power_change(forced = FALSE) + if(!..()) + return if(linked_core) linked_core.refresh_zlevels() @@ -176,7 +177,7 @@ if("toggle_active") if(check_power_on()) active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) if(linked_core) linked_core.refresh_zlevels() else diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index fb99f983d5f..2fa2ddd13e9 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/machines/recycling.dmi' icon_state = "separator-AO1" layer = MOB_LAYER+1 // Overhead - anchored = 1 + anchored = TRUE density = 1 /// TRUE if the factory can transform dead mobs. var/transform_dead = TRUE @@ -47,12 +47,12 @@ if(istype(west, /turf/simulated/floor)) new /obj/machinery/conveyor/auto(west, WEST) -/obj/machinery/transformer/power_change() - ..() - update_icon() +/obj/machinery/transformer/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) -/obj/machinery/transformer/update_icon() - ..() +/obj/machinery/transformer/update_icon_state() if(is_on_cooldown || stat & (BROKEN|NOPOWER)) icon_state = "separator-AO0" else @@ -67,7 +67,7 @@ /// Resets `is_on_cooldown` to `FALSE` and updates our icon. Used in a callback after the transformer does a transformation. /obj/machinery/transformer/proc/reset_cooldown() is_on_cooldown = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/transformer/Bumped(atom/movable/moving_atom) ..() @@ -97,7 +97,7 @@ // Activate the cooldown is_on_cooldown = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), cooldown_duration) addtimer(CALLBACK(null, PROC_REF(playsound), loc, 'sound/machines/ping.ogg', 50, 0), 3 SECONDS) @@ -152,7 +152,7 @@ // Activate the cooldown is_on_cooldown = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), cooldown_duration) /obj/machinery/transformer/xray @@ -176,12 +176,12 @@ if(istype(west2, /turf/simulated/floor)) new /obj/machinery/conveyor/auto(west2, EAST) -/obj/machinery/transformer/xray/power_change() - ..() - update_icon() +/obj/machinery/transformer/xray/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) -/obj/machinery/transformer/xray/update_icon() - ..() +/obj/machinery/transformer/xray/update_icon_state() if(stat & (BROKEN|NOPOWER)) icon_state = "separator-AO0" else diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index ec6e73fca91..ea8a9be1709 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -88,8 +88,10 @@ else control_area = null - power_change() //Checks power and initial settings - return + updateTurrets() + update_icon(UPDATE_ICON_STATE) + update_turret_light() + /obj/machinery/turretid/proc/isLocked(mob/user) if(isrobot(user) && !iscogscarab(user) || isAI(user)) @@ -219,28 +221,46 @@ if(faction == aTurret.faction) aTurret.setState(TC) - update_icon() + update_icon(UPDATE_ICON_STATE) + update_turret_light() -/obj/machinery/turretid/power_change() - ..() + +/obj/machinery/turretid/power_change(forced = FALSE) + if(!..()) + return updateTurrets() - update_icon() + update_icon(UPDATE_ICON_STATE) + update_turret_light() -/obj/machinery/turretid/update_icon() - ..() + +/obj/machinery/turretid/proc/update_turret_light() if(stat & NOPOWER) - icon_state = "control_off" set_light(0) - else if(enabled) + return + + if(enabled) if(lethal) - icon_state = "control_kill" set_light(1.5, 1,"#990000") else - icon_state = "control_stun" set_light(1.5, 1,"#FF9900") - else - icon_state = "control_standby" - set_light(1.5, 1,"#003300") + return + + set_light(1.5, 1,"#003300") + + +/obj/machinery/turretid/update_icon_state() + if(stat & NOPOWER) + icon_state = "control_off" + return + if(enabled) + if(lethal) + icon_state = "control_kill" + else + icon_state = "control_stun" + return + + icon_state = "control_standby" + /obj/machinery/turretid/emp_act(severity) if(enabled) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 9ee654e226a..185399e5027 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,3 +1,12 @@ +// Vendor flick sequence bitflags +/// Machine is not using vending/denying overlays +#define FLICK_NONE 0 +/// Machine is currently vending wares, and will not update its icon, unless its stat change. +#define FLICK_VEND 1 +/// Machine is currently denying wares, and will not update its icon, unless its stat change. +#define FLICK_DENY 2 + + /** * Datum used to hold information about a product in a vending machine */ @@ -15,17 +24,41 @@ name = "\improper Vendomat" desc = "A generic vending machine." icon = 'icons/obj/machines/vending.dmi' - icon_state = "generic" - layer = 2.9 - anchored = 1 - density = 1 + icon_state = "generic_off" + layer = BELOW_OBJ_LAYER + anchored = TRUE + density = TRUE max_integrity = 300 integrity_failure = 100 armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) - /// Icon_state when vending - var/icon_vend - /// Icon_state when denying access - var/icon_deny + + // All the overlay controlling variables + /// Overlay of vendor maintenance panel. + var/panel_overlay = "" + /// Overlay of a vendor screen, will not apply of stat is NOPOWER. + var/screen_overlay = "" + /// Lightmask used when vendor is working properly. + var/lightmask_overlay = "" + /// Damage overlay applied if vendor is damaged enough. + var/broken_overlay = "" + /// Special lightmask for broken overlay. If vendor is BROKEN, but not dePOWERED we will see this, instead of `lightmask_overlay`. + var/broken_lightmask_overlay = "" + /// Overlay applied when machine is vending goods. + var/vend_overlay = "" + /// Special lightmask that will override default `lightmask_overlay`, while machine is vending goods. + var/vend_lightmask = "" + /// Amount of time until vending sequence is reseted. + var/vend_overlay_time = 5 SECONDS + /// Overlay applied when machine is denying its wares. + var/deny_overlay = "" + /// Special lightmask that will override default `lightmask_overlay`, while machine is denying its wares. + var/deny_lightmask = "" + /// Amount of time until denying sequence is reseted. + var/deny_overlay_time = 1.5 SECONDS + /// Flags used to correctly manipulate with vend/deny sequences. + var/flick_sequence = FLICK_NONE + /// If `TRUE` machine will only react to BROKEN/NOPOWER stat, when updating overlays. + var/skip_non_primary_icon_updates = FALSE // Power use_power = IDLE_POWER_USE @@ -34,11 +67,11 @@ // Vending-related /// No sales pitches if off - var/active = 1 + var/active = TRUE /// If off, vendor is busy and unusable until current action finishes var/vend_ready = TRUE /// How long vendor takes to vend one item. - var/vend_delay = 10 + var/vend_delay = 1 SECONDS /// Item currently being bought var/datum/data/vending_product/currently_vending = null @@ -100,6 +133,9 @@ /// do I look unpowered, even when powered? var/force_no_power_icon_state = FALSE + var/light_range_on = 1 + var/light_power_on = 0.5 + /obj/machinery/vending/Initialize(mapload) . = ..() var/build_inv = FALSE @@ -128,7 +164,8 @@ // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is created. last_slogan = world.time + rand(0, slogan_delay) - power_change() + update_icon(UPDATE_OVERLAYS) + /obj/machinery/vending/Destroy() SStgui.close_uis(wires) @@ -151,28 +188,88 @@ for(var/obj/item/vending_refill/VR in component_parts) restock(VR) -/obj/machinery/vending/update_icon() - cut_overlays() - if(panel_open) - add_overlay(image(icon, "[initial(icon_state)]-panel")) + +/obj/machinery/vending/update_icon(updates = ALL) + if(skip_non_primary_icon_updates && !(stat & (NOPOWER|BROKEN))) + return ..(NONE) + return ..() + + +/obj/machinery/vending/update_overlays() + . = ..() + + underlays.Cut() + + if(panel_overlay && panel_open) + . += panel_overlay + + if((stat & NOPOWER) || force_no_power_icon_state) + if(broken_overlay && (stat & BROKEN)) + . += broken_overlay + return if(stat & BROKEN) + if(broken_overlay) + . += broken_overlay + if(broken_lightmask_overlay) + underlays += emissive_appearance(icon, broken_lightmask_overlay) + else + if(screen_overlay) + . += screen_overlay + + var/lightmask_used = FALSE + if(vend_overlay && (flick_sequence & FLICK_VEND)) + . += vend_overlay + if(vend_lightmask) + lightmask_used = TRUE + . += vend_lightmask + + else if(deny_overlay && (flick_sequence & FLICK_DENY)) + . += deny_overlay + if(deny_lightmask) + lightmask_used = TRUE + . += deny_lightmask + + if(!lightmask_used && lightmask_overlay) + underlays += emissive_appearance(icon, lightmask_overlay) + + +/obj/machinery/vending/power_change(forced = FALSE) + . = ..() + if(stat & NOPOWER) set_light(0) - icon_state = "[initial(icon_state)]-broken" - else if (stat & NOPOWER || force_no_power_icon_state) - set_light(0) - icon_state = "[initial(icon_state)]-off" else - set_light(1, 1, COLOR_WHITE) - icon_state = initial(icon_state) + set_light(light_range_on, light_power_on) + if(.) + update_icon(UPDATE_OVERLAYS) /obj/machinery/vending/extinguish_light(force = FALSE) - if(light_range) + if(light) set_light(0) underlays.Cut() +/obj/machinery/vending/proc/flick_vendor_overlay(flick_flag = FLICK_NONE) + if(flick_sequence & (FLICK_VEND|FLICK_DENY)) + return + if((flick_flag & FLICK_VEND) && !vend_overlay) + return + if((flick_flag & FLICK_DENY) && !deny_overlay) + return + flick_sequence = flick_flag + update_icon(UPDATE_OVERLAYS) + skip_non_primary_icon_updates = TRUE + var/flick_time = (flick_flag & FLICK_VEND) ? vend_overlay_time : (flick_flag & FLICK_DENY) ? deny_overlay_time : 0 + addtimer(CALLBACK(src, PROC_REF(flick_reset)), flick_time) + + +/obj/machinery/vending/proc/flick_reset() + skip_non_primary_icon_updates = FALSE + flick_sequence = FLICK_NONE + update_icon(UPDATE_OVERLAYS) + + /* * Reimp, flash the screen on and off repeatedly. */ @@ -196,13 +293,13 @@ for(var/i in 1 to amount) force_no_power_icon_state = TRUE - update_icon() + update_icon(UPDATE_OVERLAYS) sleep(rand(1, 3)) force_no_power_icon_state = FALSE - update_icon() + update_icon(UPDATE_OVERLAYS) sleep(rand(1, 10)) - update_icon() + update_icon(UPDATE_OVERLAYS) flickering = FALSE /** @@ -337,7 +434,6 @@ return ..() - /obj/machinery/vending/crowbar_act(mob/user, obj/item/I) if(!component_parts) return @@ -627,7 +723,7 @@ return if (R.amount <= 0) to_chat(usr, "Sold out of [R.name].") - flick(icon_deny, src) + flick_vendor_overlay(FLICK_VEND) return vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved. @@ -644,7 +740,7 @@ // --- THE REST OF THIS PROC IS JUST PAYMENT LOGIC --- if(!GLOB.vendor_account || GLOB.vendor_account.suspended) to_chat(usr, "Vendor account offline. Unable to process transaction.") - flick(icon_deny, src) + flick_vendor_overlay(FLICK_DENY) vend_ready = TRUE return @@ -665,7 +761,7 @@ else to_chat(usr, span_warning("Payment failure: you have no ID or other method of payment.")) vend_ready = TRUE - flick(icon_deny, src) + flick_vendor_overlay(FLICK_DENY) . = TRUE // we set this because they shouldn't even be able to get this far, and we want the UI to update. return if(paid) @@ -683,7 +779,7 @@ /obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) if(!allowed(user) && !user.can_admin_interact() && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH to_chat(user, span_warning("Access denied."))//Unless emagged of course - flick(icon_deny, src) + flick_vendor_overlay(FLICK_DENY) vend_ready = TRUE return @@ -715,17 +811,21 @@ last_reply = world.time use_power(vend_power_usage) //actuators and stuff - if(icon_vend) //Show the vending animation if needed - flick(icon_vend, src) + flick_vendor_overlay(FLICK_VEND) //Show the vending animation if needed playsound(get_turf(src), 'sound/machines/machine_vend.ogg', 50, TRUE) addtimer(CALLBACK(src, PROC_REF(delayed_vend), R, user), vend_delay) + /obj/machinery/vending/proc/delayed_vend(datum/data/vending_product/R, mob/user) do_vend(R, user) vend_ready = TRUE currently_vending = null -//override this proc to add handling for what to do with the vended product when you have a inserted item and remember to include a parent call for this generic handling + +/** + * Override this proc to add handling for what to do with the vended product + * when you have a inserted item and remember to include a parent call for this generic handling + */ /obj/machinery/vending/proc/do_vend(datum/data/vending_product/R, mob/user) if(!item_slot || !inserted_item) var/put_on_turf = TRUE @@ -769,6 +869,7 @@ if(shoot_inventory && prob(shoot_chance)) throw_item() + /obj/machinery/vending/proc/speak(message) if(stat & NOPOWER) return @@ -777,42 +878,37 @@ atom_say(message) -/obj/machinery/vending/power_change() - if(powered()) - stat &= ~NOPOWER - update_icon() - else - spawn(rand(0, 15)) - stat |= NOPOWER - update_icon() /obj/machinery/vending/obj_break(damage_flag) - if(!(stat & BROKEN)) - stat |= BROKEN - update_icon() + if(stat & BROKEN) + return + + stat |= BROKEN + update_icon(UPDATE_OVERLAYS) + + var/dump_amount = 0 + var/found_anything = TRUE + while (found_anything) + found_anything = FALSE + for(var/record in shuffle(product_records)) + var/datum/data/vending_product/R = record + if(R.amount <= 0) //Try to use a record that actually has something to dump. + continue + var/dump_path = R.product_path + if(!dump_path) + continue + R.amount-- + // busting open a vendor will destroy some of the contents + if(found_anything && prob(80)) + continue + + var/obj/O = new dump_path(loc) + step(O, pick(GLOB.alldirs)) + found_anything = TRUE + dump_amount++ + if(dump_amount >= 16) + return - var/dump_amount = 0 - var/found_anything = TRUE - while (found_anything) - found_anything = FALSE - for(var/record in shuffle(product_records)) - var/datum/data/vending_product/R = record - if(R.amount <= 0) //Try to use a record that actually has something to dump. - continue - var/dump_path = R.product_path - if(!dump_path) - continue - R.amount-- - // busting open a vendor will destroy some of the contents - if(found_anything && prob(80)) - continue - - var/obj/O = new dump_path(loc) - step(O, pick(GLOB.alldirs)) - found_anything = TRUE - dump_amount++ - if(dump_amount >= 16) - return //Somebody cut an important wire and now we're following a new definition of "pitch." /obj/machinery/vending/proc/throw_item() @@ -856,7 +952,16 @@ */ + /obj/machinery/vending/assist + + icon_state = "generic_off" + panel_overlay = "generic_panel" + screen_overlay = "generic" + lightmask_overlay = "generic_lightmask" + broken_overlay = "generic_broken" + broken_lightmask_overlay = "generic_broken_lightmask" + products = list( /obj/item/assembly/prox_sensor = 5,/obj/item/assembly/igniter = 3,/obj/item/assembly/signaler = 4, /obj/item/wirecutters = 1, /obj/item/cartridge/signal = 4) contraband = list(/obj/item/flashlight = 5,/obj/item/assembly/timer = 2, /obj/item/assembly/voice = 2, /obj/item/assembly/health = 2) @@ -866,8 +971,15 @@ /obj/machinery/vending/boozeomat name = "\improper Booze-O-Mat" desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." - icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles - icon_deny = "boozeomat-deny" + + icon_state = "boozeomat_off" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles + panel_overlay = "boozeomat_panel" + screen_overlay = "boozeomat" + lightmask_overlay = "boozeomat_lightmask" + broken_overlay = "boozeomat_broken" + broken_lightmask_overlay = "boozeomat_broken_lightmask" + deny_overlay = "boozeomat_deny" + products = list(/obj/item/reagent_containers/food/drinks/bottle/gin = 5, /obj/item/reagent_containers/food/drinks/bottle/whiskey = 5, /obj/item/reagent_containers/food/drinks/bottle/tequila = 5, @@ -914,8 +1026,16 @@ name = "\improper Solar's Best Hot Drinks" desc = "A vending machine which dispenses hot drinks." ads_list = list("Выпейте!","Выпьем!","На здоровье!","Не хотите горячего супчику?","Я бы убил за чашечку кофе!","Лучшие зёрна в галактике","Для Вас — только лучшие напитки","М-м-м-м… Ничто не сравнится с кофе","Я люблю кофе, а Вы?","Кофе помогает работать!","Возьмите немного чайку","Надеемся, Вы предпочитаете лучшее!","Отведайте наш новый шоколад!","Admin conspiracies") - icon_state = "coffee" - icon_vend = "coffee-vend" + + icon_state = "coffee_off" + panel_overlay = "coffee_panel" + screen_overlay = "coffee" + lightmask_overlay = "coffee_lightmask" + broken_overlay = "coffee_broken" + broken_lightmask_overlay = "coffee_broken_lightmask" + vend_overlay = "coffee_vend" + vend_lightmask = "coffee_vend_lightmask" + item_slot = TRUE vend_delay = 34 products = list(/obj/item/reagent_containers/food/drinks/coffee = 25,/obj/item/reagent_containers/food/drinks/tea = 25,/obj/item/reagent_containers/food/drinks/h_chocolate = 25, @@ -975,7 +1095,14 @@ desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars." slogan_list = list("Попробуйте наш новый батончик с нугой!","Вдвое больше калорий за полцены!") ads_list = list("The healthiest!","Award-winning chocolate bars!","Mmm! So good!","Oh my god it's so juicy!","Have a snack.","Snacks are good for you!","Have some more Getmore!","Best quality snacks straight from mars.","We love chocolate!","Try our new jerky!") - icon_state = "snack" + + icon_state = "snack_off" + panel_overlay = "snack_panel" + screen_overlay = "snack" + lightmask_overlay = "snack_lightmask" + broken_overlay = "snack_broken" + broken_lightmask_overlay = "snack_broken_lightmask" + products = list(/obj/item/reagent_containers/food/snacks/candy/candybar = 6,/obj/item/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/reagent_containers/food/snacks/doshik = 6,/obj/item/reagent_containers/food/snacks/doshik_spicy = 6,/obj/item/reagent_containers/food/snacks/chips =6, /obj/item/reagent_containers/food/snacks/sosjerky = 6,/obj/item/reagent_containers/food/snacks/no_raisin = 6,/obj/item/reagent_containers/food/snacks/pistachios =6, /obj/item/reagent_containers/food/snacks/spacetwinkie = 6,/obj/item/reagent_containers/food/snacks/cheesiehonkers = 6,/obj/item/reagent_containers/food/snacks/tastybread = 6) @@ -992,7 +1119,14 @@ name = "\improper Mr. Chang" desc = "A self-serving Chinese food machine, for all your Chinese food needs." slogan_list = list("Попробуйте 5000 лет культуры!","Мистер Чанг, одобрен для безопасного потребления в более чем 10 секторах!","Китайская кухня отлично подходит для вечернего свидания или одинокого вечера!","Вы не ошибетесь, если попробуете настоящую китайскую кухню от мистера Чанга.!") - icon_state = "chang" + + icon_state = "chang_off" + panel_overlay = "chang_panel" + screen_overlay = "chang" + lightmask_overlay = "chang_lightmask" + broken_overlay = "chang_broken" + broken_lightmask_overlay = "chang_broken_lightmask" + products = list(/obj/item/reagent_containers/food/snacks/chinese/chowmein = 6, /obj/item/reagent_containers/food/snacks/chinese/tao = 6, /obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball = 6, /obj/item/reagent_containers/food/snacks/chinese/newdles = 6, /obj/item/reagent_containers/food/snacks/chinese/rice = 6, /obj/item/reagent_containers/food/snacks/fortunecookie = 6) prices = list(/obj/item/reagent_containers/food/snacks/chinese/chowmein = 50, /obj/item/reagent_containers/food/snacks/chinese/tao = 50, /obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball = 50, /obj/item/reagent_containers/food/snacks/chinese/newdles = 50, @@ -1005,16 +1139,24 @@ /obj/machinery/vending/cola name = "\improper Robust Softdrinks" desc = "A soft drink vendor provided by Robust Industries, LLC." - icon_state = "Cola_Machine" + + icon_state = "cola-machine_off" + panel_overlay = "cola-machine_panel" + screen_overlay = "cola-machine" + lightmask_overlay = "cola-machine_lightmask" + broken_overlay = "cola-machine_broken" + broken_lightmask_overlay = "cola-machine_broken_lightmask" + slogan_list = list("Роб+аст с+офтдринкс: крепче, чем тулбоксом по голове!") ads_list = list("Освежает!","Надеюсь, вас одолела жажда!","Продано больше миллиона бутылок!","Хотите пить? Почему бы не взять колы?","Пожалуйста, купите напиток","Выпьем!","Лучшие напитки во всём космосе") products = list(/obj/item/reagent_containers/food/drinks/cans/cola = 10,/obj/item/reagent_containers/food/drinks/cans/space_mountain_wind = 10, /obj/item/reagent_containers/food/drinks/cans/dr_gibb = 10,/obj/item/reagent_containers/food/drinks/cans/starkist = 10, /obj/item/reagent_containers/food/drinks/cans/space_up = 10,/obj/item/reagent_containers/food/drinks/cans/grape_juice = 10) - contraband = list(/obj/item/reagent_containers/food/drinks/cans/thirteenloko = 5) + contraband = list(/obj/item/reagent_containers/food/drinks/cans/thirteenloko = 5, /obj/item/reagent_containers/food/drinks/zaza = 1) prices = list(/obj/item/reagent_containers/food/drinks/cans/cola = 20,/obj/item/reagent_containers/food/drinks/cans/space_mountain_wind = 20, /obj/item/reagent_containers/food/drinks/cans/dr_gibb = 20,/obj/item/reagent_containers/food/drinks/cans/starkist = 20, - /obj/item/reagent_containers/food/drinks/cans/space_up = 20,/obj/item/reagent_containers/food/drinks/cans/grape_juice = 20) + /obj/item/reagent_containers/food/drinks/cans/space_up = 20,/obj/item/reagent_containers/food/drinks/cans/grape_juice = 20, + /obj/item/reagent_containers/food/drinks/zaza = 200) refill_canister = /obj/item/vending_refill/cola /obj/machinery/vending/cola/free @@ -1024,8 +1166,15 @@ name = "\improper PTech" desc = "Cartridges for PDA's." slogan_list = list("Карточки в дорогу!") - icon_state = "cart" - icon_deny = "cart-deny" + + icon_state = "cart_off" + panel_overlay = "cart_panel" + screen_overlay = "cart" + lightmask_overlay = "cart_lightmask" + broken_overlay = "cart_broken" + broken_lightmask_overlay = "cart_broken_lightmask" + deny_overlay = "cart_deny" + products = list(/obj/item/pda =10,/obj/item/eftpos = 6,/obj/item/cartridge/mob_hunt_game = 25,/obj/item/cartridge/medical = 10,/obj/item/cartridge/chemistry = 10, /obj/item/cartridge/engineering = 10,/obj/item/cartridge/atmos = 10,/obj/item/cartridge/janitor = 10, /obj/item/cartridge/signal/toxins = 10,/obj/item/cartridge/signal = 10) @@ -1041,7 +1190,14 @@ /obj/machinery/vending/liberationstation name = "\improper Liberation Station" desc = "An overwhelming amount of ancient patriotism washes over you just by looking at the machine." - icon_state = "liberationstation" + + icon_state = "liberationstation_off" + panel_overlay = "liberationstation_panel" + screen_overlay = "liberationstation" + lightmask_overlay = "liberationstation_lightmask" + broken_overlay = "liberationstation_broken" + broken_lightmask_overlay = "liberationstation_broken_lightmask" + req_access = list(ACCESS_SECURITY) slogan_list = list("Liberation Station: Your one-stop shop for all things second amendment!","Be a patriot today, pick up a gun!","Quality weapons for cheap prices!","Better dead than red!") ads_list = list("Float like an astronaut, sting like a bullet!","Express your second amendment today!","Guns don't kill people, but you can!","Who needs responsibilities when you have guns?") @@ -1059,7 +1215,14 @@ /obj/machinery/vending/toyliberationstation name = "\improper Syndicate Donksoft Toy Vendor" desc = "An ages 8 and up approved vendor that dispenses toys. If you were to find the right wires, you can unlock the adult mode setting!" - icon_state = "syndi" + + icon_state = "syndi_off" + panel_overlay = "syndi_panel" + screen_overlay = "syndi" + lightmask_overlay = "syndi_lightmask" + broken_overlay = "syndi_broken" + broken_lightmask_overlay = "syndi_broken_lightmask" + slogan_list = list("Get your cool toys today!","Trigger a valid hunter today!","Quality toy weapons for cheap prices!","Give them to HoPs for all access!","Give them to HoS to get permabrigged!") ads_list = list("Feel robust with your toys!","Express your inner child today!","Toy weapons don't kill people, but valid hunters do!","Who needs responsibilities when you have toy weapons?","Make your next murder FUN!") vend_reply = "Come back for more!" @@ -1090,7 +1253,14 @@ slogan_list = list("Космосигареты весьма хороши на вкус, какими они и должны быть","I'd rather toolbox than switch.","Затянитесь!","Не верьте исследованиям — курите!") ads_list = list("Наверняка не очень-то и вредно для Вас!","Не верьте учёным!","На здоровье!","Не бросайте курить, купите ещё!","Затянитесь!","Никотиновый рай","Лучшие сигареты с 2150 года","Сигареты с множеством наград") vend_delay = 34 - icon_state = "cigs" + + icon_state = "cigs_off" + panel_overlay = "cigs_panel" + screen_overlay = "cigs" + lightmask_overlay = "cigs_lightmask" + broken_overlay = "cigs_broken" + broken_lightmask_overlay = "cigs_broken_lightmask" + products = list(/obj/item/storage/fancy/cigarettes/cigpack_robust = 12, /obj/item/storage/fancy/cigarettes/cigpack_uplift = 6, /obj/item/storage/fancy/cigarettes/cigpack_random = 6, /obj/item/reagent_containers/food/pill/patch/nicotine = 10, /obj/item/storage/box/matches = 10,/obj/item/lighter/random = 4,/obj/item/storage/fancy/rollingpapers = 5) contraband = list(/obj/item/lighter/zippo = 4, /obj/item/clothing/mask/cigarette/pipe/oldpipe = 3) premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2, /obj/item/storage/fancy/cigarettes/cigpack_robustgold = 1) @@ -1135,8 +1305,15 @@ /obj/machinery/vending/medical name = "\improper NanoMed Plus" desc = "Medical drug dispenser." - icon_state = "med" - icon_deny = "med-deny" + + icon_state = "med_off" + panel_overlay = "med_panel" + screen_overlay = "med" + lightmask_overlay = "med_lightmask" + broken_overlay = "med_broken" + broken_lightmask_overlay = "med_broken_lightmask" + deny_overlay = "med_deny" + ads_list = list("Иди и спаси несколько жизней!","Лучшее снаряжение для вашего медотдела","Только лучшие инструменты","Натуральные химикаты!","Эта штука спасает жизни","Может сами примете?","Пинг!") req_access = list(ACCESS_MEDICAL) products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/food/pill/patch/styptic = 4, /obj/item/reagent_containers/food/pill/patch/silver_sulf = 4, /obj/item/reagent_containers/applicator/brute = 3, /obj/item/reagent_containers/applicator/burn = 3, @@ -1155,8 +1332,15 @@ /obj/machinery/vending/medical/syndicate_access name = "\improper SyndiMed Plus" - icon_state = "syndi-big-med" - icon_deny = "syndi-big-med-deny" + + icon_state = "syndi-big-med_off" + panel_overlay = "syndi-big-med_panel" + screen_overlay = "syndi-big-med" + lightmask_overlay = "med_lightmask" + broken_overlay = "med_broken" + broken_lightmask_overlay = "med_broken_lightmask" + deny_overlay = "syndi-big-med_deny" + req_access = list(ACCESS_SYNDICATE) /obj/machinery/vending/medical/syndicate_access/beamgun @@ -1165,6 +1349,14 @@ /obj/machinery/vending/plasmaresearch name = "\improper Toximate 3000" desc = "All the fine parts you need in one vending machine!" + + icon_state = "generic_off" + panel_overlay = "generic_panel" + screen_overlay = "generic" + lightmask_overlay = "generic_lightmask" + broken_overlay = "generic_broken" + broken_lightmask_overlay = "generic_broken_lightmask" + products = list(/obj/item/assembly/prox_sensor = 8, /obj/item/assembly/igniter = 8, /obj/item/assembly/signaler = 8, /obj/item/wirecutters = 1, /obj/item/assembly/timer = 8) contraband = list(/obj/item/flashlight = 5, /obj/item/assembly/voice = 3, /obj/item/assembly/health = 3, /obj/item/assembly/infra = 3) @@ -1174,8 +1366,15 @@ name = "\improper NanoMed" desc = "Wall-mounted Medical Equipment dispenser." ads_list = list("Иди и спаси несколько жизней!","Лучшее снаряжение для вашего медотдела","Только лучшие инструменты","Натуральные химикаты!","Эта штука спасает жизни","Может сами примете?","Пинг!") - icon_state = "wallmed" - icon_deny = "wallmed-deny" + + icon_state = "wallmed_off" + panel_overlay = "wallmed_panel" + screen_overlay = "wallmed" + lightmask_overlay = "wallmed_lightmask" + broken_overlay = "wallmed_broken" + broken_lightmask_overlay = "wallmed_broken_lightmask" + deny_overlay = "wallmed_deny" + density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1) contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4, /obj/item/reagent_containers/syringe/antiviral = 4, /obj/item/reagent_containers/food/pill/tox = 1) @@ -1186,8 +1385,16 @@ /obj/machinery/vending/wallmed/syndicate name = "\improper SyndiWallMed" desc = "EVIL wall-mounted Medical Equipment dispenser." - icon_state = "syndimed" - icon_deny = "syndimed-deny" + + icon_state = "syndimed_off" + panel_overlay = "wallmed_panel" + screen_overlay = "syndimed" + lightmask_overlay = "wallmed_lightmask" + broken_overlay = "wallmed_broken" + broken_lightmask_overlay = "wallmed_broken_lightmask" + deny_overlay = "syndimed_deny" + + broken_lightmask_overlay = "wallmed_broken_lightmask" ads_list = list("Иди и оборви несколько жизней!","Лучшее снаряжение для вашего корабля","Только лучшие инструменты","Натуральные химикаты!","Эта штука спасает жизни","Может сами примете?","Пинг!") req_access = list(ACCESS_SYNDICATE) products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/reagent_containers/hypospray/autoinjector = 4,/obj/item/healthanalyzer = 1) @@ -1198,22 +1405,37 @@ name = "\improper SecTech" desc = "A security equipment vendor." ads_list = list("Круши черепа капиталистов!","Отбей несколько голов!","Не забывай, вредительство - полезно!","Твое оружие здесь.","Наручники!","Стоять, подонок!","Не бей меня, брат!","Убей их, брат.","Почему бы не съесть пончик?") - icon_state = "sec" - icon_deny = "sec-deny" + + icon_state = "sec_off" + panel_overlay = "sec_panel" + screen_overlay = "sec" + lightmask_overlay = "sec_lightmask" + broken_overlay = "sec_broken" + broken_lightmask_overlay = "sec_broken_lightmask" + deny_overlay = "sec_deny" + req_access = list(ACCESS_SECURITY) products = list(/obj/item/restraints/handcuffs = 8,/obj/item/restraints/handcuffs/cable/zipties = 8,/obj/item/grenade/flashbang = 4,/obj/item/flash = 5, /obj/item/reagent_containers/food/snacks/donut = 12,/obj/item/storage/box/evidence = 6,/obj/item/flashlight/seclite = 4,/obj/item/restraints/legcuffs/bola/energy = 7, - /obj/item/clothing/mask/muzzle/safety = 4, /obj/item/storage/box/swabs = 6, /obj/item/storage/box/fingerprints = 6, /obj/item/eftpos/sec = 4, + /obj/item/clothing/mask/muzzle/safety = 4, /obj/item/storage/box/swabs = 6, /obj/item/storage/box/fingerprints = 6, /obj/item/eftpos/sec = 4, /obj/item/storage/belt/security/webbing = 2, ) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/storage/fancy/donut_box = 2,/obj/item/hailer = 5) + prices = list(/obj/item/storage/belt/security/webbing = 2000,) refill_canister = /obj/item/vending_refill/security /obj/machinery/vending/security/training name = "\improper SecTech Training" desc = "A security training equipment vendor." ads_list = list("Соблюдай чистоту на стрельбище!","Даже я стреляю лучше тебя!","Почему так косо, бухой что ли?!","Техника безопасности нам не писана, да?","1 из 10 попаданий... А ты хорош!","Инструктор это твой папочка!","Эй, ты куда целишься?!") - icon_state = "sectraining" - icon_deny = "sectraining-deny" + + icon_state = "sectraining_off" + panel_overlay = "sec_panel" + screen_overlay = "sec" + lightmask_overlay = "sec_lightmask" + broken_overlay = "sec_broken" + broken_lightmask_overlay = "sectraining_broken_lightmask" + deny_overlay = "sec_deny" + req_access = list(ACCESS_SECURITY) products = list(/obj/item/clothing/ears/earmuffs = 2, /obj/item/gun/energy/laser/practice = 2, /obj/item/gun/projectile/automatic/toy/pistol/enforcer = 2, /obj/item/gun/projectile/shotgun/toy = 2, /obj/item/gun/projectile/automatic/toy = 2) @@ -1225,22 +1447,18 @@ if(!powered()) return add_fingerprint(user) - var/list/available_kits = list( - "Dominator Kit" = list(/obj/item/gun/energy/dominator/sibyl, /obj/item/clothing/accessory/holster), - "Enforcer Kit" = list(/obj/item/gun/projectile/automatic/pistol/enforcer/security, /obj/item/ammo_box/magazine/enforcer, /obj/item/ammo_box/magazine/enforcer, /obj/item/clothing/accessory/holster), - ) - var/weapon_kit = input(user, "Select a weaponary kit.") as null|anything in available_kits + var/list/available_kits = list("Dominator Kit" = /obj/item/storage/box/dominator_kit, + "Enforcer Kit" = /obj/item/storage/box/enforcer_kit) + var/weapon_kit = tgui_input_list(user, "Select a weaponary kit:", "Weapon kits", available_kits) if(!weapon_kit) return if(!Adjacent(user) || QDELETED(I) || I.loc != user) return qdel(I) sleep(0.5 SECONDS) - var/obj/item/storage/box/box = new(get_turf(src)) playsound(get_turf(src), 'sound/machines/machine_vend.ogg', 50, TRUE) - box.icon_state = "box_sec" - for(var/path in available_kits[weapon_kit]) - new path(box) + var/path = available_kits[weapon_kit] + var/obj/item/box = new path(get_turf(src)) if(Adjacent(user)) user.put_in_hands(box, ignore_anim = FALSE) return @@ -1258,8 +1476,15 @@ desc = "A plant nutrients vendor" slogan_list = list("Вам не надо удобрять почву естественным путём — разве это не чудесно?","Теперь на 50% меньше вони!","Растения тоже люди!") ads_list = list("Мы любим растения!","Может сами примете?","Самые зелёные кнопки на свете.","Мы любим большие растения.","Мягкая почва…") - icon_state = "nutri" - icon_deny = "nutri-deny" + + icon_state = "nutri_off" + panel_overlay = "nutri_panel" + screen_overlay = "nutri" + lightmask_overlay = "nutri_lightmask" + broken_overlay = "nutri_broken" + broken_lightmask_overlay = "nutri_broken_lightmask" + deny_overlay = "nutri_deny" + products = list(/obj/item/reagent_containers/glass/bottle/nutrient/ez = 20,/obj/item/reagent_containers/glass/bottle/nutrient/l4z = 13,/obj/item/reagent_containers/glass/bottle/nutrient/rh = 6,/obj/item/reagent_containers/spray/pestspray = 20, /obj/item/reagent_containers/syringe = 5,/obj/item/storage/bag/plants = 5,/obj/item/cultivator = 3,/obj/item/shovel/spade = 3,/obj/item/plant_analyzer = 4) contraband = list(/obj/item/reagent_containers/glass/bottle/ammonia = 10,/obj/item/reagent_containers/glass/bottle/diethylamine = 5) @@ -1270,7 +1495,14 @@ desc = "When you need seeds fast!" slogan_list = list("THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!","Hands down the best seed selection on the station!","Also certain mushroom varieties available, more for experts! Get certified today!") ads_list = list("Мы любим растения!","Вырасти урожай!","Расти, малыш, расти-и-и-и!","Ды-а, сына!") - icon_state = "seeds" + + icon_state = "seeds_off" + panel_overlay = "seeds_panel" + screen_overlay = "seeds" + lightmask_overlay = "seeds_lightmask" + broken_overlay = "seeds_broken" + broken_lightmask_overlay = "seeds_broken_lightmask" + products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, @@ -1334,7 +1566,14 @@ /obj/machinery/vending/magivend name = "\improper MagiVend" desc = "A magic vending machine." - icon_state = "MagiVend" + + icon_state = "magivend_off" + panel_overlay = "magivend_panel" + screen_overlay = "magivend" + lightmask_overlay = "magivend_lightmask" + broken_overlay = "magivend_broken" + broken_lightmask_overlay = "magivend_broken_lightmask" + slogan_list = list("Sling spells the proper way with MagiVend!","Be your own Houdini! Use MagiVend!") vend_delay = 15 vend_reply = "Have an enchanted evening!" @@ -1372,8 +1611,15 @@ /obj/machinery/vending/autodrobe name = "\improper AutoDrobe" desc = "A vending machine for costumes." - icon_state = "theater" - icon_deny = "theater-deny" + + icon_state = "theater_off" + panel_overlay = "theater_panel" + screen_overlay = "theater" + lightmask_overlay = "theater_lightmask" + broken_overlay = "theater_broken" + broken_lightmask_overlay = "theater_broken_lightmask" + deny_overlay = "theater_deny" + slogan_list = list("Dress for success!","Suited and booted!","It's show time!","Why leave style up to fate? Use AutoDrobe!") vend_delay = 15 vend_reply = "Thank you for using AutoDrobe!" @@ -1495,30 +1741,41 @@ /obj/item/clothing/under/redhawaiianshirt = 1, /obj/item/clothing/under/pinkhawaiianshirt = 1, /obj/item/clothing/under/bluehawaiianshirt = 1, - /obj/item/clothing/under/orangehawaiianshirt = 1) + /obj/item/clothing/under/orangehawaiianshirt = 1, + /obj/item/clothing/under/ussptracksuit_red = 4, + /obj/item/clothing/under/ussptracksuit_blue = 4) contraband = list(/obj/item/clothing/suit/judgerobe = 1, - /obj/item/clothing/head/powdered_wig = 1, - /obj/item/gun/magic/wand = 1, - /obj/item/clothing/mask/balaclava =1, - /obj/item/clothing/under/syndicate/blackops_civ = 1, - /obj/item/clothing/glasses/thermal_fake = 1, - /obj/item/clothing/mask/horsehead = 2) + /obj/item/clothing/head/powdered_wig = 1, + /obj/item/gun/magic/wand = 1, + /obj/item/clothing/mask/balaclava =1, + /obj/item/clothing/under/syndicate/blackops_civ = 1, + /obj/item/clothing/glasses/thermal_fake = 1, + /obj/item/clothing/mask/horsehead = 2) premium = list(/obj/item/clothing/suit/hgpirate = 1, - /obj/item/clothing/head/hgpiratecap = 1, - /obj/item/clothing/head/helmet/roman/fake = 1, - /obj/item/clothing/head/helmet/roman/legionaire/fake = 1, - /obj/item/clothing/under/roman = 1, - /obj/item/clothing/shoes/roman = 1, - /obj/item/shield/riot/roman/fake = 1, - /obj/item/clothing/under/cuban_suit = 1, - /obj/item/clothing/head/cuban_hat = 1) + /obj/item/clothing/head/hgpiratecap = 1, + /obj/item/clothing/head/helmet/roman/fake = 1, + /obj/item/clothing/head/helmet/roman/legionaire/fake = 1, + /obj/item/clothing/under/roman = 1, + /obj/item/clothing/shoes/roman = 1, + /obj/item/shield/riot/roman/fake = 1, + /obj/item/clothing/under/cuban_suit = 1, + /obj/item/clothing/head/cuban_hat = 1, + /obj/item/clothing/under/ussptracksuit_black = 1, + /obj/item/clothing/under/ussptracksuit_white = 1) refill_canister = /obj/item/vending_refill/autodrobe /obj/machinery/vending/dinnerware name = "\improper Plasteel Chef's Dinnerware Vendor" desc = "A kitchen and restaurant equipment vendor." ads_list = list("Mm, food stuffs!","Food and food accessories.","Get your plates!","You like forks?","I like forks.","Woo, utensils.","You don't really need these...") - icon_state = "dinnerware" + + icon_state = "dinnerware_off" + panel_overlay = "dinnerware_panel" + screen_overlay = "dinnerware" + lightmask_overlay = "dinnerware_lightmask" + broken_overlay = "dinnerware_broken" + broken_lightmask_overlay = "dinnerware_broken_lightmask" + products = list(/obj/item/storage/bag/tray = 8,/obj/item/kitchen/utensil/fork = 6, /obj/item/kitchen/knife = 3,/obj/item/kitchen/rollingpin = 2, /obj/item/kitchen/sushimat = 3, @@ -1555,7 +1812,14 @@ /obj/machinery/vending/sovietsoda name = "\improper BODA" desc = "Old sweet water vending machine." - icon_state = "sovietsoda" + + icon_state = "sovietsoda_off" + panel_overlay = "sovietsoda_panel" + screen_overlay = "sovietsoda" + lightmask_overlay = "sovietsoda_lightmask" + broken_overlay = "sovietsoda_broken" + broken_lightmask_overlay = "sovietsoda_broken_lightmask" + ads_list = list("For Tsar and Country.","Have you fulfilled your nutrition quota today?","Very nice!","We are simple people, for this is all we eat.","If there is a person, there is a problem. If there is no person, then there is no problem.") products = list(/obj/item/reagent_containers/food/drinks/drinkingglass/soda = 30) contraband = list(/obj/item/reagent_containers/food/drinks/drinkingglass/cola = 20) @@ -1565,8 +1829,15 @@ /obj/machinery/vending/tool name = "\improper YouTool" desc = "Tools for tools." - icon_state = "tool" - icon_deny = "tool-deny" + + icon_state = "tool_off" + panel_overlay = "tool_panel" + screen_overlay = "tool" + lightmask_overlay = "tool_lightmask" + broken_overlay = "tool_broken" + broken_lightmask_overlay = "tool_broken_lightmask" + deny_overlay = "tool_deny" + products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/crowbar = 5,/obj/item/weldingtool = 3,/obj/item/wirecutters = 5, /obj/item/wrench = 5,/obj/item/analyzer = 5,/obj/item/t_scanner = 5,/obj/item/screwdriver = 5) contraband = list(/obj/item/weldingtool/hugetank = 2,/obj/item/clothing/gloves/color/fyellow = 2) @@ -1579,8 +1850,15 @@ /obj/machinery/vending/engivend name = "\improper Engi-Vend" desc = "Spare tool vending. What? Did you expect some witty description?" - icon_state = "engivend" - icon_deny = "engivend-deny" + + icon_state = "engivend_off" + panel_overlay = "engivend_panel" + screen_overlay = "engivend" + lightmask_overlay = "engivend_lightmask" + broken_overlay = "engivend_broken" + broken_lightmask_overlay = "engivend_broken_lightmask" + deny_overlay = "engivend_deny" + req_access = list(11,24) // Engineers and atmos techs can use this products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/multitool = 4,/obj/item/airlock_electronics = 10,/obj/item/firelock_electronics = 10,/obj/item/firealarm_electronics = 10,/obj/item/apc_electronics = 10,/obj/item/airalarm_electronics = 10,/obj/item/stock_parts/cell/high = 10,/obj/item/camera_assembly = 10) contraband = list(/obj/item/stock_parts/cell/potato = 3) @@ -1590,8 +1868,16 @@ /obj/machinery/vending/engineering name = "\improper Robco Tool Maker" desc = "Everything you need for do-it-yourself station repair." - icon_state = "engi" - icon_deny = "engi-deny" + + icon_state = "engi_off" + panel_overlay = "engi_panel" + screen_overlay = "engi" + lightmask_overlay = "engi_lightmask" + broken_overlay = "engi_broken" + broken_lightmask_overlay = "engi_broken_lightmask" + deny_overlay = "engi_deny" + deny_lightmask = "engi_deny_lightmask" + req_access = list(ACCESS_ENGINE_EQUIP) products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/workboots = 4,/obj/item/clothing/head/hardhat = 4, /obj/item/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/color/yellow = 4, /obj/item/screwdriver = 12, @@ -1604,8 +1890,16 @@ /obj/machinery/vending/robotics name = "\improper Robotech Deluxe" desc = "All the tools you need to create your own robot army." - icon_state = "robotics" - icon_deny = "robotics-deny" + + icon_state = "robotics_off" + panel_overlay = "robotics_panel" + screen_overlay = "robotics" + lightmask_overlay = "robotics_lightmask" + broken_overlay = "robotics_broken" + broken_lightmask_overlay = "robotics_broken_lightmask" + deny_overlay = "robotics_deny" + deny_lightmask = "robotics_deny_lightmask" + req_access = list(ACCESS_ROBOTICS) products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/flash = 4, /obj/item/stock_parts/cell/high = 12, /obj/item/assembly/prox_sensor = 3,/obj/item/assembly/signaler = 3,/obj/item/healthanalyzer = 3, @@ -1618,7 +1912,15 @@ desc = "A vending machine which vends food, as required by section 47-C of the NT's Prisoner Ethical Treatment Agreement." slogan_list = list("Enjoy your meal.","Enough calories to support strenuous labor.") ads_list = list("The healthiest!","Award-winning chocolate bars!","Mmm! So good!","Oh my god it's so juicy!","Have a snack.","Snacks are good for you!","Have some more Getmore!","Best quality snacks straight from mars.","We love chocolate!","Try our new jerky!") - icon_state = "sustenance" + + icon_state = "sustenance_off" + panel_overlay = "snack_panel" + screen_overlay = "snack" + lightmask_overlay = "snack_lightmask" + broken_overlay = "snack_broken" + broken_lightmask_overlay = "snack_broken_lightmask" + + broken_lightmask_overlay = "snack_broken_lightmask" products = list(/obj/item/reagent_containers/food/snacks/tofu = 24, /obj/item/reagent_containers/food/drinks/ice = 12, /obj/item/reagent_containers/food/snacks/candy/candy_corn = 6) @@ -1638,7 +1940,14 @@ /obj/machinery/vending/hatdispenser name = "\improper Hatlord 9000" desc = "It doesn't seem the slightest bit unusual. This frustrates you immensely." - icon_state = "hats" + + icon_state = "hats_off" + panel_overlay = "hats_panel" + screen_overlay = "hats" + lightmask_overlay = "hats_lightmask" + broken_overlay = "hats_broken" + broken_lightmask_overlay = "hats_broken_lightmask" + ads_list = list("Warning, not all hats are dog/monkey compatible. Apply forcefully with care.","Apply directly to the forehead.","Who doesn't love spending cash on hats?!","From the people that brought you collectable hat crates, Hatlord!") products = list(/obj/item/clothing/head/bowlerhat = 10, /obj/item/clothing/head/beaverhat = 10, @@ -1653,7 +1962,14 @@ /obj/machinery/vending/suitdispenser name = "\improper Suitlord 9000" desc = "You wonder for a moment why all of your shirts and pants come conjoined. This hurts your head and you stop thinking about it." - icon_state = "suits" + + icon_state = "suits_off" + panel_overlay = "suits_panel" + screen_overlay = "suits" + lightmask_overlay = "suits_lightmask" + broken_overlay = "suits_broken" + broken_lightmask_overlay = "suits_broken_lightmask" + ads_list = list("Pre-Ironed, Pre-Washed, Pre-Wor-*BZZT*","Blood of your enemies washes right out!","Who are YOU wearing?","Look dapper! Look like an idiot!","Dont carry your size? How about you shave off some pounds you fat lazy- *BZZT*") products = list( /obj/item/clothing/under/color/black = 10, @@ -1684,7 +2000,15 @@ /obj/machinery/vending/shoedispenser name = "\improper Shoelord 9000" desc = "Wow, hatlord looked fancy, suitlord looked streamlined, and this is just normal. The guy who designed these must be an idiot." - icon_state = "shoes" + + icon_state = "shoes_off" + icon_state = "shoes_off" + panel_overlay = "shoes_panel" + screen_overlay = "shoes" + lightmask_overlay = "shoes_lightmask" + broken_overlay = "shoes_broken" + broken_lightmask_overlay = "shoes_broken_lightmask" + ads_list = list("Put your foot down!","One size fits all!","IM WALKING ON SUNSHINE!","No hobbits allowed.","NO PLEASE WILLY, DONT HURT ME- *BZZT*") products = list(/obj/item/clothing/shoes/black = 10,/obj/item/clothing/shoes/brown = 10,/obj/item/clothing/shoes/blue = 10,/obj/item/clothing/shoes/green = 10,/obj/item/clothing/shoes/yellow = 10,/obj/item/clothing/shoes/purple = 10,/obj/item/clothing/shoes/red = 10,/obj/item/clothing/shoes/white = 10,/obj/item/clothing/shoes/sandal=10) contraband = list(/obj/item/clothing/shoes/orange = 5) @@ -1697,7 +2021,14 @@ slogan_list = list("Космосигареты на вкус хороши, какими они и должны быть.","I'd rather toolbox than switch.","Затянитесь!","Не верьте исследованиям — курите сегодня!") ads_list = list("Наверняка не очень-то и вредно для Вас!","Не верьте учёным!","На здоровье!","Не бросайте курить, купите ещё!","Затянитесь!","Никотиновый рай.","Лучшие сигареты с 2150 года.","Сигареты с множеством наград.") vend_delay = 34 - icon_state = "cigs" + + icon_state = "cigs_off" + panel_overlay = "cigs_panel" + screen_overlay = "cigs" + lightmask_overlay = "cigs_lightmask" + broken_overlay = "cigs_broken" + broken_lightmask_overlay = "cigs_broken_lightmask" + products = list(/obj/item/storage/fancy/cigarettes/syndicate = 10,/obj/item/lighter/random = 5) @@ -1706,7 +2037,14 @@ desc = "A modified snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars" slogan_list = list("Try our new nougat bar!","Twice the calories for half the price!") ads_list = list("The healthiest!","Award-winning chocolate bars!","Mmm! So good!","Oh my god it's so juicy!","Have a snack.","Snacks are good for you!","Have some more Getmore!","Best quality snacks straight from mars.","We love chocolate!","Try our new jerky!") - icon_state = "snack" + + icon_state = "snack_off" + panel_overlay = "snack_panel" + screen_overlay = "snack" + lightmask_overlay = "snack_lightmask" + broken_overlay = "snack_broken" + broken_lightmask_overlay = "snack_broken_lightmask" + products = list(/obj/item/reagent_containers/food/snacks/chips =6,/obj/item/reagent_containers/food/snacks/sosjerky = 6, /obj/item/reagent_containers/food/snacks/syndicake = 6, /obj/item/reagent_containers/food/snacks/cheesiehonkers = 6) @@ -1714,8 +2052,16 @@ name = "Синди Робо-ДеЛюкс!" desc = "Всё что нужно, чтобы сделать личного железного друга из ваших врагов!" ads_list = list("Make them beep-boop like a robot should!","Robotisation is NOT a crime!","Nyoom!") - icon_state = "robotics" - icon_deny = "robotics-deny" + + icon_state = "robotics_off" + panel_overlay = "robotics_panel" + screen_overlay = "robotics" + lightmask_overlay = "robotics_lightmask" + broken_overlay = "robotics_broken" + broken_lightmask_overlay = "robotics_broken_lightmask" + deny_overlay = "robotics_deny" + deny_lightmask = "robotics_deny_lightmask" + req_access = list(ACCESS_SYNDICATE) products = list(/obj/item/robot_parts/robot_suit = 2, /obj/item/robot_parts/chest = 2, @@ -1735,7 +2081,14 @@ /obj/machinery/vending/clothing name = "\improper ClothesMate" //renamed to make the slogan rhyme desc = "A vending machine for clothing." - icon_state = "clothes" + + icon_state = "clothes_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + slogan_list = list("Dress for success!","Prepare to look swagalicious!","Look at all this free swag!","Why leave style up to fate? Use the ClothesMate!") vend_delay = 15 vend_reply = "Thank you for using the ClothesMate!" @@ -1835,7 +2188,14 @@ slogan_list = list("Stop by for all your artistic needs!","Color the floors with crayons, not blood!","Don't be a starving artist, use ArtVend. ","Don't fart, do art!") ads_list = list("Just like Kindergarten!","Now with 1000% more vibrant colors!","Screwing with the janitor was never so easy!","Creativity is at the heart of every spessman.") vend_delay = 15 - icon_state = "artvend" + + icon_state = "artvend_off" + panel_overlay = "artvend_panel" + screen_overlay = "artvend" + lightmask_overlay = "artvend_lightmask" + broken_overlay = "artvend_broken" + broken_lightmask_overlay = "artvend_broken_lightmask" + products = list(/obj/item/toy/crayon/spraycan = 2,/obj/item/stack/cable_coil/random = 10,/obj/item/camera = 4,/obj/item/camera_film = 6, /obj/item/storage/photo_album = 2,/obj/item/stack/wrapping_paper = 4,/obj/item/stack/tape_roll = 5,/obj/item/stack/packageWrap = 4, /obj/item/storage/fancy/crayons = 4,/obj/item/hand_labeler = 4,/obj/item/paper = 10, @@ -1851,7 +2211,14 @@ slogan_list = list("Stop by for all your animal's needs!","Cuddly pets deserve a stylish collar!","Pets in space, what could be more adorable?","Freshest fish eggs in the system!","Rocks are the perfect pet, buy one today!") ads_list = list("House-training costs extra!","Now with 1000% more cat hair!","Allergies are a sign of weakness!","Dogs are man's best friend. Remember that Vulpkanin!"," Heat lamps for Unathi!"," Vox-y want a cracker?") vend_delay = 15 - icon_state = "crittercare" + + icon_state = "crittercare_off" + panel_overlay = "crittercare_panel" + screen_overlay = "crittercare" + lightmask_overlay = "crittercare_lightmask" + broken_overlay = "crittercare_broken" + broken_lightmask_overlay = "crittercare_broken_lightmask" + products = list(/obj/item/clothing/accessory/petcollar = 5, /obj/item/storage/firstaid/aquatic_kit/full =5, /obj/item/fish_eggs/goldfish = 5, /obj/item/fish_eggs/clownfish = 5, /obj/item/fish_eggs/shark = 5, /obj/item/fish_eggs/feederfish = 10, /obj/item/fish_eggs/salmon = 5, /obj/item/fish_eggs/catfish = 5, /obj/item/fish_eggs/glofish = 5, @@ -1874,7 +2241,6 @@ /obj/machinery/vending/clothing/departament name = "\improper Broken Departament ClothesMate" desc = "Автомат-помощник по выдаче одежды отдела." - icon_state = "clothes" slogan_list = list( "Одежда успешного работника!", "Похвала на глаза!", "Ну наконец-то нормально оделся!", "Одевай одежду, надевай еще и шляпку!", "Вот это гордость такое надевать!", "Выглядишь отпадно!", @@ -1897,8 +2263,14 @@ /obj/machinery/vending/clothing/departament/security name = "\improper Departament Security ClothesMate" desc = "Автомат-помощник по выдаче одежды Отдела Службы Безопасности." - icon_state = "clothes-dep-sec" - //slogan_list += list() + + icon_state = "clothes-dep-sec_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-sec" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-sec_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_SEC_DOORS) products = list( /obj/item/clothing/head/soft/sec = 10, @@ -1925,6 +2297,7 @@ /obj/item/clothing/mask/balaclava = 10, /obj/item/clothing/mask/bandana/red = 10, /obj/item/clothing/mask/bandana/black = 10, + /obj/item/clothing/mask/secscarf = 10, /obj/item/clothing/gloves/color/black = 10, /obj/item/clothing/gloves/color/red = 10, @@ -1966,8 +2339,14 @@ /obj/machinery/vending/clothing/departament/medical name = "\improper Departament Medical ClothesMate" desc = "Автомат-помощник по выдаче одежды Медицинского Отдела." - icon_state = "clothes-dep-med" - //slogan_list += list() + + icon_state = "clothes-dep-med_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-med" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-med_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_MEDICAL) products = list( /obj/item/clothing/head/beret/med = 10, @@ -2057,9 +2436,15 @@ /obj/machinery/vending/clothing/departament/engineering name = "\improper Departament Engineering ClothesMate" desc = "Автомат-помощник по выдаче одежды Инженерного Отдела." - icon_state = "clothes-dep-eng" + + icon_state = "clothes-dep-eng_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-eng" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-eng_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_ENGINE_EQUIP) - //slogan_list += list() products = list( /obj/item/clothing/head/hardhat = 10, /obj/item/clothing/head/hardhat/orange = 10, @@ -2110,8 +2495,14 @@ /obj/machinery/vending/clothing/departament/science name = "\improper Departament Science ClothesMate" desc = "Автомат-помощник по выдаче одежды Научного Отдела." - icon_state = "clothes-dep-sci" - //slogan_list += list() + + icon_state = "clothes-dep-sci_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-sci" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-sci_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_RESEARCH) products = list( /obj/item/clothing/head/beret/purple_normal = 10, @@ -2159,8 +2550,14 @@ /obj/machinery/vending/clothing/departament/cargo name = "\improper Departament Cargo ClothesMate" desc = "Автомат-помощник по выдаче одежды Отдела Поставок." - icon_state = "clothes-dep-car" - //slogan_list += list() + + icon_state = "clothes-dep-car_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-car" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-car_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_MINING) products = list( /obj/item/clothing/head/soft = 10, @@ -2211,9 +2608,15 @@ /obj/machinery/vending/clothing/departament/law name = "\improper Departament Law ClothesMate" desc = "Автомат-помощник по выдаче одежды Юридического Отдела." - icon_state = "clothes-dep-sec" - //slogan_list += list() - req_access = list(38) + + icon_state = "clothes-dep-sec_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-sec" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-sec_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + + req_access = list(ACCESS_LAWYER) products = list( /obj/item/clothing/under/rank/internalaffairs = 10, /obj/item/clothing/under/lawyer/female = 10, @@ -2263,8 +2666,6 @@ /obj/machinery/vending/clothing/departament/service name = "\improper Departament Service ClothesMate" desc = "Автомат-помощник по выдаче одежды Сервисного отдела." - icon_state = "clothes" - //slogan_list += list() req_access = list() products = list() refill_canister = /obj/item/vending_refill/ @@ -2272,8 +2673,14 @@ /obj/machinery/vending/clothing/departament/service/chaplain name = "\improper Departament Service ClothesMate Chaplain" desc = "Автомат-помощник по выдаче одежды Сервисного отдела церкви." - icon_state = "clothes-dep-car" - //slogan_list += list() + + icon_state = "clothes-dep-car_off" + panel_overlay = "clothes_panel" + screen_overlay = "clothes-dep-car" + lightmask_overlay = "clothes_lightmask" + broken_overlay = "clothes-dep-car_broken" + broken_lightmask_overlay = "clothes_broken_lightmask" + req_access = list(ACCESS_CHAPEL_OFFICE) products = list( /obj/item/clothing/under/rank/chaplain = 5, @@ -2303,8 +2710,6 @@ /obj/machinery/vending/clothing/departament/service/botanical name = "\improper Departament Service ClothesMate Botanical" desc = "Автомат-помощник по выдаче одежды Сервисного отдела ботаники." - icon_state = "clothes" - //slogan_list += list() req_access = list(ACCESS_HYDROPONICS) products = list( /obj/item/clothing/under/rank/hydroponics = 5, @@ -2333,9 +2738,17 @@ name = "NT Ammunition" desc = "A special equipment vendor." ads_list = list("Возьми патрон!","Не забывай, снаряжаться - полезно!","Бжж-Бзз-з!.","Обезопасить, Удержать, Сохранить!","Стоять, снярядись на задание!") - icon_state = "nta" - icon_deny = "nta_deny" - icon_vend = "nta_vend" + + icon_state = "nta_base" + panel_overlay = "nta_panel" + screen_overlay = "nta" + lightmask_overlay = "nta_lightmask" + broken_overlay = "nta_broken" + broken_lightmask_overlay = "nta_lightmask" + vend_overlay = "nta_vend" + deny_overlay = "nta_deny" + vend_overlay_time = 3 SECONDS + req_access = list(ACCESS_SECURITY) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2371,12 +2784,43 @@ contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/storage/fancy/donut_box = 2,/obj/item/grenade/clusterbuster/apocalypsefake = 1) refill_canister = /obj/item/vending_refill/nta + +/obj/machinery/vending/nta/ertarmory/update_overlays() + . = list() + + underlays.Cut() + + . += base_icon_state + + if(panel_open) + . += "nta_panel" + + if((stat & NOPOWER) || force_no_power_icon_state) + . += "nta_off" + return + + if(stat & BROKEN) + . += "nta_broken" + else + if(flick_sequence & FLICK_VEND) + . += vend_overlay + + else if(flick_sequence & FLICK_DENY) + . += deny_overlay + + underlays += emissive_appearance(icon, "nta_lightmask") + + /obj/machinery/vending/nta/ertarmory/blue name = "NT ERT Medium Gear & Ammunition" desc = "A ERT Medium equipment vendor." ads_list = list("Круши черепа синдиката!","Не забывай, спасать - полезно!","Бжж-Бзз-з!.","Обезопасить, Удержать, Сохранить!","Стоять, снярядись на задание!") - icon_state = "nta_blue" - icon_deny = "nta_blue_deny" + + icon_state = "nta_base" + base_icon_state = "nta-blue" + vend_overlay = "nta_vend" + deny_overlay = "nta-blue_deny" + req_access = list(ACCESS_CENT_SECURITY) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2400,8 +2844,12 @@ name = "NT ERT Heavy Gear & Ammunition" desc = "A ERT Heavy equipment vendor." ads_list = list("Круши черепа синдиката!","Не забывай, спасать - полезно!","Бжж-Бзз-з!.","Обезопасить, Удержать, Сохранить!","Стоять, снярядись на задание!") - icon_state = "nta_red" - icon_deny = "nta_red_deny" + + icon_state = "nta_base" + base_icon_state = "nta-red" + vend_overlay = "nta_vend" + deny_overlay = "nta-red_deny" + req_access = list(ACCESS_CENT_SECURITY) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2425,8 +2873,12 @@ name = "NT ERT Light Gear & Ammunition" desc = "A ERT Light equipment vendor." ads_list = list("Круши черепа синдиката!","Не забывай, спасать - полезно!","Бжж-Бзз-з!.","Обезопасить, Удержать, Сохранить!","Стоять, снярядись на задание!") - icon_state = "nta_green" - icon_deny = "nta_green_deny" + + icon_state = "nta_base" + base_icon_state = "nta-green" + vend_overlay = "nta_vend" + deny_overlay = "nta-green_deny" + req_access = list(ACCESS_CENT_SECURITY) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2444,7 +2896,8 @@ /obj/item/ammo_box/speedloader/shotgun = 4, /obj/item/gun/projectile/automatic/wt550 = 3, /obj/item/ammo_box/magazine/wt550m9 = 6, - /obj/item/gun/energy/dominator/sibyl = 2 + /obj/item/gun/energy/dominator/sibyl = 2, + /obj/item/melee/classic_baton/telescopic = 4 ) contraband = list(/obj/item/storage/fancy/donut_box = 2) refill_canister = /obj/item/vending_refill/nta @@ -2453,8 +2906,12 @@ name = "NT ERT Death Wish Gear & Ammunition" desc = "A ERT Death Wish equipment vendor." ads_list = list("Круши черепа ВСЕХ!","Не забывай, УБИВАТЬ - полезно!","УБИВАТЬ УБИВАТЬ УБИВАТЬ УБИВАТЬ!.","УБИВАТЬ, Удержать, УБИВАТЬ!","Стоять, снярядись на УБИВАТЬ!") - icon_state = "nta_yellow" - icon_deny = "nta_yellow_deny" + + icon_state = "nta_base" + base_icon_state = "nta-yellow" + vend_overlay = "nta_vend" + deny_overlay = "nta-yellow_deny" + req_access = list(ACCESS_CENT_SECURITY) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2477,8 +2934,12 @@ name = "NT ERT Medical Gear" desc = "A ERT medical equipment vendor." ads_list = list("Лечи раненых от рук синдиката!","Не забывай, лечить - полезно!","Бжж-Бзз-з!.","Перевязать, Оперировать, Выписать!","Стоять, снярядись медикаментами на задание!") - icon_state = "nta_medical" - icon_deny = "nta_medical_deny" + + icon_state = "nta_base" + base_icon_state = "nta-medical" + vend_overlay = "nta_vend" + deny_overlay = "nta-medical_deny" + req_access = list(ACCESS_CENT_MEDICAL) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2511,8 +2972,12 @@ name = "NT ERT Engineer Gear" desc = "A ERT engineering equipment vendor." ads_list = list("Чини станцию от рук синдиката!","Не забывай, чинить - полезно!","Бжж-Бзз-з!.","Починить, Заварить, Трубить!","Стоять, снярядись на починку труб!") - icon_state = "nta_engi" - icon_deny = "nta_engi_deny" + + icon_state = "nta_base" + base_icon_state = "nta-engi" + vend_overlay = "nta_vend" + deny_overlay = "nta-engi_deny" + req_access = list(ACCESS_CENT_GENERAL) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2538,8 +3003,12 @@ name = "NT ERT Janitor Gear" desc = "A ERT ccleaning equipment vendor." ads_list = list("Чисть станцию от рук синдиката!","Не забывай, чистить - полезно!","Вилкой чисти!.","Помыть, Постирать, Оттереть!","Стоять, снярядись клинерами!") - icon_state = "nta_janitor" - icon_deny = "nta_janitor_deny" + + icon_state = "nta_base" + base_icon_state = "nta-janitor" + vend_overlay = "nta_vend" + deny_overlay = "nta-janitor_deny" + req_access = list(ACCESS_CENT_GENERAL) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF products = list( @@ -2563,7 +3032,14 @@ /obj/machinery/vending/pai name = "\improper RoboFriends" desc = "Wonderful vendor of PAI friends" - icon_state = "paivend" + + icon_state = "paivend_off" + panel_overlay = "paivend_panel" + screen_overlay = "paivend" + lightmask_overlay = "paivend_lightmask" + broken_overlay = "paivend_broken" + broken_lightmask_overlay = "paivend_broken_lightmask" + ads_list = list("А вы любите нас?","Мы твои друзья!","Эта покупка войдет в историю","Я ПАИ простой, купишь меня, а я тебе друга!","Спасибо за покупку.") resistance_flags = FIRE_PROOF products = list( @@ -2591,3 +3067,9 @@ /obj/item/pai_cartridge/memory = 350 ) refill_canister = /obj/item/vending_refill/pai + + +#undef FLICK_NONE +#undef FLICK_VEND +#undef FLICK_DENY + diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index d4b9ecbccd2..6edc0abcc19 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/machines/washing_machine.dmi' icon_state = "wm_10" density = 1 - anchored = 1.0 + anchored = TRUE var/state = 1 //1 = empty, open door //2 = empty, closed door @@ -162,10 +162,6 @@ for(var/obj/item/clothing/shoes/S in contents) if(!S.dyeable) continue - if(S.chained == 1) - S.chained = 0 - S.slowdown = SHOES_SLOWDOWN - new /obj/item/restraints/handcuffs( src ) S.icon_state = new_shoe_icon_state S.item_color = wash_color S.name = new_shoe_name @@ -221,7 +217,7 @@ usr.loc = src.loc -/obj/machinery/washing_machine/update_icon() +/obj/machinery/washing_machine/update_icon_state() icon_state = "wm_[state][panel]" /obj/machinery/washing_machine/attackby(obj/item/W as obj, mob/user as mob, params) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index ac467769754..b0fd6eb75d3 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -330,7 +330,7 @@ if(reagents.total_volume<=0) occupant_message(span_alert("No available reagents to load syringe with.")) return FALSE - var/turf/trg = get_turf(target) + var/turf/target_turf = get_turf(target) var/obj/item/reagent_containers/syringe/mechsyringe = syringes[1] mechsyringe.forceMove(get_turf(chassis)) reagents.trans_to(mechsyringe, min(mechsyringe.volume, reagents.total_volume)) @@ -340,42 +340,49 @@ playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) log_message("Launched [mechsyringe] from [src], targeting [target].") start_cooldown() + INVOKE_ASYNC(src, PROC_REF(async_syringe_gun_action), mechsyringe, target_turf) + + +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/async_syringe_gun_action(obj/item/reagent_containers/syringe/mechsyringe, turf/target_turf) var/mob/originaloccupant = chassis.occupant var/original_target_zone = originaloccupant.zone_selected - spawn(0) - src = null //if src is deleted, still process the syringe - var/max_range = 6 - for(var/i=0, i= 200) add_attack_logs(user, target, "gibbed") - if(LAZYLEN(target.butcher_results)) + if(LAZYLEN(target.butcher_results) || issmall(target)) target.harvest(chassis) // Butcher the mob with our drill. else target.gib() @@ -147,23 +147,19 @@ icon_state = "mecha_analyzer" equip_cooldown = 1.5 SECONDS -/obj/item/mecha_parts/mecha_equipment/mining_scanner/Initialize(mapload) - . = ..() - START_PROCESSING(SSfastprocess, src) - /obj/item/mecha_parts/mecha_equipment/mining_scanner/Destroy() - STOP_PROCESSING(SSfastprocess, src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/mining_scanner/attach_act(obj/mecha/M) - START_PROCESSING(SSfastprocess, src) + START_PROCESSING(SSobj, src) -/obj/item/mecha_parts/mecha_equipment/mining_scanner/detach_act() - STOP_PROCESSING(SSfastprocess, src) +/obj/item/mecha_parts/mecha_equipment/mining_scanner/detach_act(obj/mecha/M) + STOP_PROCESSING(SSobj, src) /obj/item/mecha_parts/mecha_equipment/mining_scanner/process() if(!chassis) - STOP_PROCESSING(SSfastprocess, src) + STOP_PROCESSING(SSobj, src) return TRUE if(!action_checks(src)) return FALSE diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index df453c0f2da..68a38ecba92 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -7,7 +7,6 @@ equip_cooldown = 1.5 SECONDS energy_drain = 10 var/dam_force = 20 - var/obj/mecha/working/cargo_holder harmful = TRUE /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/M) @@ -16,29 +15,23 @@ return TRUE return FALSE -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach_act(obj/mecha/M) - cargo_holder = M - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach_act() - cargo_holder = null - /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(atom/target) if(!action_checks(target)) return FALSE - if(!cargo_holder) + if(!chassis) return FALSE - if(istype(target,/obj)) + if(isobj(target)) var/obj/O = target if(!O.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + if(length(chassis.cargo) < chassis.cargo_capacity) chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") O.anchored = TRUE if(do_after_cooldown(target)) - cargo_holder.cargo += O + LAZYADD(chassis.cargo, O) O.loc = chassis O.anchored = FALSE occupant_message(span_notice("[target] successfully loaded.")) - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + log_message("Loaded [O]. Cargo compartment capacity: [chassis.cargo_capacity - length(chassis.cargo)]") return TRUE else O.anchored = initial(O.anchored) @@ -47,7 +40,7 @@ else occupant_message(span_warning("[target] is firmly secured!")) return FALSE - else if(istype(target,/mob/living)) + if(isliving(target)) var/mob/living/M = target if(chassis.occupant.a_intent == INTENT_HARM) M.take_overall_damage(dam_force) @@ -64,15 +57,15 @@ occupant_message(span_warning("БЕГИ, ИДИОТ, НЕ ВРЕМЯ ДЛЯ ОБНИМАШЕК!!!")) return FALSE if(!M.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + if(length(chassis.cargo) < chassis.cargo_capacity) chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") M.anchored = TRUE if(do_after_cooldown(target)) - cargo_holder.cargo += M + LAZYADD(chassis.cargo, M) M.loc = chassis M.anchored = FALSE occupant_message(span_notice("[target] successfully loaded.")) - log_message("Loaded [M]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + log_message("Loaded [M]. Cargo compartment capacity: [chassis.cargo_capacity - length(chassis.cargo)]") return TRUE else M.anchored = initial(M.anchored) @@ -99,47 +92,27 @@ /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target) if(!action_checks(target)) return FALSE - if(!cargo_holder) + if(!chassis) return FALSE - if(istype(target,/obj)) - var/obj/O = target - if(!O.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - O.anchored = TRUE - if(do_after_cooldown(target)) - cargo_holder.cargo += O - O.loc = chassis - O.anchored = FALSE - occupant_message(span_notice("[target] successfully loaded.")) - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - return TRUE - else - O.anchored = initial(O.anchored) - return FALSE - else - occupant_message(span_warning("Not enough room in cargo compartment!")) - return FALSE - else - occupant_message(span_warning("[target] is firmly secured!")) - return FALSE - else if(istype(target,/mob/living)) - var/mob/living/M = target - if(M.stat == DEAD) - return FALSE - if(chassis.occupant.a_intent == INTENT_HARM) - target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), - span_userdanger("[chassis] destroys [target] in an unholy fury.")) - M.gib() - /*if(chassis.occupant.a_intent == INTENT_DISARM) - target.visible_message("[chassis] rips [target]'s arms off.", - "[chassis] rips [target]'s arms off.")*/ - else - step_away(M,chassis) - target.visible_message("[chassis] tosses [target] like a piece of paper.") - start_cooldown() - return TRUE + if(!isliving(target)) + return ..() + + var/mob/living/M = target + if(M.stat == DEAD) + return FALSE + if(chassis.occupant.a_intent == INTENT_HARM) + target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), + span_userdanger("[chassis] destroys [target] in an unholy fury.")) + M.gib() + /*if(chassis.occupant.a_intent == INTENT_DISARM) + target.visible_message("[chassis] rips [target]'s arms off.", + "[chassis] rips [target]'s arms off.")*/ + else + step_away(M,chassis) + target.visible_message("[chassis] tosses [target] like a piece of paper.") + start_cooldown() + return TRUE /obj/item/mecha_parts/mecha_equipment/cargo_upgrade name = "Cargo expansion upgrade" @@ -150,21 +123,17 @@ /obj/item/mecha_parts/mecha_equipment/cargo_upgrade/can_attach(obj/mecha/M) if(..()) - if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat/lockersyndie)) + if(istype(M, /obj/mecha/working)) return TRUE return FALSE -/obj/item/mecha_parts/mecha_equipment/cargo_upgrade/attach_act() - if(istype(loc, /obj/mecha/working)) - var/obj/mecha/working/W = loc - W.cargo_expanded = TRUE - W.cargo_capacity = 40 - -/obj/item/mecha_parts/mecha_equipment/cargo_upgrade/detach_act() - if(istype(loc, /obj/mecha/working)) - var/obj/mecha/working/R = loc - R.cargo_expanded = FALSE - R.cargo_capacity = initial(R.cargo_capacity) +/obj/item/mecha_parts/mecha_equipment/cargo_upgrade/attach_act(obj/mecha/M) + chassis.cargo_expanded = TRUE + chassis.cargo_capacity = 40 + +/obj/item/mecha_parts/mecha_equipment/cargo_upgrade/detach_act(obj/mecha/M) + chassis.cargo_expanded = FALSE + chassis.cargo_capacity = initial(chassis.cargo_capacity) /obj/item/mecha_parts/mecha_equipment/rcd name = "Mounted RCD" diff --git a/code/game/mecha/makeshift/lockermech.dm b/code/game/mecha/makeshift/lockermech.dm index ef53e5607db..d5f1ac563a6 100644 --- a/code/game/mecha/makeshift/lockermech.dm +++ b/code/game/mecha/makeshift/lockermech.dm @@ -12,64 +12,9 @@ max_equip = 2 //You only have two arms and the control system is shitty wreckage = null mech_enter_time = 20 - var/list/cargo = list() - var/cargo_capacity = 5 // you can fit a few things in this locker but not much. -/obj/mecha/makeshift/Topic(href, href_list) - ..() - if(href_list["drop_from_cargo"]) - var/obj/O = locate(sanitize(href_list["drop_from_cargo"])) - if(O && (O in cargo)) - occupant_message("You unload [O].") - O.forceMove(loc) - cargo -= O - log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") - return - -/obj/mecha/makeshift/go_out() - ..() - update_icon() + cargo_capacity = 5 // you can fit a few things in this locker but not much. -/obj/mecha/makeshift/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() - - -/obj/mecha/makeshift/Exit(atom/movable/O) - if(O in cargo) - return 0 - return ..() - -// /obj/mecha/makeshift/contents_explosion(severity, target) -// for(var/X in cargo) -// var/obj/O = X -// if(prob(30/severity)) -// cargo -= O -// O.forceMove(loc) -// . = ..() - -/obj/mecha/makeshift/get_stats_part() - var/output = ..() - output += "Cargo Compartment Contents:
    " - if(cargo.len) - for(var/obj/O in cargo) - output += "Unload : [O]
    " - else - output += "Nothing" - output += "
    " - return output - -// /obj/mecha/makeshift/relay_container_resist(mob/living/user, obj/O) -// to_chat(user, "You lean on the back of [O] and start pushing so it falls out of [src].") -// if(do_after(user, 10, target = O))//Its a fukken locker -// if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) -// return -// to_chat(user, "You successfully pushed [O] out of [src]!") -// O.loc = loc -// cargo -= O -// else -// if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. -// to_chat(user, "You fail to push [O] out of [src]!") /obj/mecha/makeshift/Destroy() new /obj/structure/closet(loc) @@ -92,13 +37,6 @@ max_equip = 4 wreckage = null -/obj/mecha/combat/lockersyndie/go_out() - ..() - update_icon() - -/obj/mecha/combat/lockersyndie/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() /obj/mecha/combat/lockersyndie/add_cell() cell = new /obj/item/stock_parts/cell/high/slime(src) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 543e425bcb5..fb580773f06 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -12,7 +12,7 @@ /obj/machinery/mech_bay_recharge_port name = "Mech Bay Power Port" density = 1 - anchored = 1 + anchored = TRUE dir = EAST icon = 'icons/obj/mecha/mech_bay.dmi' icon_state = "recharge_port" @@ -113,7 +113,7 @@ /obj/machinery/computer/mech_bay_power_console name = "mech bay power control console" density = 1 - anchored = 1 + anchored = TRUE icon = 'icons/obj/machines/computer.dmi' icon_keyboard = "tech_key" icon_screen = "recharge_comp" @@ -122,12 +122,17 @@ var/obj/machinery/mech_bay_recharge_port/recharge_port -/obj/machinery/computer/mech_bay_power_console/update_icon() - if(!recharge_port || !recharge_port.recharging_mecha || !recharge_port.recharging_mecha.cell || !(recharge_port.recharging_mecha.cell.charge < recharge_port.recharging_mecha.cell.maxcharge) || stat & (NOPOWER|BROKEN)) - icon_screen = "recharge_comp" +/obj/machinery/computer/mech_bay_power_console/update_overlays() + if(stat & (NOPOWER|BROKEN)) + icon_screen = "recharge_comp" // off else - icon_screen = "recharge_comp_on" - ..() + var/obj/item/stock_parts/cell/cell = recharge_port?.recharging_mecha?.cell + if(!cell || cell.charge >= cell.maxcharge) + icon_screen = "recharge_comp" // don't have a reachable cell to charge or fully charged + else + icon_screen = "recharge_comp_on" // now we working! + . = ..() + /obj/machinery/computer/mech_bay_power_console/proc/reconnect() if(recharge_port) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 4f48c565b60..6afc03349a1 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -34,7 +34,6 @@ var/add_req_access = TRUE var/maint_access = TRUE var/dna //dna-locking the mech - var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference var/datum/effect_system/spark_spread/spark_system = new var/lights = 0 var/lights_power = 6 @@ -42,7 +41,12 @@ var/emagged = FALSE var/frozen = FALSE var/repairing = FALSE - var/cargo_expanded = FALSE // for wide cargo module + /// The internal storage of the exosuit. For the cargo module + var/list/cargo + /// You can fit a few things in this mecha but not much. + var/cargo_capacity = 1 + /// for wide cargo module + var/cargo_expanded = FALSE //inner atmos var/use_internal_tank = FALSE @@ -744,15 +748,27 @@ if(occupant) occupant.ex_act(severity) + for(var/X in cargo) + var/atom/movable/cargo_thing = X + if(prob(30 / severity)) + cargo -= cargo_thing + cargo_thing.forceMove(drop_location()) + /obj/mecha/handle_atom_del(atom/A) if(A == occupant) occupant = null - icon_state = initial(icon_state)+"-open" + update_icon(UPDATE_ICON_STATE) setDir(dir_in) if(A in trackers) trackers -= A /obj/mecha/Destroy() + + for(var/atom/movable/cargo_thing as anything in cargo) + cargo -= cargo_thing + cargo_thing.forceMove(drop_location()) + step_rand(cargo_thing) + if(occupant) occupant.SetSleeping(destruction_sleep_duration) go_out() @@ -887,7 +903,7 @@ name = P.new_name desc = P.new_desc initial_icon = P.new_icon - reset_icon() + update_icon(UPDATE_ICON_STATE) user.temporarily_remove_item_from_inventory(P) qdel(P) @@ -1065,7 +1081,7 @@ occupant = null AI.controlled_mech = null AI.remote_control = null - icon_state = reset_icon(icon_state)+"-open" + update_icon(UPDATE_ICON_STATE) to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") to_chat(user, "[span_boldnotice("Transfer successful")]: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") @@ -1102,7 +1118,7 @@ AI.aiRestorePowerRoutine = 0 AI.forceMove(src) occupant = AI - icon_state = reset_icon(icon_state) + update_icon(UPDATE_ICON_STATE) playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) if(!hasInternalDamage()) occupant << sound(nominalsound, volume = 50) @@ -1203,10 +1219,10 @@ /obj/mecha/proc/toggle_internal_tank() internals_action.Trigger() -/obj/mecha/MouseDrop_T(mob/M, mob/user) +/obj/mecha/MouseDrop_T(mob/M, mob/user, params) if(frozen) to_chat(user, span_warning("Do not enter Admin-Frozen mechs.")) - return + return TRUE if(user.incapacitated()) return if(user != M) @@ -1215,7 +1231,7 @@ if(occupant) to_chat(user, span_warning("The [src] is already occupied!")) log_append_to_last("Permission denied.") - return + return TRUE var/passed if(dna) if(ishuman(user)) @@ -1226,17 +1242,21 @@ if(!passed) to_chat(user, span_warning("Access denied.")) log_append_to_last("Permission denied.") - return + return TRUE if(user.buckled) to_chat(user, span_warning("You are currently buckled and cannot move.")) log_append_to_last("Permission denied.") - return + return TRUE if(user.has_buckled_mobs()) //mob attached to us to_chat(user, span_warning("You can't enter the exosuit with other creatures attached to you!")) - return + return TRUE + + visible_message(span_notice("[user] starts to climb into [src]")) + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/mecha, put_in), user) + return TRUE - visible_message(span_notice("[user] starts to climb into [src].")) +/obj/mecha/proc/put_in(mob/user) if(do_after(user, mech_enter_time * gettoolspeedmod(user), target = src)) if(obj_integrity <= 0) to_chat(user, span_warning("You cannot get in the [name], it has been destroyed!")) @@ -1251,7 +1271,8 @@ else to_chat(user, span_warning("You stop entering the exosuit!")) -/obj/mecha/proc/moved_inside(var/mob/living/carbon/human/H as mob) + +/obj/mecha/proc/moved_inside(mob/living/carbon/human/H) if(H && H.client && (H in range(1))) occupant = H H.stop_pulling() @@ -1260,7 +1281,7 @@ GrantActions(H, human_occupant = 1) forceMove(loc) log_append_to_last("[H] moved in as pilot.") - icon_state = reset_icon() + update_icon(UPDATE_ICON_STATE) dir = dir_in playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) if(!activated) @@ -1324,7 +1345,7 @@ mmi_as_oc.mecha = src Entered(mmi_as_oc) Move(loc) - icon_state = reset_icon() + update_icon(UPDATE_ICON_STATE) dir = dir_in log_message("[mmi_as_oc] moved in as pilot.") if(!hasInternalDamage()) @@ -1343,14 +1364,16 @@ return TRUE return FALSE -/obj/mecha/proc/pilot_mmi_hud(var/mob/living/carbon/brain/pilot) - return - /obj/mecha/Exited(atom/movable/M, atom/newloc) ..() if(occupant && occupant == M) // The occupant exited the mech without calling go_out() go_out(1, newloc) +/obj/mecha/Exit(atom/movable/O) + if(O in cargo) + return FALSE + return ..() + /obj/mecha/proc/go_out(forced, atom/newloc = loc) if(!occupant) return @@ -1409,7 +1432,7 @@ var/obj/item/mmi/robotic_brain/R = mmi if(R.imprinted_master) to_chat(L, span_notice("Imprint re-enabled, you are once again bound to [R.imprinted_master]'s commands.")) - icon_state = reset_icon(icon_state)+"-open" + update_icon(UPDATE_ICON_STATE) dir = dir_in if(L && L.client) @@ -1513,12 +1536,6 @@ else occupant.throw_alert("charge", /obj/screen/alert/mech_nocell) -/obj/mecha/proc/reset_icon() - if(initial_icon) - icon_state = initial_icon - else - icon_state = initial(icon_state) - return icon_state ////////////////////////////////////////// //////// Mecha global iterators //////// @@ -1640,7 +1657,6 @@ AI = occupant occupant = null var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) - WR.icon_state = "[reset_icon(loc, AI)]-broken" for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) if(E.salvageable && prob(30)) WR.crowbar_salvage += E @@ -1695,4 +1711,10 @@ return FALSE return TRUE + +/obj/mecha/update_icon_state() + var/init_icon_state = initial_icon ? initial_icon : initial(icon_state) + icon_state = occupant ? init_icon_state : "[init_icon_state]-open" + + #undef OCCUPANT_LOGGING diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index 4d3f3cd9a90..192da8f919c 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -76,23 +76,34 @@ var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown" var/tank_temperature_c = internal_tank ? internal_tank.return_temperature() - T0C : "Unknown" var/cabin_pressure = round(return_pressure(),0.01) - . = "[report_internal_damage()]" - . += "[integrity<30?"DAMAGE LEVEL CRITICAL
    ":null]" - . += "Integrity: [integrity]%
    " - . += "Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
    " - . += "Air source: [use_internal_tank?"Internal Airtank":"Environment"]
    " - . += "Airtank pressure: [tank_pressure]kPa
    " - . += "Airtank temperature: [tank_temperature]°K|[tank_temperature_c]°C
    " - . += "Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
    " - . += "Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
    " - . += "Lights: [lights?"on":"off"]
    " - . += "[dna ? "DNA-locked:
    [dna] \[Reset\]
    " : ""]" - . += "[defense_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
    " : ""]" - . += "[overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
    " : ""]" - . += "[thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
    " : ""]" - . += "[smoke_action.owner ? "Smoke: [smoke]
    " : ""]" - . += "[zoom_action.owner ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
    " : ""]" - . += "[phasing_action.owner ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
    " : ""]" + var/list/stats_part_list = list() + stats_part_list += "[report_internal_damage()]" + stats_part_list += "[integrity<30?"DAMAGE LEVEL CRITICAL
    ":null]" + stats_part_list += "Integrity: [integrity]%
    " + stats_part_list += "Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
    " + stats_part_list += "Air source: [use_internal_tank?"Internal Airtank":"Environment"]
    " + stats_part_list += "Airtank pressure: [tank_pressure]kPa
    " + stats_part_list += "Airtank temperature: [tank_temperature]°K|[tank_temperature_c]°C
    " + stats_part_list += "Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
    " + stats_part_list += "Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
    " + stats_part_list += "Lights: [lights?"on":"off"]
    " + stats_part_list += "[dna ? "DNA-locked:
    [dna] \[Reset\]
    " : ""]" + stats_part_list += "[defense_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
    " : ""]" + stats_part_list += "[overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
    " : ""]" + stats_part_list += "[thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
    " : ""]" + stats_part_list += "[smoke_action.owner ? "Smoke: [smoke]
    " : ""]" + stats_part_list += "[zoom_action.owner ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
    " : ""]" + stats_part_list += "[phasing_action.owner ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
    " : ""]" + stats_part_list += "Cargo Compartment Contents:
    " + if(length(cargo)) + for(var/obj/O in cargo) + stats_part_list += "Unload : [O]
    " + for(var/mob/living/L in cargo) + stats_part_list += "Unload : [L]
    " + else + stats_part_list += "Nothing" + stats_part_list += "
    " + return stats_part_list.Join("") /obj/mecha/proc/get_commands() . = "
    " @@ -405,6 +416,14 @@ occupant_message("Recalibration failed.") log_message("Recalibration of coordination system failed with 1 error.",1) + if(href_list["drop_from_cargo"]) + var/atom/movable/cargo_thing = locateUID(href_list["drop_from_cargo"]) + if(istype(cargo_thing) && (cargo_thing in cargo)) + occupant_message(span_notice("You unload [cargo_thing].")) + cargo_thing.forceMove(loc) + cargo -= cargo_thing + log_message("Unloaded [cargo_thing]. Cargo compartment capacity: [cargo_capacity - length(cargo)]") + //debug /* if(href_list["debug"]) diff --git a/code/game/mecha/paintkits.dm b/code/game/mecha/paintkits.dm index 977b5f27560..e486b9488e6 100644 --- a/code/game/mecha/paintkits.dm +++ b/code/game/mecha/paintkits.dm @@ -309,3 +309,39 @@ new_name = "Pirate Mauler" new_icon = "piratmauler" allowed_types = list("mauler") + +/obj/item/paintkit/lockermech_nt + name = "NT Special Locker Mech customisation kit" + icon_state = "paintkit_nt1" + desc = "A kit containing all the needed tools and parts to show that Locker Mech it is the property of NT." + + new_name = "NT Special Locker Mech" + new_icon = "ntlockermech" + allowed_types = list("lockermech") + +/obj/item/paintkit/durand_nt + name = "NT Special Durand customisation kit" + icon_state = "paintkit_nt" + desc = "A kit containing all the needed tools and parts to show that Durand it is the property of NT" + + new_name = "NT Special Durand" + new_icon = "ntdurand" + allowed_types = list("durand") + +/obj/item/paintkit/ripley_nt + name = "NT Special APLU customisation kit" + icon_state = "paintkit_nt" + desc = "A kit containing all the needed tools and parts to show that APLU it is the property of NT" + + new_name = "NT Special APLU" + new_icon = "ntripley" + allowed_types = list("ripley", "firefighter") + +/obj/item/paintkit/phazon_nt + name = "NT Special Phazon customisation kit" + icon_state = "paintkit_nt" + desc = "A kit containing all the needed tools and parts to show that Phazon it is the property of NT" + + new_name = "NT Special Phazon" + new_icon = "ntphazon" + allowed_types = list("phazon") diff --git a/code/game/mecha/working/gigadrill.dm b/code/game/mecha/working/gigadrill.dm index ff3dfd01821..6f1f6a02e95 100644 --- a/code/game/mecha/working/gigadrill.dm +++ b/code/game/mecha/working/gigadrill.dm @@ -25,14 +25,14 @@ turnsound = null // wreckage = /obj/effect/decal/mecha_wreckage/gigadrill // no dmi :( -/obj/mecha/working/gigadrill/New() - ..() +/obj/mecha/working/gigadrill/Initialize() + . = ..() soundloop = new(list(src), FALSE) pixel_x = -16 pixel_y = -16 var/obj/item/mecha_parts/mecha_equipment/drill/giga/drill = new drill.attach(src) - cargo.Add(new /obj/structure/ore_box(src)) + LAZYADD(cargo, new /obj/structure/ore_box(src)) var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/clamp = new clamp.integrated = TRUE diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index fdd9c96bb96..a2e0f66a4c6 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -16,49 +16,69 @@ var/hides = 0 var/plates = 0 -/obj/mecha/working/ripley/update_icon() - ..() + +/obj/mecha/working/ripley/Destroy() + for(var/i=1, i <= hides, i++) + new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop + return ..() + + +/obj/mecha/working/ripley/update_overlays() + . = ..() + if(hides && !plates) + if(hides < 3) + . += occupant ? "ripley-g" : "ripley-g-open" + else + . += occupant ? "ripley-g-full" : "ripley-g-full-open" + + else if(plates && !hides) + if(plates < 3) + . += occupant ? "ripley-a" : "ripley-a-open" + else + . += occupant ? "ripley-a-full" : "ripley-a-full-open" + + else if(plates && hides) + if(plates < 3 && hides >= 3) + . += occupant ? "ripley-g-full" : "ripley-g-full-open" + . += occupant ? "ripley-a" : "ripley-a-open" + + else if(plates < 3 && hides < 3) + . += occupant ? "ripley-a-full" : "ripley-a-full-open" + . += occupant ? "ripley-g" : "ripley-g-open" + + else if(plates >= 3 && hides < 3) + . += occupant ? "ripley-a-full" : "ripley-a-full-open" + . += occupant ? "ripley-g" : "ripley-g-open" + + else if(plates >= 3 && hides >= 3) + . += occupant ? "ripley-g-full" : "ripley-g-full-open" + . += occupant ? "ripley-a" : "ripley-a-open" + + +/obj/mecha/working/ripley/update_desc(updates = ALL) + . = ..() + if(hides && !plates) - cut_overlays() if(hides < 3) - add_overlay(occupant ? "ripley-g" : "ripley-g-open") desc = "Autonomous Power Loader Unit. You see reinforcements made of plates of goliath hide attached to the armor." else - add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open") desc = "Autonomous Power Loader Unit. It has an intimidating carapace composed entirely of plates of goliath hide - its pilot must be an experienced monster hunter." - if(plates && !hides) - cut_overlays() + else if(plates && !hides) if(plates < 3) - add_overlay(occupant ? "ripley-a" : "ripley-a-open") desc = "Autonomous Power Loader Unit. You can see the pieces of homemade armor on the hull." else - add_overlay(occupant ? "ripley-a-full" : "ripley-a-full-open") desc = "Autonomous Power Loader Unit. Completely encrusted with reinforced debris, this shiny lump of metal looks incredibly durable." - if(plates && hides) - cut_overlays() - if(plates < 3 && hides == 3) - cut_overlays() - add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open") - add_overlay(occupant ? "ripley-a" : "ripley-a-open") + else if(plates && hides) + if(plates < 3 && hides >= 3) desc = "Autonomous Power Loader Unit. Not only is the goliath hide armor intimidating, it's additionally covered in pieces of homemade armor. How do you kill that?!" - if(plates < 3 && hides < 3) - cut_overlays() - add_overlay(occupant ? "ripley-a-full" : "ripley-a-full-open") - add_overlay(occupant ? "ripley-g" : "ripley-g-open") + else if(plates < 3 && hides < 3) desc = "Autonomous Power Loader Unit. The owner of the mech decided to go all out - clad in pieces of homemade armor and goliath skins." - if(plates == 3 && hides < 3) - cut_overlays() - add_overlay(occupant ? "ripley-a-full" : "ripley-a-full-open") - add_overlay(occupant ? "ripley-g" : "ripley-g-open") + else if(plates >= 3 && hides < 3) + desc = "Autonomous Power Loader Unit. Fully covered with homemade armor and few goliath hides on top." + else if(plates >= 3 && hides >= 3) desc = "Autonomous Power Loader Unit. Clad in homemade armor from ear to toe, with Goliath plates on top - a real tank, no other way." - if(plates == 3 && hides == 3) - cut_overlays() - add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open") - add_overlay(occupant ? "ripley-a" : "ripley-a-open") - - /obj/mecha/working/ripley/firefighter @@ -119,7 +139,7 @@ P.attach(src) //Add ore box to cargo - cargo.Add(new /obj/structure/ore_box(src)) + LAZYADD(cargo, new /obj/structure/ore_box(src)) //Attach hydraulic clamp var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new @@ -129,18 +149,6 @@ var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new scanner.attach(src) -/obj/mecha/working/ripley/Exit(atom/movable/O) - if(O in cargo) - return 0 - return ..() - -/obj/mecha/working/ripley/ex_act(severity) - ..() - for(var/X in cargo) - var/obj/O = X - if(prob(30 / severity)) - cargo -= O - O.forceMove(drop_location()) /obj/mecha/working/ripley/emag_act(mob/user) if(!emagged) diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm index 51c9a6fe2de..823f305f897 100644 --- a/code/game/mecha/working/working.dm +++ b/code/game/mecha/working/working.dm @@ -1,12 +1,11 @@ /obj/mecha/working internal_damage_threshold = 60 - var/list/cargo = new - var/cargo_capacity = 15 + cargo_capacity = 15 var/fast_pressure_step_in = 2 var/slow_pressure_step_in = 2 -/obj/mecha/working/New() - ..() +/obj/mecha/working/Initialize() + . = ..() if(!ruin_mecha) trackers += new /obj/item/mecha_parts/mecha_tracking(src) @@ -18,20 +17,6 @@ if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! ore.forceMove(ore_box) -/obj/mecha/working/Topic(href, href_list) - ..() - if(href_list["drop_from_cargo"]) - var/obj/O = locate(href_list["drop_from_cargo"]) - if(O && (O in cargo)) - occupant_message("You unload [O].") - O.loc = get_turf(src) - cargo -= O - var/turf/T = get_turf(O) - if(T) - T.Entered(O) - log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - cargo.len]") - return - /obj/mecha/working/Move() . = ..() if(.) @@ -52,53 +37,12 @@ /obj/mecha/working/go_out() ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/mecha/working/moved_inside(mob/living/carbon/human/H) ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/mecha/working/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) ..() - update_icon() - -/obj/mecha/working/Exit(atom/movable/O) - if(O in cargo) - return 0 - return ..() - -/obj/mecha/working/get_stats_part() - var/output = ..() - output += "Cargo Compartment Contents:
    " - if(cargo.len) - for(var/obj/O in cargo) - output += "Unload : [O]
    " - for(var/mob/living/L in cargo) - output += "Unload : [L]
    " - else - output += "Nothing" - output += "
    " - return output - -/obj/mecha/working/Destroy() - for(var/mob/M in src) - if(M == occupant) - continue - M.loc = get_turf(src) - M.loc.Entered(M) - step_rand(M) - for(var/atom/movable/A in cargo) - A.loc = get_turf(src) - var/turf/T = get_turf(A) - if(T) - T.Entered(A) - step_rand(A) - return ..() - -/obj/mecha/working/ex_act(severity) - ..() - for(var/X in cargo) - var/obj/O = X - if(prob(30 / severity)) - cargo -= O - O.forceMove(drop_location()) + update_icon(UPDATE_OVERLAYS) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 8e81c35e4e9..dc9fae405c7 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -23,11 +23,11 @@ return TRUE -/atom/movable/MouseDrop_T(mob/living/M, mob/living/user) +/atom/movable/MouseDrop_T(mob/living/dropping, mob/living/user, params) . = ..() - if(can_buckle && istype(M) && istype(user)) - if(user_buckle_mob(M, user)) - return TRUE + if(can_buckle && istype(dropping) && istype(user) && user_buckle_mob(dropping, user)) + return TRUE + /atom/movable/proc/has_buckled_mobs() return length(buckled_mobs) diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm index 45281197bf1..c69f4011433 100644 --- a/code/game/objects/effects/bump_teleporter.dm +++ b/code/game/objects/effects/bump_teleporter.dm @@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(bump_teleporters) var/id = null // id of this bump_teleporter. var/id_target = null // id of bump_teleporter which this moves you to. invisibility = INVISIBILITY_ABSTRACT // nope, can't see this - anchored = 1 + anchored = TRUE density = 1 opacity = 0 diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 617ebf6d62b..535dc6d88ab 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -1,7 +1,5 @@ #define DRYING_TIME 5 * 60 * 10 //for 1 unit of depth in puddle (amount var) -GLOBAL_LIST_EMPTY(splatter_cache) - /obj/effect/decal/cleanable/blood name = "blood" var/dryname = "dried blood" @@ -47,10 +45,13 @@ GLOBAL_LIST_EMPTY(splatter_cache) deltimer(dry_timer) return ..() -/obj/effect/decal/cleanable/blood/update_icon() +/obj/effect/decal/cleanable/blood/update_icon(updates = ALL) + if(!updates) + return if(basecolor == "rainbow") basecolor = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]" color = basecolor + . = ..() /obj/effect/decal/cleanable/blood/proc/dry() name = dryname @@ -144,21 +145,27 @@ GLOBAL_LIST_EMPTY(splatter_cache) random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") no_clear = TRUE mergeable_decal = FALSE - + var/image/giblets var/fleshcolor = "#FFFFFF" -/obj/effect/decal/cleanable/blood/gibs/update_icon() - var/image/giblets = new(base_icon, "[icon_state]_flesh", dir) + +/obj/effect/decal/cleanable/blood/gibs/update_icon(updates = ALL) + if(!updates) + return + giblets = new(base_icon, "[icon_state]_flesh", dir) if(!fleshcolor || fleshcolor == "rainbow") fleshcolor = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]" giblets.color = fleshcolor var/icon/blood = new(base_icon,"[icon_state]",dir) - icon = blood - overlays.Cut() - overlays += giblets . = ..() + +/obj/effect/decal/cleanable/blood/gibs/update_overlays() + . = ..() + . += giblets + + /obj/effect/decal/cleanable/blood/gibs/ex_act(severity) return diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 4537beeb4fb..fca8e26ff43 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -11,7 +11,7 @@ /obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/blood/gibs/robot/update_icon() +/obj/effect/decal/cleanable/blood/gibs/robot/update_icon(updates = ALL) color = "#FFFFFF" . = ..(NONE) diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index eb09fe2599d..ecb8ef0743d 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -84,8 +84,8 @@ GLOBAL_LIST_EMPTY(fluidtrack_cache) update_icon() -/obj/effect/decal/cleanable/blood/footprints/update_icon() - overlays.Cut() +/obj/effect/decal/cleanable/blood/footprints/update_overlays() + . = ..() for(var/Ddir in GLOB.cardinal) if(entered_dirs & Ddir) @@ -97,7 +97,7 @@ GLOBAL_LIST_EMPTY(fluidtrack_cache) GLOB.fluidtrack_cache["entered-[blood_state]-[Ddir]"] = I if(I) I.color = basecolor - overlays += I + . += I if(exited_dirs & Ddir) var/image/I if(GLOB.fluidtrack_cache["exited-[blood_state]-[Ddir]"]) @@ -107,9 +107,10 @@ GLOBAL_LIST_EMPTY(fluidtrack_cache) GLOB.fluidtrack_cache["exited-[blood_state]-[Ddir]"] = I if(I) I.color = basecolor - overlays += I + . += I + + alpha = BLOODY_FOOTPRINT_BASE_ALPHA + bloodiness - alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness /proc/createFootprintsFrom(atom/movable/A, dir, turf/T) var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T) diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index cd79ee747fe..9276465daed 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -2,7 +2,7 @@ name = "explosive particles" icon_state = "explosion_particle" opacity = 1 - anchored = 1 + anchored = TRUE /obj/effect/particle_effect/expl_particles/New() ..() @@ -26,7 +26,7 @@ icon = 'icons/effects/96x96.dmi' icon_state = "explosion" opacity = 1 - anchored = 1 + anchored = TRUE mouse_opacity = MOUSE_OPACITY_TRANSPARENT pixel_x = -32 pixel_y = -32 diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 135cbffaeba..2e2d0423cc9 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -6,7 +6,7 @@ name = "foam" icon_state = "foam" opacity = 0 - anchored = 1 + anchored = TRUE density = 0 layer = OBJ_LAYER + 0.9 animate_movement = 0 @@ -37,7 +37,7 @@ var/obj/structure/foamedmetal/M = new(src.loc) M.metal = metal - M.updateicon() + M.update_state() flick("[icon_state]-disolve", src) sleep(5) @@ -194,15 +194,20 @@ /obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) playsound(src.loc, 'sound/weapons/tap.ogg', 100, TRUE) -/obj/structure/foamedmetal/proc/updateicon() + +/obj/structure/foamedmetal/proc/update_state() if(metal == MFOAM_ALUMINUM) - icon_state = "metalfoam" max_integrity = 20 obj_integrity = max_integrity else - icon_state = "ironfoam" max_integrity = 50 obj_integrity = max_integrity + update_icon(UPDATE_ICON_STATE) + + +/obj/structure/foamedmetal/update_icon_state() + icon_state = (metal == MFOAM_ALUMINUM) ? "metalfoam" : "ironfoam" + /obj/structure/foamedmetal/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 2cba4ad52fc..e234ab15f1b 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -11,7 +11,7 @@ pixel_x = -32 pixel_y = -32 opacity = 1 - anchored = 0 + anchored = FALSE var/steps = 0 var/lifetime = 5 var/direction diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index a721820fdd0..64eeee49057 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -3,7 +3,7 @@ name = "FORCEWALL" icon = 'icons/effects/effects.dmi' icon_state = "m_shield" - anchored = 1 + anchored = TRUE opacity = 0 density = 1 var/lifetime = 30 SECONDS diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index a3fb5959215..5eae820fe87 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -3,7 +3,7 @@ icon = 'icons/misc/landmarks.dmi' icon_state = "standart" layer = 5 - anchored = 1.0 + anchored = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF /obj/effect/landmark/New() diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 820f7357954..d7a5d31501e 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -2,7 +2,7 @@ name = "dummy mine" desc = "I Better stay away from that thing." density = 0 - anchored = 1 + anchored = TRUE icon = 'icons/obj/items.dmi' icon_state = "uglyminearmed" var/triggered = 0 diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 0a8de954cab..8d7ee82c1fb 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -23,13 +23,13 @@ icon = 'icons/obj/items.dmi' icon_state = "strangepresent" density = 1 - anchored = 0 + anchored = FALSE /obj/effect/mark var/mark = "" icon = 'icons/misc/mark.dmi' icon_state = "blank" - anchored = 1 + anchored = TRUE layer = 99 plane = HUD_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT @@ -50,12 +50,12 @@ name = "begin" icon = 'icons/obj/stationobjs.dmi' icon_state = "begin" - anchored = 1.0 + anchored = TRUE /obj/effect/projection name = "Projection" desc = "This looks like a projection of something." - anchored = 1.0 + anchored = TRUE /obj/effect/shut_controller @@ -69,7 +69,7 @@ icon_state = "showcase_1" desc = "A stand with the empty body of a cyborg bolted to it." density = 1 - anchored = 1 + anchored = TRUE /obj/effect/spawner name = "object spawner" @@ -121,3 +121,19 @@ . = ..() if(!ismob(loc)) return INITIALIZE_HINT_QDEL + +/obj/effect/frosty_breath //used only for unathi firebreath, so... yeah.. + icon = 'icons/effects/effects.dmi' + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = ABOVE_MOB_LAYER + anchored = TRUE + +/obj/effect/frosty_breath/Initialize(mapload, mob/living/carbon/C) + . = ..() + dir = C.dir + if(C.buckled) + pixel_y = (C.buckled.buckle_offset + 10) + if(dir == NORTH) + layer = BELOW_MOB_LAYER + flick("breath_[C.lying_prev]", src) + QDEL_IN(src, 2 SECONDS) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index c7e66b6226e..abf62b88a03 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -24,7 +24,7 @@ icon_state = "palm1" density = 1 layer = 5 - anchored = 1 + anchored = TRUE /obj/effect/overlay/palmtree_l name = "Palm tree" @@ -32,7 +32,7 @@ icon_state = "palm2" density = 1 layer = 5 - anchored = 1 + anchored = TRUE /obj/effect/overlay/coconut name = "Coconuts" @@ -54,7 +54,7 @@ name = "Wallrot" desc = "Ick..." icon = 'icons/effects/wallrot.dmi' - anchored = 1 + anchored = TRUE density = 1 layer = 5 mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index ffe8b4a9e48..a8813512a65 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -125,6 +125,9 @@ /obj/item/wirecutters = 10, /obj/item/wrench = 40, /obj/item/relic = 35, + /obj/item/weaponcrafting/revolverbarrel = 3, + /obj/item/weaponcrafting/revolverbarrel/steel = 2, + /obj/item/ammo_box/magazine/internal/cylinder/improvised/steel = 2, /obj/item/weaponcrafting/receiver = 2, /obj/item/clothing/gloves/knuckles = 1, /obj/item/clothing/shoes/brown = 30, @@ -162,7 +165,7 @@ /obj/item/storage/pill_bottle/fakedeath = 2, /obj/item/storage/box/syndie_kit/mr_chang_technique = 1, /obj/item/clothing/glasses/chameleon/meson = 7, - "" = 68 + "" = 61 ) /obj/effect/spawner/lootdrop/crate_spawner // for ruins diff --git a/code/game/objects/effects/spawners/windowspawner.dm b/code/game/objects/effects/spawners/windowspawner.dm index 5f19720b481..0ce1cbc4eb3 100644 --- a/code/game/objects/effects/spawners/windowspawner.dm +++ b/code/game/objects/effects/spawners/windowspawner.dm @@ -5,7 +5,7 @@ var/useFull = 0 var/useGrille = 1 var/windowtospawn = /obj/structure/window/basic - anchored = 1 // No sliding out while you prime + anchored = TRUE // No sliding out while you prime /obj/effect/spawner/window/Initialize() . = ..() diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 5a9d0b5ee6f..a52929e1997 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -92,7 +92,7 @@ name = "spiderling" desc = "It never stays still for long." icon_state = "spiderling" - anchored = 0 + anchored = FALSE layer = 2.75 max_integrity = 3 var/amount_grown = 0 @@ -247,7 +247,7 @@ desc = "Green squishy mess." icon = 'icons/effects/effects.dmi' icon_state = "greenshatter" - anchored = 1 + anchored = TRUE /obj/structure/spider/cocoon name = "cocoon" diff --git a/code/game/objects/effects/temporary_visuals/cult.dm b/code/game/objects/effects/temporary_visuals/cult.dm index a1b2d4320a9..6ee3c867931 100644 --- a/code/game/objects/effects/temporary_visuals/cult.dm +++ b/code/game/objects/effects/temporary_visuals/cult.dm @@ -44,6 +44,12 @@ icon_state = "space" duration = 600 layer = ABOVE_OBJ_LAYER + var/from_lava = FALSE + + +/obj/effect/temp_visual/cult/portal/update_icon_state() + icon_state = from_lava ? "lava" : "space" + /obj/effect/temp_visual/emp/cult name = "cult emp sparks" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 66b816090af..f78054226c0 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -267,7 +267,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g msg += "No tech origins detected.
    " - if(materials.len) + if(length(materials)) msg += "Extractable materials:
    " for(var/mat in materials) msg += "[CallMaterialName(mat)]
    " //Capitize first word, remove the "$" @@ -532,6 +532,12 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g if((src == user.l_ear || src == user.r_ear) && (user.head.flags_inv & HIDEHEADSETS)) return TRUE + if(user.wear_mask) + if(src == user.glasses && (user.wear_mask.flags_inv & HIDEGLASSES)) + return TRUE + if((src == user.l_ear || src == user.r_ear) && (user.wear_mask.flags_inv & HIDEHEADSETS)) + return TRUE + return FALSE @@ -1153,12 +1159,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g /obj/item/update_atom_colour() . = ..() - if(!is_equipped()) - return update_equipped_item() - for(var/action in actions) - var/datum/action/myaction = action - myaction.UpdateButtonIcon() /obj/item/proc/add_tape() diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index 251b95fdadc..31c0cdee0c7 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -49,47 +49,73 @@ pixel_y = rand(-5, 5) pixel_x = rand(-6, 6) + /obj/item/storage/ashtray/attackby(obj/item/I, mob/user, params) if(!can_be_inserted(I)) return - handle_item_insertion(I) - if(istype(I, /obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/cig = I - if(cig.lit == TRUE) - visible_message("[user] crushes [cig] in [src], putting it out.") - var/obj/item/butt = new cig.type_butt(src) - cig.transfer_fingerprints_to(butt) - qdel(cig) - if(cig.lit == FALSE) - visible_message("[user] places [cig] in [src] without even smoking it. Why did [user.p_they()] do that?") - return - visible_message("[user] places [I] in [src].") -/obj/item/storage/ashtray/update_icon() - if(contents.len == storage_slots) + var/is_cig = istype(I, /obj/item/clothing/mask/cigarette) + if(is_cig || istype(I, /obj/item/cigbutt) || istype(I, /obj/item/match)) + if(!user.drop_item_ground(I)) + return + + handle_item_insertion(I) + + var/message_done = FALSE + if(is_cig) + var/obj/item/clothing/mask/cigarette/cig = I + if(cig.lit) + message_done = TRUE + visible_message("[user] crushes [cig] in [src], putting it out.") + var/obj/item/butt = new cig.type_butt(src) + cig.transfer_fingerprints_to(butt) + qdel(cig) + else + to_chat(user, "You place [cig] in [src] without even smoking it. Why would you do that?") + + if(!message_done) + visible_message("[user] places [I] in [src].") + add_fingerprint(user) + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + + +/obj/item/storage/ashtray/update_icon_state() + if(length(contents) == storage_slots) icon_state = icon_full - desc = initial(desc) + " It's stuffed full." - return - if(contents.len >= storage_slots * 0.5) + else if(length(contents) > storage_slots * 0.5) icon_state = icon_half - desc = initial(desc) + " It's half-filled." - return - if(contents.len < storage_slots * 0.5) + else icon_state = initial(icon_state) + + +/obj/item/storage/ashtray/update_desc(updates = ALL) + . = ..() + if(length(contents) == storage_slots) + desc = initial(desc) + " It's stuffed full." + else if(length(contents) > storage_slots * 0.5) + desc = initial(desc) + " It's half-filled." + else desc = initial(desc) + +/obj/item/storage/ashtray/proc/empty_tray() + for(var/obj/item/I in contents) + I.forceMove(loc) + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + + /obj/item/storage/ashtray/deconstruct() var/obj/item/trash/broken_ashtray/shards = new(get_turf(src)) - shards.icon_state = src.icon_broken + shards.icon_state = icon_broken visible_message("Oops, [src] broke into a lot of pieces!") return ..() + /obj/item/storage/ashtray/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - if(contents.len) - for(var/obj/item/I in contents) - I.forceMove(loc) - update_icon() + if(length(contents)) visible_message("[src] slams into [hit_atom] spilling its contents!") + empty_tray() if(rand(1,20) > max_integrity) deconstruct() return ..() + diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index da89819b411..6a8f6d0fece 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -23,45 +23,55 @@ close_sound = 'sound/items/zip.ogg' open_sound_volume = 15 close_sound_volume = 15 + density = FALSE + integrity_failure = FALSE var/item_path = /obj/item/bodybag - density = 0 - integrity_failure = 0 -/obj/structure/closet/body_bag/attackby(W as obj, mob/user as mob, params) - if(istype(W, /obj/item/pen)) - var/t = rename_interactive(user, W) +/obj/structure/closet/body_bag/attackby(obj/item/I, mob/user, params) + if(is_pen(I)) + var/t = rename_interactive(user, I) if(isnull(t)) return - cut_overlays() if(t) - add_fingerprint(user) - add_overlay(image(icon, "bodybag_label")) + update_icon(UPDATE_OVERLAYS) return - if(istype(W, /obj/item/wirecutters)) - add_fingerprint(user) - to_chat(user, "You cut the tag off the bodybag") - name = "body bag" - cut_overlays() + if(I.tool_behaviour == TOOL_WIRECUTTER) + to_chat(user, "You cut the tag off the bodybag.") + name = initial(name) + update_icon(UPDATE_OVERLAYS) return return ..() /obj/structure/closet/body_bag/close() if(..()) - density = 0 - return 1 - return 0 + density = FALSE + return TRUE + return FALSE -/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location) - . = ..() - if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) - if(!ishuman(usr) || opened || length(contents)) - return FALSE - visible_message("[usr] folds up the [name]") +/obj/structure/closet/body_bag/update_icon_state() + icon_state = opened ? icon_opened : icon_closed + + +/obj/structure/closet/body_bag/update_overlays() + . = list() + if(name != initial(name)) + . += "bodybag_label" + + +/obj/structure/closet/body_bag/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(over_object == usr && ishuman(usr) && !usr.incapacitated() && !opened && !length(contents) && usr.Adjacent(src)) + usr.visible_message( + span_notice("[usr] folds up [src]."), + span_notice("You fold up [src]."), + ) new item_path(get_turf(src)) qdel(src) + return FALSE + return ..() + /obj/structure/closet/body_bag/relaymove(mob/user as mob) if(user.stat) @@ -72,8 +82,3 @@ if(!open()) to_chat(user, "It won't budge!") -/obj/structure/closet/body_bag/update_icon() - if(!opened) - icon_state = icon_closed - else - icon_state = icon_opened diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index d25e23e1b0f..cb50ac08180 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -1,3 +1,7 @@ +#define TALL_CANDLE 1 +#define MID_CANDLE 2 +#define SHORT_CANDLE 3 + /obj/item/candle name = "red candle" desc = "In Greek myth, Prometheus stole fire from the Gods and gave it to humankind. The jewelry he kept for himself." @@ -6,36 +10,40 @@ item_state = "candle1" w_class = WEIGHT_CLASS_TINY var/wax = 200 - var/lit = 0 - var/infinite = 0 - var/start_lit = 0 + /// Index for the icon state + var/wax_index = TALL_CANDLE + var/lit = FALSE + var/infinite = FALSE + var/start_lit = FALSE + var/flickering = FALSE light_color = "#E09D37" -/obj/item/candle/New() - ..() + +/obj/item/candle/Initialize(mapload) + . = ..() if(start_lit) // No visible message light(show_message = 0) + /obj/item/candle/Destroy() STOP_PROCESSING(SSobj, src) return ..() -/obj/item/candle/update_icon() - var/i - if(wax>150) - i = 1 - else if(wax>80) - i = 2 - else i = 3 - icon_state = "candle[i][lit ? "_lit" : ""]" + +/obj/item/candle/update_icon_state() + if(flickering) + icon_state = "candle[wax_index]_flicker" + else + icon_state = "candle[wax_index][lit ? "_lit" : ""]" + /obj/item/candle/can_enter_storage(obj/item/storage/S, mob/user) if(lit) to_chat(user, "[S] can't hold [src] while it's lit!") return FALSE - else - return TRUE + return TRUE + /obj/item/candle/attackby(obj/item/W, mob/user, params) if(is_hot(W)) @@ -43,16 +51,19 @@ return return ..() + /obj/item/candle/welder_act(mob/user, obj/item/I) . = TRUE if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass light("[user] casually lights the [name] with [I], what a badass.") + /obj/item/candle/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) if(!lit) light() //honk return ..() + /obj/item/candle/proc/light(show_message) if(!lit) lit = 1 @@ -60,7 +71,32 @@ usr.visible_message(show_message) set_light(CANDLE_LUM) START_PROCESSING(SSobj, src) - update_icon() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/candle/proc/update_wax_index() + var/new_wax_index + if(wax > 150) + new_wax_index = TALL_CANDLE + else if(wax > 80) + new_wax_index = MID_CANDLE + else + new_wax_index = SHORT_CANDLE + if(wax_index != new_wax_index) + wax_index = new_wax_index + return TRUE + return FALSE + + +/obj/item/candle/proc/start_flickering() + flickering = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(stop_flickering)), 4 SECONDS, TIMER_UNIQUE) + + +/obj/item/candle/proc/stop_flickering() + flickering = FALSE + update_icon(UPDATE_ICON_STATE) /obj/item/candle/process() @@ -68,28 +104,49 @@ return if(!infinite) wax-- + if(wax_index != SHORT_CANDLE) // It's not at its shortest + if(update_wax_index()) + update_icon(UPDATE_ICON_STATE) if(!wax) - new/obj/item/trash/candle(src.loc) - if(istype(src.loc, /mob)) - var/mob/M = src.loc - M.temporarily_remove_item_from_inventory(src, force = TRUE) //src is being deleted anyway + new/obj/item/trash/candle(loc) + if(ismob(loc)) + var/mob/holder = loc + holder.drop_item_ground(src, force = TRUE) //src is being deleted anyway qdel(src) - update_icon() if(isturf(loc)) //start a fire if possible var/turf/T = loc T.hotspot_expose(700, 5) +/obj/item/candle/proc/unlight() + if(lit) + lit = FALSE + update_icon(UPDATE_ICON_STATE) + set_light(0) + + /obj/item/candle/attack_self(mob/user) if(lit) user.visible_message("[user] snuffs out [src].") - lit = 0 - update_icon() - set_light(0) + unlight() + + +/obj/item/candle/get_spooked() + if(lit) + start_flickering() + playsound(src, 'sound/effects/candle_flicker.ogg', 15, TRUE) + return TRUE + return FALSE + /obj/item/candle/eternal desc = "A candle. This one seems to have an odd quality about the wax." - infinite = 1 + infinite = TRUE + + +/obj/item/candle/eternal/wizard + desc = "A candle. It smells like magic, so that would explain why it burns brighter." + start_lit = TRUE /obj/item/candle/extinguish_light(force = FALSE) @@ -97,3 +154,9 @@ return infinite = FALSE wax = 1 // next process will burn it out + + +#undef TALL_CANDLE +#undef MID_CANDLE +#undef SHORT_CANDLE + diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 95abc042be1..c8cc639f123 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -271,8 +271,7 @@ switch(choice) if("Toggle Cap") to_chat(user, "You [capped ? "Remove" : "Replace"] the cap of the [src]") - capped = capped ? 0 : 1 - icon_state = "spraycan[capped ? "_cap" : ""]" + capped = !capped update_icon() if("Change Drawing") ..() @@ -304,8 +303,13 @@ playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5) ..() -/obj/item/toy/crayon/spraycan/update_icon() - overlays.Cut() - var/image/I = image('icons/obj/crayons.dmi',icon_state = "[capped ? "spraycan_cap_colors" : "spraycan_colors"]") + +/obj/item/toy/crayon/spraycan/update_icon_state() + icon_state = "spraycan[capped ? "_cap" : ""]" + + +/obj/item/toy/crayon/spraycan/update_overlays() + . = ..() + var/image/I = image('icons/obj/crayons.dmi', icon_state = "[capped ? "spraycan_cap_colors" : "spraycan_colors"]") I.color = colour - overlays += I + . += I diff --git a/code/game/objects/items/decorations.dm b/code/game/objects/items/decorations.dm index 20727a73635..bb53edb459c 100644 --- a/code/game/objects/items/decorations.dm +++ b/code/game/objects/items/decorations.dm @@ -226,7 +226,7 @@ icon = 'icons/obj/decorations.dmi' icon_state = "" density = 1 - anchored = 0 + anchored = FALSE max_integrity = 100 /obj/structure/decorative_structures/fireplace @@ -234,7 +234,7 @@ desc = "Looks warm and comfy." icon = 'icons/obj/fireplace.dmi' icon_state = "fireplace" - anchored = 1 + anchored = TRUE density = 0 pixel_x = -16 @@ -246,7 +246,7 @@ /obj/structure/decorative_structures/garland density = 0 - anchored = 1 + anchored = TRUE max_integrity = 100 icon_state = "xmaslights" @@ -419,7 +419,7 @@ name = "Bloody crystal" icon_state = "cult_crystal" max_integrity = 120 - anchored = 1 + anchored = TRUE /obj/structure/decorative_structures/cult_crystal/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm index 4cb4a70f3ef..9042d5eda79 100644 --- a/code/game/objects/items/devices/autopsy.dm +++ b/code/game/objects/items/devices/autopsy.dm @@ -8,7 +8,8 @@ origin_tech = "magnets=1;biotech=1" var/list/datum/autopsy_data_scanner/wdata = list() var/list/chemtraces = list() - var/target_name = null + var/target_UID = null + var/target_name = null // target.name can change after scanning, so better save it here. var/timeofdeath = null /obj/item/autopsy_scanner/Destroy() @@ -86,7 +87,7 @@ if(timeofdeath) scan_data += "Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]

    " else - scan_data += "Time of death: Unknown / Still alive

    " + scan_data += "Time of death: No data

    " if(wdata.len) var/n = 1 @@ -136,7 +137,7 @@ for(var/chemID in chemtraces) scan_data += chemID scan_data += "
    " - user.visible_message("[src] rattles and prints out a sheet of paper.") + user.visible_message(span_notice("[src] rattles and prints out a sheet of paper.")) playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) flick("autopsy_scanner_anim", src) @@ -145,7 +146,7 @@ var/obj/item/paper/P = new(drop_location()) P.name = "Autopsy Data ([target_name])" P.info = "[scan_data]" - P.overlays += "paper_words" + P.update_icon() user.put_in_hands(P, ignore_anim = FALSE) @@ -156,20 +157,21 @@ if(!can_operate(M)) return - if(target_name != M.name) + if(target_UID != M.UID()) + to_chat(user, span_notice("A new patient has been registered.[target_UID ? " Purging data for previous patient." : ""]")) + target_UID = M.UID() target_name = M.name wdata.Cut() chemtraces.Cut() timeofdeath = null - to_chat(user, "A new patient has been registered. Purging data for previous patient.") timeofdeath = M.timeofdeath var/obj/item/organ/external/S = M.get_organ(user.zone_selected) if(!S) - to_chat(user, "You can't scan this body part.") + to_chat(user, span_warning("You can't scan this body part!")) return - M.visible_message("[user] scans the wounds on [M]'s [S] with [src]") + M.visible_message(span_notice("[user] scans the wounds on [M]'s [S] with [src].")) add_data(S) - return 1 + return TRUE diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 71c180ccdcb..edb3a437360 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -21,15 +21,27 @@ var/can_overcharge = TRUE //set this to FALSE if you don't want your flash to be overcharge capable var/use_sound = 'sound/weapons/flash.ogg' + +/obj/item/flash/update_icon_state() + icon_state = "[initial(icon_state)][broken ? "burnt" : ""]" + + +/obj/item/flash/update_overlays() + . = ..() + if(overcharged) + . += "overcharge" + + /obj/item/flash/proc/clown_check(mob/user) if(user && (CLUMSY in user.mutations) && prob(50)) flash_carbon(user, user, 30 SECONDS, 0) return FALSE return TRUE + /obj/item/flash/attackby(obj/item/W, mob/user, params) if(can_overcharge) - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) if(battery_panel) to_chat(user, "You close the battery compartment on the [src].") battery_panel = FALSE @@ -41,17 +53,18 @@ to_chat(user, "You jam the cell into battery compartment on the [src].") qdel(W) overcharged = TRUE - overlays += "overcharge" + update_icon(UPDATE_OVERLAYS) + /obj/item/flash/random/New() ..() if(prob(25)) broken = TRUE - icon_state = "[initial(icon_state)]burnt" + update_icon(UPDATE_ICON_STATE) /obj/item/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. broken = TRUE - icon_state = "[initial(icon_state)]burnt" + update_icon(UPDATE_ICON_STATE) visible_message("The [src.name] burns out!") diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index bdab186f156..65a5885b425 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -13,38 +13,39 @@ var/brightness_on = 4 //luminosity when on var/togglesound = 'sound/weapons/empty.ogg' + /obj/item/flashlight/Initialize() . = ..() + update_brightness() + + +/obj/item/flashlight/update_icon_state() if(on) icon_state = "[initial(icon_state)]-on" - set_light(brightness_on) else - icon_state = initial(icon_state) - set_light(0) + icon_state = "[initial(icon_state)]" + -/obj/item/flashlight/proc/update_brightness(var/mob/user = null) +/obj/item/flashlight/proc/update_brightness() if(on) - icon_state = "[initial(icon_state)]-on" set_light(brightness_on) else - icon_state = initial(icon_state) set_light(0) + update_icon() + /obj/item/flashlight/attack_self(mob/user) if(!isturf(user.loc)) - to_chat(user, "You cannot turn the light on while in this [user.loc].")//To prevent some lighting anomalities. - - return 0 + to_chat(user, "You cannot turn the light on while in this [user.loc].") //To prevent some lighting anomalities. + return FALSE on = !on playsound(user, togglesound, 100, 1) - update_brightness(user) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - return 1 + update_brightness() + update_equipped_item() + return TRUE -/obj/item/flashlight/attack(mob/living/M as mob, mob/living/user as mob) +/obj/item/flashlight/attack(mob/living/M, mob/living/user) add_fingerprint(user) if(on && user.zone_selected == BODY_ZONE_PRECISE_EYES) @@ -174,10 +175,29 @@ var/fuel_lower = 800 var/fuel_upp = 1000 -/obj/item/flashlight/flare/New() + +/obj/item/flashlight/flare/Initialize() fuel = rand(fuel_lower, fuel_upp) + . = ..() + + +/obj/item/flashlight/flare/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + + +/obj/item/flashlight/flare/update_icon_state() + if(on) + item_state = "[initial(item_state)]-on" + else + item_state = "[initial(item_state)]" + + if(!fuel) + icon_state = "[initial(icon_state)]-empty" + return ..() + /obj/item/flashlight/flare/process() var/turf/pos = get_turf(src) if(pos && produce_heat) @@ -185,33 +205,17 @@ fuel = max(fuel - 1, 0) if(!fuel || !on) turn_off() - if(!fuel) - src.icon_state = "[initial(icon_state)]-empty" STOP_PROCESSING(SSobj, src) -/obj/item/flashlight/flare/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() /obj/item/flashlight/flare/proc/turn_off() - on = 0 - src.force = initial(src.force) - src.damtype = initial(src.damtype) - if(ismob(loc)) - var/mob/U = loc - update_brightness(U) - else - update_brightness(null) + on = FALSE + force = initial(force) + damtype = initial(damtype) + update_brightness() -/obj/item/flashlight/flare/update_brightness(var/mob/user = null) - ..() - if(on) - item_state = "[initial(item_state)]-on" - else - item_state = "[initial(item_state)]" /obj/item/flashlight/flare/attack_self(mob/user) - // Usual checks if(!fuel) to_chat(user, "[src] is out of fuel.") @@ -224,10 +228,12 @@ // All good, turn it on. if(.) user.visible_message("[user] activates [src].", "You activate [src].") - src.force = on_damage - src.damtype = "fire" + if(produce_heat) + force = on_damage + damtype = BURN START_PROCESSING(SSobj, src) + // GLOWSTICKS /obj/item/flashlight/flare/glowstick @@ -242,27 +248,26 @@ produce_heat = 0 fuel_lower = 1600 fuel_upp = 2000 + blocks_emissive = FALSE + /obj/item/flashlight/flare/glowstick/Initialize() light_color = color ..() -/obj/item/flashlight/flare/glowstick/update_icon() - item_state = "glowstick" - cut_overlays() + +/obj/item/flashlight/flare/glowstick/update_icon_state() if(!fuel) icon_state = "glowstick-empty" - cut_overlays() - update_brightness(0) - else if(on) + + +/obj/item/flashlight/flare/glowstick/update_overlays() + . = ..() + if(on) var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow") glowstick_overlay.color = color - add_overlay(glowstick_overlay) - item_state = "glowstick-on" - update_brightness(brightness_on) - else - icon_state = "glowstick" - cut_overlays() + . += glowstick_overlay + /obj/item/flashlight/flare/glowstick/red name = "red glowstick" @@ -335,12 +340,10 @@ materials = list() on = TRUE //Bio-luminesence has one setting, on. -/obj/item/flashlight/slime/New() - ..() - set_light(brightness_on) - spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me! - update_brightness() - icon_state = initial(icon_state) + +/obj/item/flashlight/slime/update_icon_state() + return + /obj/item/flashlight/slime/attack_self(mob/user) return //Bio-luminescence does not toggle. @@ -360,10 +363,11 @@ var/charge_tick = 0 -/obj/item/flashlight/emp/New() - ..() +/obj/item/flashlight/emp/Initialize() + . = ..() START_PROCESSING(SSobj, src) + /obj/item/flashlight/emp/Destroy() STOP_PROCESSING(SSobj, src) return ..() @@ -376,13 +380,15 @@ emp_cur_charges = min(emp_cur_charges+1, emp_max_charges) return TRUE -/obj/item/flashlight/emp/attack(mob/living/M as mob, mob/living/user as mob) +/obj/item/flashlight/emp/attack(mob/living/M, mob/living/user) if(on && user.zone_selected == BODY_ZONE_PRECISE_EYES) // call original attack proc only if aiming at the eyes ..() return -/obj/item/flashlight/emp/afterattack(atom/A as mob|obj, mob/user, proximity) - if(!proximity) return + +/obj/item/flashlight/emp/afterattack(atom/A, mob/user, proximity) + if(!proximity) + return if(emp_cur_charges > 0) emp_cur_charges -= 1 if(ismob(A)) @@ -392,7 +398,7 @@ A.emp_act(1) else to_chat(user, "\The [src] needs time to recharge!") - return + /obj/item/flashlight/spotlight //invisible lighting source name = "disco light" diff --git a/code/game/objects/items/devices/handheld_defib.dm b/code/game/objects/items/devices/handheld_defib.dm index 0f604428fca..dbf0e4c7b6d 100644 --- a/code/game/objects/items/devices/handheld_defib.dm +++ b/code/game/objects/items/devices/handheld_defib.dm @@ -12,6 +12,15 @@ var/cooldown = FALSE var/charge_time = 100 var/emagged = FALSE + var/shocking = FALSE + + +/obj/item/handheld_defibrillator/update_icon_state() + if(shocking) + icon_state = "[icon_base]-shock" + return + icon_state = "[icon_base][cooldown ? "-off" : "-on"]" + /obj/item/handheld_defibrillator/emag_act(mob/user) if(!emagged) @@ -83,19 +92,22 @@ else to_chat(user, span_danger("[H] has a hardsuit!")) cooldown = TRUE - icon_state = "[icon_base]-shock" - addtimer(CALLBACK(src, PROC_REF(short_charge)), 10) + shocking = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(short_charge)), 1 SECONDS) addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) else to_chat(user, span_notice("[src]'s on board medical scanner indicates that no shock is required.")) /obj/item/handheld_defibrillator/proc/short_charge() - icon_state = "[icon_base]-off" + shocking = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/item/handheld_defibrillator/proc/recharge() cooldown = FALSE - icon_state = "[icon_base]-on" + update_icon(UPDATE_ICON_STATE) playsound(loc, "sound/weapons/flash.ogg", 75, 1) /obj/item/handheld_defibrillator/syndie diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index f06b2e28add..0d4eb278382 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -16,6 +16,7 @@ var/recharging = 0 var/recharge_locked = 0 var/obj/item/stock_parts/micro_laser/diode //used for upgrading! + var/is_pointing = FALSE /obj/item/laser_pointer/red @@ -42,6 +43,9 @@ diode = new /obj/item/stock_parts/micro_laser/ultra +/obj/item/laser_pointer/update_icon_state() + icon_state = "pointer[is_pointing ? "_[pointer_icon_state]" : ""]" + /obj/item/laser_pointer/attack(mob/living/M, mob/user) laser_act(M, user) @@ -55,7 +59,7 @@ else to_chat(user, "[src] already has a cell.") - else if(istype(W, /obj/item/screwdriver)) + else if(W.tool_behaviour == TOOL_SCREWDRIVER) if(diode) to_chat(user, "You remove the [diode.name] from the [src].") diode.loc = get_turf(src.loc) @@ -64,12 +68,12 @@ ..() return -/obj/item/laser_pointer/afterattack(var/atom/target, var/mob/living/user, flag, params) +/obj/item/laser_pointer/afterattack(atom/target, mob/living/user, flag, params) if(flag) //we're placing the object on a table or in backpack return laser_act(target, user, params) -/obj/item/laser_pointer/proc/laser_act(var/atom/target, var/mob/living/user, var/params) +/obj/item/laser_pointer/proc/laser_act(atom/target, mob/living/user, params) if( !(user in (viewers(7,target))) ) return if(!diode) @@ -135,11 +139,9 @@ outmsg = "You missed the lens of [C] with [src]." //laser pointer image - icon_state = "pointer_[pointer_icon_state]" - var/list/showto = list() - for(var/mob/M in viewers(7,targloc)) - if(M.client) - showto.Add(M.client) + is_pointing = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(stop_pointing)), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_NO_HASH_WAIT) var/image/I = image('icons/obj/weapons/projectiles.dmi',targloc,pointer_icon_state,10) var/list/click_params = params2list(params) if(click_params) @@ -165,8 +167,13 @@ to_chat(user, "You've overused the battery of [src], now it needs time to recharge!") recharge_locked = 1 - flick_overlay(I, showto, 10) - icon_state = "pointer" + flick_overlay_view(I, 1 SECONDS) + + +/obj/item/laser_pointer/proc/stop_pointing() + is_pointing = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/item/laser_pointer/process() if(prob(20 - recharge_locked*5)) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index dc75d59db96..a2c3066ccc7 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -115,7 +115,7 @@ qdel(L) return - if(istype(I, /obj/item/storage)) + if(isstorage(I)) var/obj/item/storage/S = I var/found_lightbulbs = FALSE var/replaced_something = TRUE @@ -154,16 +154,29 @@ /obj/item/lightreplacer/emag_act(mob/user) if(!emagged) + emagged = TRUE add_attack_logs(user, src, "emagged") - Emag() + playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) + + +/obj/item/lightreplacer/update_name(updates = ALL) + . = ..() + if(emagged) + name = "shortcircuited [initial(name)]" + else + name = initial(name) + + +/obj/item/lightreplacer/update_icon_state() + icon_state = "lightreplacer[emagged]" + /obj/item/lightreplacer/attack_self(mob/user) for(var/obj/machinery/light/target in user.loc) ReplaceLight(target, user) to_chat(user, status_string()) -/obj/item/lightreplacer/update_icon() - icon_state = "lightreplacer[emagged]" /obj/item/lightreplacer/proc/status_string() return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)." @@ -229,14 +242,6 @@ to_chat(U, "There is a working [target.fitting] already inserted!") return -/obj/item/lightreplacer/proc/Emag() - emagged = !emagged - playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(emagged) - name = "shortcircuited [initial(name)]" - else - name = initial(name) - update_icon() /obj/item/lightreplacer/proc/CanUse(mob/living/user) add_fingerprint(user) diff --git a/code/game/objects/items/devices/memorizer.dm b/code/game/objects/items/devices/memorizer.dm index a58b541cb8f..b894e9c7967 100644 --- a/code/game/objects/items/devices/memorizer.dm +++ b/code/game/objects/items/devices/memorizer.dm @@ -18,6 +18,17 @@ var/can_overcharge = FALSE //set this to FALSE if you don't want your flash to be overcharge capable var/use_sound = 'sound/weapons/flash.ogg' + +/obj/item/memorizer/update_icon_state() + icon_state = "memorizer[broken ? "burnt" : ""]" + + +/obj/item/memorizer/update_overlays() + . = ..() + if(overcharged) + . += "overcharge" + + /obj/item/memorizer/proc/clown_check(mob/user) if(user && (CLUMSY in user.mutations) && prob(50)) memorize_carbon(user, user, 15, FALSE) @@ -27,7 +38,7 @@ /obj/item/memorizer/attackby(obj/item/W, mob/user, params) if(!can_overcharge) return - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) battery_panel = !battery_panel if(battery_panel) to_chat(user, "You open the battery compartment on the [src].") @@ -39,12 +50,13 @@ to_chat(user, "You jam the cell into battery compartment on the [src].") qdel(W) overcharged = TRUE - overlays += "overcharge" + update_icon(UPDATE_OVERLAYS) + /obj/item/memorizer/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. broken = TRUE - icon_state = "[initial(icon_state)]burnt" - visible_message("The [src.name] burns out!") + update_icon(UPDATE_ICON_STATE) + visible_message("The [name] burns out!") /obj/item/memorizer/proc/flash_recharge(var/mob/user) @@ -163,7 +175,7 @@ custom_objective.owner = fucking_target.mind fucking_target.mind.objectives += custom_objective fucking_target.mind.lost_memory = TRUE - var/list/messages = list(fucking_target.mind.prepare_announce_objectives()) + var/list/messages = list(fucking_target.mind.prepare_announce_objectives()) to_chat(fucking_target, chat_box_red(chat_box_red(messages.Join("
    ")))) last_used = world.time if(fucking_target.weakeyes) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index ca05f5d7173..69cc00a81b3 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -523,7 +523,7 @@ /obj/item/paper/pai_upgrade name = "Инструкция по применению" - icon_state = "paper" + icon_state = "paper_words" info = {"
    Инструкция по применению СпИИ

    В набор СпИИ входит:
    @@ -548,7 +548,7 @@ 5.Термальное зрение для пИИ
    "} -/obj/item/paper/pai_upgrade/update_icon() +/obj/item/paper/pai_upgrade/update_icon_state() return /obj/item/storage/box/syndie_kit/pai diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm index b49b1012c89..481b8a83772 100644 --- a/code/game/objects/items/devices/pizza_bomb.dm +++ b/code/game/objects/items/devices/pizza_bomb.dm @@ -5,22 +5,53 @@ icon_state = "pizzabox1" throw_range = 1 var/timer = 10 //Adjustable timer - var/timer_set = 0 - var/primed = 0 - var/disarmed = 0 + var/timer_set = FALSE + var/primed = FALSE + var/disarmed = FALSE var/wires = list("orange", "green", "blue", "yellow", "aqua", "purple") var/correct_wire var/armer //Used for admin purposes + +/obj/item/pizza_bomb/update_icon_state() + if(disarmed) + icon_state = "pizzabox_bomb_[correct_wire]" + return + if(primed || !timer_set) + icon_state = "pizzabox_bomb" + return + icon_state = "pizzabox1" + + +/obj/item/pizza_bomb/update_name(updates) + . = ..() + if(timer_set && !disarmed) + name = "pizza box" + else + name = "pizza bomb" + + +/obj/item/pizza_bomb/update_desc(updates) + . = ..() + if(disarmed) + desc = "A devious contraption, made of a small explosive payload hooked up to pressure-sensitive wires. It's disarmed." + return + if(primed) + desc = "OH GOD THAT'S NOT A PIZZA" + return + if(timer_set) + desc = "A box suited for pizzas." + else + desc = "It seems inactive." + + /obj/item/pizza_bomb/attack_self(mob/user) if(disarmed) to_chat(user, "\The [src] is disarmed.") return + if(!timer_set) - name = "pizza bomb" - desc = "It seems inactive." - icon_state = "pizzabox_bomb" - timer_set = 1 + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) timer = (input(user, "Set a timer, from one second to ten seconds.", "Timer", "[timer]") as num) * 10 if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained()) timer_set = 0 @@ -29,25 +60,23 @@ icon_state = "pizzabox1" return timer = clamp(timer, 10, 100) - icon_state = "pizzabox1" + timer_set = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) to_chat(user, "You set the timer to [timer / 10] before activating the payload and closing \the [src].") message_admins("[key_name_admin(usr)] has set a timer on a pizza bomb to [timer/10] seconds at [ADMIN_COORDJMP(loc)].") add_game_logs("has set the timer on a pizza bomb to [timer/10] seconds [COORD(loc)].", usr) armer = usr - name = "pizza box" - desc = "A box suited for pizzas." return + if(!primed) - name = "pizza bomb" - desc = "OH GOD THAT'S NOT A PIZZA" - icon_state = "pizzabox_bomb" audible_message("[bicon(src)] *beep* *beep*") to_chat(user, "That's no pizza! That's a bomb!") message_admins("[key_name_admin(usr)] has triggered a pizza bomb armed by [armer] at [ADMIN_COORDJMP(loc)].") add_game_logs("has triggered a pizza bomb armed by [armer] [COORD(loc)].", usr) - primed = 1 - sleep(timer) - return go_boom() + primed = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + addtimer(CALLBACK(src, PROC_REF(go_boom)), timer) + /obj/item/pizza_bomb/proc/go_boom() if(disarmed) @@ -58,8 +87,9 @@ explosion(src.loc,1,2,4,flame_range = 2) //Identical to a minibomb qdel(src) -/obj/item/pizza_bomb/attackby(var/obj/item/I, var/mob/user, params) - if(istype(I, /obj/item/wirecutters) && primed) + +/obj/item/pizza_bomb/attackby(obj/item/I, mob/user, params) + if(I.tool_behaviour == TOOL_WIRECUTTER && primed) to_chat(user, "Oh God, what wire do you cut?!") var/chosen_wire = input(user, "OH GOD OH GOD", "WHAT WIRE?!") in wires if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained()) @@ -68,19 +98,17 @@ user.visible_message("[user] cuts the [chosen_wire] wire!", "You cut the [chosen_wire] wire!") sleep(5) if(chosen_wire == correct_wire) - src.audible_message("[bicon(src)] \The [src] suddenly stops beeping and seems lifeless.") + audible_message("[bicon(src)] \The [src] suddenly stops beeping and seems lifeless.") to_chat(user, "You did it!") - icon_state = "pizzabox_bomb_[correct_wire]" - name = "pizza bomb" - desc = "A devious contraption, made of a small explosive payload hooked up to pressure-sensitive wires. It's disarmed." - disarmed = 1 - primed = 0 + disarmed = TRUE + primed = FALSE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return else to_chat(user, "WRONG WIRE!") go_boom() return - if(istype(I, /obj/item/wirecutters) && disarmed) + if(I.tool_behaviour == TOOL_WIRECUTTER && disarmed) if(!in_range(user, src)) to_chat(user, "You can't see the box well enough to cut the wires out.") return diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 60260b00bbb..6d471e726bd 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -30,7 +30,7 @@ attached = null return ..() -/obj/item/powersink/update_icon() +/obj/item/powersink/update_icon_state() icon_state = "powersink[mode == OPERATING]" /obj/item/powersink/proc/set_mode(value) @@ -60,7 +60,7 @@ density = TRUE mode = value - update_icon() + update_icon(UPDATE_ICON_STATE) set_light(0) /obj/item/powersink/screwdriver_act(mob/user, obj/item/I) @@ -135,8 +135,8 @@ if(A.operating && A.cell) A.cell.charge = max(0, A.cell.charge - 50) power_drained += 50 - if(A.charging == 2) // If the cell was full - A.charging = 1 // It's no longer full + if(A.charging == APC_FULLY_CHARGED) // If the cell was full + A.charging = APC_IS_CHARGING // It's no longer full if(drained >= drain_rate) break diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index d1ec25ddb21..9aabaf85c89 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -103,7 +103,7 @@ /obj/item/radio/beacon/engine desc = "A label on it reads: Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!." - anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations + anchored = TRUE //Let's not move these around. Some folk might get the idea to use these for assassinations var/list/enginetype = list() /obj/item/radio/beacon/engine/Initialize(mapload) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 0b593561771..a140942f86f 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -9,16 +9,17 @@ w_class = WEIGHT_CLASS_HUGE materials = list(MAT_METAL=10000, MAT_GLASS=2500) var/code = 2 + var/intensivity = TRUE -/obj/item/radio/electropack/attack_hand(mob/user as mob) +/obj/item/radio/electropack/attack_hand(mob/user) if(src == user.back) - to_chat(user, "You need help taking this off!") - return 0 + to_chat(user, span_notice("You need help taking this off!")) + return FALSE . = ..() /obj/item/radio/electropack/Destroy() - if(istype(src.loc, /obj/item/assembly/shock_kit)) - var/obj/item/assembly/shock_kit/S = src.loc + if(istype(loc, /obj/item/assembly/shock_kit)) + var/obj/item/assembly/shock_kit/S = loc if(S.part1 == src) S.part1 = null else if(S.part2 == src) @@ -26,17 +27,17 @@ master = null return ..() -/obj/item/radio/electropack/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/radio/electropack/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/clothing/head/helmet)) if(!b_stat) - to_chat(user, "[src] is not ready to be attached!") + to_chat(user, span_notice("[src] is not ready to be attached!")) return var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(drop_location()) A.icon = 'icons/obj/assemblies.dmi' if(!user.drop_transfer_item_to_loc(W, A)) - to_chat(user, "\the [W] is stuck to your hand, you cannot attach it to \the [src]!") + to_chat(user, span_notice("\the [W] is stuck to your hand, you cannot attach it to \the [src]!")) return W.master = A A.part1 = W @@ -47,26 +48,21 @@ user.put_in_hands(A, ignore_anim = FALSE) A.add_fingerprint(user) - if(src.flags & NODROP) + if(flags & NODROP) A.flags |= NODROP - /obj/item/radio/electropack/receive_signal(datum/signal/signal) if(!signal || signal.encryption != code) return if(isliving(loc) && on) var/mob/living/M = loc - var/turf/T = M.loc - if(istype(T, /turf)) - if(!M.moved_recently && M.last_move) - M.moved_recently = 1 - step(M, M.last_move) - sleep(50) - if(M) - M.moved_recently = 0 - to_chat(M, "You feel a sharp shock!") - do_sparks(3, 1, M) + if(isturf(M.loc) && M.last_move && intensivity) + step(M, M.last_move) + intensivity = FALSE + addtimer(CALLBACK(src, PROC_REF(intensify)), 5 SECONDS) + to_chat(M, span_userdanger("You feel a sharp shock!")) + do_sparks(3, TRUE, M) M.Weaken(10 SECONDS) @@ -74,6 +70,8 @@ master.receive_signal() return +/obj/item/radio/electropack/proc/intensify() + intensivity = TRUE /obj/item/radio/electropack/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 58c73fcbb45..bf5cf828ba5 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -60,11 +60,11 @@ /obj/item/radio/headset/handle_message_mode(mob/living/M, list/message_pieces, channel) if(channel == "special") if(translate_binary) - var/datum/language/binary = GLOB.all_languages["Robot Talk"] + var/datum/language/binary = GLOB.all_languages[LANGUAGE_BINARY] binary.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces))) return RADIO_CONNECTION_NON_SUBSPACE if(translate_hive) - var/datum/language/hivemind = GLOB.all_languages["Hivemind"] + var/datum/language/hivemind = GLOB.all_languages[LANGUAGE_HIVE_XENOS] hivemind.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces))) return RADIO_CONNECTION_NON_SUBSPACE return RADIO_CONNECTION_FAIL diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 5ffd2ae7b7d..5f5ea340c48 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -2,14 +2,16 @@ name = "station intercom (General)" desc = "Talk through this." icon_state = "intercom" - anchored = 1 + anchored = TRUE w_class = WEIGHT_CLASS_BULKY canhear_range = 2 flags = CONDUCT - var/circuitry_installed = 1 + blocks_emissive = FALSE + var/circuitry_installed = TRUE var/buildstage = 0 dog_fashion = null + /obj/item/radio/intercom/custom name = "station intercom (Custom)" broadcasting = 0 @@ -53,8 +55,8 @@ if(direction) setDir(direction) set_pixel_offsets_from_dir(28, -28, 28, -28) - b_stat=1 - on = 0 + b_stat = TRUE + on = FALSE GLOB.global_intercoms.Add(src) update_icon() @@ -66,7 +68,7 @@ ..() internal_channels = list( num2text(PUB_FREQ) = list(), - num2text(SEC_I_FREQ) = list(ACCESS_SECURITY) + num2text(SEC_I_FREQ) = list(ACCESS_SECURITY), ) /obj/item/radio/intercom/syndicate @@ -173,12 +175,12 @@ return if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 2) return - update_icon() - on = 1 - b_stat = 0 + update_icon(UPDATE_ICON_STATE) + on = TRUE + b_stat = FALSE buildstage = 3 to_chat(user, "You secure the electronics!") - update_icon() + update_icon(UPDATE_ICON_STATE) update_operating_status() for(var/i, i<= 5, i++) wires.on_cut(i, 1) @@ -191,8 +193,8 @@ return WIRECUTTER_SNIP_MESSAGE new /obj/item/stack/cable_coil(get_turf(src),5) - on = 0 - b_stat = 1 + on = FALSE + b_stat = TRUE buildstage = 1 update_icon() update_operating_status(FALSE) @@ -209,12 +211,18 @@ new /obj/item/mounted/frame/intercom(get_turf(src)) qdel(src) -/obj/item/radio/intercom/update_icon() +/obj/item/radio/intercom/update_icon_state() if(!circuitry_installed) icon_state="intercom-frame" return icon_state = "intercom[!on?"-p":""][b_stat ? "-open":""]" +/obj/item/radio/intercom/update_overlays() + . = ..() + underlays.Cut() + if(on && buildstage == 3) + underlays += emissive_appearance(icon, "intercom_lightmask") + /obj/item/radio/intercom/proc/update_operating_status(on = TRUE) var/area/current_area = get_area(src) if(!current_area) @@ -236,8 +244,10 @@ var/area/current_area = get_area(src) if(!current_area) on = FALSE + set_light(0) else on = current_area.powered(EQUIP) // set "on" to the equipment power status of our area. + set_light(1, LIGHTING_MINIMUM_POWER) update_icon() /obj/item/intercom_electronics diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 49de0c3c080..928bb79a3a1 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -11,21 +11,22 @@ REAGENT SCANNER desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." icon = 'icons/obj/device.dmi' icon_state = "t-ray0" - var/on = 0 + base_icon_state = "t-ray" + var/on = FALSE slot_flags = SLOT_BELT - w_class = 2 w_class = WEIGHT_CLASS_SMALL item_state = "electronic" materials = list(MAT_METAL=150) origin_tech = "magnets=1;engineering=1" var/scan_range = 1 - var/pulse_duration = 10 + var/pulse_duration = 1 SECONDS /obj/item/t_scanner/extended_range name = "T-ray сканер расширенной дальности" desc = "Излучатель и сканер терагерцевого излучения, используемый для обнаружения скрытых объектов и объектов под полом, таких как кабели и трубы. \ \nДанная модель обладает расширенным радиусом действия." icon_state = "t-ray-range0" + base_icon_state = "t-ray-range" scan_range = 3 origin_tech = "magnets=3;engineering=3" materials = list(MAT_METAL=300) @@ -35,7 +36,8 @@ REAGENT SCANNER desc = "Излучатель и сканер терагерцевого излучения, используемый для обнаружения скрытых объектов и объектов под полом, таких как кабели и трубы. \ \nДанная модель способна генерировать более продолжительные импульсы." icon_state = "t-ray-pulse0" - pulse_duration = 50 + base_icon_state = "t-ray-pulse" + pulse_duration = 5 SECONDS origin_tech = "magnets=5;engineering=3" materials = list(MAT_METAL=300) @@ -44,8 +46,9 @@ REAGENT SCANNER desc = "Излучатель и сканер терагерцевого излучения, используемый для обнаружения скрытых объектов и объектов под полом, таких как кабели и трубы. \ \nДанная модель способна генерировать более продолжительные импульсы и обладает расширенным радиусом действия." icon_state = "t-ray-advanced0" + base_icon_state = "t-ray-advanced" scan_range = 3 - pulse_duration = 50 + pulse_duration = 5 SECONDS origin_tech = "magnets=7;engineering=3" materials = list(MAT_METAL=300) @@ -54,8 +57,9 @@ REAGENT SCANNER desc = "Излучатель и сканер терагерцевого излучения, используемый для обнаружения скрытых объектов и объектов под полом, таких как кабели и трубы. \ \nВысокотехнологичная модель, способная генерировать очень продолжительные импульсы в пределах большого радиуса." icon_state = "t-ray-science0" + base_icon_state = "t-ray-science" scan_range = 5 - pulse_duration = 100 + pulse_duration = 10 SECONDS origin_tech = "magnets=8;engineering=5" materials = list(MAT_METAL=500) @@ -65,8 +69,9 @@ REAGENT SCANNER \nЭкспериментальный образец, обладающий расширенным радиусом действия и более продолжительным импульсом. \ \nСудя по его виду, эта вещь была собрана безумными учеными в ходе спонтанных экспериментов." icon_state = "t-ray-experimental0" + base_icon_state = "t-ray-experimental" scan_range = 3 - pulse_duration = 80 + pulse_duration = 8 SECONDS origin_tech = null materials = list() resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF @@ -76,14 +81,19 @@ REAGENT SCANNER STOP_PROCESSING(SSobj, src) return ..() -/obj/item/t_scanner/attack_self(mob/user) +/obj/item/t_scanner/update_icon_state() + icon_state = "[base_icon_state][on]" +/obj/item/t_scanner/proc/toggle_mode() on = !on - icon_state = copytext(icon_state, 1, length(icon_state))+"[on]" - + update_icon(UPDATE_ICON_STATE) if(on) START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) +/obj/item/t_scanner/attack_self(mob/user) + toggle_mode() /obj/item/t_scanner/process() if(!on) @@ -92,48 +102,41 @@ REAGENT SCANNER scan() /obj/item/t_scanner/proc/scan() + t_ray_scan(loc, pulse_duration, scan_range) - for(var/turf/scan_turf in range(scan_range, src.loc) ) - - if(!scan_turf.intact) +/proc/t_ray_scan(mob/viewer, flick_time, distance) + if(!ismob(viewer) || !viewer.client) + return + var/list/t_ray_images = list() + for(var/atom/movable/in_turf_atom in orange(distance, viewer)) + if(!isobj(in_turf_atom) && !isliving(in_turf_atom)) continue - for(var/obj/in_turf_object in scan_turf.contents) - + if(isobj(in_turf_atom)) + var/obj/in_turf_object = in_turf_atom if(in_turf_object.level != 1) continue - var/temp_invisibility = in_turf_object.invisibility - var/temp_alpha = in_turf_object.alpha - if(temp_invisibility == INVISIBILITY_ABSTRACT || temp_invisibility == INVISIBILITY_ANOMALY) - in_turf_object.invisibility = 0 - in_turf_object.alpha = 128 - in_turf_object.drain_act_protected = TRUE - if(in_turf_object.layer < TURF_LAYER) - in_turf_object.layer += TRAY_SCAN_LAYER_OFFSET - spawn(pulse_duration) - in_turf_object.plane = GAME_PLANE - if(in_turf_object) - var/turf/objects_turf = in_turf_object.loc - if(objects_turf && objects_turf.intact) - in_turf_object.invisibility = temp_invisibility - in_turf_object.alpha = temp_alpha - in_turf_object.drain_act_protected = FALSE - for(var/mob/living/in_turf_mob in scan_turf.contents) - var/oldalpha = in_turf_mob.alpha - if(in_turf_mob.alpha < 255 && istype(in_turf_mob)) - in_turf_mob.alpha = 255 - spawn(10) - if(in_turf_mob) - in_turf_mob.alpha = oldalpha - - var/mob/living/in_turf_mob = locate() in scan_turf - - if(in_turf_mob && in_turf_mob.invisibility == INVISIBILITY_LEVEL_TWO) - in_turf_mob.invisibility = 0 - spawn(2) - if(in_turf_mob) - in_turf_mob.invisibility = INVISIBILITY_LEVEL_TWO + if(in_turf_object.invisibility != INVISIBILITY_MAXIMUM && in_turf_object.invisibility != INVISIBILITY_ANOMALY) + continue + + if(isliving(in_turf_atom)) + var/mob/living/in_turf_living = in_turf_atom + if(!(in_turf_living.alpha < 255 || in_turf_living.invisibility == INVISIBILITY_LEVEL_TWO)) + continue + + var/image/I = new(loc = get_turf(in_turf_atom)) + var/mutable_appearance/MA = new(in_turf_atom) + MA.alpha = isliving(in_turf_atom) ? 255 : 128 + MA.dir = in_turf_atom.dir + if(MA.layer < TURF_LAYER) + MA.layer += TRAY_SCAN_LAYER_OFFSET + MA.plane = GAME_PLANE + I.appearance = MA + t_ray_images += I + + if(length(t_ray_images)) + flick_overlay(t_ray_images, list(viewer.client), flick_time) /obj/item/t_scanner/security name = "Противо-маскировочное ТГц устройство" @@ -143,13 +146,14 @@ REAGENT SCANNER righthand_file = 'icons/mob/inhands/items_righthand.dmi' item_state = "sb_t-ray" icon_state = "sb_t-ray0" + base_icon_state = "sb_t-ray" scan_range = 2 - pulse_duration = 30 var/was_alerted = FALSE // Protection against spam alerts from this scanner var/burnt = FALSE // Did emp break us? var/datum/effect_system/spark_spread/spark_system //The spark system, used for generating... sparks? origin_tech = "combat=3;magnets=5;biotech=5" + /obj/item/t_scanner/security/Initialize() . = ..() //Sets up a spark system @@ -157,43 +161,67 @@ REAGENT SCANNER spark_system.set_up(5, 0, src) spark_system.attach(src) + +/obj/item/t_scanner/security/update_icon_state() + if(burnt) + icon_state = "[base_icon_state]_burnt" + return + icon_state = "[base_icon_state][on]" + + +/obj/item/t_scanner/security/update_desc(updates = ALL) + . = ..() + if(!burnt) + desc = initial(desc) + return + desc = "Излучатель терагерцевого типа используемый для сканирования области на наличие замаскированных биоорганизмов. Устройство сгорело, теперь можно обнаружить разве что крошки от пончика оставшиеся на нём..." + + /obj/item/t_scanner/security/attack_self(mob/user) if(!burnt) on = !on - icon_state = copytext(icon_state, 1, length(icon_state))+"[on]" + update_icon(UPDATE_ICON_STATE) if(on) - START_PROCESSING(SSobj, src) + START_PROCESSING(SSprocessing, src) + else + STOP_PROCESSING(SSprocessing, src) + /obj/item/t_scanner/security/emp_act(severity) . = ..() if(prob(25) && !burnt) burnt = TRUE - on = FALSE; - icon_state = copytext(icon_state, 1, length(icon_state))+"_burnt" - desc = "Излучатель терагерцевого типа используемый для сканирования области на наличие замаскированных биоорганизмов. Устройство сгорело, теперь можно обнаружить разве что крошки от пончика оставшиеся на нём..." + on = FALSE + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) playsound(loc, "sparks", 50, TRUE, 5) spark_system.start() -/obj/item/t_scanner/security/scan() +/obj/item/t_scanner/security/scan() + var/mob/viewer = loc + if(!ismob(viewer) || !viewer.client) + return new /obj/effect/temp_visual/scan(get_turf(src)) - var/list/mobs_in_range = viewers(scan_range, get_turf(src)) - for(var/mob/living/in_turf_mob in mobs_in_range) - var/oldalpha = in_turf_mob.alpha - if(in_turf_mob.alpha < 255 && istype(in_turf_mob)) - in_turf_mob.alpha = 255 - alert_searchers(in_turf_mob) - spawn(pulse_duration) - if(in_turf_mob) - in_turf_mob.alpha = oldalpha - if(in_turf_mob && in_turf_mob.invisibility == INVISIBILITY_LEVEL_TWO) - in_turf_mob.invisibility = 0 - alert_searchers(in_turf_mob) - spawn(pulse_duration) - if(in_turf_mob) - in_turf_mob.invisibility = INVISIBILITY_LEVEL_TWO + var/list/t_ray_images = list() + for(var/mob/living/in_turf_living in viewers(scan_range, get_turf(src))) + if(!(in_turf_living.alpha < 255 || in_turf_living.invisibility == INVISIBILITY_LEVEL_TWO)) + continue + + var/image/I = new(loc = get_turf(in_turf_living)) + var/mutable_appearance/MA = new(in_turf_living) + MA.alpha = 255 + MA.dir = in_turf_living.dir + if(MA.layer < TURF_LAYER) + MA.layer += TRAY_SCAN_LAYER_OFFSET + MA.plane = GAME_PLANE + I.appearance = MA + t_ray_images += I + alert_searchers(in_turf_living) + + if(length(t_ray_images)) + flick_overlay(t_ray_images, list(viewer.client), pulse_duration) /obj/item/t_scanner/security/proc/alert_searchers(mob/living/found_mob) var/list/alerted = viewers(7, found_mob) @@ -601,6 +629,13 @@ REAGENT SCANNER if(0) to_chat(usr, "Сканер больше не показывает повреждения конечностей.") + +/obj/item/healthanalyzer/update_overlays() + . = ..() + if(advanced) + . += "advanced" + + /obj/item/healthanalyzer/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/healthupgrade)) if(advanced) @@ -608,9 +643,9 @@ REAGENT SCANNER else if(user.drop_transfer_item_to_loc(I, src)) to_chat(user, "Вы установили модуль обновления на [src].") - add_overlay("advanced") playsound(loc, I.usesound, 50, 1) advanced = TRUE + update_icon(UPDATE_OVERLAYS) qdel(I) return return ..() @@ -620,7 +655,7 @@ REAGENT SCANNER /obj/item/healthanalyzer/advanced/Initialize(mapload) . = ..() - add_overlay("advanced") + update_icon(UPDATE_OVERLAYS) /obj/item/healthupgrade @@ -787,6 +822,7 @@ REAGENT SCANNER var/obj/item/stock_parts/cell/cell var/cell_type = /obj/item/stock_parts/cell/upgraded var/ready = TRUE // Ready to scan + var/printing = FALSE var/time_to_use = 0 // How much time remaining before next scan is available. var/usecharge = 750 var/scan_time = 10 SECONDS //how long does it take to scan @@ -817,17 +853,24 @@ REAGENT SCANNER playsound(src, 'sound/machines/defib_saftyon.ogg', 50, 0) update_icon() -/obj/item/bodyanalyzer/update_icon(printing = FALSE) - overlays.Cut() - var/percent = cell.percent() + +/obj/item/bodyanalyzer/update_icon_state() + if(!cell) + icon_state = "bodyanalyzer_0" + return if(ready) icon_state = "bodyanalyzer_1" else icon_state = "bodyanalyzer_2" + +/obj/item/bodyanalyzer/update_overlays() + . = ..() + var/percent = cell.percent() var/overlayid = round(percent / 10) - overlayid = "bodyanalyzer_charge[overlayid]" - overlays += icon(icon, overlayid) + . += "bodyanalyzer_charge[overlayid]" + if(printing) + . += "bodyanalyzer_printing" /obj/item/bodyanalyzer/attack(mob/living/M, mob/living/carbon/human/user) @@ -845,6 +888,7 @@ REAGENT SCANNER to_chat(user, "The scanner beeps angrily at you! It's out of charge!") playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1) + /obj/item/bodyanalyzer/borg/attack(mob/living/M, mob/living/silicon/robot/user) if(user.incapacitated() || !user.Adjacent(M)) return @@ -858,6 +902,7 @@ REAGENT SCANNER else to_chat(user, "You need to recharge before you can use [src]") + /obj/item/bodyanalyzer/proc/mobScan(mob/living/M, mob/user) if(ishuman(M)) var/report = generate_printing_text(M, user) @@ -867,8 +912,6 @@ REAGENT SCANNER printout.info = report printout.name = "Scan report - [M.name]" playsound(user.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - flick("bodyanalyzer_anim", src) - sleep(3 SECONDS) user.put_in_hands(printout, ignore_anim = FALSE) time_to_use = world.time + scan_cd if(isrobot(user)) @@ -877,14 +920,16 @@ REAGENT SCANNER else cell.use(usecharge) ready = FALSE - update_icon(TRUE) + printing = TRUE + update_icon() addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/bodyanalyzer, setReady)), scan_cd) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 20) - + addtimer(VARSET_CALLBACK(src, printing, FALSE), 1.4 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_OVERLAYS), 1.5 SECONDS) else if(iscorgi(M) && M.stat == DEAD) to_chat(user, "You wonder if [M.p_they()] was a good dog. [src] tells you they were the best...") // :'( playsound(loc, 'sound/machines/ping.ogg', 50, 0) ready = FALSE + update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/bodyanalyzer, setReady)), scan_cd) time_to_use = world.time + scan_cd else diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index d0a65408d5b..4a81ccd38d1 100644 --- a/code/game/objects/items/devices/sensor_device.dm +++ b/code/game/objects/items/devices/sensor_device.dm @@ -17,23 +17,20 @@ QDEL_NULL(crew_monitor) return ..() -/obj/item/sensor_device/attack_self(mob/user as mob) +/obj/item/sensor_device/attack_self(mob/user) ui_interact(user) -/obj/item/sensor_device/MouseDrop(atom/over) +/obj/item/sensor_device/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(istype(over, /obj/screen)) - return FALSE - if(user.incapacitated() || !ishuman(user)) return FALSE - if(over == user) + if(over_object == user) attack_self(user) return TRUE diff --git a/code/game/objects/items/devices/signmaker.dm b/code/game/objects/items/devices/signmaker.dm index 64da2cfc406..6d163a7105e 100644 --- a/code/game/objects/items/devices/signmaker.dm +++ b/code/game/objects/items/devices/signmaker.dm @@ -29,22 +29,25 @@ return qdel(sign) sign = null - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/item/signmaker/proc/icon_flick() set waitfor = FALSE - icon_state = "signmaker_clown_on" pointer_busy = TRUE - sleep(10) + update_icon(UPDATE_ICON_STATE) + sleep(1 SECONDS) pointer_busy = FALSE - icon_state = "signmaker_clown_off" + update_icon(UPDATE_ICON_STATE) + -/obj/item/signmaker/update_icon() - if(sign) - icon_state = "signmaker_clown_on" - else +/obj/item/signmaker/update_icon_state() + if(pointer_busy) icon_state = "signmaker_clown_off" + return + icon_state = "signmaker_clown_[sign ? "on" : "off"]]" + /obj/item/signmaker/emag_act(mob/user) add_attack_logs(user, src, "emagged") diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 98c77e2f95a..218f4d6e7b3 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -36,7 +36,7 @@ ..() if(starts_with_tape) mytape = new /obj/item/tape/random(src) - update_icon() + update_icon(UPDATE_ICON_STATE) soundloop = new(list(src)) @@ -60,7 +60,7 @@ . += span_notice("[mytape] has [mytape.remaining_capacity] seconds remaining.") // to avoid having 0 minutes else . += span_notice("[mytape] has [seconds_to_time(mytape.remaining_capacity)] remaining.") - . += span_notice("Alt-Click to access the tape.") + . += span_info("Alt-Click to access the tape.") /obj/item/taperecorder/proc/update_sound() @@ -70,7 +70,7 @@ soundloop.start() -/obj/item/taperecorder/update_icon() +/obj/item/taperecorder/update_icon_state() if(!mytape) icon_state = "taperecorder_empty" else if(recording) @@ -82,7 +82,7 @@ /obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - mytape.ruin() //Fires destroy the tape + mytape?.ruin() //Fires destroy the tape return ..() @@ -91,7 +91,7 @@ mytape = I to_chat(user, span_notice("You insert [I] into [src].")) playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/taperecorder/attack_hand(mob/user) @@ -150,7 +150,7 @@ mytape.forceMove_turf() user.put_in_hands(mytape, ignore_anim = FALSE) mytape = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/taperecorder/proc/record() @@ -167,7 +167,7 @@ recording = TRUE recorder_say("Запись началась.") update_sound() - update_icon() + update_icon(UPDATE_ICON_STATE) mytape.timestamp += mytape.used_capacity var/datum/tape_piece/piece = new() piece.time = mytape.used_capacity @@ -209,7 +209,7 @@ if(!playback_override) recorder_say("Проигрывание остановлено.") playing = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) update_sound() @@ -229,7 +229,7 @@ return playing = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) update_sound() recorder_say("Проигрывание началось.") playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) @@ -317,18 +317,18 @@ var/obj/item/paper/transcript = new /obj/item/paper(drop_location()) - var/t1 = "Transcript:

    " + var/list/paper_info = list("Transcript:

    ") for(var/i = 1, length(mytape.storedinfo) >= i, i++) var/datum/tape_piece/piece = mytape.storedinfo[i] - t1 += "\[[time2text(piece.time * 10,"mm:ss")]\] " + paper_info += "\[[time2text(piece.time * 10,"mm:ss")]\] " if(piece.speaker_name) - t1 += "[piece.speaker_name] " + paper_info += "[piece.speaker_name] " if(piece.message_verb) - t1 += "[piece.message_verb], \"[piece.message]\"
    " + paper_info += "[piece.message_verb], \"[replace_characters(piece.message, list("+"))]\"
    " else - t1 += "[piece.message]
    " + paper_info += "[replace_characters(piece.message, list("+"))]
    " - transcript.info = t1 + transcript.info = paper_info.Join("") transcript.name = "paper- 'Transcript'" cooldown = world.time + 3 SECONDS @@ -377,6 +377,12 @@ . += span_notice("It has [seconds_to_time(remaining_capacity)] remaining.") +/obj/item/tape/update_overlays() + . = ..() + if(ruined) + . += "ribbonoverlay" + + /obj/item/tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) ..() ruin() @@ -414,14 +420,14 @@ to_chat(user, span_notice("You pull the tape out of [src].")) if(!ruined) - overlays += "ribbonoverlay" ruined = TRUE + update_icon(UPDATE_OVERLAYS) /obj/item/tape/proc/fix() if(ruined) - overlays -= "ribbonoverlay" ruined = FALSE + update_icon(UPDATE_OVERLAYS) /obj/item/tape/verb/wipe() diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 43f06e5b5dd..c0d5b223e9d 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -29,15 +29,17 @@ effective or pretty fucking useless. var/charges = 3 + /obj/item/batterer/examine(mob/user) . = ..() - . += "[src] has [charges] charges left." + . += span_notice("[src] has [charges] charges left.") + /obj/item/batterer/attack_self(mob/living/carbon/user, flag = 0, emp = 0) if(!user) return if(charges == 0) - to_chat(user, "The mind batterer is out of charge!") + to_chat(user, span_danger("The mind batterer is out of charge!")) return @@ -46,17 +48,18 @@ effective or pretty fucking useless. M.Weaken(rand(2,6) SECONDS) M.adjustStaminaLoss(rand(35, 60)) add_attack_logs(user, M, "Stunned with [src]") - to_chat(M, "You feel a tremendous, paralyzing wave flood your mind.") + to_chat(M, span_danger("You feel a tremendous, paralyzing wave flood your mind.")) else - to_chat(M, "You feel a sudden, electric jolt travel through your head.") + to_chat(M, span_danger("You feel a sudden, electric jolt travel through your head.")) M.Slowed(10 SECONDS) M.Confused(6 SECONDS) playsound(loc, 'sound/misc/interference.ogg', 50, 1) charges-- - to_chat(user, "You trigger [src]. It has [charges] charges left.") + to_chat(user,span_notice("You trigger [src]. It has [charges] charges left.")) addtimer(CALLBACK(src, PROC_REF(recharge)), 3 MINUTES) + /obj/item/batterer/proc/recharge() charges++ @@ -92,31 +95,43 @@ effective or pretty fucking useless. var/wavelength = 10 // time it takes for the radiation to kick in, in seconds var/used = 0 // is it cooling down? -/obj/item/rad_laser/attack(mob/living/M, mob/living/user) - if(!used) - add_attack_logs(user, M, "Irradiated by [src]") - user.visible_message("[user] analyzes [M]'s vitals.") - var/cooldown = round(max(100,(((intensity*8)-(wavelength/2))+(intensity*2))*10)) - used = 1 - icon_state = "health1" - handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength - spawn((wavelength+(intensity*4))*10) - if(M) - if(intensity >= 5) - M.Paralyse(intensity * 40/3 SECONDS) - M.apply_effect(intensity * 10, IRRADIATE) - else - to_chat(user, "The radioactive microlaser is still recharging.") -/obj/item/rad_laser/proc/handle_cooldown(cooldown) - spawn(cooldown) - used = 0 - icon_state = "health2" +/obj/item/rad_laser/update_icon_state() + icon_state = used ? "health1" : "health2" + + +/obj/item/rad_laser/attack(mob/living/target, mob/living/user) + if(used) + to_chat(user, span_warning("The radioactive microlaser is still recharging.")) + return + + add_attack_logs(user, target, "Irradiated by [src]") + user.visible_message(span_notice("[user] analyzes [target]'s vitals.")) + var/cooldown = round(max(100,(((intensity*8)-(wavelength/2))+(intensity*2))*10)) + used = TRUE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), cooldown) + addtimer(CALLBACK(src, PROC_REF(delayed_effect), target), (wavelength + (intensity * 4)) SECONDS) + + +/obj/item/rad_laser/proc/reset_cooldown() + used = FALSE + update_icon(UPDATE_ICON_STATE) + + +/obj/item/rad_laser/proc/delayed_effect(mob/living/target) + if(QDELETED(target)) + return + if(intensity >= 5) + target.Paralyse((intensity * 40 / 3) SECONDS) + target.apply_effect(intensity * 10, IRRADIATE) + /obj/item/rad_laser/attack_self(mob/user) ..() interact(user) + /obj/item/rad_laser/interact(mob/user) user.set_machine(src) @@ -131,6 +146,7 @@ effective or pretty fucking useless. popup.set_content(dat) popup.open() + /obj/item/rad_laser/Topic(href, href_list) if(..()) return 1 @@ -149,7 +165,8 @@ effective or pretty fucking useless. attack_self(usr) add_fingerprint(usr) - return + + /obj/item/jammer name = "radio jammer" @@ -159,12 +176,14 @@ effective or pretty fucking useless. var/active = FALSE var/range = 12 + /obj/item/jammer/Destroy() GLOB.active_jammers -= src return ..() + /obj/item/jammer/attack_self(mob/user) - to_chat(user,"You [active ? "deactivate" : "activate"] the [src].") + to_chat(user, span_notice("You [active ? "deactivate" : "activate"] the [src].")) active = !active if(active) GLOB.active_jammers |= src @@ -175,7 +194,8 @@ effective or pretty fucking useless. name = "Syndicate teleporter" desc = "A strange syndicate version of a cult veil shifter. Warranty voided if exposed to EMP." icon = 'icons/obj/device.dmi' - icon_state = "syndi-tele" + icon_state = "syndi-tele-4" + base_icon_state = "syndi-tele" throwforce = 5 w_class = WEIGHT_CLASS_SMALL throw_speed = 4 @@ -190,87 +210,122 @@ effective or pretty fucking useless. var/saving_throw_distance = 3 var/flawless = FALSE -/obj/item/teleporter/Initialize(mapload, ...) - . = ..() - START_PROCESSING(SSobj, src) /obj/item/teleporter/Destroy() - STOP_PROCESSING(SSobj, src) + if(isprocessing) + STOP_PROCESSING(SSobj, src) return ..() + /obj/item/teleporter/examine(mob/user) . = ..() - . += "[src] has [charges] out of [max_charges] charges left." + . += span_notice("[src] has [charges] out of [max_charges] charges left.") + + +/obj/item/teleporter/update_icon_state() + icon_state = "[base_icon_state]-[charges]" + /obj/item/teleporter/attack_self(mob/user) attempt_teleport(user, FALSE) + /obj/item/teleporter/process() - if(prob(10) && charges < max_charges) + if(charges >= max_charges) + return PROCESS_KILL + + if(prob(10)) charges++ + update_icon(UPDATE_ICON_STATE) + /obj/item/teleporter/emp_act(severity) - if(prob(50 / severity)) - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/user = loc - to_chat(user, "The [src] buzzes and activates!") - attempt_teleport(user, TRUE) - else - visible_message(" The [src] activates and blinks out of existence!") - do_sparks(2, 1, src) - qdel(src) + if(!prob(50 / severity)) + return + + if(ishuman(loc)) + var/mob/living/carbon/human/user = loc + to_chat(user, span_danger("The [src] buzzes and activates!")) + attempt_teleport(user, TRUE) + return + + // Well, it either is on a floor / locker, and won't teleport someone, + // OR it's in someones bag. As such, we need to check the turf to see if people are there. + var/teleported_something = FALSE + var/turf/teleport_turf = get_turf(src) + for(var/mob/living/user in teleport_turf) + teleported_something = TRUE + attempt_teleport(user, TRUE) + + if(teleported_something) + teleport_turf.visible_message(span_danger("[src] activates sporadically, teleporting everyone around it!")) + return + + visible_message(span_warning("The [src] activates and blinks out of existence!")) + do_sparks(2, TRUE, src) + qdel(src) + -/obj/item/teleporter/proc/attempt_teleport(mob/user, EMP_D = FALSE) +/obj/item/teleporter/proc/attempt_teleport(mob/living/user, EMP_D = FALSE) + for(var/obj/item/grab/G in user) + qdel(G) dir_correction(user) - if(!charges) - to_chat(user, "The [src] is recharging still.") + if(!charges && !EMP_D) //If it's empd, you are moving no matter what. + to_chat(user, span_warning("[src] is still recharging.")) return - var/mob/living/carbon/C = user - var/turf/mobloc = get_turf(C) - var/list/turfs = new/list() + var/turf/mobloc = get_turf(user) + var/list/turfs = list() var/found_turf = FALSE var/list/bagholding = user.search_contents_for(/obj/item/storage/backpack/holding) - for(var/turf/T in range(user, tp_range)) - if(!is_teleport_allowed(T.z)) + for(var/turf/check in range(user, tp_range)) + if(!is_teleport_allowed(check.z)) break if(!(length(bagholding) && !flawless)) //Chaos if you have a bag of holding - if(get_dir(C, T) != C.dir) + if(get_dir(user, check) != user.dir) continue - if(T in range(user, inner_tp_range)) + if(check in range(user, inner_tp_range)) continue - if(T.x > world.maxx-tp_range || T.x < tp_range) + if(check.x > world.maxx-tp_range || check.x < tp_range) continue //putting them at the edge is dumb - if(T.y > world.maxy-tp_range || T.y < tp_range) + if(check.y > world.maxy-tp_range || check.y < tp_range) continue - turfs += T + turfs += check found_turf = TRUE - if(found_turf) - if(user.loc != mobloc) // No locker / mech / sleeper teleporting, that breaks stuff - to_chat(C, "The [src] will not work here!") + if(!found_turf) + to_chat(user, span_danger("[src] will not work here!")) + return + + if(user.loc != mobloc) // No locker / mech / sleeper teleporting, that breaks stuff + to_chat(user, span_danger("[src] will not work here!")) + + if(charges > 0) //While we want EMP triggered teleports to drain charge, we also do not want it to go negative charge, as such we need this check here charges-- - var/turf/destination = pick(turfs) - if(tile_check(destination) || flawless) // Why is there so many bloody floor types - var/turf/fragging_location = destination - telefrag(fragging_location, user) - C.forceMove(destination) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) - playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(destination) - else if (EMP_D == FALSE && !(bagholding.len && !flawless)) // This is where the fun begins - var/direction = get_dir(user, destination) - panic_teleport(user, destination, direction) - else // Emp activated? Bag of holding? No saving throw for you - get_fragged(user, destination) - else - to_chat(C, "The [src] will not work here!") + update_icon(UPDATE_ICON_STATE) + if(!isprocessing) + START_PROCESSING(SSobj, src) + + var/turf/destination = pick(turfs) + if(tile_check(destination) || flawless) // Why is there so many bloody floor types + var/turf/fragging_location = destination + telefrag(fragging_location, user) + user.forceMove(destination) + playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) + playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(destination) + else if(EMP_D == FALSE && !(length(bagholding) && !flawless)) // This is where the fun begins + var/direction = get_dir(user, destination) + panic_teleport(user, destination, direction) + else // Emp activated? Bag of holding? No saving throw for you + get_fragged(user, destination) + + +/obj/item/teleporter/proc/tile_check(turf/check_turf) + return isfloorturf(check_turf) || isspaceturf(check_turf) -/obj/item/teleporter/proc/tile_check(turf/T) - if(istype(T, /turf/simulated/floor) || istype(T, /turf/space) || istype(T, /turf/simulated/floor/shuttle) || istype(T, /turf/simulated/floor/shuttle/objective_check) || istype(T, /turf/simulated/floor/shuttle/plating)) - return TRUE /obj/item/teleporter/proc/dir_correction(mob/user) //Direction movement, screws with teleport distance and saving throw, and thus must be removed first var/temp_direction = user.dir @@ -280,7 +335,8 @@ effective or pretty fucking useless. if(NORTHWEST, SOUTHWEST) user.dir = WEST -/obj/item/teleporter/proc/panic_teleport(mob/user, turf/destination, direction = NORTH) + +/obj/item/teleporter/proc/panic_teleport(mob/living/user, turf/destination, direction = NORTH) var/saving_throw switch(direction) if(NORTH, SOUTH) @@ -296,33 +352,33 @@ effective or pretty fucking useless. else saving_throw = NORTH // just in case - var/mob/living/carbon/C = user - var/turf/mobloc = get_turf(C) + var/turf/mobloc = get_turf(user) var/list/turfs = list() var/found_turf = FALSE - for(var/turf/T in range(destination, saving_throw_distance)) - if(get_dir(destination, T) != saving_throw) + for(var/turf/check in range(destination, saving_throw_distance)) + if(get_dir(destination, check) != saving_throw) continue - if(T.x > world.maxx-saving_throw_distance || T.x < saving_throw_distance) + if(check.x > world.maxx-saving_throw_distance || check.x < saving_throw_distance) continue //putting them at the edge is dumb - if(T.y > world.maxy-saving_throw_distance || T.y < saving_throw_distance) + if(check.y > world.maxy-saving_throw_distance || check.y < saving_throw_distance) continue - if(!tile_check(T)) + if(!tile_check(check)) continue // We are only looking for safe tiles on the saving throw, since we are nice - turfs += T + turfs += check found_turf = TRUE - if(found_turf) - var/turf/new_destination = pick(turfs) - var/turf/fragging_location = new_destination - telefrag(fragging_location, user) - C.forceMove(new_destination) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(new_destination) - playsound(new_destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - else //We tried to save. We failed. Death time. - get_fragged(user, destination) + if(!found_turf) + get_fragged(user, destination) //We tried to save. We failed. Death time. + return + + var/turf/new_destination = pick(turfs) + var/turf/fragging_location = new_destination + telefrag(fragging_location, user) + user.forceMove(new_destination) + playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) + new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(new_destination) + playsound(new_destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) /obj/item/teleporter/proc/get_fragged(mob/user, turf/destination) @@ -334,19 +390,19 @@ effective or pretty fucking useless. playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) playsound(destination, "sound/magic/disintegrate.ogg", 50, TRUE) destination.ex_act(rand(1,2)) - for(var/obj/item/W in user) - if(istype(W, /obj/item/organ)|| istype(W, /obj/item/implant)) - continue - if(!user.drop_item_ground(W)) - qdel(W) - to_chat(user, "You teleport into the wall, the teleporter tries to save you, but--") + for(var/obj/item/thing as anything in user.get_equipped_items(TRUE, TRUE)) + if(!user.drop_item_ground(thing)) + qdel(thing) + to_chat(user, span_dangerbigger("You teleport into the wall, the teleporter tries to save you, but--")) user.gib() + /obj/item/teleporter/proc/telefrag(turf/fragging_location, mob/user) - for(var/mob/living/M in fragging_location)//Hit everything in the turf - M.apply_damage(20, BRUTE) - M.Weaken(6 SECONDS) - to_chat(M, "[user] teleports into you, knocking you to the floor with the bluespace wave!
    ") + for(var/mob/living/target in fragging_location)//Hit everything in the turf + target.apply_damage(20, BRUTE) + target.Weaken(6 SECONDS) + to_chat(target, span_warning("[user] teleports into you, knocking you to the floor with the bluespace wave!")) + /obj/item/paper/teleporter name = "Teleporter Guide" @@ -361,18 +417,25 @@ effective or pretty fucking useless.
    Do not expose the teleporter to electromagnetic pulses or attempt to use with a bag of holding, unwanted malfunctions may occur. "} + + /obj/item/storage/box/syndie_kit/teleporter name = "syndicate teleporter kit" + /obj/item/storage/box/syndie_kit/teleporter/populate_contents() new /obj/item/teleporter(src) new /obj/item/paper/teleporter(src) new /obj/item/clothing/glasses/chameleon/meson(src) + + /obj/effect/temp_visual/teleport_abductor/syndi_teleporter duration = 5 + /obj/item/teleporter/admin desc = "A strange syndicate version of a cult veil shifter. \n This one seems EMP proof, and with much better saftey protocols." charges = 8 max_charges = 8 flawless = TRUE + diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 57fa49d5bf4..ad810bee5e0 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -110,7 +110,8 @@ if(tank_one) split_gases() valve_open = FALSE - tank_one.forceMove(get_turf(src)) + tank_one.forceMove_turf() + usr?.put_in_hands(tank_one, ignore_anim = FALSE) tank_one = null update_icon() if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) @@ -119,7 +120,8 @@ if(tank_two) split_gases() valve_open = FALSE - tank_two.forceMove(get_turf(src)) + tank_two.forceMove_turf() + usr?.put_in_hands(tank_two, ignore_anim = FALSE) tank_two = null update_icon() if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) @@ -131,7 +133,8 @@ attached_device.attack_self(usr) if("remove_device") if(attached_device) - attached_device.forceMove(get_turf(src)) + attached_device.forceMove_turf() + usr?.put_in_hands(attached_device, ignore_anim = FALSE) attached_device.holder = null attached_device = null qdel(GetComponent(/datum/component/proximity_monitor)) @@ -145,28 +148,32 @@ /obj/item/transfer_valve/proc/process_activation(obj/item/D, normal = TRUE, special = TRUE, mob/user) if(toggle) - toggle = 0 + toggle = FALSE toggle_valve(user) - spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever - toggle = 1 + addtimer(VARSET_CALLBACK(src, toggle, TRUE), 5 SECONDS) // To stop a signal being spammed from a proxy sensor constantly going off or whatever -/obj/item/transfer_valve/update_icon() - overlays.Cut() - underlays = null +/obj/item/transfer_valve/update_icon_state() if(!tank_one && !tank_two && !attached_device) icon_state = "valve_1" - return - icon_state = "valve" + else + icon_state = "valve" + +/obj/item/transfer_valve/update_overlays() + . = ..() + underlays.Cut() + if(!tank_one && !tank_two && !attached_device) + return if(tank_one) - overlays += "[tank_one.icon_state]" + . += "[tank_one.icon_state]" if(tank_two) var/icon/J = new(icon, icon_state = "[tank_two.icon_state]") J.Shift(WEST, 13) underlays += J if(attached_device) - overlays += "device" + . += "device" + /obj/item/transfer_valve/proc/merge_gases() tank_two.air_contents.volume += tank_one.air_contents.volume @@ -190,7 +197,7 @@ /obj/item/transfer_valve/proc/toggle_valve(mob/user) if(!valve_open && tank_one && tank_two) - valve_open = 1 + valve_open = TRUE var/turf/bombturf = get_turf(src) @@ -202,13 +209,17 @@ if(user) add_attack_logs(user, src, "Bomb valve opened with [attached_device ? attached_device : "no device"], attached by [key_name_log(attacher)]. Last touched by: [key_name_log(mob)]", ATKLOG_FEW) merge_gases() - spawn(20) // In case one tank bursts - for(var/i in 1 to 5) - update_icon() - sleep(10) - update_icon() + addtimer(CALLBACK(src, PROC_REF(toggle_process)), 2 SECONDS) // In case one tank bursts else if(valve_open && tank_one && tank_two) split_gases() - valve_open = 0 + valve_open = FALSE update_icon() + + +/obj/item/transfer_valve/proc/toggle_process() + for(var/i in 1 to 5) + update_icon() + sleep(1 SECONDS) + update_icon() + diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 32341ad3b27..7d369dbb619 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -246,7 +246,8 @@ GLOBAL_LIST_EMPTY(world_uplinks) "age" = html_encode(L.fields["age"]), "species" = html_encode(L.fields["species"]), "rank" = html_encode(L.fields["rank"]), - "fingerprint" = html_encode(L.fields["fingerprint"]) + "fingerprint" = html_encode(L.fields["fingerprint"]), + "exploit_record" = html_encode(L.fields["exploit_record"]), )) data["exploitable"] = exploitable diff --git a/code/game/objects/items/devices/window_painter.dm b/code/game/objects/items/devices/window_painter.dm index a44f0d13a09..8aa104f4cd8 100644 --- a/code/game/objects/items/devices/window_painter.dm +++ b/code/game/objects/items/devices/window_painter.dm @@ -11,9 +11,10 @@ /obj/structure/window/full/basic, /obj/machinery/door/window) -/obj/item/pipe_painter/window_painter/New() + +/obj/item/pipe_painter/window_painter/Initialize(mapload) . = ..() - update_icon() + update_icon(UPDATE_OVERLAYS) mode = "paint" @@ -25,11 +26,12 @@ if("Choose Color") mode = "paint" colour = input(user,"Choose Color") as color - update_icon() + update_icon(UPDATE_OVERLAYS) if("Color Presets") mode = "paint" colour = input("Which color do you want to use?", name, colour) in GLOB.pipe_colors - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/item/pipe_painter/window_painter/afterattack(atom/A, mob/user as mob) if(!is_type_in_list(A, paintable_windows) || !in_range(user, A)) @@ -43,10 +45,10 @@ colour = W.color mode = "paint" to_chat(user, span_notice("You copy color of this window.")) - update_icon() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/pipe_painter/window_painter/update_overlays() + . = ..() + . += mutable_appearance(icon, icon_state = "window_painter_colour", color = colour) -/obj/item/pipe_painter/window_painter/update_icon() - overlays.Cut() - var/image/colour_image = image('icons/obj/device.dmi', "window_painter_colour") - colour_image.color = colour - overlays += colour_image diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm index acbd3fc6722..6e1d9a05e4d 100644 --- a/code/game/objects/items/flag.dm +++ b/code/game/objects/items/flag.dm @@ -9,6 +9,7 @@ w_class = WEIGHT_CLASS_BULKY max_integrity = 40 resistance_flags = FLAMMABLE + custom_fire_overlay = "fire" var/rolled = FALSE /obj/item/flag/attackby(obj/item/W, mob/user, params) @@ -20,36 +21,34 @@ /obj/item/flag/attack_self(mob/user) rolled = !rolled user.visible_message("[user] [rolled ? "rolls up" : "unfurls"] [src].", "You [rolled ? "roll up" : "unfurl"] [src].", "You hear fabric rustling.") - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/flag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = FALSE) ..() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/flag/extinguish() ..() - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/item/flag/update_icon() - overlays.Cut() + +/obj/item/flag/update_icon_state() updateFlagIcon() item_state = icon_state if(rolled) icon_state = "[icon_state]_rolled" + custom_fire_overlay = "fire_rolled" + else + custom_fire_overlay = initial(custom_fire_overlay) if(resistance_flags & ON_FIRE) item_state = "[item_state]_fire" - if((resistance_flags & ON_FIRE) && rolled) - overlays += image('icons/obj/flag.dmi', src , "fire_rolled") - else if((resistance_flags & ON_FIRE) && !rolled) - overlays += image('icons/obj/flag.dmi', src , "fire") - if(ismob(loc)) - var/mob/M = loc - M.update_inv_r_hand() - M.update_inv_l_hand() + update_equipped_item() + /obj/item/flag/proc/updateFlagIcon() icon_state = initial(icon_state) + /obj/item/flag/nt name = "Nanotrasen flag" desc = "A flag proudly boasting the logo of NT." @@ -219,9 +218,16 @@ var/obj/item/grenade/boobytrap = null var/mob/trapper = null -/obj/item/flag/chameleon/New() + +/obj/item/flag/chameleon/Initialize(mapload) updated_icon_state = icon_state - ..() + . = ..() + + +/obj/item/flag/chameleon/Destroy() + QDEL_NULL(boobytrap) + return ..() + /obj/item/flag/chameleon/attack_self(mob/user) if(used) diff --git a/code/game/objects/items/hourglass.dm b/code/game/objects/items/hourglass.dm index 0dc486cc5c2..410b6efd85c 100644 --- a/code/game/objects/items/hourglass.dm +++ b/code/game/objects/items/hourglass.dm @@ -29,9 +29,10 @@ to_chat(user,span_notice("You stop the [src].")) //Sand magically flows back because that's more convinient to use. stop() -/obj/item/hourglass/update_icon() + +/obj/item/hourglass/update_icon_state() icon_state = "hourglass_[timing_id ? "active" : "idle"]" - return ..() + /obj/item/hourglass/proc/start() finish_time = world.time + time @@ -52,7 +53,7 @@ countdown.stop() finish_time = null animate(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/hourglass/proc/finish() visible_message(span_notice("[src] stops.")) diff --git a/code/game/objects/items/misc.dm b/code/game/objects/items/misc.dm index a4e60ce16e0..ebe0f80f87a 100644 --- a/code/game/objects/items/misc.dm +++ b/code/game/objects/items/misc.dm @@ -15,7 +15,7 @@ name = "beach ball" item_state = "beachball" density = 0 - anchored = 0 + anchored = FALSE w_class = WEIGHT_CLASS_TINY force = 0.0 throwforce = 0.0 diff --git a/code/game/objects/items/mixing_bowl.dm b/code/game/objects/items/mixing_bowl.dm index 8eed9480fb6..c29b18236f0 100644 --- a/code/game/objects/items/mixing_bowl.dm +++ b/code/game/objects/items/mixing_bowl.dm @@ -155,12 +155,12 @@ if(prob(chance)) dirty = TRUE flags = null - icon_state = dirty_icon + update_icon(UPDATE_ICON_STATE) /obj/item/mixing_bowl/proc/clean() dirty = FALSE flags = OPENCONTAINER - icon_state = clean_icon + update_icon(UPDATE_ICON_STATE) /obj/item/mixing_bowl/wash(mob/user, atom/source) if(..()) @@ -187,3 +187,8 @@ ffuu.reagents.add_reagent("carbon", amount) ffuu.reagents.add_reagent("????", amount/10) make_dirty(75) + + +/obj/item/mixing_bowl/update_icon_state() + icon_state = dirty ? dirty_icon : clean_icon + diff --git a/code/game/objects/items/mountable_frames/frames.dm b/code/game/objects/items/mountable_frames/frames.dm index 179684139fc..66b185f4148 100644 --- a/code/game/objects/items/mountable_frames/frames.dm +++ b/code/game/objects/items/mountable_frames/frames.dm @@ -9,7 +9,7 @@ /obj/item/mounted/frame/attackby(obj/item/W, mob/user) ..() - if(istype(W, /obj/item/wrench) && sheets_refunded) + if(W.tool_behaviour == TOOL_WRENCH && sheets_refunded) new /obj/item/stack/sheet/metal(get_turf(src), sheets_refunded) qdel(src) diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index 3b9caa6fed6..5fa73f398c7 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -31,7 +31,16 @@ /obj/item/stack/sheet/animalhide/random/New() ..() - var/htype = pick(/obj/item/stack/sheet/animalhide/cat,/obj/item/stack/sheet/animalhide/corgi,/obj/item/stack/sheet/animalhide/human,/obj/item/stack/sheet/animalhide/lizard,/obj/item/stack/sheet/animalhide/monkey) + var/htype = pick(/obj/item/stack/sheet/animalhide/cat, \ + /obj/item/stack/sheet/animalhide/corgi, \ + /obj/item/stack/sheet/animalhide/human, \ + /obj/item/stack/sheet/animalhide/lizard, \ + /obj/item/stack/sheet/animalhide/monkey, \ + /obj/item/stack/sheet/animalhide/wolpin, \ + /obj/item/stack/sheet/animalhide/stok, \ + /obj/item/stack/sheet/animalhide/neara, \ + /obj/item/stack/sheet/animalhide/farwa \ + ) new htype(loc, amount) qdel(src) @@ -200,7 +209,7 @@ /obj/structure/closet/crate/bin/flowers name = "flower barrel" desc = "A bin full of fresh flowers for the bereaved." - anchored = 0 + anchored = FALSE New() while(contents.len < 10) var/flowertype = pick(/obj/item/grown/sunflower,/obj/item/grown/novaflower,/obj/item/reagent_containers/food/snacks/grown/poppy, @@ -212,7 +221,7 @@ /obj/structure/closet/crate/bin/plants name = "plant barrel" desc = "Caution: Contents may contain vitamins and minerals. It is recommended that you deep fry them before eating." - anchored = 0 + anchored = FALSE New() while(contents.len < 10) var/ptype = pick(/obj/item/reagent_containers/food/snacks/grown/apple,/obj/item/reagent_containers/food/snacks/grown/banana, @@ -262,7 +271,7 @@ desc = "What could it be?" /obj/structure/largecrate/evil/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) + if(W.tool_behaviour == TOOL_CROWBAR) var/list/menace = pick( /mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/faithless,/mob/living/simple_animal/hostile/pirate, /mob/living/simple_animal/hostile/creature,/mob/living/simple_animal/hostile/pirate/ranged, /mob/living/simple_animal/hostile/hivebot,/mob/living/simple_animal/hostile/viscerator,/mob/living/simple_animal/hostile/pirate) @@ -294,7 +303,7 @@ desc = "What happens if you open it?" /obj/structure/largecrate/schrodinger/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) + if(W.tool_behaviour == TOOL_CROWBAR) add_fingerprint(user) sleep(2) var/mob/living/simple_animal/pet/cat/Cat = new(loc) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index caf8c3b9b69..2bf19296d14 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -204,7 +204,7 @@ else to_chat(user, "You need to attach a flash to it first!") - if(istype(W, /obj/item/multitool)) + if(W.tool_behaviour == TOOL_MULTITOOL) if(check_completion()) Interact(user) else @@ -366,7 +366,7 @@ if(living_user.lying || living_user.stat || living_user.IsStunned() || !Adjacent(living_user)) return var/obj/item/item_in_hand = living_user.get_active_hand() - if(!istype(item_in_hand, /obj/item/multitool)) + if(item_in_hand.tool_behaviour != TOOL_MULTITOOL) to_chat(living_user, "You need a multitool!") return diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 002f9898c18..ded789270b3 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -46,12 +46,10 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ . = ..() recipes = GLOB.rod_recipes -/obj/item/stack/rods/update_icon() +/obj/item/stack/rods/update_icon_state() var/amount = get_amount() - if((amount <= 5) && (amount > 0)) - icon_state = "rods-[amount]" - else - icon_state = "rods" + icon_state = "rods-[clamp(amount, 1, 5)]" + /obj/item/stack/rods/welder_act(mob/user, obj/item/I) if(get_amount() < 2) @@ -79,8 +77,8 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ is_cyborg = 1 cyborg_construction_stack = /obj/item/stack/rods -/obj/item/stack/rods/cyborg/update_icon() - return +/obj/item/stack/rods/cyborg/update_icon_state() + return // icon_state should always be a full stack of rods. /obj/item/stack/fireproof_rods name = "fireproof rods" @@ -103,13 +101,12 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ toolspeed = 1 usesound = 'sound/items/deconstruct.ogg' + /obj/item/stack/fireproof_rods/twentyfive amount = 25 -/obj/item/stack/fireproof_rods/update_icon() + +/obj/item/stack/fireproof_rods/update_icon_state() var/amount = get_amount() - if((amount <= 5) && (amount > 0)) - icon_state = "f_rods-[amount]" - else - icon_state = "f_rods" + icon_state = "f_rods-[clamp(amount, 1, 5)]" diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index a7401ef97ee..6dde09bc9d8 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -42,6 +42,30 @@ GLOBAL_LIST_INIT(human_recipes, list( \ singular_name = "monkey hide piece" icon_state = "sheet-monkey" +/obj/item/stack/sheet/animalhide/wolpin + name = "wolpin hide" + desc = "The by-product of wolpin farming." + singular_name = "wolpin hide piece" + icon_state = "sheet-wolpin" + +/obj/item/stack/sheet/animalhide/stok + name = "stok hide" + desc = "The by-product of stok farming." + singular_name = "stok hide piece" + icon_state = "sheet-lizzard" + +/obj/item/stack/sheet/animalhide/neara + name = "neara hide" + desc = "The by-product of neara farming." + singular_name = "neara hide piece" + icon_state = "sheet-neara" + +/obj/item/stack/sheet/animalhide/farwa + name = "farwa hide" + desc = "The by-product of farwa farming." + singular_name = "farwa hide piece" + icon_state = "sheet-farwa" + /obj/item/stack/sheet/animalhide/lizard name = "lizard skin" desc = "Sssssss..." @@ -168,17 +192,18 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \ /obj/item/clothing/head/hooded/explorer, /obj/item/clothing/head/helmet/space/plasmaman/mining, )) + /obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag) if(!proximity_flag) return - if(is_type_in_typecache(target, goliath_platable_armor_typecache) || is_type_in_typecache(target, goliath_platable_armor_with_icon_typecache)) + var/platable_armor_with_icon = is_type_in_typecache(target, goliath_platable_armor_with_icon_typecache) + if(is_type_in_typecache(target, goliath_platable_armor_typecache) || platable_armor_with_icon) var/obj/item/clothing/C = target var/datum/armor/current_armor = C.armor - - if(current_armor.getRating("melee") < 60) - C.armor = current_armor.setRating(melee_value = min(current_armor.getRating("melee") + 10, 60)) - if(is_type_in_typecache(target, goliath_platable_armor_with_icon_typecache)) - switch(C.armor.getRating("melee")) + if(current_armor.getRating(MELEE) < 60) + C.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 10, 60)) + if(platable_armor_with_icon) + switch(C.armor.getRating(MELEE)) if(40, 50) C.icon_state = "[initial(C.icon_state)]_reinf" C.item_color = "[initial(C.item_color)]_reinf" @@ -200,11 +225,11 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \ var/obj/mecha/working/ripley/D = target if(D.hides < 3) D.hides++ - D.armor = D.armor.setRating(melee_value = min(D.armor.getRating("melee") + 10, 70)) - D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating("bullet") + 5, 50)) - D.armor = D.armor.setRating(laser_value = min(D.armor.getRating("laser") + 5, 50)) + D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 10, 70)) + D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 5, 50)) + D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 5, 50)) to_chat(user, "You strengthen [target], improving its resistance against melee attacks.") - D.update_icon() + D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) use(1) else to_chat(user, "You can't improve [D] any further!") @@ -230,7 +255,7 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \ D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating("bullet") + 5, 50)) D.armor = D.armor.setRating(laser_value = min(D.armor.getRating("laser") + 5, 50)) to_chat(user, "Вы нашли куда суется [name] и пихнули её на экзокостюм, усиливая защиту против атак.") - D.update_icon() + D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) use(1) else to_chat(user, "Вы больше не можете найти куда [name] пристраивается!") diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 0c035c6161b..e735f797078 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -275,6 +275,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list( new /datum/stack_recipe("Bio bag", /obj/item/storage/bag/bio, 4), new /datum/stack_recipe("Book bag", /obj/item/storage/bag/books, 4), new /datum/stack_recipe("Chemistry bag", /obj/item/storage/bag/chemistry, 4), + new /datum/stack_recipe("Construction bag", /obj/item/storage/bag/construction, 4), new /datum/stack_recipe("Fish bag", /obj/item/storage/bag/fish, 4), new /datum/stack_recipe("Mining satchel", /obj/item/storage/bag/ore, 4), new /datum/stack_recipe("Plant bag", /obj/item/storage/bag/plants, 4), diff --git a/code/game/objects/items/stacks/stack_recipe.dm b/code/game/objects/items/stacks/stack_recipe.dm index 3a5f5ba019a..47061ddc8c1 100644 --- a/code/game/objects/items/stacks/stack_recipe.dm +++ b/code/game/objects/items/stacks/stack_recipe.dm @@ -37,25 +37,7 @@ /datum/stack_recipe/cable_restraints/post_build(obj/item/stack/S, obj/result) var/obj/item/restraints/handcuffs/cable/cable_restraints = result if(istype(cable_restraints)) - var/color = "white" - - switch(S.color) - if(WIRE_COLOR_BLUE) - color = "blue" - if(WIRE_COLOR_CYAN) - color = "cyan" - if(WIRE_COLOR_GREEN) - color = "green" - if(WIRE_COLOR_ORANGE) - color = "orange" - if(WIRE_COLOR_PINK) - color = "pink" - if(WIRE_COLOR_RED) - color = "red" - if(WIRE_COLOR_YELLOW) - color = "yellow" - - cable_restraints.icon_state = "cuff_[color]" + cable_restraints.cable_color(S.color) ..() diff --git a/code/game/objects/items/theft_items.dm b/code/game/objects/items/theft_items.dm index 898ceb055b5..3c0f7d84752 100644 --- a/code/game/objects/items/theft_items.dm +++ b/code/game/objects/items/theft_items.dm @@ -82,6 +82,17 @@ else // Not cracked or dented. . += "Fine print on the box reads \"Cybersun Industries secure container, guaranteed thermite proof, assistant proof, and explosive resistant.\"" + +/obj/item/nuke_core_container/update_icon_state() + if(sealed) + icon_state = "core_container_sealed" + return + if(core) + icon_state = cracked ? "core_container_cracked_loaded" : "core_container_loaded" + else + icon_state = cracked ? "core_container_cracked_empty" : "core_container_empty" + + /obj/item/nuke_core_container/attack_hand(mob/user) if(cracked && core) unload(user) @@ -93,7 +104,7 @@ return new_core.forceMove(src) core = new_core - icon_state = "core_container_loaded" + update_icon(UPDATE_ICON_STATE) to_chat(user, "Container is sealing...") addtimer(CALLBACK(src, PROC_REF(seal)), 10 SECONDS) @@ -101,14 +112,14 @@ core.add_fingerprint(user) user.put_in_active_hand(core) core = null - icon_state = "core_container_cracked_empty" + update_icon(UPDATE_ICON_STATE) /obj/item/nuke_core_container/proc/seal() if(!QDELETED(core)) STOP_PROCESSING(SSobj, core) ADD_TRAIT(core, TRAIT_BLOCK_RADIATION, src) - icon_state = "core_container_sealed" sealed = TRUE + update_icon(UPDATE_ICON_STATE) playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE) if(ismob(loc)) to_chat(loc, "[src] is permanently sealed, [core]'s radiation is contained.") @@ -116,7 +127,6 @@ /obj/item/nuke_core_container/attackby(obj/item/nuke_core/plutonium/core, mob/user) if(!istype(core) || cracked) return ..() - if(!user.drop_item_ground(core)) to_chat(user, "[core] is stuck to your hand!") return @@ -128,11 +138,8 @@ if(core) START_PROCESSING(SSobj, core) REMOVE_TRAIT(core, TRAIT_BLOCK_RADIATION, src) - icon_state = "core_container_cracked_loaded" - else - icon_state = "core_container_cracked_empty" - icon_state = "core_container_cracked_empty" cracked = TRUE + update_icon(UPDATE_ICON_STATE) /obj/item/paper/guides/antag/nuke_instructions info = "Как вскрыть ядерную боеголовку Нанотрейзен и вытащить из нее плутониевое ядро:
    \ @@ -182,8 +189,8 @@ return FALSE forceMove(tongs) tongs.sliver = src - tongs.icon_state = "supermatter_tongs_loaded" - tongs.item_state = "supermatter_tongs_loaded" + tongs.update_icon(UPDATE_ICON_STATE) + to_chat(user, "You carefully pick up [src] with [tongs].") else if(istype(I, /obj/item/scalpel/supermatter) || istype(I, /obj/item/nuke_core_container/supermatter)) // we don't want it to dust return @@ -243,15 +250,30 @@ QDEL_NULL(sliver) return ..() + +/obj/item/nuke_core_container/supermatter/update_name(updates = ALL) + . = ..() + name = cracked ? "broken supermatter bin" : initial(name) + + +/obj/item/nuke_core_container/supermatter/update_icon_state() + if(sealed) + icon_state = "supermatter_container_sealed" + return + if(sliver) + icon_state = cracked ? "core_container_cracked_loaded" : "core_container_loaded" + else + icon_state = "core_container_cracked_empty" + + /obj/item/nuke_core_container/supermatter/load(obj/item/retractor/supermatter/I, mob/user) if(!istype(I) || !I.sliver || sliver) return I.sliver.forceMove(src) sliver = I.sliver I.sliver = null - I.icon_state = "supermatter_tongs" - I.item_state = "supermatter_tongs" - icon_state = "supermatter_container_loaded" + I.update_icon(UPDATE_ICON_STATE) + update_icon(UPDATE_ICON_STATE) to_chat(user, "Container is sealing...") addtimer(CALLBACK(src, PROC_REF(seal)), 10 SECONDS) @@ -259,9 +281,9 @@ if(!QDELETED(sliver)) STOP_PROCESSING(SSobj, sliver) ADD_TRAIT(sliver, TRAIT_BLOCK_RADIATION, src) - icon_state = "supermatter_container_sealed" playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE) sealed = TRUE + update_icon(UPDATE_ICON_STATE) if(ismob(loc)) to_chat(loc, "[src] is permanently sealed, [sliver] is safely contained.") @@ -271,9 +293,8 @@ sliver.forceMove(I) I.sliver = sliver sliver = null - I.icon_state = "supermatter_tongs_loaded" - I.item_state = "supermatter_tongs_loaded" - icon_state = "core_container_cracked_empty" + I.update_icon(UPDATE_ICON_STATE) + update_icon(UPDATE_ICON_STATE) to_chat(user, "You carefully pick up [I.sliver] with [I].") /obj/item/nuke_core_container/supermatter/attackby(obj/item/retractor/supermatter/tongs, mob/user) @@ -300,9 +321,8 @@ message_admins("[sliver] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].") investigate_log("has consumed [key_name(user)].", "supermatter") user.gib() - icon_state = "core_container_cracked_empty" - qdel(sliver) - sliver = null + QDEL_NULL(sliver) + update_icon(UPDATE_ICON_STATE) else return ..() @@ -312,11 +332,8 @@ if(sliver) START_PROCESSING(SSobj, sliver) REMOVE_TRAIT(sliver, TRAIT_BLOCK_RADIATION, src) - icon_state = "supermatter_container_cracked_loaded" - else - icon_state = "core_container_cracked_empty" - name = "broken supermatter bin" cracked = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) /obj/item/scalpel/supermatter name = "supermatter scalpel" @@ -348,6 +365,12 @@ QDEL_NULL(sliver) return ..() + +/obj/item/retractor/supermatter/update_icon_state() + icon_state = "supermatter_tongs[sliver ? "_loaded" : ""]" + item_state = "supermatter_tongs[sliver ? "_loaded" : ""]" + + /obj/item/retractor/supermatter/afterattack(atom/O, mob/user, proximity) . = ..() if(!sliver) @@ -360,8 +383,7 @@ sliver.forceMove(loc) visible_message("[sliver] falls out of [src] as it hits the ground.") sliver = null - icon_state = "supermatter_tongs" - item_state = "supermatter_tongs" + update_icon(UPDATE_ICON_STATE) return ..() /obj/item/retractor/supermatter/proc/Consume(atom/movable/AM, mob/living/user) @@ -393,5 +415,5 @@ L.apply_effect(60, IRRADIATE) playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) QDEL_NULL(sliver) - icon_state = "supermatter_tongs" - item_state = "supermatter_tongs" + update_icon(UPDATE_ICON_STATE) + diff --git a/code/game/objects/items/tools/multitool.dm b/code/game/objects/items/tools/multitool.dm index c02177c1463..db562b1d1b9 100644 --- a/code/game/objects/items/tools/multitool.dm +++ b/code/game/objects/items/tools/multitool.dm @@ -74,12 +74,17 @@ STOP_PROCESSING(SSobj, src) return ..() + +/obj/item/multitool/ai_detect/update_icon_state() + icon_state = "[initial(icon_state)][detect_state]" + + /obj/item/multitool/ai_detect/process() if(track_cooldown > world.time) return detect_state = PROXIMITY_NONE multitool_detect() - icon_state = "[initial(icon_state)][detect_state]" + update_icon(UPDATE_ICON_STATE) track_cooldown = world.time + track_delay /obj/item/multitool/ai_detect/proc/multitool_detect() @@ -91,16 +96,19 @@ if(!detect_state && GLOB.cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z)) var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z) - if(chunk) - if(chunk.seenby.len) - for(var/mob/camera/aiEye/A in chunk.seenby) - var/turf/detect_turf = get_turf(A) - if(get_dist(our_turf, detect_turf) < rangealert) - detect_state = PROXIMITY_ON_SCREEN - break - if(get_dist(our_turf, detect_turf) < rangewarning) - detect_state = PROXIMITY_NEAR - break + if(!chunk) + return + for(var/mob/camera/aiEye/A in chunk.seenby) + //Checks if the A is to be detected or not + if(!A.ai_detector_visible) + continue + var/turf/detect_turf = get_turf(A) + if(get_dist(our_turf, detect_turf) < rangealert) + detect_state = PROXIMITY_ON_SCREEN + break + if(get_dist(our_turf, detect_turf) < rangewarning) + detect_state = PROXIMITY_NEAR + break /obj/item/multitool/ai_detect/admin desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'" //What else should I say for a meme item? diff --git a/code/game/objects/items/tools/tool_behaviour.dm b/code/game/objects/items/tools/tool_behaviour.dm index b68de693855..c0afaafb462 100644 --- a/code/game/objects/items/tools/tool_behaviour.dm +++ b/code/game/objects/items/tools/tool_behaviour.dm @@ -43,7 +43,7 @@ return tool_use_check(user, amount) // A check called by tool_start_check once, and by use_tool on every tick of delay. -/obj/item/proc/tool_use_check(mob/living/user, amount) +/obj/item/proc/tool_use_check(mob/living/user, amount, silent = FALSE) return !amount /obj/item/proc/play_tool_sound(atom/target, volume = tool_volume) diff --git a/code/game/objects/items/tools/welder.dm b/code/game/objects/items/tools/welder.dm index 2e75f52fbdf..7fcc4f70406 100644 --- a/code/game/objects/items/tools/welder.dm +++ b/code/game/objects/items/tools/welder.dm @@ -115,14 +115,16 @@ M.update_inv_l_hand() // If welding tool ran out of fuel during a construction task, construction fails. -/obj/item/weldingtool/tool_use_check(mob/living/user, amount) +/obj/item/weldingtool/tool_use_check(mob/living/user, amount, silent = FALSE) if(!tool_enabled) - to_chat(user, "[src] has to be on to complete this task!") + if(!silent) + to_chat(user, "[src] has to be on to complete this task!") return FALSE if(GET_FUEL >= amount * requires_fuel) return TRUE else - to_chat(user, "You need more welding fuel to complete this task!") + if(!silent) + to_chat(user, "You need more welding fuel to complete this task!") return FALSE // When welding is about to start, run a normal tool_use_check, then flash a mob if it succeeds. @@ -174,15 +176,8 @@ else to_chat(user, "There's not enough fuel in [A] to refuel [src]!") -/obj/item/weldingtool/proc/update_torch() - overlays.Cut() - if(tool_enabled) - overlays += "[initial(icon_state)]-on" - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" -/obj/item/weldingtool/update_icon() +/obj/item/weldingtool/update_icon_state() if(low_fuel_changes_icon) var/ratio = GET_FUEL / maximum_fuel ratio = CEILING(ratio*4, 1) * 25 @@ -190,8 +185,16 @@ icon_state = initial(icon_state) else icon_state = "[initial(icon_state)][ratio]" - update_torch() - ..() + if(tool_enabled) + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_overlays() + . = ..() + if(tool_enabled) + . += "[initial(icon_state)]-on" /obj/item/weldingtool/largetank diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index b9b13cbc6cc..77db10a3288 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -53,13 +53,16 @@ icon_state = "waterballoon-e" item_state = "waterballoon-e" + /obj/item/toy/balloon/New() ..() create_reagents(10) + /obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) return + /obj/item/toy/balloon/afterattack(atom/A, mob/user, proximity) if(!proximity) return @@ -73,17 +76,18 @@ A.reagents.trans_to(src, 10) to_chat(user, "You fill the balloon with the contents of [A].") desc = "A translucent balloon with some form of liquid sloshing around in it." - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/item/toy/balloon/wash(mob/user, atom/source) if(reagents.total_volume < 10) reagents.add_reagent("water", min(10-reagents.total_volume, 10)) to_chat(user, "You fill the balloon from the [source].") desc = "A translucent balloon with some form of liquid sloshing around in it." - update_icon() - return + update_icon(UPDATE_ICON_STATE) + -/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob, params) +/obj/item/toy/balloon/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/reagent_containers/glass) || istype(O, /obj/item/reagent_containers/food/drinks/drinkingglass)) if(O.reagents) if(O.reagents.total_volume < 1) @@ -97,8 +101,8 @@ desc = "A translucent balloon with some form of liquid sloshing around in it." to_chat(user, "You fill the balloon with the contents of [O].") O.reagents.trans_to(src, 10) - update_icon() - return + update_icon(UPDATE_ICON_STATE) + /obj/item/toy/balloon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(reagents.total_volume >= 1) @@ -110,16 +114,17 @@ spawn(5) if(src) qdel(src) - return -/obj/item/toy/balloon/update_icon() - if(src.reagents.total_volume >= 1) + +/obj/item/toy/balloon/update_icon_state() + if(reagents.total_volume >= 1) icon_state = "waterballoon" item_state = "waterballoon" else icon_state = "waterballoon-e" item_state = "waterballoon-e" + /obj/item/toy/syndicateballoon name = "syndicate balloon" desc = "There is a tag on the back that reads \"FUK NT!11!\"." @@ -420,12 +425,6 @@ desc = "Mini-Mecha action figure! Collect them all! 11/11. This one is the mysterious Phazon combat mecha! Nobody's safe!" icon_state = "phazonprize" - - -/* -|| A Deck of Cards for playing various games of chance || -*/ - /obj/item/toy/nuke name = "\improper Nuclear Fission Explosive toy" desc = "A plastic model of a Nuclear Fission Explosive." @@ -433,22 +432,41 @@ icon_state = "nuketoyidle" w_class = WEIGHT_CLASS_SMALL var/cooldown = 0 + var/animation_stage = 0 + + +/obj/item/toy/nuke/update_icon_state() + switch(animation_stage) + if(1) + icon_state = "nuketoy" + if(2) + icon_state = "nuketoycool" + else + icon_state = initial(icon_state) + /obj/item/toy/nuke/attack_self(mob/user) if(cooldown < world.time) - cooldown = world.time + 1800 //3 minutes + cooldown = world.time + 3 MINUTES user.visible_message("[user] presses a button on [src]", "You activate [src], it plays a loud noise!", "You hear the click of a button.") - spawn(5) //gia said so - icon_state = "nuketoy" - playsound(src, 'sound/machines/alarm.ogg', 100, 0, 0) - sleep(135) - icon_state = "nuketoycool" - sleep(cooldown - world.time) - icon_state = "nuketoyidle" + INVOKE_ASYNC(src, PROC_REF(async_animation)) else var/timeleft = (cooldown - world.time) to_chat(user, "Nothing happens, and '[round(timeleft/10)]' appears on a small display.") + +/obj/item/toy/nuke/proc/async_animation() + animation_stage++ + update_icon(UPDATE_ICON_STATE) + playsound(src, 'sound/machines/alarm.ogg', 100, FALSE, 0) + sleep(13 SECONDS) + animation_stage++ + update_icon(UPDATE_ICON_STATE) + sleep(cooldown - world.time) + animation_stage = 0 + update_icon(UPDATE_ICON_STATE) + + /obj/item/toy/therapy name = "therapy doll" desc = "A toy for therapeutic and recreational purposes." @@ -949,25 +967,39 @@ icon_state = "ninja_plushie_green" item_state = "ninja_plushie_green" var/cooldown = 0 + var/plushie_color + + +/obj/item/toy/plushie/ninja/update_icon_state() + switch(plushie_color) + if("green") + icon_state = "ninja_plushie_green" + item_state = "ninja_plushie_green" + if("blue") + icon_state = "ninja_plushie_blue" + item_state = "ninja_plushie_blue" + if("red") + icon_state = "ninja_plushie_red" + item_state = "ninja_plushie_red" + else + icon_state = initial(icon_state) + item_state = initial(item_state) + /obj/item/toy/plushie/ninja/attack_self(mob/user as mob) . = ..() if(cooldown < world.time) cooldown = (world.time + 30) //3 second cooldown var/plushie_color = pick("green","blue","red") - switch (plushie_color) + update_icon(UPDATE_ICON_STATE) + switch(plushie_color) if("green") - icon_state = "ninja_plushie_green" - item_state = "ninja_plushie_green" user.visible_message(span_notice("[bicon(src)] The [name] says \"I am not afraid of the darkness! I am the darkness!\"")) if("blue") - icon_state = "ninja_plushie_blue" - item_state = "ninja_plushie_blue" user.visible_message(span_notice("[bicon(src)] The [name] says \"Your simple light won't stop me!\"")) if("red") - icon_state = "ninja_plushie_red" - item_state = "ninja_plushie_red" user.visible_message(span_notice("[bicon(src)] The [name] says \"You can run, but you can't hide!\"")) + plushie_color = null //New toys from another builds /obj/item/toy/plushie/nianplushie/beeplushie @@ -1038,9 +1070,6 @@ /obj/item/toy/plushie/blahaj/twohanded/Initialize(mapload) . = ..() - apply_twohanded_component() - -/obj/item/toy/plushie/blahaj/twohanded/proc/apply_twohanded_component() AddComponent(/datum/component/two_handed, require_twohands = TRUE) /obj/item/toy/plushie/blahaj/twohanded/attack_self(mob/user) @@ -1175,13 +1204,13 @@ desc = "Watch out for angry voxes!" -/obj/item/toy/plushie/pig/MouseDrop(atom/over) +/obj/item/toy/plushie/pig/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(over != user || user.incapacitated() || !ishuman(user)) + if(over_object != user || user.incapacitated() || !ishuman(user)) return FALSE if(user.put_in_hands(src, ignore_anim = FALSE)) @@ -1541,22 +1570,33 @@ w_class = WEIGHT_CLASS_SMALL bubble_icon = "alien" var/cooldown = 0 + var/animating = FALSE + + +/obj/item/toy/toy_xeno/update_icon_state() + icon_state = animating ? "[initial(icon_state)]_used" : initial(icon_state) + /obj/item/toy/toy_xeno/attack_self(mob/user) if(cooldown <= world.time) cooldown = (world.time + 50) //5 second cooldown user.visible_message("[user] pulls back the string on [src].") - icon_state = "[initial(icon_state)]_used" - sleep(5) - atom_say("Hiss!") - var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') - playsound(get_turf(src), pick(possible_sounds), 50, 1) - spawn(45) - if(src) - icon_state = "[initial(icon_state)]" + INVOKE_ASYNC(src, PROC_REF(async_animation)) else to_chat(user, "The string on [src] hasn't rewound all the way!") - return + + +/obj/item/toy/toy_xeno/proc/async_animation() + animating = TRUE + update_icon(UPDATE_ICON_STATE) + sleep(0.5 SECONDS) + atom_say("Hiss!") + var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') + playsound(get_turf(src), pick(possible_sounds), 50, TRUE) + sleep(4.5 SECONDS) + animating = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/item/toy/russian_revolver name = "russian revolver" @@ -1669,11 +1709,8 @@ wieldsound = 'sound/weapons/chainsawstart.ogg' attack_verb = list("sawed", "cut", "hacked", "carved", "cleaved", "butchered", "felled", "timbered") -/obj/item/twohanded/toy/chainsaw/update_icon() - if(wielded) - icon_state = "chainsaw[wielded]" - else - icon_state = "chainsaw0" +/obj/item/twohanded/toy/chainsaw/update_icon_state() + icon_state = "chainsaw[HAS_TRAIT(src, TRAIT_WIELDED)]" /* * Cat Toy @@ -1994,7 +2031,7 @@ var/on = 0 var/activation_sound = 'sound/items/buttonclick.ogg' -/obj/item/toy/desk/update_icon() +/obj/item/toy/desk/update_icon_state() if(on) icon_state = "[initial(icon_state)]-on" else @@ -2004,8 +2041,8 @@ on = !on if(activation_sound) playsound(src.loc, activation_sound, 75, 1) - update_icon() - return 1 + update_icon(UPDATE_ICON_STATE) + return TRUE /obj/item/toy/desk/verb/rotate() set name = "Rotate" @@ -2046,7 +2083,7 @@ /obj/item/toy/desk/newtoncradle/attack_self(mob/user) on = !on - update_icon() + update_icon(UPDATE_ICON_STATE) if(on) soundloop.start() else @@ -2064,7 +2101,7 @@ /obj/item/toy/desk/fan/attack_self(mob/user) on = !on - update_icon() + update_icon(UPDATE_ICON_STATE) if(on) soundloop.start() else diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm index 48d606cabc7..08cdb091a93 100644 --- a/code/game/objects/items/weapons/RCL.dm +++ b/code/game/objects/items/weapons/RCL.dm @@ -34,7 +34,7 @@ loaded.amount = amount else return - update_icon() + update_icon(UPDATE_ICON_STATE) to_chat(user, "You add the cables to the [src]. It now contains [loaded.amount].") else ..() @@ -58,7 +58,7 @@ loaded.forceMove(user.loc) user.put_in_hands(loaded) loaded = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/twohanded/rcl/examine(mob/user) . = ..() @@ -71,7 +71,8 @@ active = 0 return ..() -/obj/item/twohanded/rcl/update_icon() + +/obj/item/twohanded/rcl/update_icon_state() if(!loaded) icon_state = "rcl-0" item_state = "rcl-0" @@ -89,10 +90,10 @@ else icon_state = "rcl-0" item_state = "rcl-0" - ..() + /obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1) - update_icon() + update_icon(UPDATE_ICON_STATE) if(!loaded || !loaded.amount) if(loud) to_chat(user, "The last of the cables unreel from [src].") @@ -151,4 +152,4 @@ loaded = new() loaded.max_amount = max_amount loaded.amount = max_amount - update_icon() + update_icon(UPDATE_ICON_STATE) diff --git a/code/game/objects/items/weapons/RLF.dm b/code/game/objects/items/weapons/RLF.dm index ff64326c076..8155d560e77 100644 --- a/code/game/objects/items/weapons/RLF.dm +++ b/code/game/objects/items/weapons/RLF.dm @@ -10,7 +10,7 @@ RLF icon_state = "rlf" opacity = 0 density = 0 - anchored = 0.0 + anchored = FALSE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index f28abbee5e6..747976d1fe6 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -11,7 +11,7 @@ RSF icon_state = "rsf" opacity = 0 density = 0 - anchored = 0.0 + anchored = FALSE var/matter = 0 var/mode = 1 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) @@ -31,7 +31,7 @@ RSF list("Deck of cards", 50, /obj/item/deck/cards), list("Prize ticket", 250, /obj/item/stack/tickets/five) ) - update_desc() + update_appearance(UPDATE_DESC) /obj/item/rsf/rff name = "\improper Rapid-Food-Fabricator" @@ -50,7 +50,7 @@ RSF list("Chimichanga", 3000, /obj/item/reagent_containers/food/snacks/chimichanga), list("Ikura sushi", 3000, /obj/item/reagent_containers/food/snacks/sushi_Ikura) ) - update_desc() + update_appearance(UPDATE_DESC) /obj/item/rsf/attackby(obj/item/W as obj, mob/user as mob, params) ..() @@ -72,9 +72,9 @@ RSF else mode++ to_chat(user, "Changed dispensing mode to '" + configured_items[mode][1] + "'") - update_desc() + update_appearance(UPDATE_DESC) -/obj/item/rsf/update_desc() +/obj/item/rsf/update_desc(updates = ALL) . = ..() desc = initial(desc) + " Currently set to dispense '[configured_items[mode][1]]'." diff --git a/code/game/objects/items/weapons/anomaly_extract.dm b/code/game/objects/items/weapons/anomaly_extract.dm index db8ce528f67..3ef0cf4d80d 100644 --- a/code/game/objects/items/weapons/anomaly_extract.dm +++ b/code/game/objects/items/weapons/anomaly_extract.dm @@ -1,3 +1,5 @@ +#define COOLDOWN_TO_SLIMEPERSON (10 SECONDS) +#define COOLDOWN_TO_SLIME_MOB (40 SECONDS) /obj/item/anomaly_extract name = "Strange syringe" desc = "Syringe with a blunt needle." @@ -41,7 +43,7 @@ sound = 'sound/effects/mob_effects/slime_squish.ogg' human_req = FALSE clothes_req = FALSE - base_cooldown = 1 MINUTES + base_cooldown = COOLDOWN_TO_SLIMEPERSON var/is_transformed = FALSE var/mob/living/carbon/human/original_body @@ -84,9 +86,9 @@ /obj/effect/proc_holder/spell/slime_degradation/before_cast(list/targets, mob/user) . = ..() if(is_transformed) - cooldown_handler.recharge_duration = 10 MINUTES + cooldown_handler.recharge_duration = COOLDOWN_TO_SLIME_MOB else - cooldown_handler.recharge_duration = 1 MINUTES + cooldown_handler.recharge_duration = COOLDOWN_TO_SLIMEPERSON /obj/effect/proc_holder/spell/slime_degradation/cast(list/targets, mob/living/carbon/human/user = usr) @@ -142,7 +144,7 @@ var/self_message = death_provoked ? span_userdanger("You can't take the strain of sustaining [user]'s shape in this condition, it begins to fall apart!") : span_notice("You start to transform back into human.") user.visible_message(span_warning("[user] shape becomes fuzzy before it takes human form!"), self_message, span_notice("You hear something squishing...")) if(death_provoked) - cooldown_handler.recharge_duration = 10 MINUTES + cooldown_handler.recharge_duration = COOLDOWN_TO_SLIME_MOB cooldown_handler.start_recharge() playsound(get_turf(usr), sound, 50, TRUE) user.density = FALSE @@ -237,3 +239,6 @@ M.mind.RemoveSpell(/obj/effect/proc_holder/spell/slime_degradation) M.mind.RemoveSpell(/obj/effect/proc_holder/spell/slime_selfheat) . = ..() + +#undef COOLDOWN_TO_SLIMEPERSON +#undef COOLDOWN_TO_SLIME_MOB diff --git a/code/game/objects/items/weapons/cash.dm b/code/game/objects/items/weapons/cash.dm index 02482326efa..0e3ab7cd767 100644 --- a/code/game/objects/items/weapons/cash.dm +++ b/code/game/objects/items/weapons/cash.dm @@ -22,8 +22,7 @@ max_amount = CASHMAX merge_type = /obj/item/stack/spacecash -/obj/item/stack/spacecash/update_icon() - ..() +/obj/item/stack/spacecash/update_icon_state() name = "[amount == CASHMAX ? "[CASHMAX]" : amount] Credit[amount > 1 ? "s" : ""]" switch(amount) if(CASH1 to CASH2 - 1) @@ -114,8 +113,7 @@ ..() update_icon() -/obj/item/stack/spacecash/ussp/update_icon() - ..() +/obj/item/stack/spacecash/ussp/update_icon_state() name = "[amount == CASHMAX ? "[CASHMAX]" : amount] Ruble[amount > 1 ? "s" : ""]" switch(amount) if(CASH1 to CASH2 - 1) diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index 2635469cbb5..02259af200c 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -63,8 +63,8 @@ TED = new(src.loc) qdel(src) -/obj/item/gun/energy/chrono_gun/update_icon() - return +/obj/item/gun/energy/chrono_gun/update_overlays() + return list() /obj/item/gun/energy/chrono_gun/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0) if(field) @@ -123,7 +123,7 @@ icon_state = "chronobolt" range = CHRONO_BEAM_RANGE color = null - nodamage = 1 + nodamage = TRUE var/obj/item/gun/energy/chrono_gun/gun = null /obj/item/projectile/energy/chrono_beam/fire() @@ -177,7 +177,7 @@ cached_icon.Insert(mob_icon, "frame[i]") mob_underlay = mutable_appearance(cached_icon, "frame1") - update_icon() + update_icon(UPDATE_ICON_STATE) desc = initial(desc) + "
    It appears to contain [target.name]." START_PROCESSING(SSobj, src) @@ -191,7 +191,7 @@ /obj/structure/chrono_field/has_prints() return FALSE -/obj/structure/chrono_field/update_icon() +/obj/structure/chrono_field/update_icon_state() var/ttk_frame = 1 - (tickstokill / initial(tickstokill)) ttk_frame = clamp(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) if(ttk_frame != RPpos) @@ -220,7 +220,7 @@ captured.Paralyse(8 SECONDS) if(captured.loc != src) captured.forceMove(src) - update_icon() + update_icon(UPDATE_ICON_STATE) if(gun) if(gun.field_check(src)) tickstokill-- diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index f30408adbf3..be4efb96aa6 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -151,12 +151,6 @@ LIGHTERS ARE IN LIGHTERS.DM light("[user] lights [user.p_their()] [name] with [N]. Someone please give [user.p_their()] zippo..") - //can't think of any other way to update the overlays :< - user.update_inv_wear_mask() - user.update_inv_l_hand() - user.update_inv_r_hand() - - /obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user, proximity) ..() if(!proximity) @@ -172,46 +166,59 @@ LIGHTERS ARE IN LIGHTERS.DM to_chat(user, "[src] is full.") +/obj/item/clothing/mask/cigarette/update_icon_state() + icon_state = lit ? icon_on : icon_off + item_state = lit ? icon_on : initial(item_state) + update_equipped_item() + + +/obj/item/clothing/mask/cigarette/update_name(updates = ALL) + . = ..() + name = lit ? "lit [initial(name)]" : initial(name) + + /obj/item/clothing/mask/cigarette/proc/light(flavor_text = null) - if(!lit) - lit = TRUE - name = "lit [name]" - attack_verb = list("burnt", "singed") - hitsound = 'sound/items/welder.ogg' - damtype = "fire" - force = 4 - if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire - var/datum/effect_system/reagents_explosion/e = new() - e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0) - e.start() - if(ismob(loc)) - var/mob/M = loc - M.temporarily_remove_item_from_inventory(src, force = TRUE) - qdel(src) - return - if(reagents.get_reagent_amount("fuel")) // the fuel explodes, too, but much less violently - var/datum/effect_system/reagents_explosion/e = new() - e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0) - e.start() - if(ismob(loc)) - var/mob/M = loc - M.temporarily_remove_item_from_inventory(src, force = TRUE) - qdel(src) - return - reagents.set_reacting(TRUE) - reagents.handle_reactions() - icon_state = icon_on - item_state = icon_on - if(flavor_text) - var/turf/T = get_turf(src) - T.visible_message(flavor_text) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.wear_mask == src) // Don't update if it's just in their hand - H.wear_mask_update(src) - set_light(2, 0.25, "#E38F46") - START_PROCESSING(SSobj, src) - playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE) + if(lit) + return + + lit = TRUE + attack_verb = list("burnt", "singed") + hitsound = 'sound/items/welder.ogg' + damtype = FIRE + force = 4 + + if(check_reagents_explosion()) + return + + reagents.set_reacting(TRUE) + reagents.handle_reactions() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + if(flavor_text) + var/turf/T = get_turf(src) + T.visible_message(flavor_text) + set_light(2, 0.25, "#E38F46") + START_PROCESSING(SSobj, src) + playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE) + + +/obj/item/clothing/mask/cigarette/proc/check_reagents_explosion() + var/reagent = "" + var/reagent_divisor = 2.5 + if(reagents.get_reagent_amount("plasma")) + reagent = "plasma" + else if(reagents.get_reagent_amount("fuel")) + reagent = "fuel" + reagent_divisor = 5 + if(!reagent) + return FALSE + + var/datum/effect_system/reagents_explosion/explosion = new + explosion.set_up(round(reagents.get_reagent_amount(reagent) / reagent_divisor, 1), get_turf(src), 0, 0) + if(ismob(loc)) + var/mob/user = loc + user.temporarily_remove_item_from_inventory(src, force = TRUE) + qdel(src) + return TRUE /obj/item/clothing/mask/cigarette/process() @@ -403,16 +410,11 @@ LIGHTERS ARE IN LIGHTERS.DM /obj/item/clothing/mask/cigarette/pipe/light(flavor_text = null) if(!lit) lit = TRUE - damtype = "fire" - icon_state = icon_on - item_state = icon_on + damtype = FIRE + update_icon(UPDATE_ICON_STATE) if(flavor_text) var/turf/T = get_turf(src) T.visible_message(flavor_text) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.wear_mask == src) // Don't update if it's just in their hand - H.wear_mask_update(src) START_PROCESSING(SSobj, src) /obj/item/clothing/mask/cigarette/pipe/process() @@ -420,13 +422,11 @@ LIGHTERS ARE IN LIGHTERS.DM smoketime-- if(smoketime < 1) new /obj/effect/decal/cleanable/ash(location) + lit = FALSE + update_icon(UPDATE_ICON_STATE) if(ismob(loc)) var/mob/living/M = loc to_chat(M, "Your [name] goes out, and you empty the ash.") - lit = FALSE - icon_state = icon_off - item_state = icon_off - M.update_inv_wear_mask() STOP_PROCESSING(SSobj, src) return smoke() @@ -435,8 +435,7 @@ LIGHTERS ARE IN LIGHTERS.DM if(lit) user.visible_message("[user] puts out [src].") lit = FALSE - icon_state = icon_off - item_state = icon_off + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) return if(smoketime <= 0) diff --git a/code/game/objects/items/weapons/conversion_kit.dm b/code/game/objects/items/weapons/conversion_kit.dm index 4eb09ff6f6e..98d4fe87dd3 100644 --- a/code/game/objects/items/weapons/conversion_kit.dm +++ b/code/game/objects/items/weapons/conversion_kit.dm @@ -2,20 +2,19 @@ /obj/item/conversion_kit name = "\improper Revolver Conversion Kit" desc = "A professional conversion kit used to convert any knock off revolver into the real deal capable of shooting lethal .357 rounds without the possibility of catastrophic failure." - icon_state = "kit" + icon_state = "kit_0" flags = CONDUCT w_class = WEIGHT_CLASS_SMALL origin_tech = "combat=2" - var/open = 0 + var/open = FALSE -/obj/item/conversion_kit/New() - ..() - update_icon() -/obj/item/conversion_kit/update_icon() - icon_state = "[initial(icon_state)]_[open]" +/obj/item/conversion_kit/update_icon_state() + icon_state = "kit_[open]" + /obj/item/conversion_kit/attack_self(mob/user) open = !open to_chat(user, "You [open ? "open" : "close"] the conversion kit.") - update_icon() + update_icon(UPDATE_ICON_STATE) + diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 68407db2445..03e5bee0d3f 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -58,17 +58,23 @@ colour = pick(lipstick_colors) name = "[colour] lipstick" + +/obj/item/lipstick/update_icon_state() + . = ..() + icon_state = "lipstick[open ? "_uncap" : ""]" + + +/obj/item/lipstick/update_overlays() + . = ..() + if(open) + . += mutable_appearance(icon, icon_state = "lipstick_uncap_color", color = lipstick_colors[colour]) + + /obj/item/lipstick/attack_self(mob/user) - cut_overlays() to_chat(user, "You twist \the [src] [open ? "closed" : "open"].") open = !open - if(open) - var/mutable_appearance/colored = mutable_appearance('icons/obj/items.dmi', "lipstick_uncap_color") - colored.color = lipstick_colors[colour] - icon_state = "lipstick_uncap" - add_overlay(colored) - else - icon_state = "lipstick" + update_icon() + /obj/item/lipstick/attack(mob/M, mob/user) if(!open || !istype(M)) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 0a01992d56f..1c9135d5b50 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -16,43 +16,62 @@ "Vox" = 'icons/mob/clothing/species/vox/back.dmi' ) - var/paddles_on_defib = TRUE //if the paddles are on the defib (TRUE) - var/safety = TRUE //if you can zap people with the defibs on harm mode - var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise + /// If the paddles are currently attached to the unit. + var/paddles_on_defib = TRUE + /// if there's a cell in the defib with enough power for a revive; blocks paddles from reviving otherwise + var/powered = FALSE + /// Ref to attached paddles var/obj/item/twohanded/shockpaddles/paddles + /// Ref to internal power cell. var/obj/item/stock_parts/cell/high/cell = null - var/combat = FALSE //can we revive through space suits? - + /// If false, using harm intent will let you zap people. Note that any updates to this after init will only impact icons. + var/safety = TRUE + /// If true, this can be used through hardsuits, and can cause heart attacks in harm intent. + var/combat = FALSE + // If safety is false and combat is true, the chance that this will cause a heart attack. + var/heart_attack_probability = 30 + /// If this is vulnerable to EMPs. + var/hardened = FALSE + /// If this can be emagged. + var/emag_proof = FALSE /// Type of paddles that should be attached to this defib. var/obj/item/twohanded/shockpaddles/paddle_type = /obj/item/twohanded/shockpaddles -/obj/item/defibrillator/get_cell() - return cell -/obj/item/defibrillator/New() //starts without a cell for rnd - ..() +/obj/item/defibrillator/Initialize(mapload) // Base version starts without a cell for rnd + . = ..() paddles = new paddle_type(src) - update_icon() - return + update_icon(UPDATE_OVERLAYS) -/obj/item/defibrillator/loaded/New() //starts with hicap - ..() + +/obj/item/defibrillator/Destroy() + if(!paddles_on_defib) + var/holder = get(paddles.loc, /mob/living/carbon/human) + retrieve_paddles(holder) + QDEL_NULL(paddles) + QDEL_NULL(cell) + return ..() + + +/obj/item/defibrillator/loaded/Initialize(mapload) // Loaded version starts with high-capacity cell. + . = ..() cell = new(src) - update_icon() - return + update_icon(UPDATE_OVERLAYS) + -/obj/item/defibrillator/update_icon() +/obj/item/defibrillator/get_cell() + return cell + + +/obj/item/defibrillator/update_icon(updates = ALL) update_power() - update_overlays() - update_charge() + ..() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() /obj/item/defibrillator/examine(mob/user) . = ..() - . += "Ctrl-click to remove the paddles from the defibrillator." + . += span_info("Ctrl-Click to remove the paddles from the defibrillator.") + /obj/item/defibrillator/proc/update_power() if(cell) @@ -63,190 +82,176 @@ else powered = FALSE + /obj/item/defibrillator/update_overlays() - overlays.Cut() + . = ..() if(paddles_on_defib) - overlays += "[icon_state]-paddles" + . += "[icon_state]-paddles" if(powered) - overlays += "[icon_state]-powered" - if(!cell) - overlays += "[icon_state]-nocell" + . += "[icon_state]-powered" if(!safety) - overlays += "[icon_state]-emagged" - -/obj/item/defibrillator/proc/update_charge() - if(powered && cell) //so it doesn't show charge if it's unpowered + . += "[icon_state]-emagged" + if(powered && cell) var/ratio = cell.charge / cell.maxcharge ratio = CEILING(ratio*4, 1) * 25 - overlays += "[icon_state]-charge[ratio]" + . += "[icon_state]-charge[ratio]" + if(!cell) + . += "[icon_state]-nocell" + /obj/item/defibrillator/CheckParts(list/parts_list) ..() cell = locate(/obj/item/stock_parts/cell) in contents - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/defibrillator/ui_action_click(mob/user) if(!ishuman(user) || !Adjacent(user)) return - toggle_paddles() + toggle_paddles(user) /obj/item/defibrillator/CtrlClick(mob/user) if(!ishuman(user) || !Adjacent(user)) return - toggle_paddles() + toggle_paddles(user) /obj/item/defibrillator/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stock_parts/cell)) var/obj/item/stock_parts/cell/C = W if(cell) - to_chat(user, "[src] already has a cell.") + to_chat(user, span_notice("[src] already has a cell.")) else if(C.maxcharge < paddles.revivecost) - to_chat(user, "[src] requires a higher capacity cell.") + to_chat(user, span_notice("[src] requires a higher capacity cell.")) return if(!user.drop_transfer_item_to_loc(W, src)) return cell = W - to_chat(user, "You install a cell in [src].") - - else if(istype(W, /obj/item/screwdriver)) - if(cell) - cell.update_icon() - cell.loc = get_turf(loc) - cell = null - to_chat(user, "You remove the cell from the [src].") + update_icon(UPDATE_OVERLAYS) + to_chat(user, span_notice("You install a cell in [src].")) else if(W == paddles) - toggle_paddles() - - update_icon() - return + toggle_paddles(user) -/obj/item/defibrillator/emag_act(mob/user) - if(safety) - add_attack_logs(user, src, "emagged") - safety = FALSE - if(user) - to_chat(user, "You silently disable [src]'s safety protocols with the card.") else - add_attack_logs(user, src, "un-emagged") - safety = TRUE - if(user) - to_chat(user, "You silently enable [src]'s safety protocols with the card.") - update_icon() + return ..() + + +/obj/item/defibrillator/screwdriver_act(mob/living/user, obj/item/I) + if(!cell) + to_chat(user, span_notice("[src] doesn't have a cell.")) + return + + // we want an infinite power cell to stay inside (used in advanced compact defib) + if(istype(cell, /obj/item/stock_parts/cell/infinite)) + to_chat(user, span_notice("[src] somehow resists your attempt to remove a cell.")) + return + + cell.update_icon() + cell.forceMove_turf() + cell = null + I.play_tool_sound(src) + to_chat(user, span_notice("You remove the cell from [src].")) + update_icon(UPDATE_OVERLAYS) + return TRUE /obj/item/defibrillator/emp_act(severity) if(cell) deductcharge(1000 / severity) - if(safety) - safety = FALSE - visible_message("[src] beeps: Safety protocols disabled!") - playsound(get_turf(src), 'sound/machines/defib_saftyoff.ogg', 50, 0) - else - safety = TRUE - visible_message("[src] beeps: Safety protocols enabled!") - playsound(get_turf(src), 'sound/machines/defib_saftyon.ogg', 50, 0) - update_icon() + safety = !safety + update_icon(UPDATE_OVERLAYS) + ..() + +/obj/item/defibrillator/emag_act(mob/user) + add_attack_logs(user, src, "[safety ? "" : "un-"]emagged") + safety = !safety ..() + update_icon(UPDATE_OVERLAYS) -/obj/item/defibrillator/verb/toggle_paddles() +/obj/item/defibrillator/verb/toggle_paddles_verb() set name = "Toggle Paddles" set category = "Object" + set src in oview(1) + toggle_paddles(usr) + + +/obj/item/defibrillator/proc/toggle_paddles(mob/living/carbon/human/user = usr) if(!paddles) - to_chat(usr, span_warning("[src] has no paddles!")) + to_chat(user, span_warning("[src] has no paddles!")) return if(paddles_on_defib) - //Detach the paddles into the user's hands + dispence_paddles(user) + else + retrieve_paddles(user) + + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() - var/mob/living/carbon/human/user = usr - var/obj/item/organ/external/temp2 = user.bodyparts_by_name[BODY_ZONE_PRECISE_R_HAND] - var/obj/item/organ/external/temp = user.bodyparts_by_name[BODY_ZONE_PRECISE_L_HAND] - if(user.incapacitated()) - return +/obj/item/defibrillator/proc/dispence_paddles(mob/living/carbon/human/user) + if(!paddles || !paddles_on_defib || !ishuman(user) || user.incapacitated()) + return - if(!temp || !temp.is_usable() && !temp2 || !temp2.is_usable()) - to_chat(user, span_warning("You can't use your hand to take out the paddles!")) - return + //Detach the paddles into the user's hands + var/obj/item/organ/external/hand_left = user.get_organ(BODY_ZONE_PRECISE_L_HAND) + var/obj/item/organ/external/hand_right = user.get_organ(BODY_ZONE_PRECISE_R_HAND) - if((user.r_hand != null && user.l_hand != null)) - to_chat(user, span_warning("You need a free hand to hold the paddles!")) - return + if((!hand_left || !hand_left.is_usable()) && (!hand_right || !hand_right.is_usable())) + to_chat(user, span_warning("You can't use your hands to take out the paddles!")) + return - //We need to do this like that since defib paddles have their own behavior on dropped() - if(!is_on_user(user)) - paddles.forceMove_turf() + paddles.loc = get_turf(src) // we need this to play animation properly + if(!user.put_in_hands(paddles, ignore_anim = FALSE)) + paddles.loc = src + to_chat(user, span_warning("You need a free hand to hold the paddles!")) + return - if(!user.put_in_hands(paddles, ignore_anim = FALSE)) - paddles.forceMove(src) - to_chat(user, span_warning("You need a free hand to hold the paddles!")) - return + paddles_on_defib = FALSE + paddles.update_icon(UPDATE_ICON_STATE) + update_icon(UPDATE_OVERLAYS) - paddles_on_defib = FALSE - else //remove in any case because some automatic shit - remove_paddles(usr) - update_icon() +/obj/item/defibrillator/proc/retrieve_paddles(mob/user) + if(!paddles || paddles_on_defib) + return + if(user?.is_in_hands(paddles)) + user.drop_item_ground(paddles) + paddles.do_pickup_animation(src) + paddles.forceMove(src) + paddles_on_defib = TRUE + update_icon(UPDATE_OVERLAYS) + paddles.update_icon(UPDATE_ICON_STATE) /obj/item/defibrillator/equipped(mob/user, slot) - ..() + . = ..() if(slot != slot_back) - remove_paddles(user) - update_icon() + retrieve_paddles(user) -/obj/item/defibrillator/item_action_slot_check(slot, mob/user) - if(slot == slot_back) - return TRUE - -/obj/item/defibrillator/proc/remove_paddles(mob/user) // from your hands - if(user.is_in_hands(paddles)) - return user.drop_item_ground(paddles) - return TRUE +/obj/item/defibrillator/item_action_slot_check(slot, mob/user) + return slot == slot_back -/obj/item/defibrillator/Destroy() - if(!paddles_on_defib) - var/M = get(paddles, /mob) - remove_paddles(M) - QDEL_NULL(paddles) - QDEL_NULL(cell) - return ..() -/obj/item/defibrillator/proc/deductcharge(var/chrgdeductamt) +/obj/item/defibrillator/proc/deductcharge(chrgdeductamt) if(cell) if(cell.charge < (paddles.revivecost+chrgdeductamt)) powered = FALSE - update_icon() + update_icon(UPDATE_OVERLAYS) if(cell.use(chrgdeductamt)) - update_icon() + update_icon(UPDATE_OVERLAYS) return TRUE else - update_icon() + update_icon(UPDATE_OVERLAYS) return FALSE -/obj/item/defibrillator/proc/cooldowncheck(var/mob/user) - paddles.update_icon() - spawn(50) - if(cell) - if(cell.charge >= paddles.revivecost) - user.visible_message("[src] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) - else - user.visible_message("[src] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - paddles.cooldown = FALSE - paddles.update_icon() - update_icon() - /obj/item/defibrillator/compact name = "compact defibrillator" desc = "A belt-equipped defibrillator that can be rapidly deployed." @@ -260,11 +265,10 @@ if(slot == slot_belt) return TRUE -/obj/item/defibrillator/compact/loaded/New() - ..() +/obj/item/defibrillator/compact/loaded/Initialize(mapload) + . = ..() cell = new(src) - update_icon() - return + update_icon(UPDATE_OVERLAYS) /obj/item/defibrillator/compact/combat name = "combat defibrillator" @@ -274,12 +278,12 @@ paddle_type = /obj/item/twohanded/shockpaddles/syndicate combat = TRUE safety = FALSE + heart_attack_probability = 100 -/obj/item/defibrillator/compact/combat/loaded/New() - ..() +/obj/item/defibrillator/compact/combat/loaded/Initialize(mapload) + . = ..() cell = new(src) - update_icon() - return + update_icon(UPDATE_OVERLAYS) /obj/item/defibrillator/compact/advanced name = "advanced compact defibrillator" @@ -290,17 +294,21 @@ combat = TRUE safety = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //Objective item, better not have it destroyed. + heart_attack_probability = 10 + var/next_emp_message //to prevent spam from the emagging message on the advanced defibrillator + /obj/item/defibrillator/compact/advanced/attackby(obj/item/W, mob/user, params) if(W == paddles) - toggle_paddles() - update_icon() + toggle_paddles(user) -/obj/item/defibrillator/compact/advanced/loaded/New() - ..() + +/obj/item/defibrillator/compact/advanced/loaded/Initialize(mapload) + . = ..() cell = new /obj/item/stock_parts/cell/infinite(src) - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/item/defibrillator/compact/advanced/emp_act(severity) if(world.time > next_emp_message) @@ -321,11 +329,12 @@ resistance_flags = INDESTRUCTIBLE toolspeed = 1 flags = ABSTRACT - + /// Amount of power used on a shock. var/revivecost = 1000 - var/cooldown = FALSE - var/busy = FALSE + /// Active defib this is connected to. var/obj/item/defibrillator/defib + /// Whether or not the paddles are on cooldown. Used for tracking icon states. + var/on_cooldown = FALSE /obj/item/twohanded/shockpaddles/advanced name = "advanced defibrillator paddles" @@ -339,272 +348,131 @@ icon_state = "syndiepaddles" item_state = "syndiepaddles" + /obj/item/twohanded/shockpaddles/New(mainunit) - ..() - if(check_defib_exists(mainunit, src)) - defib = mainunit - loc = defib - busy = FALSE - update_icon() - return + . = ..() + add_defib_component(mainunit) -/obj/item/twohanded/shockpaddles/proc/spend_charge() +/obj/item/twohanded/shockpaddles/proc/add_defib_component(mainunit) + if(check_defib_exists(mainunit)) + update_icon(UPDATE_ICON_STATE) + AddComponent(/datum/component/defib, actual_unit = defib, combat = defib.combat, safe_by_default = defib.safety, heart_attack_chance = defib.heart_attack_probability, emp_proof = defib.hardened, emag_proof = defib.emag_proof) + else + AddComponent(/datum/component/defib) + RegisterSignal(src, COMSIG_DEFIB_READY, PROC_REF(on_cooldown_expire)) + RegisterSignal(src, COMSIG_DEFIB_SHOCK_APPLIED, PROC_REF(after_shock)) + RegisterSignal(src, COMSIG_DEFIB_PADDLES_APPLIED, PROC_REF(on_application)) + +/obj/item/twohanded/shockpaddles/Destroy() + defib = null + return ..() + +/// Check to see if we should abort this before we've even gotten started +/obj/item/twohanded/shockpaddles/proc/on_application(obj/item/paddles, mob/living/user, mob/living/carbon/human/target, should_cause_harm) + SIGNAL_HANDLER // COMSIG_DEFIB_PADDLES_APPLIED + + if(!HAS_TRAIT(src, TRAIT_WIELDED)) + to_chat(user, "You need to wield the paddles in both hands before you can use them on someone!") + return COMPONENT_BLOCK_DEFIB_MISC + + if(!defib.powered) + return COMPONENT_BLOCK_DEFIB_DEAD + + +/obj/item/twohanded/shockpaddles/proc/on_cooldown_expire(obj/item/paddles) + SIGNAL_HANDLER // COMSIG_DEFIB_READY + on_cooldown = FALSE + if(defib.cell) + if(defib.cell.charge >= revivecost) + defib.visible_message(span_notice("[defib] beeps: Unit ready.")) + playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50) + else + defib.visible_message(span_notice("[defib] beeps: Charge depleted.")) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + update_icon(UPDATE_ICON_STATE) + defib.update_icon(UPDATE_ICON_STATE) + + +/obj/item/twohanded/shockpaddles/proc/after_shock() + SIGNAL_HANDLER // COMSIG_DEFIB_SHOCK_APPLIED + on_cooldown = TRUE defib.deductcharge(revivecost) + update_icon(UPDATE_ICON_STATE) -/obj/item/twohanded/shockpaddles/proc/trigger_cooldown(mob/user) - cooldown = TRUE - defib.cooldowncheck(user) +/obj/item/twohanded/shockpaddles/update_icon_state() + var/is_wielded = HAS_TRAIT(src, TRAIT_WIELDED) + icon_state = "[initial(icon_state)][is_wielded][on_cooldown ? "_cooldown" : ""]" + item_state = "[initial(icon_state)][is_wielded]" -/obj/item/twohanded/shockpaddles/update_icon() - icon_state = "[initial(icon_state)][wielded]" - item_state = "[initial(icon_state)][wielded]" - if(cooldown) - icon_state = "[initial(icon_state)][wielded]_cooldown" /obj/item/twohanded/shockpaddles/suicide_act(mob/user) - user.visible_message("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide.") + user.visible_message(span_suicide("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide.")) defib.deductcharge(revivecost) playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) return OXYLOSS + /obj/item/twohanded/shockpaddles/dropped(mob/user, silent = FALSE) - update_icon() + . = ..() if(defib) - to_chat(user, span_notice("The paddles snap back into the main unit.")) - if(!defib.is_on_user(user)) - do_pickup_animation(defib) - forceMove(defib) - defib.paddles_on_defib = TRUE - defib.update_icon() - else - return ..() + defib.toggle_paddles(user) + if(!silent) + to_chat(user, span_notice("The paddles snap back into the main unit.")) /obj/item/twohanded/shockpaddles/equip_to_best_slot(mob/user, force = FALSE) - user.drop_item_ground(src) + user.drop_item_ground(src) /obj/item/twohanded/shockpaddles/on_mob_move(dir, mob/user) if(defib && !in_range(defib, src)) user.drop_item_ground(src, force = TRUE) -/obj/item/twohanded/shockpaddles/proc/check_defib_exists(mainunit, var/mob/living/carbon/human/M, var/obj/O) - if(!mainunit || !istype(mainunit, /obj/item/defibrillator)) //To avoid weird issues from admin spawns - M.temporarily_remove_item_from_inventory(O, TRUE) - qdel(O) - return FALSE - else - return TRUE - -/obj/item/twohanded/shockpaddles/attack(mob/M, mob/user) - var/tobehealed - var/threshold = -HEALTH_THRESHOLD_DEAD - var/mob/living/carbon/human/H = M - - var/is_combat_borg = FALSE - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - is_combat_borg = istype(R.module, /obj/item/robot_module/syndicate_medical) || istype(R.module, /obj/item/robot_module/ninja) - - var/ignores_hardsuits = defib?.combat || is_combat_borg - - if(busy) - return - if(!isrobot(user) && !defib.powered) - user.visible_message("[defib] beeps: Unit is unpowered.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - return - if(!isrobot(user) && !wielded) - to_chat(user, "You need to wield the paddles in both hands before you can use them on someone!") - return - if(cooldown) - to_chat(user, "[defib || src] is recharging.") - return - if(!ishuman(M)) - if(isrobot(user)) - to_chat(user, "This unit is only designed to work on humanoid lifeforms.") - else - to_chat(user, "The instructions on [defib] don't mention how to revive that...") - return - else - var/can_harm - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - can_harm = R.emagged || is_combat_borg - else - can_harm = !defib.safety - - if(user.a_intent == INTENT_HARM && can_harm) - busy = TRUE - H.visible_message("[user] has touched [H.name] with [src]!", \ - "[user] has touched [H.name] with [src]!") - H.adjustStaminaLoss(50) - H.Weaken(4 SECONDS) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - H.emote("gasp") - if(!H.undergoing_cardiac_arrest() && (prob(10) || defib?.combat)) // Your heart explodes. - H.set_heartattack(TRUE) - H.shock_internal_organs(100) - add_attack_logs(user, M, "Stunned with [src]") - busy = FALSE - spend_charge(user) - trigger_cooldown(user) - return - user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.") - busy = TRUE - if(do_after(user, 30 * toolspeed * gettoolspeedmod(user), target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process - user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") - playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) - var/mob/dead/observer/ghost = H.get_ghost(TRUE) - if(ghost && !ghost.client) - // In case the ghost's not getting deleted for some reason - H.key = ghost.key - log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), src) - - QDEL_NULL(ghost) - var/tplus = world.time - H.timeofdeath - var/tlimit = DEFIB_TIME_LIMIT - var/tloss = DEFIB_TIME_LOSS - if(do_after(user, 20 * toolspeed * gettoolspeedmod(user), target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total - for(var/obj/item/carried_item in H.contents) - if(istype(carried_item, /obj/item/clothing/suit/space)) - if(!ignores_hardsuits) - user.visible_message("[defib || src] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = FALSE - return - if(H.undergoing_cardiac_arrest()) - if(!H.get_int_organ(/obj/item/organ/internal/heart) && !H.get_int_organ(/obj/item/organ/internal/brain/slime)) //prevents defibing someone still alive suffering from a heart attack attack if they lack a heart - user.visible_message("[defib || src] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = FALSE - return - else - var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart) - if(heart.is_dead()) - user.visible_message("[defib || src] buzzes: Resuscitation failed - Heart necrosis detected.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = FALSE - return - H.set_heartattack(FALSE) - H.shock_internal_organs(100) - user.visible_message("[defib || src] pings: Cardiac arrhythmia corrected.") - M.visible_message("[M]'s body convulses a bit.") - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) - busy = FALSE - spend_charge(user) - trigger_cooldown(user) - return - if(H.stat == DEAD) - var/health = H.health - M.visible_message("[M]'s body convulses a bit.") - playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - var/total_cloneloss = H.cloneloss - var/total_bruteloss = 0 - var/total_burnloss = 0 - for(var/obj/item/organ/external/O as anything in H.bodyparts) - total_bruteloss += O.brute_dam - total_burnloss += O.burn_dam - if(total_cloneloss <= 180 && total_bruteloss <= 180 && total_burnloss <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.mind && H.mind.is_revivable()) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime))) - tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you - tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived - H.adjustOxyLoss(tobehealed) - H.adjustToxLoss(tobehealed) - user.visible_message("[defib || src] pings: Resuscitation successful.") - playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) - H.update_revive(TRUE, TRUE) - H.KnockOut() - H.Paralyse(10 SECONDS) - H.emote("gasp") - if(tplus > tloss) - H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) - - if(ishuman(H.pulledby)) // for some reason, pulledby isnt a list despite it being possible to be pulled by multiple people - excess_shock(user, H, H.pulledby) - for(var/obj/item/grab/G in H.grabbed_by) - if(ishuman(G.assailant)) - excess_shock(user, H, G.assailant) - - H.shock_internal_organs(100) - H.med_hud_set_health() - H.med_hud_set_status() - add_attack_logs(user, M, "Revived with [src]") - else - if(tplus > tlimit|| !H.get_int_organ(/obj/item/organ/internal/heart)) - user.visible_message("[defib || src] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.") - else if(total_cloneloss > 180 || total_bruteloss > 180 || total_burnloss > 180) - user.visible_message("[defib || src] buzzes: Resuscitation failed - Severe tissue damage detected.") - else if(ghost) - if(!ghost.can_reenter_corpse) // DNR or AntagHUD - user.visible_message("[defib || src] buzzes: Resucitation failed: No electrical brain activity detected.") - else - user.visible_message("[defib || src] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.") - to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") - window_flash(ghost.client) - ghost << sound('sound/effects/genetics.ogg') - else - user.visible_message("[defib || src] buzzes: Resuscitation failed.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - - spend_charge(user) - trigger_cooldown(user) - else - user.visible_message("[defib || src] buzzes: Patient is not in a valid state. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = FALSE -/* - * user = the person using the defib - * origin = person being revived - * affecting = person being shocked with excess energy from the defib -*/ -/obj/item/twohanded/shockpaddles/proc/excess_shock(mob/user, mob/living/carbon/human/origin, mob/living/carbon/human/affecting) - if(user == affecting) - return - if(electrocute_mob(affecting, defib.cell, origin)) // shock anyone touching them >:) - var/obj/item/organ/internal/heart/HE = affecting.get_organ_slot(INTERNAL_ORGAN_HEART) - if(HE.parent_organ_zone == BODY_ZONE_CHEST && affecting.has_both_hands()) // making sure the shock will go through their heart (drask hearts are in their head), and that they have both arms so the shock can cross their heart inside their chest - affecting.visible_message("[affecting]'s entire body shakes as a shock travels up their arm!", \ - "You feel a powerful shock travel up your [affecting.hand ? affecting.get_organ(BODY_ZONE_L_ARM) : affecting.get_organ(BODY_ZONE_R_ARM)] and back down your [affecting.hand ? affecting.get_organ(BODY_ZONE_L_ARM) : affecting.get_organ(BODY_ZONE_R_ARM)]!") - affecting.set_heartattack(TRUE) +/obj/item/twohanded/shockpaddles/proc/check_defib_exists(obj/item/defibrillator/mainunit) + if(!mainunit || !istype(mainunit)) //To avoid weird issues from admin spawns + qdel(src) + return FALSE + loc = mainunit + defib = mainunit + return TRUE /obj/item/twohanded/shockpaddles/borg desc = "A pair of mounted paddles with flat metal surfaces that are used to deliver powerful electric shocks." icon_state = "defibpaddles0" item_state = "defibpaddles0" - -/obj/item/twohanded/shockpaddles/borg/check_defib_exists() - // No-op. + var/safety = TRUE + var/heart_attack_probability = 10 /obj/item/twohanded/shockpaddles/borg/dropped(mob/user, silent = FALSE) SHOULD_CALL_PARENT(FALSE) // No-op. -/obj/item/twohanded/shockpaddles/borg/spend_charge(mob/user) - var/mob/living/silicon/robot/R = user - R.cell.use(revivecost) - /obj/item/twohanded/shockpaddles/borg/attack_self() // Standard two-handed weapon behavior is disabled. + return -/obj/item/twohanded/shockpaddles/borg/trigger_cooldown(mob/user) - cooldown = TRUE - update_icon() - var/mob/living/silicon/robot/R = user - spawn(50) - if(R.cell.charge >= revivecost) - user.visible_message("[src] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) - else - user.visible_message("[src] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - cooldown = FALSE - update_icon() +/obj/item/twohanded/shockpaddles/borg/add_defib_component(mainunit) + var/is_combat_borg = istype(loc, /obj/item/robot_module/syndicate_medical) || istype(loc, /obj/item/robot_module/ninja) + + AddComponent(/datum/component/defib, robotic = TRUE, combat = is_combat_borg, safe_by_default = safety, emp_proof = TRUE, heart_attack_chance = heart_attack_probability) + + RegisterSignal(src, COMSIG_DEFIB_READY, PROC_REF(on_cooldown_expire)) + RegisterSignal(src, COMSIG_DEFIB_SHOCK_APPLIED, PROC_REF(after_shock)) + +/obj/item/twohanded/shockpaddles/borg/after_shock(obj/item/defib, mob/user) + on_cooldown = TRUE + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + update_icon(UPDATE_ICON_STATE) + +/obj/item/twohanded/shockpaddles/borg/on_cooldown_expire(obj/item/paddles) + visible_message(span_notice("[src] beeps: Defibrillation unit ready.")) + playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) + on_cooldown = FALSE + update_icon(UPDATE_ICON_STATE) + +/obj/item/twohanded/shockpaddles/borg/update_icon_state() + icon_state = "[initial(icon_state)][on_cooldown ? "_cooldown" : ""]" -/obj/item/twohanded/shockpaddles/borg/update_icon() - icon_state = "[initial(icon_state)]" - if(cooldown) - icon_state = "[initial(icon_state)]_cooldown" diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 8e6df9cde26..e7b90a0942c 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -6,25 +6,42 @@ can_hold = list(/obj/item/dice) allow_wrap = FALSE + /obj/item/storage/pill_bottle/dice/populate_contents() + var/special_die = pick("1", "2", "fudge", "00", "100") + if(special_die == "1") + new /obj/item/dice/d1(src) + if(special_die == "2") + new /obj/item/dice/d2(src) new /obj/item/dice/d4(src) new /obj/item/dice/d6(src) + if(special_die == "fudge") + new /obj/item/dice/fudge(src) new /obj/item/dice/d8(src) new /obj/item/dice/d10(src) + if(special_die == "00") + new /obj/item/dice/d00(src) new /obj/item/dice/d12(src) new /obj/item/dice/d20(src) - var/special_die = pick("1","2","fudge","00","100") - switch(special_die) - if("1") - new /obj/item/dice/d1(src) - if("2") - new /obj/item/dice/d2(src) - if("fudge") - new /obj/item/dice/fudge(src) - if("00") - new /obj/item/dice/d00(src) - if("100") - new /obj/item/dice/d100(src) + if(special_die == "100") + new /obj/item/dice/d100(src) + + +/obj/item/storage/box/dice + name = "Коробка игральных костей" + desc = "ЕЩЁ ОДНИ!? ДА БЛЯДЬ!" + icon_state = "box" + + +/obj/item/storage/box/dice/populate_contents() + new /obj/item/dice/d2(src) + new /obj/item/dice/d4(src) + new /obj/item/dice/d8(src) + new /obj/item/dice/d10(src) + new /obj/item/dice/d00(src) + new /obj/item/dice/d12(src) + new /obj/item/dice/d20(src) + /obj/item/storage/pill_bottle/dice/suicide_act(mob/user) user.visible_message("[user] Игра[pluralize_ru(user.gender,"ет","ют")] со смертью! Похоже, он[genderize_ru(user.gender,"","а","о","и")] пыта[pluralize_ru(user.gender,"ется","ются")] покончить жизнь самоубийством!") @@ -44,11 +61,18 @@ var/rigged = DICE_NOT_RIGGED var/rigged_value + /obj/item/dice/Initialize(mapload) . = ..() if(!result) result = roll(sides) - update_icon() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/dice/update_overlays() + . = ..() + . += "[icon_state][result]" + /obj/item/dice/suicide_act(mob/user) user.visible_message("[user] играет со смертью! Похоже [user.p_theyre()] пытается покончить жизнь самоубийством!") @@ -122,8 +146,10 @@ icon_state = "d100" sides = 100 -/obj/item/dice/d100/update_icon() - return + +/obj/item/dice/d100/update_overlays() + return list() + /obj/item/dice/d20/e20 var/triggered = FALSE @@ -151,7 +177,7 @@ comment = "ДВАДЦАТКА!" else if(sides == 20 && result == 1) comment = "М-да, невезуха." - update_icon() + update_icon(UPDATE_OVERLAYS) if(initial(icon_state) == "d00") result = (result - 1) * 10 if(length(special_faces) == sides) @@ -193,20 +219,190 @@ add_attack_logs(user, src, "detonated with a roll of [actual_result]", ATKLOG_FEW) explosion(epicenter, round(result * 0.25), round(result * 0.5), round(result), round(result * 1.5), TRUE, capped, cause = key_name(user)+" E20") -/obj/item/dice/update_icon() - overlays.Cut() - overlays += "[icon_state][result]" -/obj/item/storage/box/dice - name = "Коробка игральных костей" - desc = "ЕЩЁ ОДНИ!? ДА БЛЯДЬ!" - icon_state = "box" +// Die of Fate +/obj/item/dice/d20/fate + name = "\improper Die of Fate" + desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky." + icon_state = "d20" + var/reusable = TRUE + var/used = FALSE + +/obj/item/dice/d20/fate/stealth + name = "d20" + desc = "A die with twenty sides. The preferred die to throw at the GM." + +/obj/item/dice/d20/fate/one_use + reusable = FALSE + +/obj/item/dice/d20/fate/one_use/stealth + name = "d20" + desc = "A die with twenty sides. The preferred die to throw at the GM." + +/obj/item/dice/d20/fate/cursed + name = "cursed Die of Fate" + desc = "A die with twenty sides. You feel that rolling this is a REALLY bad idea." + color = "#00BB00" + + rigged = DICE_TOTALLY_RIGGED + rigged_value = 1 + +/obj/item/dice/d20/fate/diceroll(mob/user) + . = ..() + if(!used) + if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards)) + to_chat(user, "You feel the magic of the dice is restricted to ordinary humans!") + return + + if(!reusable) + used = TRUE + + var/turf/T = get_turf(src) + T.visible_message("[src] flares briefly.") + + addtimer(CALLBACK(src, PROC_REF(effect), user, .), 1 SECONDS) + +/obj/item/dice/d20/fate/equipped(mob/user, slot, initial) + . = ..() + + if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards)) + to_chat(user, "You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.") + user.drop_item_ground(src) + +/obj/item/dice/d20/fate/proc/create_smoke(amount) + var/datum/effect_system/smoke_spread/smoke = new + smoke.set_up(amount, 0, drop_location()) + smoke.start() + +/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user, roll) + var/turf/T = get_turf(src) + switch(roll) + if(1) + //Dust + T.visible_message("[user] turns to dust!") + user.dust() + if(2) + //Death + T.visible_message("[user] suddenly dies!") + user.death() + if(3) + //Swarm of creatures + T.visible_message("A swarm of creatures surround [user]!") + for(var/direction in GLOB.alldirs) + new /mob/living/simple_animal/hostile/netherworld(get_step(get_turf(user),direction)) + if(4) + //Destroy Equipment + T.visible_message("Everything [user] is holding and wearing disappears!") + for(var/obj/item/I in user) + if(istype(I, /obj/item/implant) || istype(I, /obj/item/organ)) + continue + qdel(I) + if(5) + //Monkeying + T.visible_message("[user] transforms into a monkey!") + user.monkeyize() + if(6) + //Cut speed + T.visible_message("[user] starts moving slower!") + var/datum/species/S = user.dna.species + S.speed_mod += 1 + if(7) + //Throw + T.visible_message("Unseen forces throw [user]!") + user.Stun(12 SECONDS) + user.adjustBruteLoss(50) + var/throw_dir = GLOB.cardinal + var/atom/throw_target = get_edge_target_turf(user, throw_dir) + user.throw_at(throw_target, 200, 4) + if(8) + //Fueltank Explosion + T.visible_message("An explosion bursts into existence around [user]!") + explosion(get_turf(user),-1,0,2, flame_range = 2, cause = src) + if(9) + //Cold + T.visible_message("[user] looks a little under the weather!") + var/datum/disease/virus/cold/D = new + D.Contract(user) + if(10) + //Nothing + T.visible_message("Nothing seems to happen.") + if(11) + //Cookie + T.visible_message("A cookie appears out of thin air!") + var/obj/item/reagent_containers/food/snacks/cookie/C = new(drop_location()) + create_smoke(2) + C.name = "Cookie of Fate" + if(12) + //Healing + T.visible_message("[user] looks very healthy!") + user.revive() + if(13) + //Mad Dosh + T.visible_message("Mad dosh shoots out of [src]!") + var/turf/Start = get_turf(src) + for(var/direction in GLOB.alldirs) + var/turf/dirturf = get_step(Start,direction) + if(rand(0,1)) + new /obj/item/stack/spacecash/c1000(dirturf) + else + var/obj/item/storage/bag/money/M = new(dirturf) + for(var/i in 1 to rand(5,50)) + new /obj/item/coin/gold(M) + if(14) + //Free Gun + T.visible_message("An impressive gun appears!") + create_smoke(2) + new /obj/item/gun/projectile/revolver/mateba(drop_location()) + if(15) + //Random One-use spellbook + T.visible_message("A magical looking book drops to the floor!") + create_smoke(2) + new /obj/item/spellbook/oneuse/random(drop_location()) + if(16) + //Servant & Servant Summon + T.visible_message("A Dice Servant appears in a cloud of smoke!") + var/mob/living/carbon/human/H = new(drop_location()) + create_smoke(2) + + H.equipOutfit(/datum/outfit/butler) + var/datum/mind/servant_mind = new /datum/mind() + var/datum/objective/O = new + O.owner = servant_mind + O.target = user.mind + O.explanation_text = "Serve [user.real_name]." + servant_mind.objectives += O + servant_mind.transfer_to(H) + + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 30 SECONDS, source = H) + if(LAZYLEN(candidates)) + var/mob/dead/observer/C = pick(candidates) + message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") + H.key = C.key + to_chat(H, "You are a servant of [user.real_name]. You must do everything in your power to follow their orders.") + + var/obj/effect/proc_holder/spell/summonmob/S = new + S.target_mob = H + user.mind.AddSpell(S) + + if(17) + //Tator Kit + T.visible_message("A suspicious box appears!") + new /obj/item/storage/box/syndicate(drop_location()) + create_smoke(2) + if(18) + //Captain ID + T.visible_message("A golden identification card appears!") + new /obj/item/card/id/captains_spare(drop_location()) + create_smoke(2) + if(19) + //Instrinct Resistance + T.visible_message("[user] looks very robust!") + var/datum/species/S = user.dna.species + S.brute_mod *= 0.5 + S.burn_mod *= 0.5 + + if(20) + //Free wizard! + T.visible_message("Magic flows out of [src] and into [user]!") + user.mind.make_Wizard() -/obj/item/storage/box/dice/populate_contents() - new /obj/item/dice/d2(src) - new /obj/item/dice/d4(src) - new /obj/item/dice/d8(src) - new /obj/item/dice/d10(src) - new /obj/item/dice/d00(src) - new /obj/item/dice/d12(src) - new /obj/item/dice/d20(src) diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index a6a59400212..c2113a08ee8 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -33,6 +33,16 @@ QDEL_NULL(buf) return ..() + +/obj/item/dnainjector/update_icon_state() + icon_state = "[initial(icon_state)][used ? "0" : ""]" + + +/obj/item/dnainjector/update_desc(updates = ALL) + . = ..() + desc = used ? "[initial(desc)] This one is used up." : initial(desc) + + /obj/item/dnainjector/proc/GetRealBlock(selblock) if(selblock == 0) return block @@ -67,51 +77,62 @@ else return buf.dna.SetUIValue(real_block,val) -/obj/item/dnainjector/proc/inject(mob/living/M, mob/user) + +/obj/item/dnainjector/proc/inject(mob/living/carbon/human/target, mob/user) if(used) return - if(isliving(M)) - M.apply_effect(rand(20 / (damage_coeff ** 2), 50 / (damage_coeff ** 2)), IRRADIATE, 0, 1) - var/mob/living/carbon/human/H - if(ishuman(M)) - H = M + + if(isliving(target)) + target.apply_effect(rand(20 / (damage_coeff ** 2), 50 / (damage_coeff ** 2)), IRRADIATE, 0, 1) + + if(!ishuman(target)) + return if(!buf) - log_runtime(EXCEPTION("[src] used by [user] on [M] failed to initialize properly."), src) + log_runtime(EXCEPTION("[src] used by [user] on [target] failed to initialize properly."), src) return used = TRUE - icon_state = "[icon_state]0" - desc += " This one is used up." - - spawn(0) //Some mutations have sleeps in them, like monkey - if(!(NOCLONE in M.mutations) && !(H && (NO_DNA in H.dna.species.species_traits))) // prevents drained people from having their DNA changed - var/prev_ue = M.dna.unique_enzymes - // UI in syringe. - if(buf.types & DNA2_BUF_UI) - if(!block) //isolated block? - M.dna.UI = buf.dna.UI.Copy() - M.dna.UpdateUI() - M.UpdateAppearance() - if(buf.types & DNA2_BUF_UE) //unique enzymes? yes - - M.real_name = buf.dna.real_name - M.name = buf.dna.real_name - M.dna.real_name = buf.dna.real_name - M.dna.unique_enzymes = buf.dna.unique_enzymes - else - M.dna.SetUIValue(block,src.GetValue()) - M.UpdateAppearance() - if(buf.types & DNA2_BUF_SE) - if(!block) //isolated block? - M.dna.SE = buf.dna.SE.Copy() - M.dna.UpdateSE() - else - M.dna.SetSEValue(block,src.GetValue()) - domutcheck(M, null, forcedmutation ? MUTCHK_FORCED : 0) - M.update_mutations() - if(H) - H.sync_organ_dna(assimilate = 0, old_ue = prev_ue) + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + INVOKE_ASYNC(src, PROC_REF(async_update), target) //Some mutations have sleeps in them, like monkey + + +/obj/item/dnainjector/proc/async_update(mob/living/carbon/human/target) + // prevents drained people from having their DNA changed + if(!target.dna || (NOCLONE in target.mutations) || (NO_DNA in target.dna.species.species_traits)) + return + + var/datum/dna/target_dna = target.dna + var/prev_UE = target_dna.unique_enzymes + + // UI in syringe + if(buf.types & DNA2_BUF_UI) + if(!block) //isolated block? + target_dna.UI = buf.dna.UI.Copy() + target_dna.UpdateUI() + target.UpdateAppearance() + + if(buf.types & DNA2_BUF_UE) //unique enzymes? yes + target.real_name = buf.dna.real_name + target.name = buf.dna.real_name + target_dna.real_name = buf.dna.real_name + target_dna.unique_enzymes = buf.dna.unique_enzymes + else + target_dna.SetUIValue(block, GetValue()) + target.UpdateAppearance() + + // SE in syringe + if(buf.types & DNA2_BUF_SE) + if(!block) //isolated block? + target_dna.SE = buf.dna.SE.Copy() + target_dna.UpdateSE() + else + target_dna.SetSEValue(block, GetValue()) + domutcheck(target, null, forcedmutation ? MUTCHK_FORCED : NONE) + target.update_mutations() + + target.sync_organ_dna(assimilate = FALSE, old_ue = prev_UE) + /obj/item/dnainjector/attack(mob/M, mob/user) if(used) diff --git a/code/game/objects/items/weapons/dna_upgrader.dm b/code/game/objects/items/weapons/dna_upgrader.dm index 3ca2bf1cdb4..4821d4d498c 100644 --- a/code/game/objects/items/weapons/dna_upgrader.dm +++ b/code/game/objects/items/weapons/dna_upgrader.dm @@ -13,6 +13,16 @@ icon_state = "dnaupgrader" var/used = FALSE + +/obj/item/dna_upgrader/update_icon_state() + icon_state = "dnaupgrader[used ? "0" : ""]" + + +/obj/item/dna_upgrader/update_name(updates = ALL) + . = ..() + name = used ? "used [initial(name)]" : initial(name) + + /obj/item/dna_upgrader/attack_self(mob/user) if(!used) ui_interact(user) @@ -79,7 +89,7 @@ H.gene_stability += 25 to_chat(H, span_notice("You feel like your body rebasing.")) used = TRUE - icon_state = "[icon_state]0" + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) return TRUE #undef VAULT_TOXIN diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm index 1dcc4a942c2..cefe9f7abc8 100644 --- a/code/game/objects/items/weapons/dnascrambler.dm +++ b/code/game/objects/items/weapons/dnascrambler.dm @@ -4,15 +4,22 @@ icon = 'icons/obj/hypo.dmi' item_state = "syringe_0" icon_state = "lepopen" - var/used = null + var/used = FALSE -/obj/item/dnascrambler/update_icon() + +/obj/item/dnascrambler/update_icon_state() if(used) icon_state = "lepopen0" else icon_state = "lepopen" -/obj/item/dnascrambler/attack(mob/M as mob, mob/user as mob) + +/obj/item/dnascrambler/update_name(updates = ALL) + . = ..() + name = used ? "used [initial(name)]" : initial(name) + + +/obj/item/dnascrambler/attack(mob/M, mob/user) if(!M || !user) return @@ -53,6 +60,6 @@ target.update_icons() add_attack_logs(user, target, "injected with [src]") - used = 1 - update_icon() - name = "used " + name + used = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index e2478d00882..edf464fd696 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -4,89 +4,108 @@ icon_state = "plastic-explosive0" item_state = "plastic-explosive" flags = NOBLUDGEON - det_time = 10 + det_time = 10 SECONDS display_timer = 0 origin_tech = "syndicate=1" toolspeed = 1 - var/atom/target = null - var/image_overlay = null - var/obj/item/assembly_holder/nadeassembly = null + var/atom/target + var/image_overlay + var/obj/item/assembly_holder/nadeassembly var/assemblyattacher var/notify_admins = TRUE -/obj/item/grenade/plastic/New() + +/obj/item/grenade/plastic/Initialize(mapload) + . = ..() image_overlay = image('icons/obj/weapons/grenade.dmi', "[item_state]2") - ..() + /obj/item/grenade/plastic/Destroy() QDEL_NULL(nadeassembly) target = null return ..() + /obj/item/grenade/plastic/attackby(obj/item/I, mob/user, params) if(!nadeassembly && istype(I, /obj/item/assembly_holder)) - var/obj/item/assembly_holder/A = I - if(!user.drop_item_ground(I)) + var/obj/item/assembly_holder/assembly_holder = I + if(!user.drop_transfer_item_to_loc(I, src)) return ..() - nadeassembly = A - A.master = src - A.loc = src + nadeassembly = assembly_holder + assembly_holder.master = src assemblyattacher = user.ckey - to_chat(user, "You add [A] to the [name].") + to_chat(user, "You add [assembly_holder] to the [name].") playsound(src, 'sound/weapons/tap.ogg', 20, 1) - update_icon() + update_icon(UPDATE_ICON_STATE) return - if(nadeassembly && istype(I, /obj/item/wirecutters)) + if(nadeassembly && I.tool_behaviour == TOOL_WIRECUTTER) playsound(src, I.usesound, 20, 1) - nadeassembly.loc = get_turf(src) + nadeassembly.forceMove_turf() nadeassembly.master = null nadeassembly = null - update_icon() + update_icon(UPDATE_ICON_STATE) return ..() + //assembly stuff /obj/item/grenade/plastic/receive_signal() prime() + /obj/item/grenade/plastic/Crossed(atom/movable/AM, oldloc) if(nadeassembly) nadeassembly.Crossed(AM, oldloc) + /obj/item/grenade/plastic/on_found(mob/finder) if(nadeassembly) nadeassembly.on_found(finder) + /obj/item/grenade/plastic/attack_self(mob/user) if(nadeassembly) nadeassembly.attack_self(user) return - var/newtime = input(usr, "Please set the timer.", "Timer", det_time) as num + var/newtime = input(usr, "Please set the timer (in seconds).", "Timer", det_time/10) as null|num + if(isnull(newtime)) + return if(user.is_in_active_hand(src)) - newtime = clamp(newtime, initial(det_time), 60000) - det_time = newtime - to_chat(user, "Timer set for [det_time] seconds.") + newtime = round(newtime) + det_time = clamp(newtime SECONDS, initial(det_time), 10 MINUTES) + to_chat(user, "Timer set for [newtime] seconds.") + + /obj/item/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag) - if (!flag) + if(!flag) + return + if(iscarbon(AM)) + to_chat(user, "You can't get the [src] to stick to [AM]!") return - if (istype(AM, /mob/living/carbon)) + if(isobserver(AM)) + to_chat(user, "Your hand just phases through [AM]!") return - to_chat(user, "You start planting the [src]. The timer is set to [det_time]...") - - if(do_after(user, 50 * toolspeed * gettoolspeedmod(user), target = AM)) - if(!user.drop_item_ground(src)) - return - src.target = AM - loc = null - if(notify_admins) - message_admins("[ADMIN_LOOKUPFLW(user)] planted [src.name] on [target.name] at [ADMIN_COORDJMP(target)] with [det_time] second fuse") - add_game_logs("planted [name] on [target.name] at [COORD(target)] with [det_time] second fuse", user) - - target.overlays += image_overlay - if(!nadeassembly) - to_chat(user, "You plant the bomb. Timer counting down from [det_time].") - addtimer(CALLBACK(src, PROC_REF(prime)), det_time*10) + to_chat(user, "You start planting [src].[isnull(nadeassembly) ? " The timer is set to [det_time/10]..." : ""]") + + if(!do_after(user, 50 * toolspeed * gettoolspeedmod(user), target = AM)) + return + + if(!user.drop_item_ground(src)) + return + + target = AM + do_pickup_animation(AM) + loc = null + if(notify_admins) + message_admins("[ADMIN_LOOKUPFLW(user)] planted [src.name] on [target.name] at [ADMIN_COORDJMP(target)] with [det_time/10] second fuse") + add_game_logs("planted [name] on [target.name] at [COORD(target)] with [det_time/10] second fuse", user) + + AddComponent(/datum/component/persistent_overlay, image_overlay, target) + if(!nadeassembly) + to_chat(user, "You plant the bomb. Timer counting down from [det_time/10].") + addtimer(CALLBACK(src, PROC_REF(prime)), det_time) + /obj/item/grenade/plastic/suicide_act(mob/user) message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src.name] at [ADMIN_COORDJMP(user)]") @@ -119,12 +138,14 @@ user.gib() return OBLITERATION -/obj/item/grenade/plastic/update_icon() + +/obj/item/grenade/plastic/update_icon_state() if(nadeassembly) icon_state = "[item_state]1" else icon_state = "[item_state]0" + ////////////////////////// ///// The Explosives ///// ////////////////////////// @@ -145,7 +166,6 @@ location = get_turf(target) // Set the explosion location to turf if planted directly on a wall or floor else location = get_atom_on_turf(target) // Otherwise, make sure we're blowing up what's on top of the turf - target.overlays -= image_overlay else location = get_atom_on_turf(src) if(location) @@ -250,7 +270,7 @@ /obj/item/grenade/plastic/x4/thermite name = "T4" desc = "A wall breaching charge, containing fuel, metal oxide and metal powder mixed in just the right way. One hell of a combination. Effective against walls, ineffective against airlocks..." - det_time = 2 + det_time = 2 SECONDS icon_state = "t4breach0" item_state = "t4breach" @@ -259,7 +279,6 @@ if(target) if(!QDELETED(target)) location = get_turf(target) - target.overlays -= image_overlay else location = get_turf(src) if(location) @@ -268,7 +287,7 @@ if(target && target.density) var/turf/T = get_step(location, aim_dir) for(var/turf/simulated/wall/W in range(1, location)) - W.thermitemelt(speed = 30) + W.thermitemelt(time = 3 SECONDS) addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, 0, 2), 3) addtimer(CALLBACK(smoke, TYPE_PROC_REF(/datum/effect_system/smoke_spread, start)), 3) else @@ -276,7 +295,6 @@ addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, 0, 2), 3) addtimer(CALLBACK(smoke, TYPE_PROC_REF(/datum/effect_system/smoke_spread, start)), 3) - if(isliving(target)) var/mob/living/M = target M.adjust_fire_stacks(2) diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 5e41af4e072..602e834f465 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -40,21 +40,34 @@ sprite_name = "miniFE" dog_fashion = null + +/obj/item/extinguisher/Initialize(mapload) + . = ..() + if(!reagents) + create_reagents(max_water) + reagents.add_reagent("water", max_water) + + /obj/item/extinguisher/examine(mob/user) . = ..() . += "The safety is [safety ? "on" : "off"]." -/obj/item/extinguisher/New() - ..() - create_reagents(max_water) - reagents.add_reagent("water", max_water) + +/obj/item/extinguisher/update_icon_state() + icon_state = "[sprite_name][!safety]" + + +/obj/item/extinguisher/update_desc(updates = ALL) + . = ..() + desc = "The safety is [safety ? "on" : "off"]." + + /obj/item/extinguisher/attack_self(mob/user as mob) safety = !safety - src.icon_state = "[sprite_name][!safety]" - src.desc = "The safety is [safety ? "on" : "off"]." + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) to_chat(user, "The safety is [safety ? "on" : "off"].") - return + /obj/item/extinguisher/attack_obj(obj/O, mob/living/user, params) if(AttemptRefill(O, user)) diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index ca0f4756b24..3a02ab76dd3 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -48,21 +48,25 @@ igniter.flamethrower_process(location) -/obj/item/flamethrower/update_icon() - cut_overlays() +/obj/item/flamethrower/update_icon(updates = ALL) + . = ..() + update_equipped_item() + + + +/obj/item/flamethrower/update_icon_state() + item_state = "flamethrower_[lit]" + + +/obj/item/flamethrower/update_overlays() + . = ..() if(igniter) - add_overlay("+igniter[status]") + . += "+igniter[status]" if(ptank) - add_overlay("+ptank") + . += "+ptank" if(lit) - add_overlay("+lit") - item_state = "flamethrower_1" - else - item_state = "flamethrower_0" - if(ismob(loc)) - var/mob/M = loc - M.update_inv_l_hand() - M.update_inv_r_hand() + . += "+lit" + /obj/item/flamethrower/can_enter_storage(obj/item/storage/S, mob/user) if(lit) diff --git a/code/game/objects/items/weapons/garrote.dm b/code/game/objects/items/weapons/garrote.dm index 132ec7649fa..09b93ee0444 100644 --- a/code/game/objects/items/weapons/garrote.dm +++ b/code/game/objects/items/weapons/garrote.dm @@ -19,12 +19,11 @@ strangling = null return ..() -/obj/item/twohanded/garrote/update_icon() +/obj/item/twohanded/garrote/update_icon_state() if(strangling) // If we're strangling someone we want our icon to stay wielded icon_state = "garrot_unwrap" return - - icon_state = "garrot_[wielded ? "un" : ""]wrap" + icon_state = "garrot_[HAS_TRAIT(src, TRAIT_WIELDED) ? "un" : ""]wrap" /obj/item/twohanded/garrote/improvised // Made via tablecrafting name = "garrote" @@ -32,12 +31,11 @@ icon_state = "garrot_I_wrap" improvised = 1 -/obj/item/twohanded/garrote/improvised/update_icon() +/obj/item/twohanded/garrote/improvised/update_icon_state() if(strangling) icon_state = "garrot_I_unwrap" return - - icon_state = "garrot_I_[wielded ? "un" : ""]wrap" + icon_state = "garrot_I_[HAS_TRAIT(src, TRAIT_WIELDED) ? "un" : ""]wrap" /obj/item/twohanded/garrote/unwield(obj/item/source, mob/living/carbon/user) @@ -46,7 +44,7 @@ "You remove the [src] from [strangling]'s neck.") strangling.garroted_by.Remove(src) strangling = null - update_icon() + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) @@ -102,7 +100,7 @@ garrote_time = world.time + 10 START_PROCESSING(SSobj, src) strangling = M - update_icon() + update_icon(UPDATE_ICON_STATE) playsound(src.loc, 'sound/weapons/cablecuff.ogg', 15, 1, -1) @@ -110,19 +108,18 @@ "[U] begins garroting you with the [src]![improvised ? "" : " You are unable to speak!"]", \ "You hear struggling and wire strain against flesh!") - return /obj/item/twohanded/garrote/process() if(!strangling) // Our mark got gibbed or similar - update_icon() + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) return if(!istype(loc, /mob/living/carbon/human)) strangling = null - update_icon() + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) return @@ -141,7 +138,7 @@ strangling.garroted_by.Remove(src) strangling = null - update_icon() + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) return @@ -152,7 +149,7 @@ strangling.garroted_by.Remove(src) strangling = null - update_icon() + update_icon(UPDATE_ICON_STATE) STOP_PROCESSING(SSobj, src) return diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 2291671194d..649897ee351 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -42,7 +42,7 @@ /obj/effect/spresent/attackby(obj/item/W as obj, mob/user as mob, params) ..() - if(!istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour != TOOL_WIRECUTTER) to_chat(user, "I need wirecutters for that.") return diff --git a/code/game/objects/items/weapons/grenades/bananade.dm b/code/game/objects/items/weapons/grenades/bananade.dm index ea2cbc5f6cf..6c954b8c497 100644 --- a/code/game/objects/items/weapons/grenades/bananade.dm +++ b/code/game/objects/items/weapons/grenades/bananade.dm @@ -45,7 +45,7 @@ qdel(I) else to_chat(usr, "The bananade is full, screwdriver it shut to lock it down.") - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) if(fillamt) var/obj/item/grenade/bananade/G = new /obj/item/grenade/bananade(drop_location()) if(!remove_item_from_storage(user)) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index ffa8a8b4b5f..15fec3a3187 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -25,22 +25,26 @@ var/contained = "" // For logging var/cores = "" // Also for logging -/obj/item/grenade/chem_grenade/New() - ..() + +/obj/item/grenade/chem_grenade/Initialize(mapload) + . = ..() create_reagents(1000) if(payload_name) payload_name += " " // formatting, ignore me update_icon() + /obj/item/grenade/chem_grenade/Destroy() QDEL_NULL(nadeassembly) if (!no_splash) QDEL_LIST(beakers) return ..() + /obj/item/grenade/chem_grenade/examine(mob/user) - . = ..() display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state + . = ..() + /obj/item/grenade/chem_grenade/proc/get_trigger() if(!nadeassembly) return null @@ -49,21 +53,11 @@ return O return null -/obj/item/grenade/chem_grenade/update_overlays() - underlays = list() - if(nadeassembly) - underlays += "[nadeassembly.a_left.icon_state]_left" - for(var/O in nadeassembly.a_left.attached_overlays) - underlays += "[O]_l" - underlays += "[nadeassembly.a_right.icon_state]_right" - for(var/O in nadeassembly.a_right.attached_overlays) - underlays += "[O]_r" -/obj/item/grenade/chem_grenade/update_icon() +/obj/item/grenade/chem_grenade/update_icon_state() if(nadeassembly) icon = 'icons/obj/assemblies/new_assemblies.dmi' icon_state = bomb_state - update_overlays() var/obj/item/assembly/A = get_trigger() if(stage != READY) name = "bomb casing[label]" @@ -75,7 +69,6 @@ else icon = 'icons/obj/weapons/grenade.dmi' icon_state = initial(icon_state) - overlays = list() switch(stage) if(EMPTY) name = "grenade casing[label]" @@ -89,12 +82,21 @@ icon_state += "_locked" name = payload_name + "grenade" + label + underlays.Cut() + if(nadeassembly) + underlays += "[nadeassembly.a_left.icon_state]_left" + for(var/O in nadeassembly.a_left.attached_overlays) + underlays += "[O]_l" + underlays += "[nadeassembly.a_right.icon_state]_right" + for(var/O in nadeassembly.a_right.attached_overlays) + underlays += "[O]_r" + /obj/item/grenade/chem_grenade/attack_self(mob/user) if(stage == READY && !active) if(nadeassembly) nadeassembly.attack_self(user) - update_icon() + update_icon(UPDATE_ICON_STATE) else if(clown_check(user)) // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. investigate_log("[key_name_log(usr)] has primed a [name] for detonation [contained].", INVESTIGATE_BOMB) @@ -127,38 +129,9 @@ else if(label) label = null - update_icon() + update_icon(UPDATE_ICON_STATE) to_chat(user, "You remove the label from [src].") return 1 - if(istype(I, /obj/item/screwdriver)) - if(stage == WIRED) - if(beakers.len) - to_chat(user, "You lock the assembly.") - playsound(loc, prime_sound, 25, -3) - stage = READY - update_icon() - contained = "" - cores = "" // clear them out so no recursive logging by accidentally - for(var/obj/O in beakers) - if(!O.reagents) continue - if(istype(O,/obj/item/slime_extract)) - cores += " [O]" - for(var/R in O.reagents.reagent_list) - var/datum/reagent/reagent = R - contained += "[reagent.volume] [reagent], " - if(contained) - if(cores) - contained = "\[[cores]; [contained]\]" - else - contained = "\[ [contained]\]" - add_attack_logs(user, src, "has completed with [contained]", ATKLOG_FEW) - else - to_chat(user, "You need to add at least one beaker before locking the assembly.") - else if(stage == READY && !nadeassembly) - det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50 - to_chat(user, "You modify the time delay. It's set for [det_time / 10] second\s.") - else if(stage == EMPTY) - to_chat(user, "You need to add an activation mechanism.") else if(stage == WIRED && is_type_in_list(I, allowed_containers)) if(beakers.len == 2) @@ -187,7 +160,7 @@ assemblyattacher = user.ckey stage = WIRED to_chat(user, "You add [A] to [src]!") - update_icon() + update_icon(UPDATE_ICON_STATE) else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/C = I @@ -195,14 +168,14 @@ stage = WIRED to_chat(user, "You rig [src].") - update_icon() + update_icon(UPDATE_ICON_STATE) - else if(stage == READY && istype(I, /obj/item/wirecutters)) + else if(stage == READY && I.tool_behaviour == TOOL_WIRECUTTER) to_chat(user, "You unlock the assembly.") stage = WIRED - update_icon() + update_icon(UPDATE_ICON_STATE) - else if(stage == WIRED && istype(I, /obj/item/wrench)) + else if(stage == WIRED && I.tool_behaviour == TOOL_WRENCH) to_chat(user, "You open the grenade and remove the contents.") stage = EMPTY payload_name = null @@ -218,7 +191,47 @@ for(var/obj/O in beakers) O.loc = get_turf(src) beakers = list() - update_icon() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/grenade/chem_grenade/screwdriver_act(mob/living/user, obj/item/I) + if(stage == WIRED) + if(!length(beakers)) + to_chat(user, "You need to add at least one beaker before locking the assembly.") + return TRUE + + to_chat(user, "You lock the assembly.") + playsound(loc, prime_sound, 25, -3) + stage = READY + update_icon(UPDATE_ICON_STATE) + contained = "" + cores = "" // clear them out so no recursive logging by accidentally + for(var/obj/O in beakers) + if(!O.reagents) + continue + if(istype(O, /obj/item/slime_extract)) + cores += " [O]" + for(var/R in O.reagents.reagent_list) + var/datum/reagent/reagent = R + contained += "[reagent.volume] [reagent], " + if(contained) + if(cores) + contained = "\[[cores]; [contained]\]" + else + contained = "\[ [contained]\]" + var/turf/bombturf = get_turf(loc) + add_attack_logs(user, src, "has completed with [contained]", ATKLOG_MOST) + log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z]. [contained]") + return TRUE + + else if(stage == READY && !nadeassembly) + det_time = det_time == 5 SECONDS ? 3 SECONDS : 5 SECONDS + to_chat(user, "You modify the time delay. It's set for [det_time / 10] second\s.") + return TRUE + + else if(stage == EMPTY) + to_chat(user, "You need to add an activation mechanism.") + return TRUE //assembly stuff @@ -281,7 +294,7 @@ O.forceMove(get_turf(src)) beakers = list() stage = EMPTY - update_icon() + update_icon(UPDATE_ICON_STATE) return if(nadeassembly) @@ -430,8 +443,9 @@ desc = "Used for emergency sealing of air breaches." stage = READY -/obj/item/grenade/chem_grenade/metalfoam/New() - ..() +/obj/item/grenade/chem_grenade/metalfoam/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -441,7 +455,7 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/firefighting @@ -449,8 +463,9 @@ desc = "Can help to put out dangerous fires from a distance." stage = READY -/obj/item/grenade/chem_grenade/firefighting/New() - ..() +/obj/item/grenade/chem_grenade/firefighting/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -459,15 +474,16 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/incendiary payload_name = "incendiary" desc = "Used for clearing rooms of living things." stage = READY -/obj/item/grenade/chem_grenade/incendiary/New() - ..() +/obj/item/grenade/chem_grenade/incendiary/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -478,7 +494,7 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/antiweed @@ -486,8 +502,9 @@ desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents." stage = READY -/obj/item/grenade/chem_grenade/antiweed/New() - ..() +/obj/item/grenade/chem_grenade/antiweed/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -499,7 +516,7 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/cleaner @@ -507,8 +524,9 @@ desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas." stage = READY -/obj/item/grenade/chem_grenade/cleaner/New() - ..() +/obj/item/grenade/chem_grenade/cleaner/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -518,7 +536,7 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/teargas @@ -526,8 +544,9 @@ desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents." stage = READY -/obj/item/grenade/chem_grenade/teargas/New() - ..() +/obj/item/grenade/chem_grenade/teargas/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -539,15 +558,16 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/facid payload_name = "acid smoke" desc = "Use to chew up opponents from the inside out." stage = READY -/obj/item/grenade/chem_grenade/facid/New() - ..() +/obj/item/grenade/chem_grenade/facid/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -559,15 +579,16 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/chem_grenade/saringas payload_name = "sarin gas" desc = "Contains sarin gas; extremely deadly and fast acting; use with extreme caution." stage = READY -/obj/item/grenade/chem_grenade/saringas/New() - ..() +/obj/item/grenade/chem_grenade/saringas/Initialize(mapload) + . = ..() + var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -579,7 +600,7 @@ beakers += B1 beakers += B2 - update_icon() + update_icon(UPDATE_ICON_STATE) #undef EMPTY #undef WIRED diff --git a/code/game/objects/items/weapons/grenades/custom_grenades.dm b/code/game/objects/items/weapons/grenades/custom_grenades.dm index 3cb0be484b0..41d473d0411 100644 --- a/code/game/objects/items/weapons/grenades/custom_grenades.dm +++ b/code/game/objects/items/weapons/grenades/custom_grenades.dm @@ -39,7 +39,7 @@ payload_name = "holy water" desc = "Then shalt thou count to three, no more, no less." stage = 2 - det_time = 30 + det_time = 3 SECONDS /obj/item/grenade/chem_grenade/holywater/New() ..() @@ -51,7 +51,7 @@ payload_name = "hell water" desc = "And he struck them down with an unholy fury that burn like one-thousands badmins." stage = 2 - det_time = 30 + det_time = 3 SECONDS /obj/item/grenade/chem_grenade/hellwater/New() ..() diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 10488d8e01e..681bb8edf63 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -78,9 +78,8 @@ if(istype(ears)) ears.receive_damage(5) if(ears.damage >= 15) - to_chat(M, "Your ears start to ring badly!") + to_chat(M, span_warning("Your ears start to ring badly!")) if(prob(ears.damage - 5)) - to_chat(M, "You can't hear anything!") - M.BecomeDeaf() + to_chat(M, span_warning("You can't hear anything!")) else if(ears.damage >= 5) - to_chat(M, "Your ears start to ring!") + to_chat(M, span_warning("Your ears start to ring!")) diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index 09ce7f8f6e0..31da0cf28e6 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -12,7 +12,7 @@ flags = CONDUCT slot_flags = SLOT_BELT active = 0 - det_time = 50 + det_time = 5 SECONDS display_timer = 0 var/list/times @@ -20,10 +20,10 @@ ..() overlays += "improvised_grenade_filled" overlays += "improvised_grenade_wired" - times = list("5" = 10, "-1" = 20, "[rand(30, 80)]" = 50, "[rand(65, 180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] + times = list("5" = 1 SECONDS, "-1" = 2 SECONDS, "[rand(3 SECONDS, 8 SECONDS)]" = 5 SECONDS, "[rand(6.5 SECONDS, 18 SECONDS)]" = 2 SECONDS)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] det_time = text2num(pickweight(times)) if(det_time < 0) //checking for 'duds' - det_time = rand(30,80) + det_time = rand(3 SECONDS, 8 SECONDS) /obj/item/grenade/iedcasing/CheckParts(list/parts_list) ..() @@ -37,6 +37,11 @@ underlays += can_underlay +/obj/item/grenade/iedcasing/update_overlays() + . = ..() + + + /obj/item/grenade/iedcasing/attack_self(mob/user) // if(!active) if(clown_check(user)) @@ -44,6 +49,7 @@ active = TRUE overlays -= "improvised_grenade_filled" icon_state = initial(icon_state) + "_active" + update_icon() add_fingerprint(user) investigate_log("[key_name_log(user)] has primed a [name] for detonation", INVESTIGATE_BOMB) add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) @@ -67,7 +73,7 @@ icon_state = "improvised_satchel" item_state = "plastic-explosive" toolspeed = 1 - det_time = 80 + det_time = 8 SECONDS var/atom/target = null var/image_overlay = null var/planted = FALSE @@ -80,6 +86,17 @@ if(burned_out) . += span_notice("Looks like wick has burned out") + +/obj/item/grenade/iedsatchel/update_icon_state() + if(active) + icon_state = "[initial(icon_state)]_active" + return + if(anchored || burned_out) + icon_state = "[initial(icon_state)]_burned" + return + icon_state = initial(icon_state) + + /obj/item/grenade/iedsatchel/afterattack(atom/T, mob/user, proximity) if(!proximity) return @@ -98,12 +115,12 @@ layer = ABOVE_OBJ_LAYER add_game_logs("planted [src] on [T.name] at [T.loc]", user) - icon_state = initial(icon_state) + "_burned" + update_icon(UPDATE_ICON_STATE) to_chat(user, span_notice("You plant the [src].")) -/obj/item/grenade/iedsatchel/attack_hand(var/mob/user) +/obj/item/grenade/iedsatchel/attack_hand(mob/user) if(anchored) - icon_state = initial(icon_state) + "_burned" + update_icon(UPDATE_ICON_STATE) return ..() @@ -114,7 +131,7 @@ to_chat(user, span_notice("You tickled a makeshift wick made of wires, it looks like it needs to be set on fire.")) /obj/item/grenade/iedsatchel/attackby(obj/item/W, user) - if(active == 1) + if(active) return if(istype(W, /obj/item/lighter)) var/obj/item/lighter/I = W @@ -126,7 +143,7 @@ var/obj/item/match/I = W if(!I.lit) return - trigger() + trigger(user) return if(istype(W, /obj/item/weldingtool)) var/obj/item/weldingtool/I = W @@ -142,17 +159,18 @@ if(I.use(5)) to_chat(user, span_notice("You made a new wick from the cable")) burned_out = FALSE + update_icon(UPDATE_ICON_STATE) return to_chat(user, span_notice("There is not enough cables to make a wick.")) - if(istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour == TOOL_WIRECUTTER) if(!anchored) return pixel_w = 0 pixel_z = 0 to_chat(user, span_notice("You unattached [src].")) - icon_state = "improvised_satchel" layer = TURF_LAYER anchored = FALSE + update_icon(UPDATE_ICON_STATE) target = null /obj/item/grenade/iedsatchel/proc/trigger(mob/user) @@ -160,9 +178,9 @@ to_chat(user, span_notice("There is no wick to ignite [src].")) return var/N = roll(11) - 1 - active = 1 + active = TRUE to_chat(user, span_danger("You ignite wires on [src]!")) - icon_state = initial(icon_state) + "_active" + update_icon(UPDATE_ICON_STATE) add_game_logs("Triggered [name] at [COORD(target)]", user) if(N <= 3) active = 1 @@ -175,10 +193,10 @@ prime() /obj/item/grenade/iedsatchel/proc/prime_fake() - src.visible_message(span_notice("The wires on [src] burned out, but nothing happened.")) - active = 0 + visible_message(span_notice("The wires on [src] burned out, but nothing happened.")) + active = FALSE burned_out = TRUE - icon_state = initial(icon_state) + "_burned" + update_icon(UPDATE_ICON_STATE) /obj/item/grenade/iedsatchel/prime() update_mob() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 7a02c0a4381..0280830be32 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -12,9 +12,16 @@ slot_flags = SLOT_BELT resistance_flags = FLAMMABLE max_integrity = 40 - var/active = 0 - var/det_time = 50 - var/display_timer = 1 + var/active = FALSE + var/det_time = 5 SECONDS + var/display_timer = TRUE + + +/obj/item/grenade/Destroy() + ///We need to clear the walk_to on destroy to allow a grenade which uses walk_to or related to properly GC + walk_to(src, 0) + return ..() + /obj/item/grenade/deconstruct(disassembled = TRUE) if(!disassembled) @@ -22,65 +29,56 @@ if(!QDELETED(src)) qdel(src) -/obj/item/grenade/proc/clown_check(var/mob/living/user) + +/obj/item/grenade/proc/clown_check(mob/living/user) if((CLUMSY in user.mutations) && prob(50)) - to_chat(user, "Huh? How does this thing work?") - active = 1 - icon_state = initial(icon_state) + "_active" - playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(5) - if(user) - user.drop_from_active_hand() - prime() - return 0 - return 1 - - -/*/obj/item/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob) - if(istype(target, /obj/item/storage)) return ..() // Trying to put it in a full container - if(istype(target, /obj/item/gun/grenadelauncher)) return ..() - if((user.is_in_active_hand(src)) && (!active) && (clown_check(user)) && target.loc != src.loc) - to_chat(user, "You prime the [name]! [det_time/10] seconds!") - active = 1 - icon_state = initial(icon_state) + "_active" - playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(det_time) - prime() - return - user.dir = get_dir(user, target) - user.drop_from_active_hand() - var/t = (isturf(target) ? target : target.loc) - walk_towards(src, t, 3) - return*/ + to_chat(user, span_warning("Huh? How does this thing work?")) + active = TRUE + update_icon(UPDATE_ICON_STATE) + playsound(loc, 'sound/weapons/armbomb.ogg', 75, TRUE, -3) + addtimer(CALLBACK(src, PROC_REF(delayed_boom)), 0.5 SECONDS) + return FALSE + return TRUE + + +/obj/item/grenade/proc/delayed_boom(mob/living/user) + if(!QDELETED(user)) + user.drop_item_ground(src) + prime() + + +/obj/item/grenade/update_icon_state() + icon_state = "[initial(icon_state)][active ? "_active" : ""]" /obj/item/grenade/examine(mob/user) . = ..() if(display_timer) if(det_time > 1) - . += "The timer is set to [det_time/10] second\s." + . += span_notice("The timer is set to [det_time/10] second\s.") else - . += "\The [src] is set for instant detonation." - -/obj/item/grenade/attack_self(mob/user as mob) - if(!active) - if(clown_check(user)) - to_chat(user, "You prime the [name]! [det_time/10] seconds!") - active = 1 - icon_state = initial(icon_state) + "_active" - add_fingerprint(user) - var/turf/bombturf = get_turf(src) - message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]") - investigate_log("[key_name_log(usr)] has primed a [name] for detonation", INVESTIGATE_BOMB) - add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.throw_mode_on() - spawn(det_time) - prime() + . += span_warning("[src] is set for instant detonation.") + + +/obj/item/grenade/attack_self(mob/user) + if(!active && clown_check(user)) + to_chat(user, "You prime the [name]! [det_time/10] seconds!") + active = TRUE + update_icon(UPDATE_ICON_STATE) + add_fingerprint(user) + var/turf/bombturf = get_turf(src) + message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]") + investigate_log("[key_name_log(usr)] has primed a [name] for detonation", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) + if(iscarbon(user)) + var/mob/living/carbon/c_user = user + c_user.throw_mode_on() + addtimer(CALLBACK(src, PROC_REF(prime)), det_time) /obj/item/grenade/proc/prime(mob/user) + return + /obj/item/grenade/proc/update_mob() if(ismob(loc)) @@ -88,24 +86,25 @@ M.drop_item_ground(src) -/obj/item/grenade/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/screwdriver)) - switch(det_time) - if("1") - det_time = 10 - to_chat(user, "You set the [name] for 1 second detonation time.") - if("10") - det_time = 30 - to_chat(user, "You set the [name] for 3 second detonation time.") - if("30") - det_time = 50 - to_chat(user, "You set the [name] for 5 second detonation time.") - if("50") - det_time = 1 - to_chat(user, "You set the [name] for instant detonation.") - add_fingerprint(user) - ..() +/obj/item/grenade/screwdriver_act(mob/living/user, obj/item/I) + switch(det_time) + if(0.1 SECONDS) + det_time = 1 SECONDS + to_chat(user, span_notice("You set [src] for 1 second detonation time.")) + if(1 SECONDS) + det_time = 3 SECONDS + to_chat(user, span_notice("You set [src] for 3 second detonation time.")) + if(3 SECONDS) + det_time = 5 SECONDS + to_chat(user, span_notice("You set [src] for 5 second detonation time.")) + if(5 SECONDS) + det_time = 0.1 SECONDS + to_chat(user, span_notice("You set [src] for instant detonation.")) + add_fingerprint(user) + return TRUE + /obj/item/grenade/attack_hand() walk(src, null, null) ..() + diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm index 715a18e9ca6..eb486c54b09 100644 --- a/code/game/objects/items/weapons/grenades/smokebomb.dm +++ b/code/game/objects/items/weapons/grenades/smokebomb.dm @@ -3,7 +3,7 @@ name = "smoke bomb" icon = 'icons/obj/weapons/grenade.dmi' icon_state = "flashbang" - det_time = 20 + det_time = 2 SECONDS item_state = "flashbang" slot_flags = SLOT_BELT var/datum/effect_system/smoke_spread/bad/smoke diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 72a36fdb90b..8b9f985e683 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -51,7 +51,7 @@ if(istype(loc, /obj/item/implanter)) var/obj/item/implanter/implanter = loc implanter.imp = null - implanter.update_icon() + implanter.update_state() if(istype(loc, /obj/item/implantpad)) var/obj/item/implantcase/implantcase = loc implantcase.imp = null @@ -92,15 +92,13 @@ to_chat(user, span_warning("You can't trigger [src] with a custom emote.")) return FALSE - if(!(emote_key in user.usable_emote_keys(trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL))) + var/intentional_cause = (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL) && !(trigger_causes & BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL) + if(!(emote_key in user.usable_emote_keys(intentional_cause))) if(!silent) - to_chat(user, span_warning("You can't trigger [src] with that emote! Try *help to see emotes you can use.")) + to_chat(user, span_warning("You can't trigger [src] with that emote [intentional_cause ? "intentionally" : "unintentionally"]! Try *help to see emotes you can use.")) return FALSE - if(!(emote_key in user.usable_emote_keys(trigger_causes & BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL))) - CRASH("User was given an bio-chip for an unintentional emote that they can't use.") - - LAZYADD(trigger_emotes, emote_key) + LAZYADDOR(trigger_emotes, emote_key) RegisterSignal(user, COMSIG_MOB_EMOTED(emote_key), PROC_REF(on_emote)) @@ -113,7 +111,7 @@ if(!(intentional && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)) && !(!intentional && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL))) return - add_attack_logs(user, user, "[intentional ? "intentionally" : "unintentionally"] [src] was [intentional ? "intentionally" : "unintentionally"] triggered with the emote [fired_emote].") + add_attack_logs(user, user, "[src] was [intentional ? "intentionally" : "unintentionally"] triggered with the emote [fired_emote].") emote_trigger(key, user, intentional) @@ -136,7 +134,7 @@ death_trigger(source, gibbed) -/obj/item/implant/proc/emote_trigger(emote, mob/source, force) +/obj/item/implant/proc/emote_trigger(emote, mob/source, intentional) return @@ -183,13 +181,13 @@ if(trigger_emotes) if(!(trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL|BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL)) CRASH("Bio-chip [src] has trigger emotes defined but no trigger cause with which to use them!") - if(!activated && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)) + if(activated == BIOCHIP_ACTIVATED_PASSIVE && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)) CRASH("Bio-chip [src] has intentional emote triggers on a passive bio-chip") // If you can't activate the implant manually, you shouldn't be able to deliberately activate it with an emote for(var/emote in trigger_emotes) set_trigger(source, emote, on_implant = TRUE) - if(activated) + if(activated == BIOCHIP_ACTIVATED_ACTIVE) for(var/datum/action/action as anything in actions) action.Grant(source) update_button(action) diff --git a/code/game/objects/items/weapons/implants/implant_sad_trombone.dm b/code/game/objects/items/weapons/implants/implant_sad_trombone.dm index 097324fe1ce..e4868acb04f 100644 --- a/code/game/objects/items/weapons/implants/implant_sad_trombone.dm +++ b/code/game/objects/items/weapons/implants/implant_sad_trombone.dm @@ -8,15 +8,15 @@ implant_state = "implant-honk" -/obj/item/implant/sad_trombone/emote_trigger(emote, mob/source, force) - activate(emote) +/obj/item/implant/sad_trombone/emote_trigger(emote, mob/source, intentional) + activate() /obj/item/implant/sad_trombone/death_trigger(mob/user, gibbed) - activate(gibbed) + activate() -/obj/item/implant/sad_trombone/activate() +/obj/item/implant/sad_trombone/activate(cause) playsound(loc, 'sound/misc/sadtrombone.ogg', 50, FALSE) diff --git a/code/game/objects/items/weapons/implants/implant_stealth.dm b/code/game/objects/items/weapons/implants/implant_stealth.dm index 7fe0ed65984..5ac03283359 100644 --- a/code/game/objects/items/weapons/implants/implant_stealth.dm +++ b/code/game/objects/items/weapons/implants/implant_stealth.dm @@ -155,7 +155,8 @@ qdel(src) -/obj/structure/closet/cardboard/agent/update_icon() // When the box is opened, it's deleted, so we never need to update this. +// When the box is opened, it's deleted, so we never need to update this. +/obj/structure/closet/cardboard/agent/update_icon_state() return diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index 5c50ffdd780..5d610eb97a4 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -36,15 +36,13 @@ origin_tech = initial(origin_tech) flags = initial(flags) reagents = null - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/implantcase/update_icon() - ..() - cut_overlays() +/obj/item/implantcase/update_overlays() + . = ..() if(imp) - var/image/implant_overlay = image('icons/obj/implants.dmi', imp.implant_state) - add_overlay(implant_overlay) + . += image('icons/obj/implants.dmi', imp.implant_state) /obj/item/implantcase/attackby(obj/item/I, mob/user) @@ -58,7 +56,8 @@ implater.imp.forceMove(src) imp = implater.imp implater.imp = null - implater.update_icon() + update_state() + implater.update_state() else if(imp) if(implater.imp) @@ -66,8 +65,8 @@ imp.forceMove(implater) implater.imp = imp imp = null - implater.update_icon() - update_state() + update_state() + implater.update_state() else return ..() diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 63de271a625..f11a3e75097 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -33,12 +33,8 @@ LAZYADD(implants_list, bio_chip) -/obj/machinery/implantchair/update_icon() - . = ..() - if(occupant) - icon_state = "implantchair_on" - else - icon_state = "implantchair" +/obj/machinery/implantchair/update_icon_state() + icon_state = "implantchair[occupant ? "_on" : ""]" /obj/machinery/implantchair/attack_hand(mob/user) @@ -124,7 +120,7 @@ return FALSE -/obj/machinery/implantchair/MouseDrop_T(mob/living/carbon/human/dropping, mob/living/user) +/obj/machinery/implantchair/MouseDrop_T(mob/living/carbon/human/dropping, mob/living/user, params) return put_mob(dropping, user) @@ -136,7 +132,7 @@ target.forceMove(src) occupant = target add_fingerprint(user) - update_icon() + update_icon(UPDATE_ICON_STATE) updateUsrDialog() return TRUE @@ -178,7 +174,7 @@ occupant.forceMove(loc) add_fingerprint(user) occupant = null - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 418fb1321fa..1cc51f73a03 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -18,7 +18,7 @@ . = ..() if(ispath(imp, /obj/item/implant)) imp = new imp(src) - update_icon() + update_state() /obj/item/implanter/Destroy() @@ -26,13 +26,13 @@ return ..() -/obj/item/implanter/update_icon() - if(imp) - icon_state = "implanter1" - origin_tech = imp.origin_tech - else - icon_state = "implanter0" - origin_tech = initial(origin_tech) +/obj/item/implanter/proc/update_state() + origin_tech = imp ? imp.origin_tech : initial(origin_tech) + update_icon(UPDATE_ICON_STATE) + + +/obj/item/implanter/update_icon_state() + icon_state = "implanter[imp ? "1" : "0"]" /obj/item/implanter/attack(mob/living/carbon/target, mob/user) @@ -50,7 +50,7 @@ else target.visible_message("[user] has implanted [target].", span_notice("[user] bio-chips you.")) imp = null - update_icon() + update_state() /obj/item/implanter/attackby(obj/item/I, mob/user, params) diff --git a/code/game/objects/items/weapons/implants/implantfluff.dm b/code/game/objects/items/weapons/implants/implantfluff.dm index db189b35b4a..86d1865dbbd 100644 --- a/code/game/objects/items/weapons/implants/implantfluff.dm +++ b/code/game/objects/items/weapons/implants/implantfluff.dm @@ -151,13 +151,6 @@ function = "Plays a sad trombone noise upon death of the implantee, allows clowns to entertain the crew even post-mortem." -/datum/implant_fluff/pathfinder - name = "Paizo Productions 5-E Pathfinder Implant" - life = "Lasts 2-12 months. Known to fail at the worst possible time, space radation may be a factor." - notes = "By use of an internal private GPS signal, allows the pathfinder module to have the MODsuit find the user. Also wirelessly transfers ID information to the suit, to allow doors to open." - function = "Allows for the recall of a Modular Outerwear Device by the implant owner at any time." - - /datum/implant_fluff/stealth name = "Syndicate S3 \"Stealth\" Bio-chip" life = "Unknown. No collected sample has been active long enough to determine lifespan." diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm index a14bcaeb9d6..75adb54aa87 100644 --- a/code/game/objects/items/weapons/implants/implantpad.dm +++ b/code/game/objects/items/weapons/implants/implantpad.dm @@ -17,11 +17,8 @@ return ..() -/obj/item/implantpad/update_icon() - if(case) - icon_state = "implantpad-on" - else - icon_state = "implantpad-off" +/obj/item/implantpad/update_icon_state() + icon_state = "implantpad-[case ? "on" : "off"]" /obj/item/implantpad/attack_self(mob/user) @@ -43,7 +40,7 @@ return user.drop_transfer_item_to_loc(new_case, src) case = new_case - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/implantpad/proc/eject_case(mob/user) @@ -57,7 +54,7 @@ case.add_fingerprint(user) case = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/implantpad/AltClick(mob/living/user) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 992b04842f7..d72f997ab0b 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -293,17 +293,20 @@ drop_sound = 'sound/items/handling/bone_drop.ogg' var/size + /obj/item/kitchen/knife/glassshiv/Initialize(mapload, obj/item/shard/sh) . = ..() if(sh) size = sh.icon_state - update_icon() - -/obj/item/kitchen/knife/glassshiv/update_icon() if(!size) size = pick("large", "medium", "small") + update_icon(UPDATE_ICON_STATE) + + +/obj/item/kitchen/knife/glassshiv/update_icon_state() icon_state = "[size]_[initial(icon_state)]" + /obj/item/kitchen/knife/glassshiv/plasma name = "plasma glass shiv" desc = "A plasma glass shard with some cloth wrapped around it" diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm index e18f2c03c14..dd7ccbd9968 100644 --- a/code/game/objects/items/weapons/legcuffs.dm +++ b/code/game/objects/items/weapons/legcuffs.dm @@ -42,11 +42,16 @@ return BRUTELOSS +/obj/item/restraints/legcuffs/beartrap/update_icon_state() + icon_state = "[initial(icon_state)][armed]" + + + /obj/item/restraints/legcuffs/beartrap/attack_self(mob/user) ..() if(ishuman(user) && !user.stat && !user.restrained()) armed = !armed - icon_state = "[initial(icon_state)][armed]" + update_icon(UPDATE_ICON_STATE) to_chat(user, span_notice("[src] is now [armed ? "armed" : "disarmed"]")) @@ -116,7 +121,7 @@ return armed = FALSE - icon_state = "[initial(icon_state)][armed]" + update_icon(UPDATE_ICON_STATE) playsound(src.loc, 'sound/effects/snap.ogg', 50, TRUE) moving_thing.visible_message(span_danger("[moving_thing] triggers [src]."), span_userdanger("You trigger [src]!")) @@ -185,6 +190,11 @@ RegisterSignal(src, COMSIG_CARBON_TOGGLE_THROW, PROC_REF(spin_up_wrapper)) +/obj/item/restraints/legcuffs/bola/update_icon_state() + item_state = spinning ? "[initial(item_state)]_spin" : initial(item_state) + update_equipped_item() + + /obj/item/restraints/legcuffs/bola/proc/spin_up_wrapper(datum/source, throw_mode_state) // so that signal handler works SIGNAL_HANDLER if(throw_mode_state) // if we actually turned throw mode on @@ -196,8 +206,7 @@ return var/mob/living/owner = loc // can only be called if the mob is holding the bola. spinning = TRUE - item_state = "[initial(item_state)]_spin" - owner.update_inv_hands() + update_icon(UPDATE_ICON_STATE) playsound(owner, spin_sound, 30, list(38000, 48000), SHORT_RANGE_SOUND_EXTRARANGE) spin_timer_id = addtimer(CALLBACK(src, PROC_REF(spin_loop), owner), 1 SECONDS, TIMER_UNIQUE|TIMER_LOOP|TIMER_STOPPABLE|TIMER_DELETE_ME) do_spin_cycle(owner) @@ -244,10 +253,9 @@ /obj/item/restraints/legcuffs/bola/proc/reset_values(mob/living/user) throw_range = initial(throw_range) throw_speed = initial(throw_speed) - item_state = initial(item_state) spin_cycle = 0 spinning = FALSE - user?.update_inv_hands() + update_icon(UPDATE_ICON_STATE) if(spin_timer_id) deltimer(spin_timer_id) diff --git a/code/game/objects/items/weapons/lighters.dm b/code/game/objects/items/weapons/lighters.dm index d4d3126cab5..02c8dbf7c05 100644 --- a/code/game/objects/items/weapons/lighters.dm +++ b/code/game/objects/items/weapons/lighters.dm @@ -280,6 +280,7 @@ pickup_sound = 'sound/items/handling/generic_small_pickup.ogg' drop_sound = 'sound/items/handling/generic_small_drop.ogg' + /obj/item/match/process() var/turf/location = get_turf(src) smoketime-- @@ -287,50 +288,65 @@ matchburnout() if(location) location.hotspot_expose(700, 5) - return + /obj/item/match/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) ..() matchignite() + /obj/item/match/extinguish_light(force = FALSE) if(!force) return matchburnout() + +/obj/item/match/update_icon_state() + icon_state = lit ? "match_lit" : "match_burnt" + item_state = lit ? "cigon" : "cigoff" + + +/obj/item/match/update_name(updates = ALL) + . = ..() + var/init_name = initial(name) + name = lit ? "lit [init_name]" : burnt ? "burnt [init_name]" : initial(name) + + +/obj/item/match/update_desc(updates = ALL) + . = ..() + var/init_name = initial(name) + desc = lit ? "A [init_name]. This one is lit." : burnt ? "A [init_name]. This one has seen better days." : initial(desc) + + /obj/item/match/proc/matchignite() if(!lit && !burnt) lit = TRUE - icon_state = "match_lit" - damtype = "fire" + damtype = FIRE force = 3 hitsound = 'sound/weapons/tap.ogg' - item_state = "cigon" - name = "lit match" - desc = "A match. This one is lit." attack_verb = list("burnt","singed") START_PROCESSING(SSobj, src) - update_icon() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return TRUE + /obj/item/match/proc/matchburnout() if(lit) lit = FALSE burnt = TRUE - damtype = "brute" + damtype = BRUTE force = initial(force) - icon_state = "match_burnt" - item_state = "cigoff" - name = "burnt match" - desc = "A match. This one has seen better days." attack_verb = list("flicked") STOP_PROCESSING(SSobj, src) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) return TRUE + /obj/item/match/dropped(mob/user, silent = FALSE) matchburnout() . = ..() + /obj/item/match/attack(mob/living/carbon/M, mob/living/carbon/user) if(!isliving(M)) return ..() @@ -359,6 +375,7 @@ else ..() + /obj/item/match/decompile_act(obj/item/matter_decompiler/C, mob/user) if(burnt) C.stored_comms["wood"] += 1 @@ -366,20 +383,24 @@ return TRUE return ..() + /obj/item/proc/help_light_cig(mob/living/M) var/mask_item = M.get_item_by_slot(slot_wear_mask) if(istype(mask_item, /obj/item/clothing/mask/cigarette)) return mask_item + /obj/item/match/firebrand name = "firebrand" desc = "An unlit firebrand. It makes you wonder why it's not just called a stick." smoketime = 20 //40 seconds -/obj/item/match/firebrand/New() - ..() + +/obj/item/match/firebrand/Initialize(mapload) + . = ..() matchignite() + /obj/item/match/unathi name = "small blaze" desc = "A little flame of your own, currently located dangerously in your mouth." @@ -391,16 +412,24 @@ lit = TRUE w_class = WEIGHT_CLASS_BULKY //to prevent it going to pockets + /obj/item/match/unathi/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) + +/obj/item/match/unathi/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) + return // we are already burning + + /obj/item/match/unathi/matchburnout() if(!lit) return lit = FALSE //to avoid a qdel loop qdel(src) + /obj/item/match/unathi/Destroy() . = ..() STOP_PROCESSING(SSobj, src) + diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index d6caf9caf68..4357fb33819 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -38,6 +38,21 @@ "[user] is falling on the [name]! It looks like [user.p_theyre()] trying to commit suicide.")) return BRUTELOSS|FIRELOSS + +/obj/item/melee/energy/update_icon_state() + if(!active) + icon_state = initial(icon_state) + set_light(0) + return + if(icon_state_on) + icon_state = icon_state_on + set_light(brightness_on, l_color = item_color ? colormap[item_color] : null) + else + icon_state = "sword[item_color]" + set_light(brightness_on, l_color = colormap[item_color]) + update_equipped_item() + + /obj/item/melee/energy/attack_self(mob/living/carbon/user) if((CLUMSY in user.mutations) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") @@ -48,14 +63,6 @@ throwforce = throwforce_on hitsound = 'sound/weapons/blade1.ogg' throw_speed = 4 - if(attack_verb_on.len) - attack_verb = attack_verb_on - if(icon_state_on) - icon_state = icon_state_on - set_light(brightness_on, l_color = item_color ? colormap[item_color] : null) - else - icon_state = "sword[item_color]" - set_light(brightness_on, l_color=colormap[item_color]) w_class = w_class_on playsound(user, 'sound/weapons/saberon.ogg', 35, 1) //changed it from 50% volume to 35% because deafness to_chat(user, "[src] is now active.") @@ -66,17 +73,12 @@ throw_speed = initial(throw_speed) if(attack_verb_on.len) attack_verb = list() - icon_state = initial(icon_state) w_class = initial(w_class) playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) //changed it from 50% volume to 35% because deafness - set_light(0) to_chat(user, "[src] can now be concealed.") - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() add_fingerprint(user) - return + update_icon(UPDATE_ICON_STATE) + /obj/item/melee/energy/axe name = "energy axe" @@ -119,7 +121,7 @@ origin_tech = "combat=3;magnets=4;syndicate=4" block_chance = 50 sharp = 1 - var/hacked = 0 + var/hacked = FALSE /obj/item/melee/energy/sword/New() ..() @@ -201,32 +203,24 @@ user.adjustBrainLoss(10) else to_chat(user, "You attach the ends of the two energy swords, making a single double-bladed weapon! You're cool.") - var/obj/item/twohanded/dualsaber/newSaber = new /obj/item/twohanded/dualsaber(drop_location()) - if(src.hacked) // That's right, we'll only check the "original" esword. - newSaber.hacked = 1 - newSaber.item_color = "rainbow" + var/obj/item/twohanded/dualsaber/newSaber = new(drop_location()) + if(hacked) // That's right, we'll only check the "original" esword. + newSaber.hacked = TRUE + newSaber.blade_color = "rainbow" user.temporarily_remove_item_from_inventory(W) user.temporarily_remove_item_from_inventory(src) qdel(W) qdel(src) user.put_in_hands(newSaber, ignore_anim = FALSE) - else if(istype(W, /obj/item/multitool)) - if(hacked == 0) - hacked = 1 - item_color = "rainbow" - to_chat(user, "RNBW_ENGAGE") - - if(active) - icon_state = "swordrainbow" - // Updating overlays, copied from welder code. - // I tried calling attack_self twice, which looked cool, except it somehow didn't update the overlays!! - if(user.r_hand == src) - user.update_inv_r_hand() - else if(user.l_hand == src) - user.update_inv_l_hand() - - else + else if(W.tool_behaviour == TOOL_MULTITOOL) + if(hacked) to_chat(user, "It's already fabulous!") + return + + hacked = TRUE + item_color = "rainbow" + to_chat(user, "RNBW_ENGAGE") + update_icon(UPDATE_ICON_STATE) /obj/item/melee/energy/sword/saber/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) @@ -337,12 +331,6 @@ throw_speed = 4 if(attack_verb_on.len) attack_verb = attack_verb_on - if(icon_state_on) - icon_state = icon_state_on - set_light(brightness_on, l_color = item_color ? colormap[item_color] : null) - else - icon_state = "sword[item_color]" - set_light(brightness_on, l_color=colormap[item_color]) w_class = w_class_on playsound(user, 'sound/magic/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000)) to_chat(user, "You open [src]. It will now cleave enemies in a wide arc and deal additional damage to fauna.") @@ -353,17 +341,10 @@ throw_speed = initial(throw_speed) if(attack_verb_on.len) attack_verb = list() - icon_state = initial(icon_state) w_class = initial(w_class) playsound(user, 'sound/magic/fellowship_armory.ogg', 35, 1) //changed it from 50% volume to 35% because deafness - set_light(0) to_chat(user, "You close [src]. It will now attack rapidly and cause fauna to bleed.") - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) /obj/item/melee/energy/cleaving_saw/examine(mob/user) diff --git a/code/game/objects/items/weapons/misc.dm b/code/game/objects/items/weapons/misc.dm index 60a67ff64ee..e19f946512c 100644 --- a/code/game/objects/items/weapons/misc.dm +++ b/code/game/objects/items/weapons/misc.dm @@ -92,12 +92,19 @@ icon = 'icons/obj/lightning.dmi' icon_state = "lightning" desc = "test lightning" + var/angle -/obj/item/lightning/New() - ..() + +/obj/item/lightning/Initialize(mapload) + . = ..() icon_state = "1" -/obj/item/lightning/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) + +/obj/item/lightning/update_icon_state() + icon_state = "[angle]" + + +/obj/item/lightning/afterattack(atom/A, mob/living/user, flag, params) var/angle = get_angle(A, user) //to_chat(world, angle) angle = round(angle) + 45 @@ -108,9 +115,7 @@ if(!angle) angle = 1 - //to_chat(world, "adjusted [angle]") - icon_state = "[angle]" - //to_chat(world, "[angle] [(get_dist(user, A) - 1)]") + update_icon(UPDATE_ICON_STATE) user.Beam(A, "lightning", 'icons/obj/zap.dmi', 50, 15) /obj/item/newton diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index 5593fe302d7..f4b6aa1dcfc 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -24,16 +24,20 @@ GLOB.janitorial_equipment -= src return ..() -/obj/item/mop/proc/wet_mop(obj/o, mob/user) - if(o.reagents.total_volume < 1) - to_chat(user, "[o] is out of water!") - if(!istype(o, /obj/item/reagent_containers/glass/bucket)) - janicart_insert(user, o) + +/obj/item/mop/proc/wet_mop(obj/target, mob/user) + if(target.reagents.total_volume < 1) + to_chat(user, "[target] is out of water!") + if(istype(target, /obj/structure/mopbucket)) + mopbucket_insert(user, target) + if(!istype(target, /obj/item/reagent_containers/glass/bucket)) + janicart_insert(user, target) return - o.reagents.trans_to(src, 5) - to_chat(user, "You wet [src] in [o].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + target.reagents.trans_to(src, 5) + to_chat(user, "You wet [src] in [target].") + playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE) + /obj/item/mop/proc/clean(turf/simulated/A) if(reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1)) @@ -69,10 +73,16 @@ else return ..() -/obj/item/mop/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) - J.put_in_cart(src, user) - J.mymop=src - J.update_icon() + +/obj/item/mop/proc/janicart_insert(mob/user, obj/structure/janitorialcart/cart) + cart.mymop = src + cart.put_in_cart(src, user) + + +/obj/item/mop/proc/mopbucket_insert(mob/user, obj/structure/mopbucket/bucket) + bucket.mymop = src + bucket.put_in_cart(src, user) + /obj/item/mop/wash(mob/user, atom/source) reagents.add_reagent("water", 5) diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm index 30c97a48fa7..93a1cd0acd6 100644 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ b/code/game/objects/items/weapons/pneumaticCannon.dm @@ -182,14 +182,14 @@ return to_chat(user, span_notice("You hook [thetank] up to [src].")) tank = thetank - update_icons() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/pneumatic_cannon/update_overlays() + . = ..() + if(tank) + . += "[tank.icon_state]" -/obj/item/pneumatic_cannon/proc/update_icons() - overlays.Cut() - if(!tank) - return - overlays += image('icons/obj/weapons/pneumaticCannon.dmi', "[tank.icon_state]") - update_icon() #undef LOW_PRESSURE #undef MID_PRESSURE diff --git a/code/game/objects/items/weapons/pneumaticRifle.dm b/code/game/objects/items/weapons/pneumaticRifle.dm index 81992d550e4..01ed69bfabb 100644 --- a/code/game/objects/items/weapons/pneumaticRifle.dm +++ b/code/game/objects/items/weapons/pneumaticRifle.dm @@ -65,7 +65,7 @@ to_chat(user, span_notice("You strapped [src], so now you can wear it on your back")) isBelted = TRUE slot_flags |= SLOT_BACK - update_icons() + update_icon(UPDATE_OVERLAYS) return else to_chat(user, span_warning("[src] is already strapped!")) @@ -166,7 +166,7 @@ return to_chat(user, span_notice("You hook [thetank] up to [src].")) tank = thetank - update_icons() + update_icon(UPDATE_OVERLAYS) /datum/crafting_recipe/pneumatic_rifle name = "Pneumatic Rifle" @@ -181,10 +181,11 @@ category = CAT_WEAPONRY subcategory = CAT_WEAPON -/obj/item/gun/pneumatic_rifle/proc/update_icons() - overlays.Cut() + +/obj/item/gun/pneumatic_rifle/update_overlays() + . = ..() if(tank) - overlays += image('icons/obj/weapons/pneumaticRifle.dmi', "[tank.icon_state]") + . += "[tank.icon_state]" if(isBelted) - overlays += image('icons/obj/weapons/pneumaticRifle.dmi', "belt") - update_icon() + . += "belt" + diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index def5938bfd3..add53a5ba3c 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -16,7 +16,7 @@ icon_state = "rpd" opacity = 0 density = 0 - anchored = 0 + anchored = FALSE flags = CONDUCT force = 10 throwforce = 10 diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 7e8fb75cb2e..cc0f5e69a7d 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -37,7 +37,7 @@ attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time -/obj/item/shield/riot/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/shield/riot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/melee/baton)) if(cooldown < world.time - 25) user.visible_message("[user] bashes [src] with [W]!") @@ -130,14 +130,14 @@ add_fingerprint(user) return -/obj/item/shield/energy/update_icon() +/obj/item/shield/energy/update_icon_state() icon_state = "eshield[active]" /obj/item/shield/energy/syndie icon_state = "syndieshield0" desc = "Reverse-engineered shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere. Property of Gorlex marauders." -/obj/item/shield/energy/syndie/update_icon() +/obj/item/shield/energy/syndie/update_icon_state() icon_state = "syndieshield[active]" /obj/item/shield/riot/tele @@ -160,9 +160,14 @@ return ..() return FALSE + +/obj/item/shield/riot/tele/update_icon_state() + icon_state = "teleriot[active]" + + /obj/item/shield/riot/tele/attack_self(mob/living/user) active = !active - icon_state = "teleriot[active]" + update_icon(UPDATE_ICON_STATE) playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) if(active) @@ -179,9 +184,6 @@ w_class = WEIGHT_CLASS_NORMAL slot_flags = null to_chat(user, "[src] can now be concealed.") - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() + update_equipped_item() add_fingerprint(user) - return + diff --git a/code/game/objects/items/weapons/spacechips.dm b/code/game/objects/items/weapons/spacechips.dm index b33ec81a7fe..f84f9478631 100644 --- a/code/game/objects/items/weapons/spacechips.dm +++ b/code/game/objects/items/weapons/spacechips.dm @@ -15,8 +15,7 @@ merge_type = /obj/item/stack/spacechips -/obj/item/stack/spacechips/update_icon()//changes icon depending on the amount of chips - ..() +/obj/item/stack/spacechips/update_icon_state()//changes icon depending on the amount of chips name = "[amount == max_amount ? "1000000" : amount] Chip[amount > 1 ? "s" : ""]" if(amount >= 1 && amount <= 20) icon_state = "c20" @@ -31,6 +30,7 @@ else icon_state = "c1000" + /obj/item/stack/spacechips/c10 amount = 10 diff --git a/code/game/objects/items/weapons/staff.dm b/code/game/objects/items/weapons/staff.dm index 3c0a03d3785..edf7cdadb62 100644 --- a/code/game/objects/items/weapons/staff.dm +++ b/code/game/objects/items/weapons/staff.dm @@ -19,37 +19,38 @@ icon_state = "broom" item_state = "broom0" + +/obj/item/twohanded/staff/broom/update_icon_state() + item_state = "broom[HAS_TRAIT(src, TRAIT_WIELDED)]" + update_equipped_item() + + /obj/item/twohanded/staff/broom/wield(obj/item/source, mob/living/carbon/user) - item_state = "broom[wielded ? 1 : 0]" - force = wielded ? 5 : 3 - attack_verb = wielded ? list("rammed into", "charged at") : list("bludgeoned", "whacked", "cleaned") - if(user) - user.update_inv_l_hand() - user.update_inv_r_hand() - if(user.mind in SSticker.mode.wizards) - user.flying = wielded ? 1 : 0 - if(wielded) - to_chat(user, "You hold \the [src] between your legs.") - user.say("QUID 'ITCH") - animate(user, pixel_y = pixel_y + 10 , time = 10, loop = 1, easing = SINE_EASING) - else - animate(user, pixel_y = pixel_y + 10 , time = 1, loop = 1) - animate(user, pixel_y = pixel_y, time = 10, loop = 1, easing = SINE_EASING) - animate(user) - if(user.lying)//aka. if they have just been stunned - user.pixel_y -= 6 - else - if(wielded) - to_chat(user, "You hold \the [src] between your legs.") + force = 5 + attack_verb = list("rammed into", "charged at") + if(!user) + return + + update_icon(UPDATE_ICON_STATE) + if(user.mind && (user.mind in SSticker.mode.wizards)) + user.flying = TRUE + user.float(TRUE) + user.say("QUID 'ITCH") + animate(user, pixel_y = pixel_y + 10 , time = 10, loop = 1, easing = SINE_EASING) + + to_chat(user, "You hold \the [src] between your legs.") /obj/item/twohanded/staff/broom/unwield(obj/item/source, mob/living/carbon/user) + update_icon(UPDATE_ICON_STATE) + force = 3 + attack_verb = list("bludgeoned", "whacked", "cleaned") user.flying = FALSE user.update_gravity(user.mob_has_gravity()) animate(user) -/obj/item/twohanded/staff/broom/attackby(var/obj/O, mob/user) +/obj/item/twohanded/staff/broom/attackby(obj/O, mob/user) if(istype(O, /obj/item/clothing/mask/horsehead)) new/obj/item/twohanded/staff/broom/horsebroom(get_turf(src)) user.temporarily_remove_item_from_inventory(O) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 9d6fcad5899..1da6a104916 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -110,7 +110,8 @@ max_w_class = WEIGHT_CLASS_NORMAL max_combined_w_class = 400 // can store a ton of shit! -/obj/item/storage/backpack/santabag/update_icon() + +/obj/item/storage/backpack/santabag/update_icon_state() var/items_count = length(contents) switch(items_count) if(1 to 10) @@ -120,10 +121,8 @@ if(21 to INFINITY) icon_state = "giftbag2" - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_l_hand() - H.update_inv_r_hand() + update_equipped_item() + /obj/item/storage/backpack/cultpack name = "trophy rack" @@ -413,14 +412,14 @@ level = 1 cant_hold = list(/obj/item/storage/backpack/satchel_flat) //muh recursive backpacks -/obj/item/storage/backpack/satchel_flat/hide(var/intact) +/obj/item/storage/backpack/satchel_flat/hide(intact) if(intact) - invisibility = INVISIBILITY_ABSTRACT - anchored = 1 //otherwise you can start pulling, cover it, and drag around an invisible backpack. + invisibility = INVISIBILITY_MAXIMUM + anchored = TRUE //otherwise you can start pulling, cover it, and drag around an invisible backpack. icon_state = "[initial(icon_state)]2" else invisibility = initial(invisibility) - anchored = 0 + anchored = FALSE icon_state = initial(icon_state) /obj/item/storage/backpack/satchel_flat/populate_contents() diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index df8f52adbeb..8344ed4bd03 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -49,8 +49,9 @@ playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) return TOXLOSS -/obj/item/storage/bag/trash/update_icon() - switch(contents.len) + +/obj/item/storage/bag/trash/update_icon_state() + switch(length(contents)) if(21 to INFINITY) icon_state = "[initial(icon_state)]3" if(11 to 20) @@ -59,11 +60,8 @@ icon_state = "[initial(icon_state)]1" else icon_state = "[initial(icon_state)]" - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_l_hand() - H.update_inv_r_hand() - ..() + update_equipped_item() + /obj/item/storage/bag/trash/cyborg @@ -451,18 +449,12 @@ if(prob(10)) M.Weaken(4 SECONDS) -/obj/item/storage/bag/tray/proc/rebuild_overlays() - overlays.Cut() - for(var/obj/item/I in contents) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) -/obj/item/storage/bag/tray/remove_from_storage(obj/item/W, atom/new_location) - ..() - rebuild_overlays() +/obj/item/storage/bag/tray/update_overlays() + . = ..() + for(var/obj/item/item in contents) + . += image(icon = item.icon, icon_state = item.icon_state, layer = -1, pixel_x = rand(-4,4), pixel_y = rand(-4,4)) -/obj/item/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) - ..() /obj/item/storage/bag/tray/cyborg @@ -482,8 +474,6 @@ else // they clicked on a table dropspot = target.loc - overlays = null - var/droppedSomething = 0 for(var/obj/item/I in contents) @@ -502,18 +492,19 @@ user.visible_message("[user] unloads [user.p_their()] service tray.") else user.visible_message("[user] drops all the items on [user.p_their()] tray.") - + update_icon(UPDATE_OVERLAYS) return ..() /obj/item/storage/bag/tray/cookies_tray var/cookie = /obj/item/reagent_containers/food/snacks/cookie + /obj/item/storage/bag/tray/cookies_tray/populate_contents() /// By Azule Utama, thank you a lot! for(var/i in 1 to 6) var/obj/item/C = new cookie(src) handle_item_insertion(C) // Done this way so the tray actually has the cookies visible when spawned - rebuild_overlays() + /obj/item/storage/bag/tray/cookies_tray/sugarcookie cookie = /obj/item/reagent_containers/food/snacks/sugarcookie @@ -560,18 +551,11 @@ M.Weaken(4 SECONDS) -/obj/item/storage/bag/dangertray/proc/rebuild_overlays() - overlays.Cut() - for(var/obj/item/I in contents) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) - -/obj/item/storage/bag/dangertray/remove_from_storage(obj/item/W, atom/new_location) - ..() - rebuild_overlays() +/obj/item/storage/bag/dangertray/update_overlays() + . = ..() + for(var/obj/item/item in contents) + . += image(icon = item.icon, icon_state = item.icon_state, layer = -1, pixel_x = rand(-4,4), pixel_y = rand(-4,4)) -/obj/item/storage/bag/dangertray/handle_item_insertion(obj/item/I, prevent_warning = 0) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) - ..() /* * Chemistry bag diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index bb506aef1e3..95396f4a984 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -7,6 +7,7 @@ lefthand_file = 'icons/mob/inhands/equipment/belt_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/belt_righthand.dmi' slot_flags = SLOT_BELT + flags_2 = BLOCKS_LIGHT_2 attack_verb = list("whipped", "lashed", "disciplined") max_integrity = 300 pickup_sound = 'sound/items/handling/backpack_pickup.ogg' @@ -14,13 +15,16 @@ drop_sound = 'sound/items/handling/backpack_drop.ogg' var/use_item_overlays = FALSE // Do we have overlays for items held inside the belt? -/obj/item/storage/belt/update_icon() - if(use_item_overlays) - overlays.Cut() - for(var/obj/item/I in contents) - if(I.belt_icon) - overlays += "[I.belt_icon]" - ..() + +/obj/item/storage/belt/update_overlays() + . = ..() + if(!use_item_overlays) + return + for(var/obj/item/item in contents) + if(!item.belt_icon) + continue + . += mutable_appearance(icon, item.belt_icon, color = item.color) + /obj/item/storage/belt/proc/can_use() return is_equipped() @@ -450,6 +454,12 @@ new /obj/item/grenade/plastic/x4/thermite(src) new /obj/item/storage/pill_bottle/sovietstimulants(src) +/obj/item/storage/belt/military/assault/gammaert/full/populate_contents() + new /obj/item/storage/pouch/fast(src) + new /obj/item/storage/pouch/fast(src) + new /obj/item/storage/pouch/fast(src) + new /obj/item/melee/classic_baton/telescopic(src) + /obj/item/storage/belt/janitor name = "janibelt" desc = "A belt used to hold most janitorial supplies." @@ -501,21 +511,16 @@ /obj/item/storage/belt/lazarus/Initialize(mapload) . = ..() - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/item/storage/belt/lazarus/update_icon() - ..() +/obj/item/storage/belt/lazarus/update_icon_state() icon_state = "[initial(icon_state)]_[length(contents)]" /obj/item/storage/belt/lazarus/attackby(obj/item/W, mob/user) var/amount = length(contents) . = ..() if(amount != length(contents)) - update_icon() - -/obj/item/storage/belt/lazarus/remove_from_storage(obj/item/W, atom/new_location) - ..() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/storage/belt/bandolier name = "bandolier" @@ -544,19 +549,14 @@ new /obj/item/ammo_casing/shotgun/beanbag/fake(src) update_icon() -/obj/item/storage/belt/bandolier/update_icon() - ..() +/obj/item/storage/belt/bandolier/update_icon_state() icon_state = "[initial(icon_state)]_[length(contents)]" /obj/item/storage/belt/bandolier/attackby(obj/item/W, mob/user) var/amount = length(contents) . = ..() if(amount != length(contents)) - update_icon() - -/obj/item/storage/belt/bandolier/remove_from_storage(obj/item/W, atom/new_location) - ..() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/storage/belt/holster name = "shoulder holster" @@ -695,16 +695,14 @@ return playsound(src, 'sound/weapons/blade_unsheath.ogg', 20) -/obj/item/storage/belt/rapier/update_icon() - . = ..() +/obj/item/storage/belt/rapier/update_icon_state() icon_state = initial(icon_state) item_state = initial(item_state) if(length(contents)) icon_state = "[icon_state]-rapier" item_state = "[item_state]-rapier" - if(isliving(loc)) - var/mob/living/L = loc - L.update_inv_belt() + update_equipped_item() + // ------------------------------------- // Bluespace Belt @@ -977,22 +975,19 @@ sheath_sound = 'sound/weapons/blade_dark_sheath.ogg' unsheath_sound = 'sound/weapons/blade_dark_unsheath.ogg' -/obj/item/storage/belt/claymore/update_icon() - . = ..() +/obj/item/storage/belt/claymore/update_icon_state() if(length(contents)) icon_state = "[initial(icon_state)]_blade" item_state = "[initial(icon_state)]_blade" else icon_state = initial(icon_state) item_state = initial(item_state) - if(isliving(loc)) - var/mob/living/L = loc - L.update_inv_belt() - L.update_inv_s_store() + update_equipped_item() + /obj/item/storage/belt/claymore/populate_contents() new claymore_path(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/storage/belt/claymore/attack_hand(mob/user) if(loc != user) @@ -1008,7 +1003,7 @@ var/obj/item/I = contents[1] H.visible_message(span_notice("[H] takes [I] out of [src]."), span_notice("You take [I] out of [src].")) H.put_in_hands(I, ignore_anim = FALSE) - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(user, span_warning("[src] is empty!")) diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index e8bb99075a5..20754ee59d4 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -85,10 +85,10 @@ else M.LAssailant = user - if(!(ishuman(user) || SSticker) && SSticker.mode.name != "monkey") + if(!ishuman(user) || ismonkeybasic(user)) to_chat(user, "You don't have the dexterity to do this!") return - if(!user.mind?.isholy) + if(!user.mind || !user.mind.isholy) to_chat(user, "The book sizzles in your hands.") user.take_organ_damage(0, 10) return @@ -181,21 +181,6 @@ item_state = choice_icons["inhand"] customisable = FALSE - // Carpet symbol icons are currently broken, so commented out until it's fixed - /*var/carpet_dir - switch(choice) - if("Bible") - carpet_dir = 2 - if("Koran") - carpet_dir = 4 - if("Scientology") - carpet_dir = 8 - if(carpet_dir) - for(var/area/chapel/main/A in world) - for(var/turf/T in A.contents) - if(T.icon_state == "carpetsymbol") - T.dir = carpet_dir*/ - SSblackbox.record_feedback("text", "religion_book", 1, "[choice]", 1) if(SSticker) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index f07c412fd44..35518f02d05 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -269,7 +269,7 @@ new /obj/item/implantcase/tracking(src) new /obj/item/implanter(src) new /obj/item/implantpad(src) - new /obj/item/locator(src) + new /obj/item/gps/security(src) /obj/item/storage/box/minertracker name = "boxed tracking implant kit" @@ -281,7 +281,7 @@ new /obj/item/implantcase/tracking(src) new /obj/item/implanter(src) new /obj/item/implantpad(src) - new /obj/item/locator(src) + new /obj/item/gps/security(src) /obj/item/storage/box/chemimp name = "chemical implant kit" @@ -647,6 +647,7 @@ icon = 'icons/obj/cigarettes.dmi' icon_state = "matchbox" item_state = "matchbox" + base_icon_state = "matchbox" storage_slots = 10 w_class = WEIGHT_CLASS_TINY max_w_class = WEIGHT_CLASS_TINY @@ -663,7 +664,19 @@ if(istype(W, /obj/item/match) && !W.lit) W.matchignite() playsound(user.loc, 'sound/goonstation/misc/matchstick_light.ogg', 50, 1) - return + + +/obj/item/storage/box/matches/update_icon_state() + switch(length(contents)) + if(10 to INFINITY) + icon_state = base_icon_state + if(5 to 9) + icon_state = "[base_icon_state]_almostfull" + if(1 to 4) + icon_state = "[base_icon_state]_almostempty" + else + icon_state = "[base_icon_state]_e" + /obj/item/storage/box/autoinjectors name = "box of injectors" @@ -762,13 +775,29 @@ foldable = null var/design = NODESIGN -/obj/item/storage/box/papersack/update_icon() - if(!contents.len) - icon_state = "[item_state]" - else icon_state = "[item_state]_closed" + +/obj/item/storage/box/papersack/update_desc(updates = ALL) + . = ..() + switch(design) + if(NODESIGN) + desc = "A sack neatly crafted out of paper." + if(NANOTRASEN) + desc = "A standard Nanotrasen paper lunch sack for loyal employees on the go." + if(SYNDI) + desc = "The design on this paper sack is a remnant of the notorious 'SyndieSnacks' program." + if(HEART) + desc = "A paper sack with a heart etched onto the side." + if(SMILE) + desc = "A paper sack with a crude smile etched onto the side." + + +/obj/item/storage/box/papersack/update_icon_state() + item_state = "paperbag_[design]" + icon_state = length(contents) ? "[item_state]_closed" : "[item_state]" + /obj/item/storage/box/papersack/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/pen)) + if(is_pen(W)) //if a pen is used on the sack, dialogue to change its design appears if(contents.len) to_chat(user, "You can't modify [src] with items still inside!") @@ -784,19 +813,7 @@ return to_chat(usr, "You make some modifications to [src] using your pen.") design = switchDesign - icon_state = "paperbag_[design]" - item_state = "paperbag_[design]" - switch(design) - if(NODESIGN) - desc = "A sack neatly crafted out of paper." - if(NANOTRASEN) - desc = "A standard Nanotrasen paper lunch sack for loyal employees on the go." - if(SYNDI) - desc = "The design on this paper sack is a remnant of the notorious 'SyndieSnacks' program." - if(HEART) - desc = "A paper sack with a heart etched onto the side." - if(SMILE) - desc = "A paper sack with a crude smile etched onto the side." + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) return else if(is_sharp(W)) if(!contents.len) @@ -844,8 +861,7 @@ new /obj/item/crowbar/red(src) new /obj/item/kitchen/knife/combat(src) new /obj/item/radio/centcom(src) - new /obj/item/reagent_containers/food/pill/patch/synthflesh(src) - new /obj/item/reagent_containers/hypospray/autoinjector(src) + new /obj/item/storage/firstaid/crew(src) /obj/item/storage/box/soviet name = "boxed survival kit" @@ -1018,6 +1034,24 @@ new /obj/item/clothing/gloves/combat(src) new /obj/item/storage/backpack/security(src) +/obj/item/storage/box/dominator_kit + name = "Dominator kit" + icon_state = "box_dominator" + +/obj/item/storage/box/dominator_kit/populate_contents() + new /obj/item/gun/energy/dominator/sibyl(src) + new /obj/item/clothing/accessory/holster(src) + +/obj/item/storage/box/enforcer_kit + name = "Enforcer kit" + icon_state = "box_enforcer" + +/obj/item/storage/box/enforcer_kit/populate_contents() + new /obj/item/gun/projectile/automatic/pistol/enforcer/security(src) + new /obj/item/ammo_box/magazine/enforcer(src) + new /obj/item/ammo_box/magazine/enforcer(src) + new /obj/item/clothing/accessory/holster(src) + /obj/item/storage/box/hardmode_box name = "box of HRD-MDE project box" desc = "Contains everything needed to get yourself killed for a medal." diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index acf687cfa60..2c9df74c88e 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -18,10 +18,10 @@ resistance_flags = FLAMMABLE var/icon_type -/obj/item/storage/fancy/update_icon(var/itemremoved = 0) - var/total_contents = src.contents.len - itemremoved - src.icon_state = "[src.icon_type]box[total_contents]" - return + +/obj/item/storage/fancy/update_icon_state() + icon_state = "[icon_type]box[length(contents)]" + /obj/item/storage/fancy/examine(mob/user) . = ..() @@ -47,23 +47,29 @@ foldable = /obj/item/stack/sheet/cardboard foldable_amt = 1 -/obj/item/storage/fancy/donut_box/update_icon() - overlays.Cut() - for(var/i = 1 to length(contents)) - var/obj/item/reagent_containers/food/snacks/donut/donut = contents[i] - var/icon/new_donut_icon = icon('icons/obj/food/containers.dmi', "donut_[donut.donut_sprite_type]") - new_donut_icon.Shift(EAST, 3 * (i-1)) - overlays += new_donut_icon +/obj/item/storage/fancy/donut_box/update_icon_state() + return + + +/obj/item/storage/fancy/donut_box/update_overlays() + . = ..() + for(var/I = 1 to length(contents)) + var/obj/item/reagent_containers/food/snacks/donut/donut = contents[I] + var/icon/new_donut_icon = icon(icon, "donut_[donut.donut_sprite_type]") + new_donut_icon.Shift(EAST, 3 * (I - 1)) + . += new_donut_icon + . += "donutbox_front" - overlays += icon('icons/obj/food/containers.dmi', "donutbox_front") /obj/item/storage/fancy/donut_box/populate_contents() for(var/i = 1 to storage_slots) new /obj/item/reagent_containers/food/snacks/donut(src) - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/item/storage/fancy/donut_box/empty/populate_contents() + update_icon(UPDATE_OVERLAYS) return /* @@ -135,17 +141,23 @@ new /obj/item/toy/crayon/blue(src) new /obj/item/toy/crayon/purple(src) new /obj/item/toy/crayon/black(src) - update_icon() + update_icon(UPDATE_OVERLAYS) + -/obj/item/storage/fancy/crayons/update_icon() - overlays = list() //resets list - overlays += image('icons/obj/crayons.dmi',"crayonbox") +/obj/item/storage/fancy/crayons/update_icon_state() + return + + +/obj/item/storage/fancy/crayons/update_overlays() + . = ..() for(var/obj/item/toy/crayon/crayon in contents) - overlays += image('icons/obj/crayons.dmi',crayon.colourName) + . += crayon.colourName + -/obj/item/storage/fancy/crayons/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/toy/crayon)) - switch(W:colourName) +/obj/item/storage/fancy/crayons/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/crayon = I + switch(crayon.colourName) if("mime") to_chat(usr, "This crayon is too sad to be contained in this box.") return @@ -182,58 +194,57 @@ for(var/i = 1 to storage_slots) new cigarette_type(src) -/obj/item/storage/fancy/cigarettes/update_icon() //lazy as hell - switch(contents.len) +/obj/item/storage/fancy/cigarettes/update_icon_state() + var/init_state = initial(icon_state) + switch(length(contents)) if(17 to INFINITY) - icon_state = "[initial(icon_state)]6" + icon_state = "[init_state]6" if(14 to 16) - icon_state = "[initial(icon_state)]5" + icon_state = "[init_state]5" if(11 to 13) - icon_state = "[initial(icon_state)]4" + icon_state = "[init_state]4" if(7 to 10) - icon_state = "[initial(icon_state)]3" + icon_state = "[init_state]3" if(4 to 6) - icon_state = "[initial(icon_state)]2" + icon_state = "[init_state]2" if(1 to 3) - icon_state = "[initial(icon_state)]1" + icon_state = "[init_state]1" else - icon_state = "[initial(icon_state)]0" - -/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(!istype(M, /mob)) - return - - if(istype(M) && M == user && user.zone_selected == "mouth" && contents.len > 0 && !user.wear_mask) - var/got_cig = 0 - for(var/num=1, num <= contents.len, num++) - var/obj/item/I = contents[num] - if(istype(I, /obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/C = I - user.equip_to_slot_if_possible(C, slot_wear_mask) - to_chat(user, "You take \a [C.name] out of the pack.") - update_icon() - got_cig = 1 - break - if(!got_cig) - to_chat(user, "There are no smokables in the pack!") + icon_state = "[init_state]0" + + +/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/human/target, mob/living/carbon/user) + if(!ishuman(target) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH) + return ..() + + var/obj/item/clothing/mask/cigarette/cigar = locate() in src + if(!cigar) + to_chat(user, span_warning("There are no smokables in the pack!")) + return TRUE + + if(target.equip_to_slot_if_possible(cigar, slot_wear_mask, disable_warning = TRUE)) + to_chat(user, span_notice("You took \a [cigar.name] out of the pack[target != user ? " and deftly place it in [target] mouth" : ""].")) else - ..() + to_chat(user, span_warning("Something is blocking [target] mouth!")) + + return TRUE -/obj/item/storage/fancy/cigarettes/can_be_inserted(obj/item/W as obj, stop_messages = 0) + +/obj/item/storage/fancy/cigarettes/can_be_inserted(obj/item/W , stop_messages = 0) if(istype(W, /obj/item/match)) - var/obj/item/match/M = W - if(M.lit == 1) + var/obj/item/match/match = W + if(match.lit) if(!stop_messages) - to_chat(usr, "Putting a lit [W] in [src] probably isn't a good idea.") - return 0 + to_chat(usr, span_notice("Putting a lit [W] in [src] probably isn't a good idea.")) + return FALSE if(istype(W, /obj/item/lighter)) - var/obj/item/lighter/L = W - if(L.lit == 1) + var/obj/item/lighter/lighter = W + if(lighter.lit) if(!stop_messages) - to_chat(usr, "Putting [W] in [src] while lit probably isn't a good idea.") - return 0 - //if we get this far, handle the insertion checks as normal - .=..() + to_chat(usr, span_notice("Putting [W] in [src] while lit probably isn't a good idea.")) + return FALSE + return ..() + /obj/item/storage/fancy/cigarettes/decompile_act(obj/item/matter_decompiler/C, mob/user) if(!length(contents)) @@ -336,10 +347,15 @@ for(var/i in 1 to storage_slots) new /obj/item/rollingpaper(src) -/obj/item/storage/fancy/rollingpapers/update_icon() - overlays.Cut() - if(!contents.len) - overlays += "[icon_state]_empty" + +/obj/item/storage/fancy/crayons/update_icon_state() + return + + +/obj/item/storage/fancy/rollingpapers/update_icon_state() + . = ..() + if(!length(contents)) + . += "[icon_state]_empty" /* * cigcase @@ -353,10 +369,10 @@ storage_slots = 7 can_hold = list(/obj/item/clothing/mask/cigarette/cigar) -/obj/item/storage/fancy/cigcase/update_icon(var/itemremoved = 0) - var/total_contents = src.contents.len - itemremoved - src.icon_state = "[src.icon_type]case[total_contents]" - return + +/obj/item/storage/fancy/cigcase/update_icon_state() + icon_state = "[icon_type]case[length(contents)]" + /obj/item/storage/fancy/cigcase/populate_contents() for(var/I = 1 to storage_slots) @@ -390,27 +406,25 @@ storage_slots = 6 req_access = list(ACCESS_VIROLOGY) + /obj/item/storage/lockbox/vials/populate_contents() for(var/I = 1 to storage_slots) new /obj/item/reagent_containers/glass/beaker/vial(src) update_icon() -/obj/item/storage/lockbox/vials/update_icon(var/itemremoved = 0) - var/total_contents = src.contents.len - itemremoved - src.icon_state = "vialbox[total_contents]" - src.overlays.Cut() + +/obj/item/storage/lockbox/vials/update_icon_state() + icon_state = "vialbox[length(contents)]" + + +/obj/item/storage/lockbox/vials/update_overlays() + . = ..() if(!broken) - overlays += image(icon, src, "led[locked]") + . += "led[locked]" if(locked) - overlays += image(icon, src, "cover") + . += "cover" else - overlays += image(icon, src, "ledb") - return - -/obj/item/storage/lockbox/vials/attackby(obj/item/W as obj, mob/user as mob, params) - ..() - update_icon() - + . += "ledb" ///Aquatic Starter Kit diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 6bc66cb282c..6b33df174aa 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -353,22 +353,25 @@ new /obj/item/reagent_containers/food/pill/charcoal(src) new /obj/item/reagent_containers/food/pill/charcoal(src) -/obj/item/storage/pill_bottle/MouseDrop(obj/over_object as obj) // Best utilized if you're a cantankerous doctor with a Vicodin habit. - if(iscarbon(over_object)) - var/mob/living/carbon/C = over_object - if(loc == C && src == C.get_active_hand()) - if(!contents.len) - to_chat(C, "There is nothing in [src]!") - return - C.visible_message("[C] [rapid_intake_message]") - if(do_mob(C, C, 100)) // 10 seconds - for(var/obj/item/reagent_containers/food/pill/P in contents) - P.attack(C, C) - C.visible_message("[C] [rapid_post_instake_message]") - return + +/obj/item/storage/pill_bottle/MouseDrop(mob/living/carbon/user, src_location, over_location, src_control, over_control, params) // Best utilized if you're a cantankerous doctor with a Vicodin habit. + if(iscarbon(user) && src == user.get_active_hand()) + if(!length(contents)) + to_chat(user, span_notice("There is nothing in [src]!")) + return FALSE + + user.visible_message(span_danger("[user] [rapid_intake_message]")) + if(!do_mob(user, user, 10 SECONDS) || src != user.get_active_hand()) + return FALSE + + for(var/obj/item/reagent_containers/food/pill/pill in src) + pill.attack(user, user) + user.visible_message(span_danger("[user] [rapid_post_instake_message]")) + return FALSE return ..() + /obj/item/storage/pill_bottle/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/pen) || istype(I, /obj/item/flashlight/pen)) rename_interactive(user, I) diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index e9f3455468a..1c08db71d6e 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -34,70 +34,36 @@ * If you are using these you will probably want to override attackby() as well. * See /obj/item/clothing/suit/storage for an example. * Items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour. - * Returns `TRUE` if the master item's parent's MouseDrop() should be called, `FALSE` otherwise. It's strange, but no other way of + * Returns `FALSE` if the master item's parent's MouseDrop() should be called, `TRUE` otherwise. It's strange, but no other way of * doing it without the ability to call another proc's parent, really. */ -/obj/item/storage/internal/proc/handle_mousedrop(mob/user, obj/over_object) - if(ishuman(user)) //so monkeys can take off their backpacks -- Urist - - if(istype(user.loc,/obj/mecha)) // stops inventory actions in a mech - return FALSE - - if(over_object == user && Adjacent(user)) // this must come before the screen objects only block - src.open(user) - return FALSE - - if(!(istype(over_object, /obj/screen))) - return TRUE - - //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away. - //there's got to be a better way of doing this... - if(!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) - return FALSE - - if(!(user.restrained() ) && !(user.stat)) - switch(over_object.name) - if("r_hand") - if(!master_item.remove_item_from_storage(drop_location())) - user.drop_item_ground(master_item) - user.put_in_r_hand(master_item) - if("l_hand") - if(!master_item.remove_item_from_storage(drop_location())) - user.drop_item_ground(master_item) - user.put_in_l_hand(master_item) - master_item.add_fingerprint(user) - return FALSE - return FALSE +/obj/item/storage/internal/proc/handle_mousedrop(mob/living/carbon/human/user, obj/over_object) + . = FALSE + if(over_object == user && ishuman(user) && !user.incapacitated() && !ismecha(user.loc) && !is_ventcrawling(user) && user.Adjacent(master_item)) + open(user) + master_item.add_fingerprint(user) + return TRUE /** * Items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour. - * Returns `TRUE` if the master item's parent's attack_hand() should be called, 0 otherwise. + * Returns `FALSE` if the master item's parent's attack_hand() should be called, `TRUE` otherwise. * It's strange, but no other way of doing it without the ability to call another proc's parent, really. */ -/obj/item/storage/internal/proc/handle_attack_hand(mob/user) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket. - H.put_in_hands(master_item) - H.l_store = null - return FALSE - if(H.r_store == master_item && !H.get_active_hand()) - H.put_in_hands(master_item) - H.r_store = null - return FALSE - - src.add_fingerprint(user) - if(master_item.loc == user) - src.open(user) +/obj/item/storage/internal/proc/handle_attack_hand(mob/living/carbon/human/user) + . = TRUE + if(master_item.loc != user || !ishuman(user) || user.incapacitated() || ismecha(user.loc) || is_ventcrawling(user)) return FALSE - for(var/mob/M in range(1, master_item.loc)) - if(M.s_active == src) - src.close(M) - return TRUE + //Prevents opening if it's in a pocket. + if(!user.get_active_hand() && (master_item == user.l_store || master_item == user.r_store)) + user.temporarily_remove_item_from_inventory(master_item) + user.put_in_hands(master_item) + return . + open(user) + master_item.add_fingerprint(user) -/obj/item/storage/internal/Adjacent(var/atom/neighbor) + +/obj/item/storage/internal/Adjacent(atom/neighbor) return master_item.Adjacent(neighbor) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index e48f0e8d6cc..c001c82d5ac 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -8,12 +8,20 @@ max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. storage_slots = 4 req_access = list(ACCESS_ARMORY) - var/locked = 1 - var/broken = 0 + var/locked = TRUE + var/broken = FALSE var/icon_locked = "lockbox+l" var/icon_closed = "lockbox" var/icon_broken = "lockbox+b" + +/obj/item/storage/lockbox/update_icon_state() + if(broken) + icon_state = icon_broken + return + icon_state = locked ? icon_locked : icon_closed + + /obj/item/storage/lockbox/attackby(obj/item/I, mob/user, params) if(I.GetID()) if(broken) @@ -21,14 +29,13 @@ return if(check_access(I)) locked = !locked + update_icon() if(locked) - icon_state = icon_locked to_chat(user, "You lock \the [src]!") if(user.s_active) user.s_active.close(user) return else - icon_state = icon_closed to_chat(user, "You unlock \the [src]!") origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. return @@ -42,36 +49,39 @@ ..() else to_chat(user, "It's locked!") - return -/obj/item/storage/lockbox/show_to(mob/user as mob) + +/obj/item/storage/lockbox/show_to(mob/user) if(locked) to_chat(user, "It's locked!") else ..() return + /obj/item/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0) if(!locked) return ..() if(!stop_messages) to_chat(usr, "[src] is locked!") - return 0 + return FALSE + /obj/item/storage/lockbox/emag_act(mob/user) if(!broken) add_attack_logs(user, src, "emagged") - broken = 1 - locked = 0 + broken = TRUE + locked = FALSE desc = "It appears to be broken." - icon_state = icon_broken + update_icon() if(user) to_chat(user, "You unlock \the [src].") origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. -/obj/item/storage/lockbox/hear_talk(mob/living/M as mob, list/message_pieces) -/obj/item/storage/lockbox/hear_message(mob/living/M as mob, msg) +/obj/item/storage/lockbox/hear_talk(mob/living/M, list/message_pieces) + +/obj/item/storage/lockbox/hear_message(mob/living/M, msg) /obj/item/storage/lockbox/mindshield name = "Lockbox (Mindshield Implants)" @@ -83,6 +93,9 @@ new /obj/item/implantcase/mindshield(src) new /obj/item/implanter/mindshield(src) +/obj/item/storage/lockbox/mindshield/ert + w_class = WEIGHT_CLASS_NORMAL + /obj/item/storage/lockbox/sibyl_system_mod name = "lockbox (Sibyl System Mods)" desc = "Contains proprietary Sibyl System mods for energy guns." @@ -126,6 +139,7 @@ name = "lockbox (T4)" desc = "Contains three T4 breaching charges." req_access = list(ACCESS_CENT_SPECOPS) + w_class = WEIGHT_CLASS_NORMAL /obj/item/storage/lockbox/t4/populate_contents() for(var/I in 1 to 3) diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 77376ffa221..f0360a18106 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -27,11 +27,21 @@ max_w_class = WEIGHT_CLASS_SMALL max_combined_w_class = 14 + /obj/item/storage/secure/examine(mob/user) . = ..() if(in_range(user, src)) . += "The service panel is [open ? "open" : "closed"]." + +/obj/item/storage/secure/update_overlays() + . = ..() + if(emagged) + . += icon_locking + else if(!locked) + . += icon_opened + + /obj/item/storage/secure/populate_contents() new /obj/item/paper(src) new /obj/item/pen(src) @@ -41,13 +51,13 @@ if((istype(W, /obj/item/melee/energy/blade)) && (!emagged)) emag_act(user, W) - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) if(do_after(user, 20 * W.toolspeed * gettoolspeedmod(user), target = src)) open = !open user.show_message("You [open ? "open" : "close"] the service panel.", 1) return - if((istype(W, /obj/item/multitool)) && (open) && (!l_hacking)) + if((W.tool_behaviour = TOOL_MULTITOOL) && (open) && (!l_hacking)) user.show_message("Now attempting to reset internal memory, please hold.", 1) l_hacking = TRUE if(do_after(user, 100 * W.toolspeed * gettoolspeedmod(user), target = src)) @@ -70,30 +80,34 @@ return ..() + /obj/item/storage/secure/emag_act(mob/user, obj/weapon) - if(!emagged) - add_attack_logs(user, src, "emagged") - emagged = TRUE - overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - overlays.Cut() - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = FALSE - if(istype(weapon, /obj/item/melee/energy/blade)) - do_sparks(5, 0, loc) - playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(user) - to_chat(user, "You slice through the lock on [src].") - else if(user) - to_chat(user, "You short out the lock on [src].") + if(emagged) + return + + add_attack_logs(user, src, "emagged") + emagged = TRUE + locked = FALSE + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, icon_sparking), 1 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) + + if(istype(weapon, /obj/item/melee/energy/blade)) + do_sparks(5, 0, loc) + playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + if(user) + to_chat(user, "You slice through the lock on [src].") + else if(user) + to_chat(user, "You short out the lock on [src].") + /obj/item/storage/secure/AltClick(mob/living/user) if(istype(user) && !try_to_open()) return FALSE return ..() -/obj/item/storage/secure/MouseDrop(over_object, src_location, over_location) +/obj/item/storage/secure/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) if(!try_to_open()) return FALSE return ..() @@ -138,8 +152,8 @@ switch(action) if("close") locked = TRUE - overlays.Cut() code = null + update_icon(UPDATE_OVERLAYS) close(usr) if("setnumber") switch(params["buttonValue"]) @@ -150,9 +164,8 @@ to_chat(usr, "The code was set successfully.") else if((code == l_code) && l_set) locked = FALSE - overlays.Cut() - overlays += image('icons/obj/storage.dmi', icon_opened) code = null + update_icon(UPDATE_OVERLAYS) else code = "ERROR" if("R") @@ -232,7 +245,7 @@ force = 8 w_class = WEIGHT_CLASS_HUGE max_w_class = 8 - anchored = 1 + anchored = TRUE density = 0 cant_hold = list(/obj/item/storage/secure/briefcase) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index ce9e95495ac..5f06e4bc428 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -9,6 +9,7 @@ name = "storage" icon = 'icons/obj/storage.dmi' w_class = WEIGHT_CLASS_NORMAL + flags_2 = BLOCKS_LIGHT_2 ///No message on putting items in var/silent = FALSE ///List of objects which this item can store (if set, it can't store anything else) @@ -98,40 +99,44 @@ continue hide_from(player) -/obj/item/storage/MouseDrop(obj/over_object) - if(ishuman(usr)) //so monkeys can take off their backpacks -- Urist - var/mob/M = usr - if(istype(M.loc,/obj/mecha) || M.incapacitated(FALSE, TRUE, TRUE)) // Stops inventory actions in a mech as well as while being incapacitated - return +/obj/item/storage/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(!ishuman(usr)) + return FALSE - if(over_object == M && Adjacent(M)) // this must come before the screen objects only block - if(M.s_active) - M.s_active.close(M) - open(M) - return + var/mob/living/carbon/human/user = usr - if((istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor)) \ - && contents.len && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && over_object.Adjacent(usr) \ - && !istype(src, /obj/item/storage/lockbox)) - var/turf/T = get_turf(over_object) - if(istype(over_object, /turf/simulated/floor)) - if(get_turf(usr) != T) - return // Can only empty containers onto the floor under you - if("Yes" != alert(usr,"Empty \the [src] onto \the [T]?","Confirm","Yes","No")) - return - if(!(usr && over_object && contents.len && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && get_turf(usr) == T)) - return // Something happened while the player was thinking - hide_from(usr) - usr.face_atom(over_object) - usr.visible_message("[usr] empties \the [src] onto \the [over_object].", - "You empty \the [src] onto \the [over_object].") - for(var/obj/item/I in contents) - remove_from_storage(I, T) - update_icon() // For content-sensitive icons - return + // Stops inventory actions in a mech, while ventcrawling and while being incapacitated + if(ismecha(user.loc) || is_ventcrawling(user) || user.incapacitated(FALSE, TRUE, TRUE)) + return FALSE + + if(over_object == user && user.Adjacent(src)) // this must come before the screen objects only block + open(user) + return FALSE + + if((!istype(src, /obj/item/storage/lockbox) && (istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor)) \ + && length(contents) && loc == user && !user.incapacitated() && user.Adjacent(over_object))) + + if(alert(user, "Empty [src] onto [over_object]?", "Confirm", "Yes", "No") != "Yes") + return FALSE + + if(!user || !over_object || user.incapacitated() || loc != user || !user.Adjacent(over_object)) + return FALSE + + close(user) + user.face_atom(over_object) + user.visible_message( + span_notice("[user] empties [src] onto [over_object]."), + span_notice("You empty [src] onto [over_object]."), + ) + var/turf/object_turf = get_turf(over_object) + for(var/obj/item/item in src) + remove_from_storage(item, object_turf) + + update_icon() // For content-sensitive icons + return FALSE - return ..() + return ..() /obj/item/storage/AltClick(mob/user) @@ -186,6 +191,14 @@ if(user.s_active == src) user.s_active = null + +/obj/item/storage/proc/hide_from_all_viewers() + if(!LAZYLEN(mobs_viewing)) + return + for(var/mob/viewer as anything in mobs_viewing) + hide_from(viewer) + + /obj/item/storage/proc/update_viewers() for(var/_M in mobs_viewing) var/mob/M = _M @@ -438,7 +451,7 @@ if(istype(src, /obj/item/storage/fancy)) var/obj/item/storage/fancy/F = src - F.update_icon(TRUE) + F.update_icon() for(var/_M in mobs_viewing) var/mob/M = _M diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index b27d66f347e..86dd971d773 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -35,56 +35,70 @@ var/obj/item/card/id/front_id = null var/image/front_id_overlay = null -/obj/item/storage/wallet/proc/id_check() - front_id = (locate(/obj/item/card/id) in contents) - if(!front_id) - name = "[item_color] leather wallet" - return FALSE - name = "[item_color] leather wallet with [front_id] on the front" - return TRUE -/obj/item/storage/wallet/remove_from_storage(obj/item/W, atom/new_location) - . = ..(W, new_location) - if(.) - id_check() - update_icon() +/obj/item/storage/wallet/remove_from_storage(obj/item/I, atom/new_location) + . = ..() + if(. && istype(I, /obj/item/card/id)) + refresh_ID() + + +/obj/item/storage/wallet/handle_item_insertion(obj/item/I, prevent_warning = FALSE) + . = ..() + if(. && istype(I, /obj/item/card/id)) + refresh_ID() -/obj/item/storage/wallet/handle_item_insertion(obj/item/W, prevent_warning = 0) - . = ..(W, prevent_warning) - if(.) - id_check() - update_icon() /obj/item/storage/wallet/swap_items(obj/item/item_1, obj/item/item_2, mob/user) - . = ..(item_1, item_2, user) + . = ..() if(.) - id_check() - update_icon() + refresh_ID() + +/obj/item/storage/wallet/orient2hud(mob/user) + . = ..() + refresh_ID() + + +/obj/item/storage/wallet/proc/refresh_ID() + // Locate the first ID in the wallet + front_id = (locate(/obj/item/card/id) in contents) -/obj/item/storage/wallet/update_icon() if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.wear_id == src) - H.sec_hud_set_ID() - overlays -= front_id_overlay + var/mob/living/carbon/human/wearing_human = loc + if(wearing_human.wear_id == src) + wearing_human.sec_hud_set_ID() + + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) + + +/obj/item/storage/wallet/update_overlays() + . = ..() if(!front_id) - front_id_overlay = null return var/front_id_icon_state_holder = front_id.icon_state - if (copytext(front_id_icon_state_holder,1,4) == "ERT") + if(copytext(front_id_icon_state_holder,1,4) == "ERT") front_id_icon_state_holder = "ERT" else if(!(front_id_icon_state_holder in icon_states(src.icon))) front_id_icon_state_holder = "id" - front_id_overlay = image('icons/obj/wallets.dmi', front_id_icon_state_holder) - overlays += front_id_overlay + . += mutable_appearance('icons/obj/wallets.dmi', front_id_icon_state_holder) + + +/obj/item/storage/wallet/update_name(updates = ALL) + . = ..() + if(front_id) + name = "[item_color] leather wallet with [front_id] on the front" + else + name = "[item_color] leather wallet" + /obj/item/storage/wallet/GetID() return front_id ? front_id : ..() + /obj/item/storage/wallet/GetAccess() return front_id ? front_id.GetAccess() : ..() + /obj/item/storage/wallet/random/populate_contents() var/cash = pick(/obj/item/stack/spacecash, /obj/item/stack/spacecash/c10, @@ -110,6 +124,7 @@ icon = 'icons/obj/wallets.dmi' item_state = "wallet" + /obj/item/storage/wallet/color/Initialize(mapload) . = ..() if(!item_color) @@ -117,31 +132,17 @@ new color_wallet(src.loc) qdel(src) return - UpdateDesc() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) -/obj/item/storage/wallet/color/proc/UpdateDesc() - name = "[item_color] wallet" - desc = "[item_color] wallet made from... leather?" - icon_state = "[item_color]_wallet" +/obj/item/storage/wallet/color/update_icon_state() + icon_state = "[item_color]_wallet" -/obj/item/storage/wallet/color/remove_from_storage(obj/item/W, atom/new_location) - . = ..(W, new_location) - if(.) - id_check() - update_icon() -/obj/item/storage/wallet/color/handle_item_insertion(obj/item/W, prevent_warning = 0) - . = ..(W, prevent_warning) - if(.) - id_check() - update_icon() +/obj/item/storage/wallet/color/update_desc(updates = ALL) + . = ..() + desc = "[item_color] wallet made from... leather?" -/obj/item/storage/wallet/color/swap_items(obj/item/item_1, obj/item/item_2, mob/user) - . = ..(item_1, item_2, user) - if(.) - id_check() - update_icon() /obj/item/storage/wallet/color/blue item_color = "blue" diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index cf670bd194f..526780bc215 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -54,14 +54,18 @@ A.UpdateButtonIcon() +/obj/item/tank/jetpack/update_icon_state() + icon_state = "[initial(icon_state)][on ? "-on" : ""]" + + /obj/item/tank/jetpack/proc/turn_on(mob/user) on = TRUE - icon_state = "[initial(icon_state)]-on" + update_icon(UPDATE_ICON_STATE) /obj/item/tank/jetpack/proc/turn_off(mob/user) on = FALSE stabilizers = FALSE - icon_state = initial(icon_state) + update_icon(UPDATE_ICON_STATE) /obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user, should_leave_trail) if(!on) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index b592c3d220a..e9040c412c3 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -62,7 +62,7 @@ if(!silent) to_chat(C, "You are not wearing a suitable mask or helmet.") return FALSE - if(M.mask_adjusted) // If the mask is equipped but pushed down + if(M.up) // If the mask is equipped but pushed down M.adjustmask(C) // Adjust it back if(!silent) diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 357d0ccabef..ea7891ca7b9 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -190,12 +190,28 @@ /obj/item/watertank/atmos/make_noz() return new /obj/item/extinguisher/mini/nozzle(src) + +/obj/item/watertank/atmos/update_icon_state() + var/obj/item/extinguisher/mini/nozzle/our_noz = noz + switch(our_noz.nozzle_mode) + if(EXTINGUISHER) + icon_state = "waterbackpackatmos_0" + if(NANOFROST) + icon_state = "waterbackpackatmos_1" + if(METAL_FOAM) + icon_state = "waterbackpackatmos_2" + else + icon_state = "waterbackpackatmos" + + /obj/item/watertank/atmos/dropped(mob/user, silent = FALSE) - ..() - icon_state = "waterbackpackatmos" - if(istype(noz, /obj/item/extinguisher/mini/nozzle)) - var/obj/item/extinguisher/mini/nozzle/N = noz - N.nozzle_mode = 0 + . = ..() + if(!noz) + return + var/obj/item/extinguisher/mini/nozzle/our_noz = noz + our_noz.nozzle_mode = NONE + update_icon(UPDATE_ICON_STATE) + /obj/item/extinguisher/mini/nozzle name = "extinguisher nozzle" @@ -210,11 +226,12 @@ cooling_power = 5 w_class = WEIGHT_CLASS_HUGE flags = NODROP //Necessary to ensure that the nozzle and tank never seperate - var/obj/item/watertank/tank - var/nozzle_mode = 0 + var/obj/item/watertank/atmos/tank + var/nozzle_mode = NONE var/metal_synthesis_cooldown = 0 var/nanofrost_cooldown = 0 + /obj/item/extinguisher/mini/nozzle/New(parent_tank) . = ..() if(check_tank_exists(parent_tank, src)) @@ -222,32 +239,30 @@ reagents = tank.reagents max_water = tank.volume loc = tank - return + /obj/item/extinguisher/mini/nozzle/Move() . = ..() if(tank && loc != tank.loc) loc = tank - return -/obj/item/extinguisher/mini/nozzle/attack_self(mob/user as mob) + +/obj/item/extinguisher/mini/nozzle/attack_self(mob/user) switch(nozzle_mode) if(EXTINGUISHER) nozzle_mode = NANOFROST - tank.icon_state = "waterbackpackatmos_1" to_chat(user, "Swapped to nanofrost launcher") - return + if(NANOFROST) nozzle_mode = METAL_FOAM - tank.icon_state = "waterbackpackatmos_2" to_chat(user, "Swapped to metal foam synthesizer") - return + if(METAL_FOAM) nozzle_mode = EXTINGUISHER - tank.icon_state = "waterbackpackatmos_0" to_chat(user, "Swapped to water extinguisher") - return - return + + tank.update_icon(UPDATE_ICON_STATE) + /obj/item/extinguisher/mini/nozzle/dropped(mob/user, silent = FALSE) ..() diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index a66470628d4..d4cfa546b95 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -9,10 +9,9 @@ amount = 25 max_amount = 25 -/obj/item/stack/tape_roll/New(var/loc, var/amount=null) +/obj/item/stack/tape_roll/New(loc, amount=null) ..() - - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/stack/tape_roll/attack(mob/living/carbon/human/M, mob/living/user) if(!istype(M)) //What good is a duct tape mask if you are unable to speak? @@ -43,7 +42,8 @@ M.equip_to_slot_if_possible(G, slot_wear_mask) G.add_fingerprint(user) -/obj/item/stack/tape_roll/update_icon() + +/obj/item/stack/tape_roll/update_icon_state() var/amount = get_amount() if((amount <= 2) && (amount > 0)) icon_state = "[initial(icon_state)]" @@ -55,7 +55,7 @@ icon_state = "[initial(icon_state)]4" else icon_state = "[initial(icon_state)]4" - ..() + /obj/item/stack/tape_roll/thick name = "incredibly thick tape roll" @@ -90,3 +90,4 @@ var/obj/item/clothing/mask/muzzle/G = new /obj/item/clothing/mask/muzzle/tapegag/thick M.equip_to_slot_if_possible(G, slot_wear_mask) G.add_fingerprint(user) + diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index be1e86f519d..171ab0f1a5e 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -1,103 +1,10 @@ -/* Teleportation devices. - * Contains: - * Locator - * Hand-tele - */ - -/* - * Locator - */ -/obj/item/locator - name = "locator" - desc = "Used to track those with locater implants." - icon = 'icons/obj/device.dmi' - icon_state = "locator" - var/temp = null - var/frequency = 1451 - var/broadcasting = null - var/listening = 1.0 - flags = CONDUCT - w_class = WEIGHT_CLASS_SMALL - item_state = "electronic" - throw_speed = 4 - throw_range = 20 - materials = list(MAT_METAL=400) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - origin_tech = "magnets=3;bluespace=2" - -/obj/item/locator/attack_self(mob/user as mob) - add_fingerprint(user) - var/dat = {""} - if(temp) - dat += "[src.temp]

    Clear" - else - dat += {" -Persistent Signal Locator
    -Frequency: -- -- [format_frequency(src.frequency)] -+ -+
    - -Refresh"} - user << browse(dat, "window=radio") - onclose(user, "radio") - return - -/obj/item/locator/Topic(href, href_list) - if(..()) - return 1 - - var/turf/current_location = get_turf(usr)//What turf is the user on? - if(!current_location || is_admin_level(current_location.z))//If turf was not found or they're in the admin zone - to_chat(usr, "\The [src] is malfunctioning.") - return 1 - - if(href_list["refresh"]) - temp = "Persistent Signal Locator
    " - var/turf/sr = get_turf(src) - - if(sr) - temp += "Located Beacons:
    " - - for(var/obj/item/radio/beacon/W in GLOB.beacons) - if(W.frequency == frequency && !W.syndicate) - if(W && W.z == z) - var/turf/TB = get_turf(W) - temp += "[W.code]: [TB.x], [TB.y], [TB.z]
    " - - temp += "Located Implants:
    " - for(var/obj/item/implant/tracking/T in GLOB.tracked_implants) - if(!T.implanted || !T.imp_in) - continue - var/turf/Tr = get_turf(T) - - if(Tr && Tr.z == sr.z) - temp += "[T.gps_tag]: [Tr.x], [Tr.y], [Tr.z]
    " - - temp += "You are at \[[sr.x],[sr.y],[sr.z]\]." - temp += "

    Refresh
    " - else - temp += "Processing error: Unable to locate orbital position.
    " - else - if(href_list["freq"]) - frequency += text2num(href_list["freq"]) - frequency = sanitize_frequency(frequency) - else - if(href_list["temp"]) - temp = null - - attack_self(usr) - return 1 - -/* - * Hand-tele - */ +/// Hand-tele /obj/item/hand_tele name = "hand tele" desc = "A portable item using blue-space technology." icon = 'icons/obj/device.dmi' icon_state = "hand_tele" + base_icon_state = "hand_tele" item_state = "electronic" throwforce = 0 w_class = WEIGHT_CLASS_SMALL @@ -163,7 +70,7 @@ Frequency: /obj/item/hand_tele/proc/make_inactive(severity) - var/time = rand(20 SECONDS, 30 SECONDS) * severity + var/time = rand(10 SECONDS, 15 SECONDS) * (severity == EMP_HEAVY ? 2 : 1) emp_timer = world.time + time update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, PROC_REF(check_inactive), emp_timer), time) @@ -182,7 +89,7 @@ Frequency: /obj/item/hand_tele/update_icon_state() - icon_state = (emp_timer > world.time) ? icon_state_inactive : initial(icon_state) + icon_state = (emp_timer > world.time) ? icon_state_inactive : base_icon_state /obj/item/hand_tele/portal_destroyed(obj/effect/portal/P) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index df52cc09e1e..515128f65d2 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -115,15 +115,14 @@ resistance_flags = FIRE_PROOF -/obj/item/twohanded/fireaxe/update_icon() //Currently only here to fuck with the on-mob icons. - icon_state = "fireaxe[wielded]" - ..() +/obj/item/twohanded/fireaxe/update_icon_state() //Currently only here to fuck with the on-mob icons. + icon_state = "fireaxe[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/fireaxe/afterattack(atom/A, mob/user, proximity) if(!proximity) return - if(wielded) //destroys windows and grilles in one hit + if(HAS_TRAIT(src, TRAIT_WIELDED)) //destroys windows and grilles in one hit if(istype(A, /obj/structure/window) || istype(A, /obj/structure/grille)) var/obj/structure/W = A W.obj_destruction("fireaxe") @@ -136,8 +135,8 @@ needs_permit = TRUE -/obj/item/twohanded/fireaxe/boneaxe/update_icon() - icon_state = "bone_axe[wielded]" +/obj/item/twohanded/fireaxe/boneaxe/update_icon_state() + icon_state = "bone_axe[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/fireaxe/energized @@ -148,8 +147,8 @@ var/max_charge = 30 -/obj/item/twohanded/fireaxe/energized/update_icon() - if(wielded) +/obj/item/twohanded/fireaxe/energized/update_icon_state() + if(HAS_TRAIT(src, TRAIT_WIELDED)) icon_state = "fireaxe2" else icon_state = "fireaxe0" @@ -171,7 +170,7 @@ /obj/item/twohanded/fireaxe/energized/attack(mob/M, mob/user) . = ..() - if(wielded && charge == max_charge) + if(HAS_TRAIT(src, TRAIT_WIELDED) && charge == max_charge) if(isliving(M)) var/mob/living/target = M charge = 0 @@ -241,27 +240,26 @@ /obj/item/twohanded/dualsaber/IsReflect() - if(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) return TRUE -/obj/item/twohanded/dualsaber/update_icon() - if(wielded) - icon_state = "dualsaber[blade_color][wielded]" - set_light(brightness_on, l_color=colormap[blade_color]) +/obj/item/twohanded/dualsaber/update_icon_state() + if(HAS_TRAIT(src, TRAIT_WIELDED)) + icon_state = "dualsaber[blade_color]1" + set_light(brightness_on, l_color = colormap[blade_color]) else icon_state = "dualsaber0" set_light(0) - ..() /obj/item/twohanded/dualsaber/attack(mob/target, mob/living/user) ..() - if((CLUMSY in user.mutations) && (wielded) && prob(40)) + if((CLUMSY in user.mutations) && HAS_TRAIT(src, TRAIT_WIELDED) && prob(40)) to_chat(user, "You twirl around a bit before losing your balance and impaling yourself on the [src].") user.take_organ_damage(20, 25) return - if((wielded) && prob(50)) + if(HAS_TRAIT(src, TRAIT_WIELDED) && prob(50)) INVOKE_ASYNC(src, PROC_REF(jedi_spin), user) @@ -274,7 +272,7 @@ /obj/item/twohanded/dualsaber/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(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) return ..() return FALSE @@ -344,8 +342,8 @@ var/icon_prefix = "spearglass" -/obj/item/twohanded/spear/update_icon() - icon_state = "[icon_prefix][wielded]" +/obj/item/twohanded/spear/update_icon_state() + icon_state = "[icon_prefix][HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/spear/CheckParts(list/parts_list) @@ -365,7 +363,7 @@ return if(isturf(AM)) //So you can actually melee with it return - if(explosive && wielded) + if(explosive && HAS_TRAIT(src, TRAIT_WIELDED)) explosive.forceMove(AM) explosive.prime() qdel(src) @@ -580,15 +578,12 @@ flags &= ~NODROP -/obj/item/twohanded/chainsaw/update_icon() - if(wielded) - icon_state = "chainsaw[wielded]" - else - icon_state = "chainsaw0" - ..() +/obj/item/twohanded/chainsaw/update_icon_state() + icon_state = "chainsaw[HAS_TRAIT(src, TRAIT_WIELDED)]" + /obj/item/twohanded/chainsaw/attack(mob/living/target, mob/living/user) - if(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) playsound(loc, 'sound/weapons/chainsaw.ogg', 100, 1, -1) //incredibly loud; you ain't goin' for stealth with this thing. Credit to Lonemonk of Freesound for this sound. if(isrobot(target)) ..() @@ -638,9 +633,9 @@ if(charged < 5) charged++ -/obj/item/twohanded/singularityhammer/update_icon() //Currently only here to fuck with the on-mob icons. - icon_state = "mjollnir[wielded]" - ..() +/obj/item/twohanded/singularityhammer/update_icon_state() //Currently only here to fuck with the on-mob icons. + icon_state = "mjollnir[HAS_TRAIT(src, TRAIT_WIELDED)]" + /obj/item/twohanded/singularityhammer/proc/vortex(turf/pull, mob/wielder) for(var/atom/movable/X in orange(5, pull)) @@ -664,7 +659,7 @@ /obj/item/twohanded/singularityhammer/afterattack(atom/A, mob/user, proximity) if(!proximity) return - if(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) if(charged == 5) charged = 0 if(isliving(A)) @@ -699,9 +694,7 @@ /obj/item/twohanded/mjollnir/attack(mob/living/M, mob/user) ..() - if(wielded) - //if(charged == 5) - //charged = 0 + if(HAS_TRAIT(src, TRAIT_WIELDED)) playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(isliving(M)) M.Stun(4 SECONDS) @@ -714,9 +707,9 @@ L.Stun(4 SECONDS) shock(L) -/obj/item/twohanded/mjollnir/update_icon() //Currently only here to fuck with the on-mob icons. - icon_state = "mjollnir[wielded]" - ..() +/obj/item/twohanded/mjollnir/update_icon_state() //Currently only here to fuck with the on-mob icons. + icon_state = "mjollnir[HAS_TRAIT(src, TRAIT_WIELDED)]" + /obj/item/twohanded/knighthammer name = "singuloth knight's hammer" @@ -745,9 +738,9 @@ if(charged < 5) charged++ -/obj/item/twohanded/knighthammer/update_icon() //Currently only here to fuck with the on-mob icons. - icon_state = "knighthammer[wielded]" - ..() +/obj/item/twohanded/knighthammer/update_icon_state() //Currently only here to fuck with the on-mob icons. + icon_state = "knighthammer[HAS_TRAIT(src, TRAIT_WIELDED)]" + /obj/item/twohanded/knighthammer/afterattack(atom/A, mob/user, proximity) if(!proximity) @@ -763,13 +756,13 @@ var/atom/throw_target = get_edge_target_turf(Z, get_dir(src, get_step_away(Z, src))) Z.throw_at(throw_target, 200, 4) playsound(user, 'sound/weapons/marauder.ogg', 50, 1) - else if(wielded && Z.health < 1) + else if(HAS_TRAIT(src, TRAIT_WIELDED) && Z.health < 1) Z.visible_message("[Z.name] was blown to pieces by the power of [name]!", \ "You feel a powerful blow rip you apart!", \ "You hear a heavy impact and the sound of ripping flesh!.") Z.gib() playsound(user, 'sound/weapons/marauder.ogg', 50, 1) - if(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) if(istype(A, /turf/simulated/wall)) var/turf/simulated/wall/Z = A Z.ex_act(2) @@ -816,8 +809,8 @@ force_unwielded = 100 force_wielded = 500000 // Kills you DEAD. -/obj/item/twohanded/pitchfork/update_icon() - icon_state = "pitchfork[wielded]" +/obj/item/twohanded/pitchfork/update_icon_state() + icon_state = "pitchfork[HAS_TRAIT(src, TRAIT_WIELDED)]" /obj/item/twohanded/pitchfork/suicide_act(mob/user) user.visible_message("[user] impales \himself in \his abdomen with [src]! It looks like \he's trying to commit suicide...") @@ -844,7 +837,7 @@ // It's no fun being the lord of all hell if you can't get out of a simple room /obj/item/twohanded/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity) - if(!proximity || !wielded) + if(!proximity || !HAS_TRAIT(src, TRAIT_WIELDED)) return if(istype(target, /turf/simulated/wall)) var/turf/simulated/wall/W = target @@ -872,8 +865,8 @@ embed_chance = 50 embedded_ignore_throwspeed_threshold = TRUE -/obj/item/twohanded/bamboospear/update_icon() - icon_state = "bamboo_spear[wielded]" +/obj/item/twohanded/bamboospear/update_icon_state() + icon_state = "bamboo_spear[HAS_TRAIT(src, TRAIT_WIELDED)]" //pyro claws /obj/item/twohanded/required/pyro_claws @@ -1013,9 +1006,6 @@ w_class = initial(w_class) item_state = "" -/obj/item/twohanded/fishingrod/update_icon() - if(wielded) - icon_state = "fishing_rod[wielded]" - else - icon_state = "fishing_rod0" - ..() +/obj/item/twohanded/fishingrod/update_icon_state() + icon_state = "fishing_rod[HAS_TRAIT(src, TRAIT_WIELDED)]" + diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 6cc621bd3ce..736cca7b9f3 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -349,7 +349,6 @@ В официальных документах эта бита проходит под элегантным названием \"Высокоскоростная система доставки СРП\". \ Выдаваясь только самым верным и эффективным офицерам NanoTrasen, это оружие является одновременно символом статуса \ и инструментом высшего правосудия." - slot_flags = SLOT_BELT w_class = WEIGHT_CLASS_SMALL can_deflect = FALSE @@ -374,22 +373,39 @@ /// Attack verbs when extended (created on Initialize) var/list/attack_verb_on = list("smacked", "struck", "cracked", "beaten") + /obj/item/melee/baseball_bat/homerun/central_command/srt name = "тактическая бита ГСН" desc = "Выдвижная тактическая бита Центрального Командования Nanotrasen. Скорее всего, к этому моменту командование станции уже осознало, что их коленные чашечки не переживут эту встречу." - item_state = "srt_bat_0" item_state_on = "srt_bat_1" icon_state = "srt_bat_0" icon_state_on = "srt_bat_1" -/obj/item/melee/baseball_bat/homerun/central_command/Initialize(mapload) - . = ..() + +/obj/item/melee/baseball_bat/homerun/central_command/update_icon_state() icon_state = on ? icon_state_on : initial(icon_state) + item_state = on ? item_state_on : initial(item_state) + + +/obj/item/melee/baseball_bat/homerun/central_command/proc/toggle(mob/living/user) + on = !on + slot_flags = on ? NONE : SLOT_BELT force = on ? force_on : initial(force) attack_verb = on ? attack_verb_on : initial(attack_verb) w_class = on ? WEIGHT_CLASS_HUGE : WEIGHT_CLASS_SMALL homerun_able = on + homerun_ready = on + update_icon(UPDATE_ICON_STATE) + update_equipped_item() + playsound(loc, extend_sound, 50, TRUE) + add_fingerprint(user) + if(on) + to_chat(user, span_userdanger("Вы активировали [name] - время для правосудия!")) + else + to_chat(user, span_notice("Вы деактивировали [name].")) + + /obj/item/melee/baseball_bat/homerun/central_command/pickup(mob/living/user) if(!(isertmindshielded(user))) @@ -404,31 +420,10 @@ return FALSE return ..() + /obj/item/melee/baseball_bat/homerun/central_command/attack_self(mob/user) - on = !on - icon_state = on ? icon_state_on : initial(icon_state) - if(on) - to_chat(user, "Вы активировали [src.name] - время для правосудия!") - item_state = item_state_on - w_class = WEIGHT_CLASS_HUGE //doesnt fit in backpack when its on for balance - force = force_on - attack_verb = attack_verb_on - homerun_ready = TRUE - else - to_chat(user, "Вы деактивировали [src.name].") - item_state = initial(item_state) - slot_flags = SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - force = initial(force) - attack_verb = initial(attack_verb) - homerun_ready = FALSE - // Update mob hand visuals - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - playsound(loc, extend_sound, 50, TRUE) - add_fingerprint(user) + toggle(user) + /obj/item/claymore/bone name = "bone sword" @@ -441,3 +436,4 @@ armour_penetration = 15 w_class = WEIGHT_CLASS_BULKY block_chance = 30 + diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index ef71c1cc4bf..31751386403 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -193,8 +193,8 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF)) resistance_flags |= ON_FIRE SSfires.processing[src] = src - add_overlay(GLOB.fire_overlay, TRUE) - return 1 + add_overlay(custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay) + return TRUE ///called when the obj is destroyed by fire /obj/proc/burn() @@ -206,7 +206,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e /obj/proc/extinguish() if(resistance_flags & ON_FIRE) resistance_flags &= ~ON_FIRE - cut_overlay(GLOB.fire_overlay, TRUE) + cut_overlay(custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay, TRUE) SSfires.processing -= src ///Called when the obj is hit by a tesla bolt. diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 138cd396ed8..47ba86c7220 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -79,11 +79,11 @@ do_climb(usr) -/obj/structure/MouseDrop_T(var/atom/movable/C, mob/user as mob) - if(..()) - return - if(C == user) +/obj/structure/MouseDrop_T(atom/movable/dropping, mob/user, params) + . = ..() + if(!. && dropping == user) do_climb(user) + return TRUE /obj/structure/proc/density_check() for(var/obj/O in orange(0, src)) @@ -212,18 +212,18 @@ /obj/structure/proc/can_touch(mob/living/user) if(!istype(user)) - return 0 + return FALSE if(!Adjacent(user)) - return 0 + return FALSE if(user.restrained() || user.buckled) - to_chat(user, "You need your hands and legs free for this.") - return 0 - if(user.stat || user.IsParalyzed() || user.IsSleeping() || user.lying || user.IsWeakened()) - return 0 + to_chat(user, span_notice("You need your hands and legs free for this.")) + return FALSE + if(user.incapacitated()) + return FALSE if(issilicon(user)) - to_chat(user, "You need hands for this.") - return 0 - return 1 + to_chat(user, span_notice("You need hands for this.")) + return FALSE + return TRUE /obj/structure/examine(mob/user) . = ..() @@ -235,17 +235,19 @@ var/examine_status = examine_status(user) if(examine_status) . += examine_status + if(climbable) + . += "You can Click-Drag someone to [src] to put them on the table after a short delay." /obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. var/healthpercent = (obj_integrity/max_integrity) * 100 switch(healthpercent) if(50 to 99) - return "It looks slightly damaged." + . += "It looks slightly damaged." if(25 to 50) - return "It appears heavily damaged." + . += "It appears heavily damaged." if(0 to 25) if(!broken) - return "It's falling apart!" + . += "It's falling apart!" /obj/structure/proc/prevents_buckled_mobs_attacking() return FALSE diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index f7060c17f70..607555ec888 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -150,7 +150,7 @@ return ..() -/obj/structure/alien/resin/door/update_icon() +/obj/structure/alien/resin/door/update_icon_state() switch(state) if(RESIN_DOOR_CLOSED) icon_state = "resin_door_closed" @@ -460,18 +460,35 @@ status = BURST icon_state = "egg_hatched" -/obj/structure/alien/egg/New() - new /obj/item/clothing/mask/facehugger(src) - ..() - if(status == BURST) - obj_integrity = integrity_failure - else if(status != GROWN) - spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME)) - Grow() + +/obj/structure/alien/egg/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) + switch(status) + if(GROWING) + new /obj/item/clothing/mask/facehugger(src) + addtimer(CALLBACK(src, PROC_REF(Grow)), rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME)) + if(GROWN) + new /obj/item/clothing/mask/facehugger(src) + AddComponent(/datum/component/proximity_monitor) + if(BURST) + obj_integrity = integrity_failure + + +/obj/structure/alien/egg/update_icon_state() + switch(status) + if(GROWING) + icon_state = "egg_growing" + if(GROWN) + icon_state = "egg" + if(BURST) + icon_state = "egg_hatched" + /obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user) return attack_hand(user) + /obj/structure/alien/egg/attack_hand(mob/living/user) if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)) switch(status) @@ -485,7 +502,7 @@ return if(GROWN) to_chat(user, "You retrieve the child.") - Burst(0) + Burst(kill = FALSE) return else to_chat(user, "It feels slimy.") @@ -495,51 +512,62 @@ /obj/structure/alien/egg/proc/GetFacehugger() return locate(/obj/item/clothing/mask/facehugger) in contents + /obj/structure/alien/egg/proc/Grow() - icon_state = "egg" status = GROWN + update_icon(UPDATE_ICON_STATE) AddComponent(/datum/component/proximity_monitor) + +///Need to carry the kill from Burst() to Hatch(), this section handles the alien opening the egg /obj/structure/alien/egg/proc/Burst(kill = TRUE) //drops and kills the hugger if any is remaining if(status == GROWN || status == GROWING) playsound(get_turf(src), 'sound/creatures/alien/xeno_egg_crack.ogg', 50) - icon_state = "egg_hatched" flick("egg_opening", src) status = BURSTING qdel(GetComponent(/datum/component/proximity_monitor)) - spawn(15) - status = BURST - var/obj/item/clothing/mask/facehugger/child = GetFacehugger() - if(child) - child.loc = get_turf(src) - if(kill && istype(child)) - child.Die() - else - for(var/mob/M in range(1,src)) - if(CanHug(M)) - child.Attach(M) - break + addtimer(CALLBACK(src, PROC_REF(Hatch), kill), 1.5 SECONDS) + + +///We now check HOW the hugger is hatching, kill carried from Burst() and obj_break() +/obj/structure/alien/egg/proc/Hatch(kill) + status = BURST + update_icon(UPDATE_ICON_STATE) + var/obj/item/clothing/mask/facehugger/child = GetFacehugger() + if(!child) + return + child.forceMove(get_turf(src)) + if(kill) + child.Die() + return + for(var/mob/living/victim in range(1, src)) + if(CanHug(victim)) + child.Attach(victim) + break + /obj/structure/alien/egg/obj_break(damage_flag) - if(!(flags & NODECONSTRUCT)) - if(status != BURST) - Burst(kill = TRUE) + if(!(flags & NODECONSTRUCT) && status != BURST) + Burst(kill = TRUE) + /obj/structure/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() if(exposed_temperature > 500) take_damage(5, BURN, 0, 0) + /obj/structure/alien/egg/HasProximity(atom/movable/AM) if(status == GROWN) if(!CanHug(AM)) return - var/mob/living/carbon/C = AM - if(C.stat == CONSCIOUS && C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)) + var/mob/living/carbon/target = AM + if(iscarbon(target) && target.stat == CONSCIOUS && target.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)) return - Burst(0) + Burst(kill = FALSE) + #undef BURST #undef BURSTING diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index c71ec0075d7..38f3a956792 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -6,6 +6,7 @@ req_access = list(ACCESS_BAR) max_integrity = 500 integrity_failure = 250 + blocks_emissive = FALSE armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) var/list/barsigns=list() var/list/hiddensigns diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index f6398b2f16e..d3e03623d6a 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -246,7 +246,7 @@ LINEN BINS desc = "A linen bin. It looks rather cosy." icon = 'icons/obj/structures.dmi' icon_state = "linenbin-full" - anchored = 1 + anchored = TRUE resistance_flags = FLAMMABLE max_integrity = 70 var/amount = 20 @@ -263,7 +263,7 @@ LINEN BINS else . += "There are [amount] bed sheets in the bin." -/obj/structure/bedsheetbin/update_icon() +/obj/structure/bedsheetbin/update_icon_state() switch(amount) if(0) icon_state = "linenbin-empty" @@ -276,13 +276,13 @@ LINEN BINS /obj/structure/bedsheetbin/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) if(amount) amount = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) ..() /obj/structure/bedsheetbin/burn() amount = 0 extinguish() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/bedsheetbin/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/bedsheet)) @@ -338,7 +338,7 @@ LINEN BINS B.loc = loc to_chat(user, "You telekinetically remove [B] from [src].") - update_icon() + update_icon(UPDATE_ICON_STATE) if(hidden) hidden.loc = loc diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index 1d2d70ebdf1..2f0f691800e 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -3,104 +3,103 @@ desc = "Rack that holds coats." icon = 'icons/obj/coatrack.dmi' icon_state = "coatrack0" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE var/obj/item/clothing/suit/coat - var/list/allowed = list( + var/static/list/allowed = list( /obj/item/clothing/suit/storage/labcoat, /obj/item/clothing/suit/storage/det_suit, /obj/item/clothing/suit/storage/blueshield, /obj/item/clothing/suit/leathercoat, - /obj/item/clothing/suit/browntrenchcoat + /obj/item/clothing/suit/browntrenchcoat, ) + /obj/structure/coatrack/Initialize(mapload) . = ..() icon_state = "coatrack[rand(0, 1)]" + /obj/structure/coatrack/attack_hand(mob/living/user) if(coat) add_fingerprint(user) - user.visible_message("[user] takes [coat] off \the [src].", "You take [coat] off the \the [src].") + user.visible_message("[user] takes [coat] off [src].", "You take [coat] off [src].") coat.forceMove_turf() user.put_in_active_hand(coat, ignore_anim = FALSE) coat = null - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/structure/coatrack/attackby(obj/item/W, mob/living/user, params) - var/can_hang = FALSE - for(var/T in allowed) - if(istype(W,T)) - can_hang = TRUE - break - if(can_hang && !coat) - add_fingerprint(user) - user.visible_message("[user] hangs [W] on \the [src].", "You hang [W] on the \the [src].") - coat = W - user.drop_transfer_item_to_loc(W, src) - update_icon() - else +/obj/structure/coatrack/attackby(obj/item/W, mob/living/user, params) + if(!move_on_rack(W, user)) return ..() -/obj/structure/coatrack/MouseDrop_T(obj/item/W, mob/user) + +/obj/structure/coatrack/MouseDrop_T(obj/item/I, mob/user, params) + . = TRUE + move_on_rack(I, user) + + +/obj/structure/coatrack/Bumped(atom/movable/moving_atom) + . = ..() + move_on_rack(moving_atom) + + +/obj/structure/coatrack/proc/move_on_rack(atom/movable/moving_atom, mob/living/user) + . = FALSE + if(coat) + return . + var/can_hang = FALSE - for(var/T in allowed) - if(istype(W,T)) + for(var/check_type in allowed) + if(istype(moving_atom, check_type)) can_hang = TRUE break - if(can_hang && !coat) - add_fingerprint(user) - user.visible_message("[user] hangs [W] on \the [src].", "You hang [W] on the \the [src].") - coat = W - user.drop_transfer_item_to_loc(W, src) - update_icon() - else - return ..() + if(can_hang) + if(user && !user.drop_transfer_item_to_loc(moving_atom, src)) + return . + . = TRUE + coat = moving_atom + if(user) + add_fingerprint(user) + user.visible_message("[user] hangs [coat] on [src].", "You hang [coat] on [src].") + else + visible_message("[coat] lands on [src].") + coat.forceMove(src) + update_icon(UPDATE_OVERLAYS) -// Hanging a coat on the hanger only after a bump. Force stoping throwing -/obj/structure/coatrack/Bumped(atom/movable/moving_atom) - ..() - if (coat) - return +/obj/structure/coatrack/update_overlays() + . = ..() - for (var/T in allowed) - if (!istype(moving_atom, T)) - continue - visible_message("[moving_atom] lands on \the [src].") - moving_atom.forceMove(src) - coat = moving_atom - update_icon() + if(!coat) return -/obj/structure/coatrack/update_icon() - overlays.Cut() - if(istype(coat, /obj/item/clothing/suit/storage/labcoat)) - overlays += image(icon, icon_state = "coat_lab") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/cmo)) - overlays += image(icon, icon_state = "coat_cmo") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/mad)) - overlays += image(icon, icon_state = "coat_mad") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/genetics)) - overlays += image(icon, icon_state = "coat_gen") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/chemist)) - overlays += image(icon, icon_state = "coat_chem") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/virologist)) - overlays += image(icon, icon_state = "coat_vir") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/science)) - overlays += image(icon, icon_state = "coat_sci") - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/mortician)) - overlays += image(icon, icon_state = "coat_mor") - if(istype(coat, /obj/item/clothing/suit/storage/blueshield)) - overlays += image(icon, icon_state = "coat_blue") - if(istype(coat, /obj/item/clothing/suit/storage/det_suit)) - overlays += image(icon, icon_state = "coat_det") - if(istype(coat, /obj/item/clothing/suit/browntrenchcoat)) - overlays += image(icon, icon_state = "coat_brtrench") - if(istype(coat, /obj/item/clothing/suit/leathercoat)) - overlays += image(icon, icon_state = "coat_leather") + var/static/list/type2overlay = list( + /obj/item/clothing/suit/storage/labcoat/cmo = "coat_cmo", + /obj/item/clothing/suit/storage/labcoat/mad = "coat_mad", + /obj/item/clothing/suit/storage/labcoat/genetics = "coat_gen", + /obj/item/clothing/suit/storage/labcoat/chemist = "coat_chem", + /obj/item/clothing/suit/storage/labcoat/virologist = "coat_vir", + /obj/item/clothing/suit/storage/labcoat/science = "coat_sci", + /obj/item/clothing/suit/storage/labcoat/mortician = "coat_mor", + /obj/item/clothing/suit/storage/labcoat = "coat_lab", + /obj/item/clothing/suit/storage/blueshield = "coat_det", + /obj/item/clothing/suit/browntrenchcoat = "coat_brtrench", + /obj/item/clothing/suit/leathercoat = "coat_leather", + ) + + var/coat_found = FALSE + for(var/path in type2overlay) + if(coat.type == path) // we need to check type explicitly + . += type2overlay[path] + coat_found = TRUE + break + + if(!coat_found) + . += "coat_lab" + /obj/structure/coatrack/crowbar_act(mob/user, obj/item/I) . = TRUE @@ -109,16 +108,19 @@ TOOL_DISMANTLE_SUCCESS_MESSAGE deconstruct(disassembled = TRUE) + /obj/structure/coatrack/wrench_act(mob/user, obj/item/I) . = TRUE default_unfasten_wrench(user, I, time = 10) + /obj/structure/coatrack/deconstruct(disassembled = FALSE) var/mat_drop = 2 if(disassembled) mat_drop = 10 new /obj/item/stack/sheet/wood(drop_location(), mat_drop) if(coat) - coat.loc = get_turf(src) + coat.forceMove_turf() coat = null ..() + diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 91af470b716..1ac4691d5b6 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -1,13 +1,18 @@ +GLOBAL_LIST_EMPTY(closets) + /obj/structure/closet name = "closet" desc = "It's a basic storage unit." icon = 'icons/obj/closet.dmi' icon_state = "closed" - density = 1 + density = TRUE layer = LOW_ITEM_LAYER //Prevents items from dropping on turf visually max_integrity = 200 integrity_failure = 50 armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + + /// Special marker for the closet to use default icon_closed/icon_opened states, skipping everything else. + var/no_overlays = FALSE var/icon_closed = "closed" //stays here for compatibility issues var/icon_opened = "open" @@ -19,12 +24,13 @@ var/custom_door_overlay = null //handles overlay of door looking into screen var/custom_open_overlay = null //handles overlay of opened door (its inner side) + var/ignore_density_closed = FALSE var/opened = FALSE var/welded = FALSE var/locked = FALSE var/large = TRUE var/can_be_emaged = FALSE - var/wall_mounted = 0 //never solid (You can always pass over it) + var/wall_mounted = FALSE //never solid (You can always pass over it) var/lastbang var/open_sound = 'sound/machines/closet_open.ogg' var/close_sound = 'sound/machines/closet_close.ogg' @@ -42,6 +48,7 @@ // Please dont override this unless you absolutely have to /obj/structure/closet/Initialize(mapload) . = ..() + GLOB.closets += src if(mapload && !opened) // Youre probably asking, why is this a 0 seconds timer AA? // Well, I will tell you. One day, all /obj/effect/spawner will use Initialize @@ -60,7 +67,8 @@ /obj/structure/closet/proc/take_contents() var/itemcount = 0 for(var/obj/item/I in loc) - if(I.density || I.anchored || I == src) continue + if(I.density || I.anchored || I == src) + continue I.forceMove(src) // Ensure the storage cap is respected if(++itemcount >= storage_capacity) @@ -68,6 +76,7 @@ // Fix for #383 - C4 deleting fridges with corpses /obj/structure/closet/Destroy() + GLOB.closets -= src dump_contents() return ..() @@ -162,12 +171,14 @@ playsound(loc, close_sound, close_sound_volume, TRUE, -3) else playsound(loc, 'sound/machines/click.ogg', close_sound_volume, TRUE, -3) - density = TRUE + density = ignore_density_closed ? FALSE : TRUE return TRUE /obj/structure/closet/proc/toggle(mob/user) + . = TRUE if(!(opened ? close() : open())) - to_chat(user, "It won't budge!") + . = FALSE + to_chat(user, span_notice("It won't budge!")) /obj/structure/closet/proc/bust_open() welded = FALSE //applies to all lockers @@ -247,10 +258,10 @@ user.visible_message("[user] welds [src] [adjective]!", "You weld [src] [adjective]!") welded = !welded update_icon() - return -/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user) - ..() + +/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user, params) + . = ..() if(istype(O, /obj/screen)) //fix for HUD elements making their way into the world -Pete return if(O.loc == user) @@ -271,6 +282,7 @@ if(user != O) user.visible_message("[user] stuffs [O] into [src]!", "You stuff [O] into [src]!") add_fingerprint(user) + return TRUE /obj/structure/closet/attack_ai(mob/user) if(isrobot(user) && Adjacent(user)) //Robots can open/close it, but not the AI @@ -300,8 +312,7 @@ // tk grab then use on self /obj/structure/closet/attack_self_tk(mob/user) add_fingerprint(user) - if(!toggle()) - to_chat(usr, "It won't budge!") + toggle() /obj/structure/closet/verb/verb_toggleopen() set src in oview(1) @@ -317,20 +328,43 @@ else to_chat(usr, "This mob type can't use this verb.") -/obj/structure/closet/update_icon() //Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot) - overlays.Cut() - if(!opened) - if(custom_door_overlay) - overlays += "[custom_door_overlay]_door" + +/obj/structure/closet/update_icon(updates = ALL) + if(no_overlays) + return ..(UPDATE_ICON_STATE) + return ..() + + +/obj/structure/closet/update_icon_state() + if(no_overlays) + icon_state = opened ? icon_opened : icon_closed + + +/obj/structure/closet/update_overlays() + . = ..() + if(opened) + if(custom_open_overlay) + . += "[custom_open_overlay]_open" else - overlays += "[icon_state]_door" //No initials because of custom map-made closets. - if(welded) - overlays += "welded" + . += "[icon_state]_open" else - if(custom_open_overlay) - overlays += "[custom_open_overlay]_open" + for(var/olay in apply_contents_overlays()) + . += olay + if(custom_door_overlay) + . += "[custom_door_overlay]_door" else - overlays += "[icon_state]_open" + . += "[icon_state]_door" //No initials because of custom map-made closets. + if(welded) + . += "welded" + + +/** + * Additional overlays for contents inside the closet. Usefull when the door is transparent. + */ +/obj/structure/closet/proc/apply_contents_overlays() + RETURN_TYPE(/list) + . = list() + // Objects that try to exit a locker by stepping were doing so successfully, // and due to an oversight in turf/Enter() were going through walls. That @@ -434,23 +468,26 @@ transparent = transparency update_icon() -/obj/structure/closet/bluespace/update_icon() - overlays.Cut() - icon_state = initial(icon_state) + +/obj/structure/closet/bluespace/update_icon_state() + icon_state = "[initial(icon_state)][transparent ? "_trans" : ""]" + + +/obj/structure/closet/bluespace/update_overlays() + . = list() if(!opened) - if(welded) - overlays += "welded" if(transparent) - icon_state += "_trans" - overlays += "[initial(icon_state)]_door_trans" + . += "[initial(icon_state)]_door_trans" else - overlays += "[initial(icon_state)]_door" + . += "[initial(icon_state)]_door" + if(welded) + . += "welded" else if(transparent) - icon_state += "_trans" - overlays += "[initial(icon_state)]_open_trans" + . += "[initial(icon_state)]_open_trans" else - overlays += "[initial(icon_state)]_open" + . += "[initial(icon_state)]_open" + /obj/structure/closet/bluespace/Crossed(atom/movable/AM, oldloc) if(AM.density) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 448e51d9949..5b71d629ad4 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -3,8 +3,6 @@ desc = "Just a box..." icon = 'icons/obj/cardboard_boxes.dmi' icon_state = "cardboard" - icon_opened = "cardboard_open" - icon_closed = "cardboard" resistance_flags = FLAMMABLE max_integrity = 70 integrity_failure = 0 @@ -13,6 +11,7 @@ open_sound_volume = 35 close_sound_volume = 35 material_drop = /obj/item/stack/sheet/cardboard + no_overlays = TRUE var/decal = "" var/amt = 4 var/move_delay = FALSE @@ -71,7 +70,7 @@ /obj/structure/closet/cardboard/attackby(obj/item/W as obj, mob/user as mob, params) if(src.opened) - if(istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour == TOOL_WIRECUTTER) var/obj/item/wirecutters/WC = W new /obj/item/stack/sheet/cardboard(src.loc, amt) for(var/mob/M in viewers(src)) @@ -105,7 +104,7 @@ update_icon() -/obj/structure/closet/cardboard/update_icon() //Not deriving, because of different logic. +/obj/structure/closet/cardboard/update_icon_state() //Not deriving, because of different logic. if(!opened) if(decal) icon_state = "cardboard_" + decal @@ -116,3 +115,8 @@ icon_state = "cardboard_open_" + decal else icon_state = "cardboard_open" + + +/obj/structure/closet/cardboard/update_overlays() + . = list() + diff --git a/code/game/objects/structures/crates_lockers/closets/coffin.dm b/code/game/objects/structures/crates_lockers/closets/coffin.dm index edb3d1e50d1..eb8d7490fbd 100644 --- a/code/game/objects/structures/crates_lockers/closets/coffin.dm +++ b/code/game/objects/structures/crates_lockers/closets/coffin.dm @@ -11,12 +11,8 @@ close_sound = 'sound/machines/wooden_closet_close.ogg' open_sound_volume = 25 close_sound_volume = 50 + no_overlays = TRUE -/obj/structure/closet/coffin/update_icon() - if(!opened) - icon_state = icon_closed - else - icon_state = icon_opened /obj/structure/closet/coffin/sarcophagus name = "sarcophagus" diff --git a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm b/code/game/objects/structures/crates_lockers/closets/crittercrate.dm index 8370048ecd0..83f34b4eb07 100644 --- a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/closets/crittercrate.dm @@ -2,6 +2,4 @@ name = "critter crate" desc = "A crate which can sustain life for a while." icon_state = "critter" - icon_opened = "critteropen" - icon_closed = "critter" material_drop = /obj/item/stack/sheet/wood diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index 1b9f3d38738..3c6f12d69c7 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -2,234 +2,204 @@ /obj/structure/closet/fireaxecabinet name = "fire axe cabinet" desc = "There is small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if." - icon_state = "fireaxe1000" - icon_closed = "fireaxe1000" - icon_opened = "fireaxe1100" + icon_state = "fireaxe_full_0hits" + icon_closed = "fireaxe_full_0hits" + icon_opened = "fireaxe_full_open" anchored = TRUE density = FALSE - armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) - opened = TRUE - locked = TRUE + no_overlays = TRUE + armor = list(MELEE = 50, BULLET = 20, LASER = 0, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 90, ACID = 50) var/obj/item/twohanded/fireaxe/fireaxe var/localopened = FALSE //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri + opened = TRUE var/hitstaken = FALSE + locked = TRUE var/smashed = FALSE + var/operating = FALSE + var/has_axe = null // Use a string over a boolean value to make the sprite names more readable -/obj/structure/closet/fireaxecabinet/Initialize(mapload) - . = ..() - if(!fireaxe) - fireaxe = new(src) - update_icon() +/obj/structure/closet/fireaxecabinet/Destroy() + if(!obj_integrity) + if(fireaxe) + fireaxe.forceMove(loc) + fireaxe = null + else + QDEL_NULL(fireaxe) + return ..() + + +/obj/structure/closet/fireaxecabinet/populate_contents() + fireaxe = new(src) + has_axe = "full" + update_icon(UPDATE_ICON_STATE) // So its initial icon doesn't show it without the fireaxe /obj/structure/closet/fireaxecabinet/examine(mob/user) . = ..() - . += "Use a multitool to lock/unlock it." + if(!smashed) + . += span_notice("Use a multitool to lock/unlock it.") + else + . += span_notice("It is damaged beyond repair.") -/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri + +/obj/structure/closet/fireaxecabinet/attackby(obj/item/I, mob/living/user) + add_fingerprint(user) if(isrobot(user) || locked) - if(istype(O, /obj/item/multitool)) - to_chat(user, "Resetting circuitry...") - playsound(user, 'sound/machines/lockreset.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src)) - add_fingerprint(user) - locked = FALSE - to_chat(user, " You disable the locking modules.") - update_icon() - return - else if(istype(O, /obj/item)) - user.changeNext_move(CLICK_CD_MELEE) - var/obj/item/W = O - if(smashed || localopened) - if(localopened) - add_fingerprint(user) - localopened = FALSE - update_icon_closing() + if(ismultitool(I)) + to_chat(user, span_warning("Resetting circuitry...")) + playsound(user, 'sound/machines/lockreset.ogg', 50, TRUE) + if(!do_after_once(user, 2 SECONDS * I.toolspeed, target = src)) return - else - user.do_attack_animation(src) - playsound(user, 'sound/effects/glasshit.ogg', 100, 1) //We don't want this playing every time - if(W.force < 15) - to_chat(user, "The cabinet's protective glass glances off the hit.") - else - hitstaken++ - if(hitstaken == 4) - playsound(user, 'sound/effects/glassbr3.ogg', 100, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that. - smashed = TRUE - locked = FALSE - localopened = TRUE - add_fingerprint(user) - update_icon() + + locked = FALSE + to_chat(user, span_caution("You disable the locking modules.")) + update_icon(UPDATE_ICON_STATE) + return + + user.changeNext_move(CLICK_CD_MELEE) + if(smashed || localopened) + if(localopened) + operate_panel() + return + + user.do_attack_animation(src) + playsound(user, 'sound/effects/glasshit.ogg', 100, TRUE) //We don't want this playing every time + if(I.force < 15) + to_chat(user, span_notice("The cabinet's protective glass glances off the hit.")) + else + hitstaken++ + if(hitstaken == 4) + playsound(user, 'sound/effects/glassbr3.ogg', 100, TRUE) //Break cabinet, receive goodies. Cabinet's fucked for life after that. + smashed = TRUE + locked = FALSE + localopened = TRUE + update_icon(UPDATE_ICON_STATE) return - if(istype(O, /obj/item/twohanded/fireaxe) && localopened) + + if(istype(I, /obj/item/twohanded/fireaxe) && localopened) if(!fireaxe) - var/obj/item/twohanded/fireaxe/F = O - if(F.wielded) - to_chat(user, "Unwield \the [F] first.") - return - if(!user.drop_item_ground(F)) - to_chat(user, "\The [F] stays stuck to your hands!") + var/obj/item/twohanded/fireaxe/placed_axe = I + if(HAS_TRAIT(placed_axe, TRAIT_WIELDED)) + to_chat(user, span_warning("Unwield [placed_axe] first.")) return - add_fingerprint(user) - fireaxe = F - contents += F - to_chat(user, "You place \the [F] back in the [name].") - update_icon() - else - if(smashed) + if(!user.drop_transfer_item_to_loc(placed_axe, src)) + to_chat(user, span_warning("[placed_axe] stays stuck to your hands!")) return - else - add_fingerprint(user) - localopened = !localopened - if(localopened) - update_icon_opening() - else - update_icon_closing() - else + fireaxe = placed_axe + has_axe = "full" + to_chat(user, span_notice("You place [placed_axe] back in the [name].")) + update_icon(UPDATE_ICON_STATE) + return + if(smashed) return - if(istype(O, /obj/item/multitool)) - if(localopened) - add_fingerprint(user) - localopened = FALSE - update_icon_closing() - return - else - to_chat(user, "Resetting circuitry...") - playsound(user, 'sound/machines/lockenable.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src)) - add_fingerprint(user) - locked = TRUE - to_chat(user, " You re-enable the locking modules.") - return - else - add_fingerprint(user) - localopened = !localopened - if(localopened) - update_icon_opening() - else - update_icon_closing() -/obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob) + operate_panel() + return + + if(smashed) + return + + if(ismultitool(I)) + if(localopened) + operate_panel() + return + + to_chat(user, span_warning("Resetting circuitry...")) + playsound(user, 'sound/machines/lockenable.ogg', 50, TRUE) + if(!do_after_once(user, 2 SECONDS * I.toolspeed, target = src)) + return + + locked = TRUE + to_chat(user, span_caution("You re-enable the locking modules.")) + return + + operate_panel() + + +/obj/structure/closet/fireaxecabinet/attack_hand(mob/user) if(locked) - to_chat(user, "The cabinet won't budge!") + to_chat(user, span_warning("The cabinet won't budge!")) return - if(localopened) - if(fireaxe) - add_fingerprint(user) - fireaxe.forceMove_turf() - user.put_in_hands(fireaxe, ignore_anim = FALSE) - to_chat(user, "You take \the [fireaxe] from the [src].") - fireaxe = null - add_fingerprint(user) - update_icon() - else - if(smashed) - return - else - add_fingerprint(user) - localopened = !localopened - if(localopened) - update_icon_opening() - else - update_icon_closing() + if(localopened && fireaxe) + fireaxe.forceMove_turf() + user.put_in_hands(fireaxe, ignore_anim = FALSE) + to_chat(user, span_notice("You take [fireaxe] from [src].")) + has_axe = "empty" + fireaxe = null - else add_fingerprint(user) - localopened = !localopened //I'm pretty sure we don't need an if(smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri - if(localopened) - update_icon_opening() - else - update_icon_closing() + update_icon(UPDATE_ICON_STATE) + return + + if(smashed) + return -/obj/structure/closet/fireaxecabinet/attack_tk(mob/user as mob) + operate_panel() + + +/obj/structure/closet/fireaxecabinet/attack_tk(mob/user) if(localopened && fireaxe) fireaxe.forceMove(loc) - to_chat(user, "You telekinetically remove \the [fireaxe].") + to_chat(user, span_notice("You telekinetically remove \the [fireaxe].")) + has_axe = "empty" fireaxe = null - update_icon() + update_icon(UPDATE_ICON_STATE) return attack_hand(user) -/obj/structure/closet/fireaxecabinet/verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri - set name = "Open/Close" - set category = "Object" - if(isrobot(usr) || locked || smashed) - if(locked) - to_chat(usr, "The cabinet won't budge!") - else if(smashed) - to_chat(usr, "The protective glass is broken!") +/obj/structure/closet/fireaxecabinet/attack_ai(mob/user) + if(smashed) + to_chat(user, span_warning("The security of the cabinet is compromised.")) return - localopened = !localopened - update_icon() + locked = !locked + if(locked) + to_chat(user, span_warning("Cabinet locked.")) + else + to_chat(user, span_notice("Cabinet unlocked.")) -/obj/structure/closet/fireaxecabinet/verb/remove_fire_axe() - set name = "Remove Fire Axe" - set category = "Object" - if(isrobot(usr)) +/obj/structure/closet/fireaxecabinet/proc/operate_panel() + if(operating) return + operating = TRUE + localopened = !localopened + do_animate() + operating = FALSE - if(localopened) - if(fireaxe) - fireaxe.forceMove_turf() - usr.put_in_hands(fireaxe, ignore_anim = FALSE) - to_chat(usr, "You take \the [fireaxe] from the [src].") - fireaxe = null - else - to_chat(usr, "The [src] is empty.") - else - to_chat(usr, "The [src] is closed.") - update_icon() -/obj/structure/closet/fireaxecabinet/attack_ai(mob/user as mob) - if(smashed) - to_chat(user, "The security of the cabinet is compromised.") - return +/obj/structure/closet/fireaxecabinet/proc/do_animate() + if(!localopened) + flick("fireaxe_[has_axe]_closing", src) else - locked = !locked - if(locked) - to_chat(user, "Cabinet locked.") - else - to_chat(user, "Cabinet unlocked.") + flick("fireaxe_[has_axe]_opening", src) + sleep(1 SECONDS) + update_icon(UPDATE_ICON_STATE) -/obj/structure/closet/fireaxecabinet/proc/update_icon_opening() - var/hasaxe = fireaxe != null - icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" - spawn(10) - update_icon() -/obj/structure/closet/fireaxecabinet/proc/update_icon_closing() - var/hasaxe = fireaxe != null - icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() +/obj/structure/closet/fireaxecabinet/update_icon_state() + if(localopened && !smashed) + icon_state = "fireaxe_[has_axe]_open" + else + icon_state = "fireaxe_[has_axe]_[hitstaken]hits" -/obj/structure/closet/fireaxecabinet/update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers - var/hasaxe = fireaxe != null - icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]" /obj/structure/closet/fireaxecabinet/open() return + /obj/structure/closet/fireaxecabinet/close() return + /obj/structure/closet/fireaxecabinet/welder_act(mob/user, obj/item/I) //A bastion of sanity in a sea of madness return -/obj/structure/closet/fireaxecabinet/Destroy() - if(!obj_integrity) - if(fireaxe) - fireaxe.forceMove(loc) - fireaxe = null - else - QDEL_NULL(fireaxe) - return ..() + //mining "fireaxe" /obj/structure/fishingrodcabinet @@ -240,42 +210,45 @@ anchored = TRUE var/obj/item/twohanded/fishingrod/olreliable //what the fuck? -/obj/structure/fishingrodcabinet/Initialize() + +/obj/structure/fishingrodcabinet/Initialize(mapload) . = ..() - if(!olreliable) - olreliable = new(src) - update_icon() + olreliable = new(src) + update_icon(UPDATE_OVERLAYS) + -/obj/structure/fishingrodcabinet/update_icon() +/obj/structure/fishingrodcabinet/update_overlays() . = ..() - cut_overlays() if(olreliable) - add_overlay("rod") + . += "rod" -/obj/structure/fishingrodcabinet/attackby(var/obj/item/O as obj, var/mob/living/user as mob) - if(istype(O, /obj/item/twohanded/fishingrod)) - var/obj/item/twohanded/fishingrod/R = O - if(R.wielded) - to_chat(user, "Unwield \the [R] first.") - return - if(!user.drop_item_ground(R)) - to_chat(user, "\The [R] stays stuck to your hands!") - return - add_fingerprint(user) - olreliable = R - contents += R - to_chat(user, "You place \the [R] back in the [name].") - update_icon() +/obj/structure/fishingrodcabinet/attackby(obj/item/I, mob/living/user) + if(!istype(I, /obj/item/twohanded/fishingrod)) + return ..() + var/obj/item/twohanded/fishingrod/rod = I + if(HAS_TRAIT(rod, TRAIT_WIELDED)) + to_chat(user, span_warning("Unwield [rod] first.")) + return + if(!user.drop_transfer_item_to_loc(rod, src)) + to_chat(user, span_warning("[rod] stays stuck to your hands!")) + return -/obj/structure/fishingrodcabinet/attack_hand(mob/user as mob) - if(olreliable) - add_fingerprint(user) - olreliable.forceMove_turf() - user.put_in_hands(olreliable, ignore_anim = FALSE) - to_chat(user, "You take \the [olreliable] from the [src].") - olreliable = null + olreliable = rod + to_chat(user, span_notice("You place [rod] back in [src].")) + update_icon(UPDATE_OVERLAYS) + + + +/obj/structure/fishingrodcabinet/attack_hand(mob/user) + if(!olreliable) + return ..() + + add_fingerprint(user) + olreliable.forceMove_turf() + user.put_in_hands(olreliable, ignore_anim = FALSE) + to_chat(user, span_notice("You take [olreliable] from [src].")) + olreliable = null + update_icon(UPDATE_OVERLAYS) - add_fingerprint(user) - update_icon() diff --git a/code/game/objects/structures/crates_lockers/closets/gimmick.dm b/code/game/objects/structures/crates_lockers/closets/gimmick.dm index 426764dc1b4..c0fc2f9d336 100644 --- a/code/game/objects/structures/crates_lockers/closets/gimmick.dm +++ b/code/game/objects/structures/crates_lockers/closets/gimmick.dm @@ -13,23 +13,17 @@ name = "strange closet" desc = "It looks alien!" icon_state = "acloset" - icon_closed = "acloset" - icon_opened = "aclosetopen" /obj/structure/closet/gimmick name = "administrative supply closet" desc = "It's a storage unit for things that have no right being here." icon_state = "syndicate1" - icon_closed = "syndicate1" - icon_opened = "syndicate1open" - anchored = 0 + anchored = FALSE /obj/structure/closet/gimmick/russian name = "russian surplus closet" desc = "It's a storage unit for Russian standard-issue surplus." icon_state = "syndicate1" - icon_closed = "syndicate1" - icon_opened = "syndicate1open" /obj/structure/closet/gimmick/russian/populate_contents() new /obj/item/clothing/head/ushanka(src) @@ -48,8 +42,6 @@ name = "tacticool gear closet" desc = "It's a storage unit for Tacticool gear." icon_state = "syndicate1" - icon_closed = "syndicate1" - icon_opened = "syndicate1open" /obj/structure/closet/gimmick/tacticool/populate_contents() new /obj/item/clothing/glasses/eyepatch(src) @@ -72,9 +64,7 @@ name = "\improper Thunderdome closet" desc = "Everything you need!" icon_state = "syndicate" - icon_closed = "syndicate" - icon_opened = "syndicateopen" - anchored = 1 + anchored = TRUE /obj/structure/closet/thunderdome/tdred name = "red-team Thunderdome closet" @@ -102,8 +92,6 @@ /obj/structure/closet/thunderdome/tdgreen name = "green-team Thunderdome closet" icon_state = "syndicate1" - icon_closed = "syndicate1" - icon_opened = "syndicate1open" /obj/structure/closet/thunderdome/tdgreen/populate_contents() new /obj/item/clothing/suit/armor/tdome/green(src) diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm index fcd763292e6..5665c22e234 100644 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ b/code/game/objects/structures/crates_lockers/closets/malfunction.dm @@ -2,8 +2,6 @@ /obj/structure/closet/malf/suits desc = "It's a storage unit for operational gear." icon_state = "syndicate" - icon_closed = "syndicate" - icon_opened = "syndicateopen" /obj/structure/closet/malf/suits/populate_contents() new /obj/item/tank/jetpack/void(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/depot.dm b/code/game/objects/structures/crates_lockers/closets/secure/depot.dm index e1b48bf48c7..cf71573a99b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/depot.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/depot.dm @@ -3,7 +3,7 @@ name = "depot supply closet" desc = "" locked = 0 - anchored = 1 + anchored = TRUE req_access = list() max_integrity = 250 icon_state = "secure" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index ab676f2564b..834f1565aa7 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -43,7 +43,7 @@ /obj/structure/closet/secure_closet/freezer/meat/populate_contents() for(var/i in 1 to 4) - new /obj/item/reagent_containers/food/snacks/meat/monkey(src) + new /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey(src) /obj/structure/closet/secure_closet/freezer/meat/open req_access = null diff --git a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm index 4f662b78086..bed6882aab6 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm @@ -2,43 +2,35 @@ name = "gun cabinet" req_access = list(ACCESS_ARMORY) icon = 'icons/obj/guncabinet.dmi' - icon_state = "base" + icon_state = "guncabinet" -/obj/structure/closet/secure_closet/guncabinet/toggle() - ..() - update_icon() -/obj/structure/closet/secure_closet/guncabinet/update_icon() - overlays.Cut() - if(opened) - overlays += icon(icon,"door_open") - else - var/lazors = 0 - var/shottas = 0 - for(var/obj/item/gun/G in contents) - if(istype(G, /obj/item/gun/energy)) - lazors++ - if(istype(G, /obj/item/gun/projectile/)) - shottas++ - if(lazors || shottas) - for(var/i = 0 to 2) - var/image/gun = image(icon(src.icon)) +/obj/structure/closet/secure_closet/guncabinet/Initialize(mapload) + . = ..() + // we need to update our guns inside, after closet is filled + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_OVERLAYS), 1 SECONDS) - if(lazors > 0 && (shottas <= 0 || prob(50))) - lazors-- - gun.icon_state = "laser" - else if(shottas > 0) - shottas-- - gun.icon_state = "projectile" - gun.pixel_x = i*4 - overlays += gun +/obj/structure/closet/secure_closet/guncabinet/apply_contents_overlays() + . = ..() - overlays += icon(src.icon,"door") + var/lazors = 0 + var/shottas = 0 + for(var/thing in contents) + if(istype(thing, /obj/item/gun/energy)) + lazors++ + if(istype(thing, /obj/item/gun/projectile)) + shottas++ + + if(lazors || shottas) + for(var/i = 1 to 2) + var/choise = "" + if(lazors > 0 && (shottas <= 0 || prob(50))) + lazors-- + choise = "laser" + else if(shottas > 0) + shottas-- + choise = "projectile" + if(choise) + . += image(icon, icon_state = choise, pixel_x = i * 4) - if(broken) - overlays += icon(src.icon,"door_broken") - else if(locked) - overlays += icon(src.icon,"door_locked") - else - overlays += icon(src.icon,"door") diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 93fc4230675..782447a1683 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -185,7 +185,7 @@ overlay_locked = "m_locked" overlay_locker = "m_locker" overlay_unlocked = "m_unlocked" - anchored = 1 + anchored = TRUE density = 0 wall_mounted = 1 req_access = list(ACCESS_MEDICAL) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 9822f33c632..491ad76e1e9 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -1,47 +1,63 @@ +#define CLOSET_BREAKOUT_TIME (2 MINUTES) + /obj/structure/closet/secure_closet name = "secure locker" desc = "It's an immobile card-locked storage unit." icon = 'icons/obj/closet.dmi' icon_state = "secure" - density = 1 - opened = 0 - locked = 1 - broken = 0 + density = TRUE + opened = FALSE + locked = TRUE + broken = FALSE can_be_emaged = TRUE max_integrity = 250 armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) damage_deflection = 20 - wall_mounted = 0 //never solid (You can always pass over it) + wall_mounted = FALSE //never solid (You can always pass over it) /obj/structure/closet/secure_closet/can_open() - if(!..()) - return 0 if(locked) - return 0 + return FALSE return ..() /obj/structure/closet/secure_closet/close() - if(..()) - if(broken) - update_icon() - return 1 - else - return 0 + . = ..() + if(. && broken) + update_icon() + /obj/structure/closet/secure_closet/emp_act(severity) - for(var/obj/O in src) - O.emp_act(severity) + for(var/obj/object in src) + object.emp_act(severity) + + if(broken || opened) + return + + if(prob(50 / severity)) + locked = !locked + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, overlay_sparking), 1 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) + + if(prob(20 / severity)) + if(locked) + req_access = list() + req_access += pick(get_all_accesses()) + return + open() + + +/obj/structure/closet/secure_closet/emag_act(mob/user) if(!broken) - if(prob(50/severity)) - locked = !locked - update_icon() - if(prob(20/severity) && !opened) - if(!locked) - open() - else - req_access = list() - req_access += pick(get_all_accesses()) - ..() + add_attack_logs(user, src, "emagged") + broken = TRUE + locked = FALSE + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, overlay_sparking), 1 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance), UPDATE_ICON|UPDATE_DESC), 1 SECONDS) + if(user) + to_chat(user, "You break the lock on [src].") + /obj/structure/closet/secure_closet/proc/togglelock(mob/living/user) if(!istype(user) || user.incapacitated()) @@ -71,15 +87,6 @@ if(Adjacent(user)) togglelock(user) -/obj/structure/closet/secure_closet/emag_act(mob/user) - if(!broken) - add_attack_logs(user, src, "emagged") - broken = TRUE - locked = FALSE - overlays += overlay_sparking - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) - if(user) - to_chat(user, "You break the lock on \the [src].") /obj/structure/closet/secure_closet/attack_hand(mob/user) add_fingerprint(user) @@ -102,60 +109,75 @@ else to_chat(usr, "This mob type can't use this verb.") -/obj/structure/closet/secure_closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot) - ..() - if(!opened) - //overlays += overlay_locker //uncomment if you want to add locker overlay to all secure closets - if(!broken) - if(locked) - overlays += overlay_locked - else - overlays += overlay_unlocked - -/obj/structure/closet/secure_closet/container_resist(var/mob/living/L) - var/breakout_time = 2 //2 minutes by default + +/obj/structure/closet/secure_closet/update_overlays() + . = ..() + if(!opened && !broken) + if(locked) + . += overlay_locked + else + . += overlay_unlocked + + +/obj/structure/closet/secure_closet/update_desc(updates = ALL) + . = ..() + if(broken) + desc = "It appears to be broken." + else + desc = initial(desc) + + +/obj/structure/closet/secure_closet/container_resist(mob/living/user) if(opened) - if(L.loc == src) - L.forceMove(get_turf(src)) // Let's just be safe here + if(user.loc == src) + user.forceMove(get_turf(src)) // Let's just be safe here return //Door's open... wait, why are you in it's contents then? + if(!locked && !welded) return //It's a secure closet, but isn't locked. Easily escapable from, no need to 'resist' //okay, so the closet is either welded or locked... resist!!! - to_chat(L, "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)") - for(var/mob/O in viewers(src)) - O.show_message("The [src] begins to shake violently!", 1) - - - spawn(0) - if(do_after(usr,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds - if(!src || !L || L.stat != CONSCIOUS || L.loc != src || opened) //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened - return - - //Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'... - if(!locked && !welded) - return - - //Well then break it! - desc = "It appears to be broken." - flick_overlay_view(image(icon=icon, icon_state=overlay_sparking), 1 SECONDS) - sleep(10) - flick_overlay_view(image(icon=icon, icon_state=overlay_sparking), 1 SECONDS) - sleep(10) - broken = 1 - locked = 0 - welded = 0 - update_icon() - to_chat(usr, "You successfully break out!") - for(var/mob/O in viewers(L.loc)) - O.show_message("\the [usr] successfully broke out of \the [src]!", 1) - if(istype(loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace) - var/obj/structure/bigDelivery/BD = loc - BD.attack_hand(usr) - if(isobj(loc)) - var/obj/loc_as_obj = loc - loc_as_obj.container_resist(L) - open() + visible_message( + span_danger("[src] begins to shake violently!"), + span_warning("You lean on the back of [src] and start pushing the door open. (this will take about [CLOSET_BREAKOUT_TIME / 10] minutes.)") + ) + INVOKE_ASYNC(src, PROC_REF(resist_async), user) + + +/obj/structure/closet/secure_closet/proc/resist_async(mob/living/user) + if(!do_after(user, CLOSET_BREAKOUT_TIME, target = src)) + return + + //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened + if(!src || !user || user.incapacitated() || user.loc != src || opened) + return + + //Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'... + if(!locked && !welded) + return + + //Well then break it! + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, overlay_sparking), 1 SECONDS) + broken = TRUE + locked = FALSE + welded = FALSE + update_appearance(UPDATE_ICON|UPDATE_DESC) + visible_message( + span_danger("[user] successfully broke out of [src]!"), + span_warning("You successfully break out!"), + ) + + if(istype(loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace) + var/obj/structure/bigDelivery/BD = loc + BD.attack_hand(user) + + if(isobj(loc)) + var/obj/loc_as_obj = loc + loc_as_obj.container_resist(user) + + open() + /obj/structure/closet/secure_closet/screwdriver_act(mob/living/user, obj/item/I) . = ..() 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 5ce2ef9270e..c2f23dad71b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -38,35 +38,6 @@ new /obj/item/clothing/accessory/medal/service(src) new /obj/item/storage/garmentbag/hop(src) -/*/obj/structure/closet/secure_closet/hop2 //dont realy need this because of garment bag - name = "head of personnel's attire" - req_access = list(ACCESS_HOP) - icon_state = "hopsecure1" - icon_closed = "hopsecure" - icon_locked = "hopsecure1" - icon_opened = "hopsecureopen" - icon_broken = "hopsecurebroken" - icon_off = "hopsecureoff" - -/obj/structure/closet/secure_closet/hop2/populate_contents() - new /obj/item/clothing/neck/mantle/head_of_personnel(src) - new /obj/item/clothing/neck/cloak/head_of_personnel(src) - new /obj/item/clothing/under/dress/dress_hr(src) - new /obj/item/clothing/under/lawyer/female(src) - new /obj/item/clothing/under/lawyer/black(src) - new /obj/item/clothing/under/lawyer/red(src) - new /obj/item/clothing/under/lawyer/oldman(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/leather(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/under/rank/head_of_personnel_whimsy(src) - new /obj/item/clothing/under/rank/head_of_personnel_alt(src) - new /obj/item/clothing/under/rank/head_of_personnel_f(src) - new /obj/item/clothing/suit/hop_jacket(src) - new /obj/item/clothing/suit/hop_jacket/female(src) -*/ - /obj/structure/closet/secure_closet/hos name = "head of security's locker" req_access = list(ACCESS_HOS) diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index bb2509c6423..434ee88e4c8 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -4,8 +4,9 @@ icon = 'icons/obj/statue.dmi' icon_state = "human_male" density = 1 - anchored = 1 + anchored = TRUE max_integrity = 0 //destroying the statue kills the mob within + no_overlays = TRUE var/intialTox = 0 //these are here to keep the mob from taking damage from things that logically wouldn't affect a rock var/intialFire = 0 //it's a little sloppy I know but it was this or the GODMODE flag. Lesser of two evils. var/intialBrute = 0 @@ -17,7 +18,7 @@ if(ishuman(L) || iscorgi(L)) if(L.buckled) L.buckled = 0 - L.anchored = 0 + L.anchored = FALSE L.forceMove(src) ADD_TRAIT(L, TRAIT_MUTE, "statue") max_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues @@ -94,7 +95,7 @@ /obj/structure/closet/statue/welder_act() return -/obj/structure/closet/statue/MouseDrop_T() +/obj/structure/closet/statue/MouseDrop_T(atom/dropping, mob/user, params) return /obj/structure/closet/statue/relaymove() @@ -106,7 +107,7 @@ /obj/structure/closet/statue/verb_toggleopen() return -/obj/structure/closet/statue/update_icon() +/obj/structure/closet/statue/update_icon_state() return /obj/structure/closet/statue/proc/shatter(mob/user) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index ab5070d0871..90d830553c4 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -2,8 +2,6 @@ name = "armoury closet" desc = "Why is this here?" icon_state = "syndicate" - icon_closed = "syndicate" - icon_opened = "syndicateopen" /obj/structure/closet/syndicate/personal diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index dc3a1aacb38..a557800d9b0 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -16,8 +16,6 @@ name = "emergency closet" desc = "It's a storage unit for emergency breathmasks and o2 tanks." icon_state = "emergency" - icon_closed = "emergency" - icon_opened = "emergencyopen" /obj/structure/closet/emcloset/anchored anchored = TRUE @@ -67,8 +65,6 @@ name = "fire-safety closet" desc = "It's a storage unit for fire-fighting supplies." icon_state = "firecloset" - icon_closed = "firecloset" - icon_opened = "fireclosetopen" /obj/structure/closet/firecloset/populate_contents() new /obj/item/extinguisher(src) @@ -93,8 +89,6 @@ name = "tool closet" desc = "It's a storage unit for tools." icon_state = "toolcloset" - icon_closed = "toolcloset" - icon_opened = "toolclosetopen" /obj/structure/closet/toolcloset/populate_contents() if(prob(40)) @@ -149,8 +143,6 @@ name = "\improper EOD closet" desc = "It's a storage unit for explosion-protective suits." icon_state = "bombsuit" - icon_closed = "bombsuit" - icon_opened = "bombsuitopen" /obj/structure/closet/bombcloset/populate_contents() new /obj/item/clothing/suit/bomb_suit( src ) @@ -163,8 +155,6 @@ name = "\improper EOD closet" desc = "It's a storage unit for explosion-protective suits." icon_state = "bombsuitsec" - icon_closed = "bombsuitsec" - icon_opened = "bombsuitsecopen" /obj/structure/closet/bombclosetsecurity/populate_contents() new /obj/item/clothing/suit/bomb_suit/security( src ) @@ -179,9 +169,7 @@ name = "fire-safety closet" desc = "It's a storage unit for fire-fighting supplies." icon_state = "hydrant" - icon_closed = "hydrant" - icon_opened = "hydrant_open" - anchored = 1 + anchored = TRUE density = 0 wall_mounted = 1 @@ -200,7 +188,7 @@ name = "first-aid closet" desc = "It's wall-mounted storage unit for first aid supplies." icon_state = "medical_wall" - anchored = 1 + anchored = TRUE density = 0 wall_mounted = 1 diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 4eb7efc4da1..06c801cad14 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -3,8 +3,6 @@ desc = "A rectangular steel crate." icon = 'icons/obj/crates.dmi' icon_state = "crate" - icon_opened = "crateopen" - icon_closed = "crate" climbable = TRUE open_sound = 'sound/machines/crate_open.ogg' close_sound = 'sound/machines/crate_close.ogg' @@ -15,11 +13,17 @@ // A list of beacon names that the crate will announce the arrival of, when delivered. var/list/announce_beacons = list() -/obj/structure/closet/crate/update_icon() - //..() is not needed here because of different overlay handling logic for crates - overlays.Cut() + +/obj/structure/closet/crate/update_icon_state() + icon_state = "[initial(icon_state)][opened ? "open" : ""]" + + +/obj/structure/closet/crate/update_overlays() + // . = ..() is not needed here because of different overlay handling logic for crates + . = list() if(manifest) - overlays += "manifest" + . += "manifest" + /obj/structure/closet/crate/can_open() return TRUE @@ -53,8 +57,9 @@ O.forceMove(loc) for(var/mob/M in src) //Mobs M.forceMove(loc) - icon_state = icon_opened + opened = TRUE + update_icon() if(climbable) structure_shaken() @@ -80,8 +85,8 @@ O.forceMove(src) itemcount++ - icon_state = icon_closed opened = FALSE + update_icon() return TRUE @@ -162,12 +167,11 @@ desc = "A secure crate." name = "Secure crate" icon_state = "securecrate" - icon_opened = "securecrateopen" - icon_closed = "securecrate" - var/redlight = "securecrater" - var/greenlight = "securecrateg" - var/sparks = "securecratesparks" - var/emag = "securecrateemag" + overlay_locked = "securecrater" + overlay_unlocked = "securecrateg" + overlay_sparking = "securecratesparks" + /// Overlay for crate with broken lock + var/overlay_broken = "securecrateemag" max_integrity = 500 armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) damage_deflection = 25 @@ -176,17 +180,16 @@ locked = TRUE can_be_emaged = TRUE -/obj/structure/closet/crate/secure/update_icon() - ..() - overlays.Cut() - if(manifest) - overlays += "manifest" + +/obj/structure/closet/crate/secure/update_overlays() + . = ..() if(locked) - overlays += redlight - else if(broken) - overlays += emag + . += overlay_locked + else if(broken && overlay_broken) + . += overlay_broken else - overlays += greenlight + . += overlay_unlocked + /obj/structure/closet/crate/secure/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) if(prob(tamperproof) && damage_amount >= DAMAGE_PRECISION) @@ -204,9 +207,16 @@ explosion(get_turf(src), 0, 1, 5, 5, cause = src) qdel(src) + /obj/structure/closet/crate/secure/can_open() return !locked + +/obj/structure/closet/crate/secure/AltClick(mob/living/user) + if(iscarbon(user) && !user.incapacitated() && Adjacent(user)) + togglelock(user) + + /obj/structure/closet/crate/secure/proc/togglelock(mob/user) if(opened) to_chat(user, "Close the crate first.") @@ -222,6 +232,7 @@ else to_chat(user, "Access Denied") + /obj/structure/closet/crate/secure/verb/verb_togglelock() set src in oview(1) // One square distance set category = null @@ -236,6 +247,7 @@ else to_chat(usr, "This mob type can't use this verb.") + /obj/structure/closet/crate/secure/attack_hand(mob/user) if(manifest) add_fingerprint(user) @@ -253,99 +265,74 @@ else toggle(user, by_hand = TRUE) + /obj/structure/closet/crate/secure/closed_item_click(mob/user) togglelock(user) + /obj/structure/closet/crate/secure/emag_act(mob/user) if(locked) add_attack_logs(user, src, "emagged") - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - src.locked = 0 - src.broken = 1 - update_icon() + locked = FALSE + broken = TRUE + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, overlay_sparking), 1 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) if(user) - to_chat(user, "You unlock \the [src].") + to_chat(user, span_notice("You unlock [src].")) + /obj/structure/closet/crate/secure/emp_act(severity) - for(var/obj/O in src) - O.emp_act(severity) - if(!broken && !opened && prob(50/severity)) - if(!locked) - src.locked = 1 + for(var/obj/object in src) + object.emp_act(severity) + + if(broken || opened) + return + + if(prob(50 / severity)) + locked = !locked + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + flick_overlay_view(image(icon, src, overlay_sparking), 1 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) + + if(prob(20 / severity)) + if(locked) + req_access = list() + req_access += pick(get_all_accesses()) else - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, TRUE) - src.locked = 0 - update_icon() - if(!opened && prob(20/severity)) - if(!locked) open() - else - src.req_access = list() - src.req_access += pick(get_all_accesses()) - ..() + /obj/structure/closet/crate/plastic name = "plastic crate" desc = "A rectangular plastic crate." icon_state = "plasticcrate" - icon_opened = "plasticcrateopen" - icon_closed = "plasticcrate" /obj/structure/closet/crate/internals desc = "A internals crate." name = "internals crate" icon_state = "o2crate" - icon_opened = "o2crateopen" - icon_closed = "o2crate" /obj/structure/closet/crate/trashcart desc = "A heavy, metal trashcart with wheels." name = "trash Cart" icon_state = "trashcart" - icon_opened = "trashcartopen" - icon_closed = "trashcart" pull_push_speed_modifier = 1 /obj/structure/closet/crate/trashcart/gibs desc = "A heavy, metal trashcart with wheels. You better don't ask." name = "trash cart with gibs" icon_state = "trashcartgib" - icon_opened = "trashcartgibopen" - icon_closed = "trashcartgib" - -/*these aren't needed anymore -/obj/structure/closet/crate/hat - desc = "A crate filled with Valuable Collector's Hats!." - name = "Hat Crate" - icon_state = "crate" - icon_opened = "crateopen" - icon_closed = "crate" - -/obj/structure/closet/crate/contraband - name = "Poster crate" - desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist." - icon_state = "crate" - icon_opened = "crateopen" - icon_closed = "crate" -*/ /obj/structure/closet/crate/medical desc = "A medical crate." name = "medical crate" icon_state = "medicalcrate" - icon_opened = "medicalcrateopen" - icon_closed = "medicalcrate" /obj/structure/closet/crate/rcd desc = "A crate for the storage of the RCD." name = "\improper RCD crate" icon_state = "crate" - icon_opened = "crateopen" - icon_closed = "crate" /obj/structure/closet/crate/rcd/populate_contents() new /obj/item/rcd_ammo(src) @@ -357,8 +344,6 @@ desc = "A freezer." name = "Freezer" icon_state = "freezer" - icon_opened = "freezeropen" - icon_closed = "freezer" var/target_temp = T0C - 40 var/cooling_power = 40 @@ -384,8 +369,6 @@ desc = "A large can, looks like a bin to me." name = "garbage can" icon_state = "largebin" - icon_opened = "largebinopen" - icon_closed = "largebin" anchored = TRUE /obj/structure/closet/crate/can/wrench_act(mob/user, obj/item/I) @@ -398,8 +381,6 @@ desc = "A crate with a radiation sign on it." name = "radioactive gear crate" icon_state = "radiation" - icon_opened = "radiationopen" - icon_closed = "radiation" /obj/structure/closet/crate/radiation/populate_contents() new /obj/item/clothing/suit/radiation(src) @@ -415,58 +396,46 @@ desc = "A secure weapons crate." name = "weapons crate" icon_state = "weaponcrate" - icon_opened = "weaponcrateopen" - icon_closed = "weaponcrate" /obj/structure/closet/crate/secure/plasma desc = "A secure plasma crate." name = "plasma crate" icon_state = "plasmacrate" - icon_opened = "plasmacrateopen" - icon_closed = "plasmacrate" /obj/structure/closet/crate/secure/gear desc = "A secure gear crate." name = "gear crate" icon_state = "secgearcrate" - icon_opened = "secgearcrateopen" - icon_closed = "secgearcrate" /obj/structure/closet/crate/secure/hydrosec desc = "A crate with a lock on it, painted in the scheme of the station's botanists." name = "secure hydroponics crate" icon_state = "hydrosecurecrate" - icon_opened = "hydrosecurecrateopen" - icon_closed = "hydrosecurecrate" /obj/structure/closet/crate/secure/bin desc = "A secure bin." name = "secure bin" icon_state = "largebins" - icon_opened = "largebinsopen" - icon_closed = "largebins" - redlight = "largebinr" - greenlight = "largebing" - sparks = "largebinsparks" - emag = "largebinemag" + overlay_locked = "largebinr" + overlay_unlocked = "largebing" + overlay_sparking = "largebinsparks" + overlay_broken = "largebinemag" /obj/structure/closet/crate/large name = "large crate" desc = "A hefty metal crate." icon_state = "largemetal" - icon_opened = "largemetalopen" - icon_closed = "largemetal" integrity_failure = 0 //Makes the crate break when integrity reaches 0, instead of opening and becoming an invisible sprite. /obj/structure/closet/crate/large/close() . = ..() if(.)//we can hold up to one large item - var/found = 0 + var/found = FALSE for(var/obj/structure/S in src.loc) if(S == src) continue if(!S.anchored) - found = 1 + found = TRUE S.forceMove(src) break if(!found) @@ -479,10 +448,9 @@ name = "large crate" desc = "A hefty metal crate with an electronic locking system." icon_state = "largemetal" - icon_opened = "largemetalopen" - icon_closed = "largemetal" - redlight = "largemetalr" - greenlight = "largemetalg" + overlay_locked = "largemetalr" + overlay_unlocked = "largemetalg" + overlay_broken = "" /obj/structure/closet/crate/secure/large/close() . = ..() @@ -505,15 +473,11 @@ /obj/structure/closet/crate/secure/large/reinforced desc = "A hefty, reinforced metal crate with an electronic locking system." icon_state = "largermetal" - icon_opened = "largermetalopen" - icon_closed = "largermetal" /obj/structure/closet/crate/hydroponics name = "hydroponics crate" desc = "All you need to destroy those pesky weeds and pests." icon_state = "hydrocrate" - icon_opened = "hydrocrateopen" - icon_closed = "hydrocrate" /obj/structure/closet/crate/hydroponics/prespawned //This exists so the prespawned hydro crates spawn with their contents. @@ -539,36 +503,26 @@ name = "science crate" desc = "A science crate." icon_state = "scicrate" - icon_opened = "scicrateopen" - icon_closed = "scicrate" /obj/structure/closet/crate/secure/scisec name = "secure science crate" desc = "A crate with a lock on it, painted in the scheme of the station's scientists." icon_state = "scisecurecrate" - icon_opened = "scisecurecrateopen" - icon_closed = "scisecurecrate" /obj/structure/closet/crate/engineering name = "engineering crate" desc = "An engineering crate." icon_state = "engicrate" - icon_opened = "engicrateopen" - icon_closed = "engicrate" /obj/structure/closet/crate/secure/engineering name = "secure engineering crate" desc = "A crate with a lock on it, painted in the scheme of the station's engineers." icon_state = "engisecurecrate" - icon_opened = "engisecurecrateopen" - icon_closed = "engisecurecrate" /obj/structure/closet/crate/engineering/electrical name = "electrical engineering crate" desc = "An electrical engineering crate." icon_state = "electricalcrate" - icon_opened = "electricalcrateopen" - icon_closed = "electricalcrate" /obj/structure/closet/crate/tape/populate_contents() if(prob(10)) @@ -578,8 +532,6 @@ name = "secure biohazard crate" desc = "An protected biohazard crate." icon_state = "biohazard" - icon_opened = "biohazardopen" - icon_closed = "biohazard" //crates of gear in the free golem ship /obj/structure/closet/crate/golemgear/populate_contents() @@ -594,19 +546,14 @@ //syndie crates by Furukai /obj/structure/closet/crate/syndicate - desc = "Definitely a property of an evil corporation!" icon_state = "syndiecrate" - icon_opened = "syndiecrateopen" - icon_closed = "syndiecrate" material_drop = /obj/item/stack/sheet/mineral/plastitanium /obj/structure/closet/crate/secure/syndicate name = "Secure suspicious crate" desc = "Definitely a property of an evil corporation! And it has a hardened lock! And a microphone?" icon_state = "syndiesecurecrate" - icon_opened = "syndiesecurecrateopen" - icon_closed = "syndiesecurecrate" material_drop = /obj/item/stack/sheet/mineral/plastitanium can_be_emaged = FALSE diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm index 6c4bf01ee6a..cf15893c72c 100644 --- a/code/game/objects/structures/crates_lockers/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/crittercrate.dm @@ -2,8 +2,6 @@ name = "critter crate" desc = "A crate designed for safe transport of animals. Only openable from the outside." icon_state = "critter" - icon_opened = "critteropen" - icon_closed = "critter" open_sound = 'sound/machines/wooden_closet_open.ogg' close_sound = 'sound/machines/wooden_closet_close.ogg' var/already_opened = 0 diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 9d670424371..bc7103b462a 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -6,17 +6,14 @@ density = 1 var/obj/item/paper/manifest/manifest -/obj/structure/largecrate/Initialize(mapload) - . = ..() - update_icon() -/obj/structure/largecrate/update_icon() - ..() - overlays.Cut() +/obj/structure/largecrate/update_overlays() + . = ..() if(manifest) - overlays += "manifest" + . += "manifest" -/obj/structure/largecrate/attack_hand(mob/user as mob) + +/obj/structure/largecrate/attack_hand(mob/user) if(manifest) add_fingerprint(user) to_chat(user, "You tear the manifest off of the crate.") @@ -25,18 +22,18 @@ if(ishuman(user)) user.put_in_hands(manifest, ignore_anim = FALSE) manifest = null - update_icon() - return - else - to_chat(user, "You need a crowbar to pry this open!") + update_icon(UPDATE_OVERLAYS) return -/obj/structure/largecrate/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) + to_chat(user, "You need a crowbar to pry this open!") + + +/obj/structure/largecrate/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_CROWBAR) if(manifest) manifest.forceMove(loc) manifest = null - update_icon() + update_icon(UPDATE_OVERLAYS) new /obj/item/stack/sheet/wood(src) var/turf/T = get_turf(src) for(var/O in contents) @@ -56,8 +53,8 @@ /obj/structure/largecrate/lisa icon_state = "lisacrate" -/obj/structure/largecrate/lisa/attackby(obj/item/W as obj, mob/user as mob) //ugly but oh well - if(istype(W, /obj/item/crowbar)) +/obj/structure/largecrate/lisa/attackby(obj/item/W, mob/user) //ugly but oh well + if(W.tool_behaviour == TOOL_CROWBAR) new /mob/living/simple_animal/pet/dog/corgi/Lisa(loc) return ..() @@ -65,8 +62,8 @@ name = "cow crate" icon_state = "lisacrate" -/obj/structure/largecrate/cow/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) +/obj/structure/largecrate/cow/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_CROWBAR) new /mob/living/simple_animal/cow(loc) return ..() @@ -74,8 +71,8 @@ name = "goat crate" icon_state = "lisacrate" -/obj/structure/largecrate/goat/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) +/obj/structure/largecrate/goat/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_CROWBAR) new /mob/living/simple_animal/hostile/retaliate/goat(loc) return ..() @@ -83,8 +80,8 @@ name = "chicken crate" icon_state = "lisacrate" -/obj/structure/largecrate/chick/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) +/obj/structure/largecrate/chick/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_CROWBAR) var/num = rand(4, 6) for(var/i = 0, i < num, i++) new /mob/living/simple_animal/chick(loc) @@ -94,7 +91,7 @@ name = "cat crate" icon_state = "lisacrate" -/obj/structure/largecrate/cat/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/crowbar)) +/obj/structure/largecrate/cat/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_CROWBAR) new /mob/living/simple_animal/pet/cat(loc) return ..() diff --git a/code/game/objects/structures/crates_lockers/walllocker.dm b/code/game/objects/structures/crates_lockers/walllocker.dm index 4a2f9a7ed88..c127b629719 100644 --- a/code/game/objects/structures/crates_lockers/walllocker.dm +++ b/code/game/objects/structures/crates_lockers/walllocker.dm @@ -6,15 +6,13 @@ name = "wall locker" icon = 'icons/obj/walllocker.dmi' icon_state = "wall-locker" - density = 0 - anchored = 1 + density = FALSE + anchored = TRUE + ignore_density_closed = TRUE + no_overlays = TRUE icon_closed = "wall-locker" icon_opened = "wall-lockeropen" -/obj/structure/closet/walllocker/close() - ..() - density = 0 //It's a locker in a wall, you aren't going to be walking into it. - /obj/structure/closet/walllocker/emerglocker name = "emergency locker" desc = "A wall mounted locker with emergency supplies" @@ -22,6 +20,7 @@ icon_closed = "emerg" icon_opened = "emergopen" + /obj/structure/closet/walllocker/emerglocker/populate_contents() new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/tank/internals/emergency_oxygen(src) diff --git a/code/game/objects/structures/delta_statue.dm b/code/game/objects/structures/delta_statue.dm index 6c329b44a3b..c02c97501a3 100644 --- a/code/game/objects/structures/delta_statue.dm +++ b/code/game/objects/structures/delta_statue.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/delta_statue.dmi' icon_state = "" density = 1 - anchored = 1 + anchored = TRUE max_integrity = 500 /obj/structure/delta_statue/nw diff --git a/code/game/objects/structures/depot.dm b/code/game/objects/structures/depot.dm index 9f0e20f4d52..dd65b68fde1 100644 --- a/code/game/objects/structures/depot.dm +++ b/code/game/objects/structures/depot.dm @@ -4,7 +4,7 @@ desc = "" icon = 'icons/obj/device.dmi' icon_state = "powersink1" - anchored = 1 + anchored = TRUE max_integrity = 50 var/area/syndicate_depot/core/depotarea var/has_overloaded = FALSE @@ -74,7 +74,7 @@ icon_state = "energy_ball" pixel_x = -32 pixel_y = -32 - anchored = 1 + anchored = TRUE var/cycles = 0 var/beepsound = 'sound/items/timer.ogg' var/deliberate = FALSE @@ -88,7 +88,7 @@ if(istype(depotarea)) if(!depotarea.used_self_destruct) depotarea.used_self_destruct = TRUE // Silences all further alerts from this point onwards. - depotarea.updateicon() + depotarea.update_state() depotarea.shields_down() else log_debug("[src] at [x],[y],[z] failed depotarea istype check during Initialize()! Either it was spawned outside the depot area (bad idea), or a bug is happening.") @@ -105,7 +105,7 @@ depotarea = get_area(src) if(istype(depotarea)) depotarea.destroyed = TRUE - depotarea.updateicon() + depotarea.update_state() for(var/obj/structure/closet/L in range(30, T)) for(var/obj/O in L) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 198344cf275..4813c2a3e13 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -22,8 +22,7 @@ /obj/structure/door_assembly/Initialize(mapload) . = ..() - update_icon() - update_name() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) /obj/structure/door_assembly/Destroy() QDEL_NULL(electronics) @@ -142,8 +141,7 @@ to_chat(user, "You cannot add [S] to [src]!") else return ..() - update_name() - update_icon() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) /obj/structure/door_assembly/crowbar_act(mob/user, obj/item/I) if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) @@ -164,8 +162,7 @@ ae = electronics electronics = null ae.forceMove(loc) - update_icon() - update_name() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) /obj/structure/door_assembly/screwdriver_act(mob/user, obj/item/I) if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) @@ -199,7 +196,7 @@ electronics.forceMove(door) electronics = null qdel(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/door_assembly/wirecutter_act(mob/user, obj/item/I) if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) @@ -213,7 +210,7 @@ to_chat(user, "You cut the wires from the airlock assembly.") new/obj/item/stack/cable_coil(get_turf(user), 1) state = AIRLOCK_ASSEMBLY_NEEDS_WIRES - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/door_assembly/wrench_act(mob/user, obj/item/I) if(state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) @@ -266,17 +263,19 @@ return to_chat(user, "You disassemble the airlock assembly.") deconstruct(TRUE) - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/structure/door_assembly/update_icon() - overlays.Cut() + +/obj/structure/door_assembly/update_overlays() + . = ..() if(!glass) - overlays += get_airlock_overlay("fill_construction", icon) + . += get_airlock_overlay("fill_construction", icon) else if(glass) - overlays += get_airlock_overlay("glass_construction", overlays_file) - overlays += get_airlock_overlay("panel_c[state+1]", overlays_file) + . += get_airlock_overlay("glass_construction", overlays_file) + . += get_airlock_overlay("panel_c[state+1]", overlays_file) -/obj/structure/door_assembly/update_name() + +/obj/structure/door_assembly/update_name(updates = ALL) . = ..() name = "" switch(state) @@ -289,6 +288,7 @@ name = "near finished " name += "[heat_proof_finished ? "heat-proofed " : ""][glass ? "window " : ""][base_name] assembly" + /obj/structure/door_assembly/proc/transfer_assembly_vars(obj/structure/door_assembly/source, obj/structure/door_assembly/target, previous = FALSE) target.glass = source.glass target.heat_proof_finished = source.heat_proof_finished @@ -300,8 +300,7 @@ if(electronics) target.electronics = source.electronics source.electronics.forceMove(target) - target.update_icon() - target.update_name() + target.update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) qdel(source) /obj/structure/door_assembly/deconstruct(disassembled = TRUE) diff --git a/code/game/objects/structures/door_assembly_types.dm b/code/game/objects/structures/door_assembly_types.dm index 04899537e55..b8f20a99dc9 100644 --- a/code/game/objects/structures/door_assembly_types.dm +++ b/code/game/objects/structures/door_assembly_types.dm @@ -173,7 +173,7 @@ . = ..() icon = SSticker.cultdat?.airlock_runed_icon_file overlays_file = SSticker.cultdat?.airlock_runed_overlays_file - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/door_assembly/door_assembly_cult_fake name = "cult airlock assembly" @@ -187,7 +187,7 @@ . = ..() icon = SSticker.cultdat?.airlock_runed_icon_file overlays_file = SSticker.cultdat?.airlock_runed_overlays_file - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/door_assembly/door_assembly_cult/unruned icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' @@ -199,7 +199,7 @@ . = ..() icon = SSticker.cultdat?.airlock_unruned_icon_file overlays_file = SSticker.cultdat?.airlock_unruned_overlays_file - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/door_assembly/door_assembly_clock name = "clock airlock assembly" diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 5fcd58bb734..8f0b992ad4d 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "dresser" density = 1 - anchored = 1 + anchored = TRUE /obj/structure/dresser/attack_hand(mob/user as mob) if(!Adjacent(user))//no tele-grooming diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 491ce2f5523..cd532bf025c 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -4,13 +4,15 @@ icon_state = "echair0" item_chair = null anchored = TRUE - var/obj/item/assembly/shock_kit/part = null - var/last_time = 1.0 - var/delay_time = 50 + var/obj/item/assembly/shock_kit/part + var/last_time = 0 + var/delay_time = 5 SECONDS + var/shocking = FALSE + /obj/structure/chair/e_chair/Initialize(mapload, obj/item/assembly/shock_kit/sk) . = ..() - overlays += image('icons/obj/chairs.dmi', src, "echair_over", MOB_LAYER + 1, dir) + update_icon(UPDATE_OVERLAYS) if(sk) part = sk @@ -25,64 +27,96 @@ part.part1 = part1 part.part2 = part2 -/obj/structure/chair/e_chair/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wrench)) - var/obj/structure/chair/C = new /obj/structure/chair(loc) - transfer_fingerprints_to(C) - playsound(loc, W.usesound, 50, 1) - C.dir = dir - part.loc = loc + +/obj/structure/chair/e_chair/Destroy() + if(part) + QDEL_NULL(part) + return ..() + + +/obj/structure/chair/e_chair/rotate() + if(..()) + update_icon(UPDATE_OVERLAYS) + + +/obj/structure/chair/e_chair/update_icon_state() + icon_state = "echair[shocking]" + + +/obj/structure/chair/e_chair/update_overlays() + . = ..() + . += image(icon, icon_state = "echair_over", layer = ABOVE_MOB_LAYER, dir = src.dir) + if(shocking) + . += image(icon, icon_state = "echair_shock", layer = ABOVE_MOB_LAYER) + + +/obj/structure/chair/e_chair/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_WRENCH) + var/obj/structure/chair/chair = new (loc) + transfer_fingerprints_to(chair) + playsound(loc, W.usesound, 50, TRUE) + chair.dir = dir + part.forceMove(loc) part.master = null part = null qdel(src) return return ..() + +/obj/structure/chair/e_chair/examine(mob/user) + . = ..() + . += span_warning("You can Alt-Shift-Click [src] to activate it.") + + +/obj/structure/chair/e_chair/AltShiftClick(mob/living/user) + if(!Adjacent(user)) + return ..() + shock(user) + + /obj/structure/chair/e_chair/verb/activate_e_chair() set name = "Activate Electric Chair" set category = "Object" set src in oview(1) - if(usr.stat || !usr.canmove || usr.restrained()) - return - if(last_time + delay_time > world.time) - to_chat(usr, "\The [src] is not ready yet!") - return - to_chat(usr, "You activate \the [src].") - shock() -/obj/structure/chair/e_chair/rotate() - ..() - overlays.Cut() - overlays += image('icons/obj/chairs.dmi', src, "echair_over", MOB_LAYER + 1, dir) //there's probably a better way of handling this, but eh. -Pete + shock(usr) -/obj/structure/chair/e_chair/proc/shock() - if(last_time + delay_time > world.time) - return - last_time = world.time - icon_state = "echair1" - spawn(delay_time) - icon_state = "echair0" +/obj/structure/chair/e_chair/proc/shock(mob/living/user) + if(isliving(user) && (user.incapacitated() || user.restrained())) + return // special power handling - var/area/A = get_area(src) - if(!isarea(A)) + var/area/our_area = get_area(src) + if(!our_area || !our_area.powered(EQUIP)) return - if(!A.powered(EQUIP)) + + if(last_time + delay_time > world.time) + if(user) + to_chat(user, span_warning("[src] is not ready yet!")) return - A.use_power(5000, EQUIP) - var/light = A.power_light - A.updateicon() + last_time = world.time + our_area.use_power(5000, EQUIP) + our_area.update_icon(UPDATE_ICON_STATE) + + if(user) + to_chat(user, span_notice("You activate [src].")) - flick("echair_shock", src) + shocking = TRUE + update_icon() do_sparks(12, 1, src) - visible_message("The electric chair went off!", "You hear a deep sharp shock!") + visible_message(span_danger("The electric chair went off!")) + addtimer(CALLBACK(src, PROC_REF(reset_echair)), delay_time, TIMER_DELETE_ME) + if(has_buckled_mobs()) - for(var/m in buckled_mobs) - var/mob/living/buckled_mob = m + for(var/mob/living/buckled_mob as anything in buckled_mobs) buckled_mob.electrocute_act(110, src, 1) - to_chat(buckled_mob, "You feel a deep shock course through your body!") - spawn(1) - buckled_mob.electrocute_act(110, src, 1) - A.power_light = light - A.updateicon() + to_chat(buckled_mob, span_userdanger("You feel a deep shock course through your body!")) + addtimer(CALLBACK(buckled_mob, TYPE_PROC_REF(/mob/living, electrocute_act), 110, src, 1), 0.1 SECONDS, TIMER_DELETE_ME) + + +/obj/structure/chair/e_chair/proc/reset_echair() + shocking = FALSE + update_icon() + diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm index 9de1ce1c470..fba6f2a5f5b 100644 --- a/code/game/objects/structures/engicart.dm +++ b/code/game/objects/structures/engicart.dm @@ -3,7 +3,7 @@ desc = "A cart for storing engineering items." icon = 'icons/obj/engicart.dmi' icon_state = "cart" - anchored = 0 + anchored = FALSE density = 1 pull_push_speed_modifier = 1 var/obj/item/stack/sheet/glass/myglass = null @@ -38,7 +38,7 @@ add_fingerprint(user) put_in_cart(I, user) myglass=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/stack/sheet/metal)) @@ -46,7 +46,7 @@ add_fingerprint(user) put_in_cart(I, user) mymetal=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/stack/sheet/plasteel)) @@ -54,7 +54,7 @@ add_fingerprint(user) put_in_cart(I, user) myplasteel=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/flashlight)) @@ -62,7 +62,7 @@ add_fingerprint(user) put_in_cart(I, user) myflashlight=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/storage/toolbox/mechanical)) @@ -70,7 +70,7 @@ add_fingerprint(user) put_in_cart(I, user) mybluetoolbox=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/storage/toolbox/electrical)) @@ -78,7 +78,7 @@ add_fingerprint(user) put_in_cart(I, user) myyellowtoolbox=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) else if(istype(I, /obj/item/storage/toolbox)) @@ -86,10 +86,10 @@ add_fingerprint(user) put_in_cart(I, user) myredtoolbox=I - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, fail_msg) - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) if(!anchored && !isinspace()) playsound(src.loc, I.usesound, 50, 1) @@ -97,14 +97,14 @@ "[user] tightens \the [src]'s casters.", \ " You have tightened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 1 + anchored = TRUE else if(anchored) playsound(src.loc, I.usesound, 50, 1) user.visible_message( \ "[user] loosens \the [src]'s casters.", \ " You have loosened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 0 + anchored = FALSE else to_chat(usr, "You cannot interface your modules [src]!") @@ -178,22 +178,24 @@ to_chat(user, "You take [myyellowtoolbox] from [src].") myyellowtoolbox = null - update_icon() + update_icon(UPDATE_OVERLAYS) updateUsrDialog() -/obj/structure/engineeringcart/update_icon() - overlays.Cut() + +/obj/structure/engineeringcart/update_overlays() + . = ..() if(myglass) - overlays += "cart_glass" + . += "cart_glass" if(mymetal) - overlays += "cart_metal" + . += "cart_metal" if(myplasteel) - overlays += "cart_plasteel" + . += "cart_plasteel" if(myflashlight) - overlays += "cart_flashlight" + . += "cart_flashlight" if(mybluetoolbox) - overlays += "cart_bluetoolbox" + . += "cart_bluetoolbox" if(myredtoolbox) - overlays += "cart_redtoolbox" + . += "cart_redtoolbox" if(myyellowtoolbox) - overlays += "cart_yellowtoolbox" + . += "cart_yellowtoolbox" + diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 20c58523d17..550aea991cd 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -8,7 +8,7 @@ desc = "A small wall mounted cabinet designed to hold a fire extinguisher." icon = 'icons/obj/closet.dmi' icon_state = "extinguisher_closed" - anchored = 1 + anchored = TRUE density = 0 max_integrity = 200 integrity_failure = 50 @@ -29,6 +29,7 @@ has_extinguisher = new/obj/item/extinguisher/mini(src) else has_extinguisher = new/obj/item/extinguisher(src) + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/examine(mob/user) . = ..() @@ -44,7 +45,7 @@ return playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) opened = !opened - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/Destroy() QDEL_NULL(has_extinguisher) @@ -58,7 +59,7 @@ /obj/structure/extinguisher_cabinet/handle_atom_del(atom/A) if(A == has_extinguisher) has_extinguisher = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user, params) if(isrobot(user) || isalien(user)) @@ -69,18 +70,18 @@ return add_fingerprint(user) has_extinguisher = O - update_icon() + update_icon(UPDATE_ICON_STATE) to_chat(user, "You place [O] in [src].") return TRUE else playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) opened = !opened - update_icon() + update_icon(UPDATE_ICON_STATE) else if(user.a_intent != INTENT_HARM) add_fingerprint(user) playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) opened = !opened - update_icon() + update_icon(UPDATE_ICON_STATE) else return ..() @@ -123,7 +124,7 @@ else playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) opened = !opened - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/attack_tk(mob/user) if(has_extinguisher) @@ -136,7 +137,7 @@ else playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) opened = !opened - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/obj_break(damage_flag) if(!broken && !(flags & NODECONSTRUCT)) @@ -145,7 +146,7 @@ if(has_extinguisher) has_extinguisher.forceMove(loc) has_extinguisher = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/extinguisher_cabinet/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) @@ -155,7 +156,7 @@ has_extinguisher = null qdel(src) -/obj/structure/extinguisher_cabinet/update_icon() +/obj/structure/extinguisher_cabinet/update_icon_state() if(!opened) icon_state = "extinguisher_closed" return diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 2847d2f54af..4eb87c6d37b 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -45,13 +45,14 @@ var/healthpercent = (obj_integrity/max_integrity) * 100 switch(healthpercent) if(100) - return "It looks fully intact." + . = "It looks fully intact." if(70 to 99) - return "It looks slightly damaged." + . = "It looks slightly damaged." if(40 to 70) - return "It looks moderately damaged." + . = "It looks moderately damaged." if(0 to 40) - return "It looks heavily damaged." + . = "It looks heavily damaged." + . += "
    Using a lit welding tool on this item will allow you to slice through it, eventually removing the outer layer." /obj/structure/falsewall/ratvar_act() new /obj/structure/falsewall/brass(loc) @@ -73,31 +74,31 @@ . = ..() toggle(user) + /obj/structure/falsewall/proc/toggle(mob/user) if(opening) return - - opening = 1 + opening = TRUE if(density) add_fingerprint(user) do_the_flick() - sleep(4) - density = 0 - set_opacity(0) - update_icon(0) + sleep(0.4 SECONDS) + density = FALSE + set_opacity(FALSE) else var/srcturf = get_turf(src) for(var/mob/living/obstacle in srcturf) //Stop people from using this as a shield - opening = 0 + opening = FALSE return add_fingerprint(user) do_the_flick() - density = 1 - sleep(4) - set_opacity(1) - update_icon() - air_update_turf(1) - opening = 0 + density = TRUE + sleep(0.4 SECONDS) + set_opacity(TRUE) + air_update_turf(TRUE) + opening = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/structure/falsewall/proc/do_the_flick() if(density) @@ -107,7 +108,8 @@ else flick("fwall_closing", src) -/obj/structure/falsewall/update_icon() + +/obj/structure/falsewall/update_icon_state() if(density) icon_state = initial(icon_state) smooth = SMOOTH_TRUE @@ -115,6 +117,7 @@ else icon_state = "fwall_open" + /obj/structure/falsewall/proc/ChangeToWall(delete = TRUE) var/turf/T = get_turf(src) T.ChangeTurf(walltype) @@ -132,7 +135,7 @@ if(T.density) to_chat(user, "[src] is blocked!") return - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) if(!istype(T, /turf/simulated/floor)) to_chat(user, "[src] bolts must be tightened on the floor!") return diff --git a/code/game/objects/structures/firepit.dm b/code/game/objects/structures/firepit.dm index 075c83e7033..f3f48243f0a 100644 --- a/code/game/objects/structures/firepit.dm +++ b/code/game/objects/structures/firepit.dm @@ -2,7 +2,7 @@ name = "firepit" desc = "Warm and toasty." icon = 'icons/obj/fireplace.dmi' - icon_state = "firepit-active" + icon_state = "firepit" density = FALSE anchored = TRUE max_integrity = 50 @@ -10,9 +10,6 @@ var/lighter // Who lit the thing var/fire_stack_strength = 5 -/obj/structure/firepit/Initialize(mapload) - . = ..() - update_icon() /obj/structure/firepit/attack_hand(mob/living/user) if(active) @@ -31,18 +28,26 @@ else W.fire_act() -/obj/structure/firepit/update_icon() - . = ..() + +/obj/structure/firepit/proc/adjust_light() if(active) set_light(4, ,"#ffb366") - icon_state = "firepit-active" else set_light(0) + + +/obj/structure/firepit/update_icon_state() + if(active) + icon_state = "firepit-active" + else icon_state = "firepit" + /obj/structure/firepit/proc/toggleFirepit() active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) + adjust_light() + /obj/structure/firepit/extinguish() . = ..() diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index 10a5bf70a74..948020d288b 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -69,10 +69,15 @@ else . = ..() -/obj/structure/fireplace/update_icon() + +/obj/structure/fireplace/update_desc(updates = ALL) + . = ..() + desc = lit ? "A large stone brick fireplace, warm and cozy." : initial(desc) + + +/obj/structure/fireplace/update_overlays() . = ..() - overlays.Cut() if(!lit) return @@ -81,17 +86,18 @@ switch(burn_time_remaining()) if(0 to 500) firepower = "fireplace_fire0" - if(500 to 1000) + if(501 to 1000) firepower = "fireplace_fire1" - if(1000 to 1500) + if(1001 to 1500) firepower = "fireplace_fire2" - if(1500 to 2000) + if(1501 to 2000) firepower = "fireplace_fire3" - if(2000 to MAXIMUM_BURN_TIMER) + if(2001 to MAXIMUM_BURN_TIMER) firepower = "fireplace_fire4" - overlays += icon('icons/obj/fireplace.dmi', "[firepower]") - overlays += icon('icons/obj/fireplace.dmi', "fireplace_glow") + . += "[firepower]" + . += "fireplace_glow" + /obj/structure/fireplace/proc/adjust_light() if(!lit) @@ -101,15 +107,16 @@ switch(burn_time_remaining()) if(0 to 500) set_light(1, ,"#ffb366") - if(500 to 1000) + if(501 to 1000) set_light(2, ,"#ffb366") - if(1000 to 1500) + if(1001 to 1500) set_light(3, ,"#ffb366") - if(1500 to 2000) + if(1501 to 2000) set_light(4, ,"#ffb366") - if(2000 to MAXIMUM_BURN_TIMER) + if(2001 to MAXIMUM_BURN_TIMER) set_light(6, ,"#ffb366") + /obj/structure/fireplace/process(seconds_per_tick) if(!lit) return @@ -120,9 +127,10 @@ playsound(src, 'sound/effects/comfyfire.ogg',40,FALSE, FALSE, TRUE) var/turf/T = get_turf(src) T.hotspot_expose(700, 2.5 * seconds_per_tick) - update_icon() + update_icon(UPDATE_OVERLAYS) adjust_light() + /obj/structure/fireplace/extinguish() . = ..() if(lit) @@ -131,6 +139,7 @@ put_out() adjust_fuel_timer(fuel) + /obj/structure/fireplace/proc/adjust_fuel_timer(amount) if(lit) flame_expiry_timer += amount @@ -139,25 +148,27 @@ else fuel_added = clamp(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) + /obj/structure/fireplace/proc/burn_time_remaining() if(lit) return max(0, flame_expiry_timer - world.time) else return max(0, fuel_added) + /obj/structure/fireplace/proc/ignite() lit = TRUE - desc = "A large stone brick fireplace, warm and cozy." flame_expiry_timer = world.time + fuel_added fuel_added = 0 - update_icon() + update_appearance(UPDATE_OVERLAYS|UPDATE_DESC) adjust_light() + /obj/structure/fireplace/proc/put_out() lit = FALSE - update_icon() + update_appearance(UPDATE_OVERLAYS|UPDATE_DESC) adjust_light() - desc = initial(desc) + #undef LOG_BURN_TIMER #undef PAPER_BURN_TIMER diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index e259b83049f..44f3844f07c 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -5,7 +5,7 @@ //trees /obj/structure/flora/tree name = "tree" - anchored = 1 + anchored = TRUE density = 1 pixel_x = -16 layer = 9 @@ -65,7 +65,7 @@ /obj/structure/flora/grass name = "grass" icon = 'icons/obj/flora/snowflora.dmi' - anchored = 1 + anchored = TRUE max_integrity = 15 /obj/structure/flora/grass/brown @@ -96,7 +96,7 @@ name = "bush" icon = 'icons/obj/flora/snowflora.dmi' icon_state = "snowbush1" - anchored = 1 + anchored = TRUE max_integrity = 15 /obj/structure/flora/bush/Initialize(mapload) @@ -109,7 +109,7 @@ name = "bush" icon = 'icons/obj/flora/ausflora.dmi' icon_state = "firstbush_1" - anchored = 1 + anchored = TRUE max_integrity = 15 /obj/structure/flora/ausbushes/Initialize(mapload) @@ -227,7 +227,7 @@ icon = 'icons/obj/flora/plants.dmi' icon_state = "plant-1" flags = NO_PIXEL_RANDOM_DROP - anchored = 0 + anchored = FALSE layer = ABOVE_MOB_LAYER w_class = WEIGHT_CLASS_HUGE force = 10 @@ -321,7 +321,7 @@ icon_state = "rock1" icon = 'icons/obj/flora/rocks.dmi' resistance_flags = FIRE_PROOF - anchored = 1 + anchored = TRUE /obj/structure/flora/rock/Initialize(mapload) . = ..() @@ -370,7 +370,7 @@ name = "corn stalk" icon = 'icons/obj/flora/plants.dmi' icon_state = "cornstalk1" - anchored = 0 + anchored = FALSE layer = 5 /obj/structure/flora/corn_stalk/alt_1 @@ -398,7 +398,7 @@ icon = 'icons/obj/flora/plants.dmi' icon_state = "bush1" density = 1 - anchored = 1 + anchored = TRUE layer = 3.2 var/indestructable = 0 var/stump = 0 diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 4fbe7ef4542..66f7b6e1792 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -11,7 +11,7 @@ var/deconstructible = TRUE /obj/structure/fluff/attackby(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/wrench) && deconstructible) + if(I.tool_behaviour == TOOL_WRENCH && deconstructible) user.visible_message("[user] starts disassembling [src]...", "You start disassembling [src]...") playsound(loc, I.usesound, 50, 1) if(do_after(src, 50 * I.toolspeed * gettoolspeedmod(user), target = src)) diff --git a/code/game/objects/structures/foodcart.dm b/code/game/objects/structures/foodcart.dm index 24d051e6b89..0abbccffb8d 100644 --- a/code/game/objects/structures/foodcart.dm +++ b/code/game/objects/structures/foodcart.dm @@ -3,7 +3,7 @@ desc = "A cart for transporting food and drinks." icon = 'icons/obj/foodcart.dmi' icon_state = "cart" - anchored = 0 + anchored = FALSE density = 1 pull_push_speed_modifier = 1 //Food slots @@ -39,7 +39,6 @@ add_fingerprint(user) put_in_cart(I, user) food_slots[s]=I - update_icon() success = 1 break if(!success) @@ -51,12 +50,11 @@ add_fingerprint(user) put_in_cart(I, user) drink_slots[s]=I - update_icon() success = 1 break if(!success) to_chat(user, fail_msg) - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) if(!anchored && !isinspace()) playsound(src.loc, I.usesound, 50, 1) @@ -64,14 +62,14 @@ "[user] tightens \the [src]'s casters.", \ " You have tightened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 1 + anchored = TRUE else if(anchored) playsound(src.loc, I.usesound, 50, 1) user.visible_message( \ "[user] loosens \the [src]'s casters.", \ " You have loosened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 0 + anchored = FALSE else to_chat(usr, "You cannot interface your modules [src]!") @@ -198,7 +196,6 @@ to_chat(user, "You take [drink] from [src].") drink_slots[6] = null - update_icon() //Not really needed without overlays, but keeping just in case updateUsrDialog() /obj/structure/foodcart/deconstruct(disassembled = TRUE) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index b4505000959..157d28d38cd 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -1,7 +1,7 @@ /obj/structure/girder name = "girder" icon_state = "girder" - anchored = 1 + anchored = TRUE density = 1 layer = BELOW_OBJ_LAYER var/state = GIRDER_NORMAL @@ -439,7 +439,7 @@ /obj/structure/girder/displaced name = "displaced girder" icon_state = "displaced" - anchored = 0 + anchored = FALSE state = GIRDER_DISPLACED girderpasschance = 25 max_integrity = 120 diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 2a7cbe1ffc7..a8c693301b8 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -43,9 +43,6 @@ //height=42 icon='icons/obj/fence-ns.dmi' -/obj/structure/grille/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration) - . = ..() - update_icon() /obj/structure/grille/examine(mob/user) . = ..() diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index c1fbb87d958..9106bf66cb6 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -2,15 +2,18 @@ #define GUILLOTINE_DECAP_MIN_SHARP 7 // Minimum amount of sharpness for decapitation. Any less and it will just deal brute damage #define GUILLOTINE_ANIMATION_LENGTH 9 // How many deciseconds the animation is #define GUILLOTINE_BLADE_RAISED 1 -#define GUILLOTINE_BLADE_MOVING 2 -#define GUILLOTINE_BLADE_DROPPED 3 -#define GUILLOTINE_BLADE_SHARPENING 4 +#define GUILLOTINE_BLADE_RAISING 2 +#define GUILLOTINE_BLADE_DROPPING 3 +#define GUILLOTINE_BLADE_DROPPED 4 +#define GUILLOTINE_BLADE_SHARPENING 5 + #define GUILLOTINE_HEAD_OFFSET 16 // How much we need to move the player to center their head #define GUILLOTINE_LAYER_DIFF 1.2 // How much to increase/decrease a head when it's buckled/unbuckled #define GUILLOTINE_ACTIVATE_DELAY 30 // Delay for executing someone #define GUILLOTINE_WRENCH_DELAY 10 -#define GUILLOTINE_ACTION_INUSE 5 -#define GUILLOTINE_ACTION_WRENCH 6 + +#define GUILLOTINE_ACTION_INUSE 1 +#define GUILLOTINE_ACTION_WRENCH 2 /obj/structure/guillotine name = "guillotine" @@ -26,7 +29,7 @@ var/blade_sharpness = GUILLOTINE_BLADE_MAX_SHARP // How sharp the blade is var/kill_count = 0 var/force_clap = FALSE //You WILL clap if I want you to - var/current_action = 0 // What's currently happening to the guillotine + var/current_action = NONE// What's currently happening to the guillotine /obj/structure/guillotine/Initialize(mapload) LAZYINITLIST(buckled_mobs) @@ -51,6 +54,31 @@ msg += "
    " msg += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." . += "[msg]" + + +/obj/structure/guillotine/update_icon_state() + switch(blade_status) + if(GUILLOTINE_BLADE_DROPPED) + icon_state = "guillotine" + if(GUILLOTINE_BLADE_RAISED) + icon_state = "guillotine_raised" + if(GUILLOTINE_BLADE_RAISING) + icon_state = "guillotine_raise" + if(GUILLOTINE_BLADE_DROPPING) + icon_state = "guillotine_drop" + + +/obj/structure/guillotine/update_overlays() + . = ..() + switch(kill_count) + if(1) + . += mutable_appearance(icon, "guillotine_bloody_overlay") + if(2) + . += mutable_appearance(icon, "guillotine_bloodier_overlay") + if(3 to INFINITY) + . += mutable_appearance(icon, "guillotine_bloodiest_overlay") + + /obj/structure/guillotine/attack_hand(mob/user) // Currently being used by something @@ -58,12 +86,12 @@ return switch(blade_status) - if(GUILLOTINE_BLADE_MOVING) + if(GUILLOTINE_BLADE_RAISING, GUILLOTINE_BLADE_DROPPING) return if(GUILLOTINE_BLADE_DROPPED) add_fingerprint(user) - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_raise" + blade_status = GUILLOTINE_BLADE_RAISING + update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, PROC_REF(raise_blade)), GUILLOTINE_ANIMATION_LENGTH) return if(GUILLOTINE_BLADE_RAISED) @@ -75,26 +103,28 @@ if(do_after(user, GUILLOTINE_ACTIVATE_DELAY, target = src) && blade_status == GUILLOTINE_BLADE_RAISED) add_fingerprint(user) - current_action = 0 - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_drop" + current_action = NONE + blade_status = GUILLOTINE_BLADE_DROPPING + update_icon(UPDATE_ICON_STATE) playsound(src, 'sound/items/unsheath.ogg', 100, 1) addtimer(CALLBACK(src, PROC_REF(drop_blade), user), GUILLOTINE_ANIMATION_LENGTH - 2) // Minus two so we play the sound and decap faster else - current_action = 0 + current_action = NONE else add_fingerprint(user) unbuckle_all_mobs() else add_fingerprint(user) - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_drop" + blade_status = GUILLOTINE_BLADE_DROPPING + update_icon(UPDATE_ICON_STATE) playsound(src, 'sound/items/unsheath.ogg', 100, 1) addtimer(CALLBACK(src, PROC_REF(drop_blade)), GUILLOTINE_ANIMATION_LENGTH) + /obj/structure/guillotine/proc/raise_blade() blade_status = GUILLOTINE_BLADE_RAISED - icon_state = "guillotine_raised" + update_icon(UPDATE_ICON_STATE) + /obj/structure/guillotine/proc/drop_blade(mob/user) if(has_buckled_mobs() && blade_sharpness) @@ -102,14 +132,14 @@ if(!H) blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" + update_icon(UPDATE_ICON_STATE) return var/obj/item/organ/external/head/head = H.get_organ(BODY_ZONE_HEAD) if(QDELETED(head)) blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" + update_icon(UPDATE_ICON_STATE) return playsound(src, 'sound/weapons/bladeslice.ogg', 100, 1) @@ -118,18 +148,8 @@ add_attack_logs(user, H, "beheaded with [src]") H.regenerate_icons() unbuckle_all_mobs() - kill_count += 1 - - var/blood_overlay = "bloody" - - if(kill_count == 2) - blood_overlay = "bloodier" - else if(kill_count > 2) - blood_overlay = "bloodiest" - - blood_overlay = "guillotine_" + blood_overlay + "_overlay" - overlays.Cut() - overlays += mutable_appearance(icon, blood_overlay) + kill_count++ + update_icon(UPDATE_OVERLAYS) if(force_clap) // The crowd is pleased @@ -147,7 +167,7 @@ blade_sharpness -= 1 blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" + update_icon(UPDATE_ICON_STATE) /obj/structure/guillotine/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/whetstone)) @@ -185,13 +205,13 @@ return current_action = GUILLOTINE_ACTION_WRENCH if(!I.use_tool(src, user, GUILLOTINE_WRENCH_DELAY, volume = I.tool_volume)) - current_action = 0 + current_action = NONE return if(has_buckled_mobs()) to_chat(user, "Can't unfasten, someone's strapped in!") return - current_action = 0 + current_action = NONE to_chat(user, "You [anchored ? "un" : ""]secure [src].") anchored = !anchored playsound(src, 'sound/items/deconstruct.ogg', 50, 1) @@ -244,7 +264,8 @@ #undef GUILLOTINE_DECAP_MIN_SHARP #undef GUILLOTINE_ANIMATION_LENGTH #undef GUILLOTINE_BLADE_RAISED -#undef GUILLOTINE_BLADE_MOVING +#undef GUILLOTINE_BLADE_RAISING +#undef GUILLOTINE_BLADE_DROPPING #undef GUILLOTINE_BLADE_DROPPED #undef GUILLOTINE_BLADE_SHARPENING #undef GUILLOTINE_HEAD_OFFSET diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index a13532d1f0f..5dc13e56008 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -15,9 +15,9 @@ /obj/structure/inflatable name = "inflatable wall" desc = "An inflated membrane. Do not puncture." - density = 1 - anchored = 1 - opacity = 0 + density = TRUE + anchored = TRUE + opacity = FALSE max_integrity = 50 icon = 'icons/obj/inflatable.dmi' icon_state = "wall" @@ -39,20 +39,30 @@ else return FALSE + /obj/structure/inflatable/CanAtmosPass(turf/T) return !density -/obj/structure/inflatable/attack_hand(mob/user as mob) + +/obj/structure/inflatable/attackby(obj/item/I, mob/living/user, params) + if(I.sharp || is_type_in_typecache(I, GLOB.pointed_types)) + user.do_attack_animation(src, used_item = I) + deconstruct(FALSE) + return FALSE + return ..() + +/obj/structure/inflatable/attack_hand(mob/user) add_fingerprint(user) /obj/structure/inflatable/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated() || user.restrained()) + if(!istype(user) || user.incapacitated()) to_chat(user, "You can't do that right now!") return if(!Adjacent(user)) return deconstruct(TRUE) + /obj/structure/inflatable/deconstruct(disassembled = TRUE) playsound(loc, 'sound/machines/hiss.ogg', 75, 1) if(!disassembled) @@ -62,17 +72,20 @@ qdel(src) else visible_message("[src] slowly deflates.") - spawn(50) - var/obj/item/inflatable/R = new intact(loc) - transfer_fingerprints_to(R) - qdel(src) + addtimer(CALLBACK(src, PROC_REF(deflate)), 5 SECONDS) + + +/obj/structure/inflatable/proc/deflate() + var/obj/item/inflatable/R = new intact(loc) + transfer_fingerprints_to(R) + qdel(src) /obj/structure/inflatable/verb/hand_deflate() set name = "Deflate" set category = "Object" set src in oview(1) - if(usr.stat || usr.restrained()) + if(usr.incapacitated()) return deconstruct(TRUE) @@ -93,27 +106,24 @@ /obj/structure/inflatable/door //Based on mineral door code name = "inflatable door" - density = 1 - anchored = 1 - opacity = 0 - icon = 'icons/obj/inflatable.dmi' icon_state = "door_closed" + opacity = TRUE torn = /obj/item/inflatable/door/torn intact = /obj/item/inflatable/door - var/state = 0 //closed, 1 == open - var/isSwitchingStates = 0 + var/state_closed = TRUE + var/is_operating = FALSE -/obj/structure/inflatable/door/attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral +/obj/structure/inflatable/door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral if(isAI(user)) //so the AI can't open it return else if(isrobot(user)) //but cyborgs can if(get_dist(user,src) <= 1) //not remotely though - return TryToSwitchState(user) + return try_to_operate(user) -/obj/structure/inflatable/door/attack_hand(mob/user as mob) - return TryToSwitchState(user) +/obj/structure/inflatable/door/attack_hand(mob/user) + return try_to_operate(user) /obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASS_OTHER_THINGS)) @@ -125,59 +135,45 @@ /obj/structure/inflatable/door/CanAtmosPass(turf/T) return !density -/obj/structure/inflatable/door/proc/TryToSwitchState(atom/user) - if(isSwitchingStates) + +/obj/structure/inflatable/door/proc/try_to_operate(atom/user) + if(is_operating) return if(ismob(user)) var/mob/M = user - if(world.time - user.last_bumped <= 60) - return //NOTE do we really need that? if(M.client) if(iscarbon(M)) var/mob/living/carbon/C = M if(!C.handcuffed) - add_fingerprint(user) - SwitchState() + operate() else - add_fingerprint(user) - SwitchState() - else if(istype(user, /obj/mecha)) - SwitchState() - -/obj/structure/inflatable/door/proc/SwitchState() - if(state) - Close() - else - Open() - air_update_turf(1) - -/obj/structure/inflatable/door/proc/Open() - isSwitchingStates = 1 - //playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1) - flick("door_opening",src) - sleep(10) - density = 0 - opacity = 0 - state = 1 - update_icon() - isSwitchingStates = 0 - -/obj/structure/inflatable/door/proc/Close() - isSwitchingStates = 1 - //playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1) - flick("door_closing",src) - sleep(10) - density = 1 - opacity = 0 - state = 0 - update_icon() - isSwitchingStates = 0 - -/obj/structure/inflatable/door/update_icon() - if(state) - icon_state = "door_open" + operate() + else if(ismecha(user)) + operate() + + +/obj/structure/inflatable/door/proc/operate() + is_operating = TRUE + if(state_closed) + flick("door_opening", src) else - icon_state = "door_closed" + flick("door_closing", src) + + sleep(1 SECONDS) + if(QDELETED(src)) + return + + state_closed = !state_closed + density = state_closed + set_opacity(state_closed) + update_icon(UPDATE_ICON_STATE) + air_update_turf(TRUE) + is_operating = FALSE + + +/obj/structure/inflatable/door/update_icon_state() + icon_state = "door_[state_closed ? "closed" : "open"]" + /obj/item/inflatable/torn name = "torn inflatable wall" @@ -206,6 +202,7 @@ item_state = "syringe_kit" max_combined_w_class = 21 w_class = WEIGHT_CLASS_NORMAL + can_hold = list(/obj/item/inflatable) /obj/item/storage/briefcase/inflatable/populate_contents() new /obj/item/inflatable/door(src) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index dc2567bc6a7..ced660b34c8 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -5,8 +5,8 @@ desc = "This is the alpha and omega of sanitation." icon = 'icons/obj/janitor.dmi' icon_state = "cart" - anchored = 0 - density = 1 + anchored = FALSE + density = TRUE container_type = OPENCONTAINER pull_push_speed_modifier = 1 //copypaste sorry @@ -32,14 +32,16 @@ QDEL_NULL(myreplacer) return ..() + /obj/structure/janitorialcart/proc/put_in_cart(obj/item/I, mob/user) user.drop_transfer_item_to_loc(I, src) updateUsrDialog() to_chat(user, "You put [I] into [src].") - return + update_icon(UPDATE_OVERLAYS) + /obj/structure/janitorialcart/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/janitorialcart/attackby(obj/item/I, mob/user, params) var/fail_msg = "There is already one of those in [src]." @@ -66,9 +68,8 @@ else if(istype(I, /obj/item/reagent_containers/spray/cleaner)) if(!myspray) add_fingerprint(user) - put_in_cart(I, user) myspray=I - update_icon() + put_in_cart(I, user) else to_chat(user, fail_msg) else if(istype(I, /obj/item/lightreplacer)) @@ -81,19 +82,18 @@ else if(istype(I, /obj/item/caution)) if(signs < max_signs) add_fingerprint(user) - put_in_cart(I, user) signs++ - update_icon() + put_in_cart(I, user) else to_chat(user, "[src] can't hold any more signs.") - else if(istype(I, /obj/item/crowbar)) + else if(I.tool_behaviour == TOOL_CROWBAR) user.visible_message("[user] begins to empty the contents of [src].") if(do_after(user, 30 * I.toolspeed * gettoolspeedmod(user), target = src)) add_fingerprint(user) to_chat(usr, "You empty the contents of [src]'s bucket onto the floor.") reagents.reaction(src.loc) src.reagents.clear_reagents() - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) if(!anchored && !isinspace()) playsound(src.loc, I.usesound, 50, 1) @@ -101,14 +101,14 @@ "[user] tightens \the [src]'s casters.", \ " You have tightened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 1 + anchored = TRUE else if(anchored) playsound(src.loc, I.usesound, 50, 1) user.visible_message( \ "[user] loosens \the [src]'s casters.", \ " You have loosened \the [src]'s casters.", \ "You hear ratchet.") - anchored = 0 + anchored = FALSE else if(mybag) add_fingerprint(user) mybag.attackby(I, user, params) @@ -176,26 +176,26 @@ WARNING("Signs ([signs]) didn't match contents") signs = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) updateUsrDialog() -/obj/structure/janitorialcart/update_icon() - overlays = null +/obj/structure/janitorialcart/update_overlays() + . = ..() if(mybag) - overlays += "cart_garbage" + . += "cart_garbage" if(mymop) - overlays += "cart_mop" + . += "cart_mop" if(myspray) - overlays += "cart_spray" + . += "cart_spray" if(myreplacer) - overlays += "cart_replacer" + . += "cart_replacer" if(signs) - overlays += "cart_sign[signs]" + . += "cart_sign[signs]" if(reagents.total_volume > 0) var/image/reagentsImage = image(icon,src,"cart_reagents0") reagentsImage.alpha = 150 - switch((reagents.total_volume/reagents.maximum_volume)*100) + switch((reagents.total_volume / reagents.maximum_volume) * 100) if(1 to 25) reagentsImage.icon_state = "cart_reagents1" if(26 to 50) @@ -205,4 +205,5 @@ if(76 to 100) reagentsImage.icon_state = "cart_reagents4" reagentsImage.icon += mix_color_from_reagents(reagents.reagent_list) - add_overlay(reagentsImage) + . += reagentsImage + diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 0245e372f36..58764470efb 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -7,18 +7,18 @@ icon_state = "spikeframe" desc = "The frame of a meat spike." density = 1 - anchored = 0 + anchored = FALSE max_integrity = 200 /obj/structure/kitchenspike_frame/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/wrench)) + if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) if(anchored) to_chat(user, "You unwrench [src] from the floor.") - anchored = 0 + anchored = FALSE else to_chat(user, "You wrench [src] into place.") - anchored = 1 + anchored = TRUE else if(istype(I, /obj/item/stack/rods)) var/obj/item/stack/rods/R = I if(R.get_amount() >= 4) @@ -38,7 +38,7 @@ icon_state = "spike" desc = "A spike for collecting meat from animals." density = 1 - anchored = 1 + anchored = TRUE buckle_lying = FALSE can_buckle = TRUE max_integrity = 250 @@ -53,7 +53,7 @@ ..() /obj/structure/kitchenspike/attackby(obj/item/grab/G, mob/user) - if(istype(G, /obj/item/crowbar)) + if(G.tool_behaviour == TOOL_CROWBAR) if(!has_buckled_mobs()) playsound(loc, G.usesound, 100, 1) if(do_after(user, 20 * G.toolspeed * gettoolspeedmod(user), target = src)) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index cb093c9521a..de42568a598 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -14,11 +14,11 @@ if (up) src.up = up up.down = src - up.update_icon() + up.update_icon(UPDATE_ICON_STATE) if (down) src.down = down down.up = src - down.update_icon() + down.update_icon(UPDATE_ICON_STATE) return INITIALIZE_HINT_LATELOAD /obj/structure/ladder/Destroy(force) @@ -35,7 +35,7 @@ for(var/obj/structure/ladder/L in locate(T.x, T.y, T.z - 1)) down = L L.up = src // Don't waste effort looping the other way - L.update_icon() + L.update_icon(UPDATE_ICON_STATE) break if(!up) for (var/obj/structure/ladder/L in locate(T.x, T.y, T.z + 1)) @@ -44,7 +44,7 @@ L.update_icon() break - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/ladder/proc/disconnect() if(up && up.down == src) @@ -55,7 +55,7 @@ down.update_icon() up = down = null -/obj/structure/ladder/update_icon() +/obj/structure/ladder/update_icon_state() if(up && down) icon_state = "ladder11" @@ -153,7 +153,7 @@ /obj/structure/ladder/unbreakable/LateInitialize() // Override the parent to find ladders based on being height-linked if(!id || (up && down)) - update_icon() + update_icon(UPDATE_ICON_STATE) return for(var/O in GLOB.ladders) @@ -163,17 +163,17 @@ if(!down && L.height == height - 1) down = L L.up = src - L.update_icon() + L.update_icon(UPDATE_ICON_STATE) if (up) break // break if both our connections are filled else if(!up && L.height == height + 1) up = L L.down = src - L.update_icon() + L.update_icon(UPDATE_ICON_STATE) if (down) break // break if both our connections are filled - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/ladder/unbreakable/dive_point/buoy name = "diving point buoy" @@ -198,5 +198,5 @@ . = ..() set_light(light_range, light_power) //magical glowing anchor -/obj/structure/ladder/unbreakable/dive_point/update_icon() +/obj/structure/ladder/unbreakable/dive_point/update_icon_state() return diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 542a5a367a9..79b596c0c99 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -2,7 +2,7 @@ /obj/structure/mineral_door name = "metal door" density = 1 - anchored = 1 + anchored = TRUE opacity = 1 icon = 'icons/obj/doors/mineral_doors.dmi' @@ -98,7 +98,7 @@ opacity = 0 state = 1 air_update_turf(1) - update_icon() + update_icon(UPDATE_ICON_STATE) isSwitchingStates = 0 if(close_delay != -1) @@ -119,15 +119,17 @@ opacity = 1 state = 0 air_update_turf(1) - update_icon() + update_icon(UPDATE_ICON_STATE) isSwitchingStates = 0 -/obj/structure/mineral_door/update_icon() + +/obj/structure/mineral_door/update_icon_state() if(state) icon_state = "[initial_state]open" else icon_state = initial_state + /obj/structure/mineral_door/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pickaxe)) var/obj/item/pickaxe/digTool = W diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index f69dc79ffae..d60b3ab5c1e 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "mirror" density = 0 - anchored = 1 + anchored = TRUE max_integrity = 200 integrity_failure = 100 flags_2 = CHECK_RICOCHET_2 diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm index 290068b0e2e..6e83e2bd56b 100644 --- a/code/game/objects/structures/misc.dm +++ b/code/game/objects/structures/misc.dm @@ -8,7 +8,7 @@ /obj/structure/signpost icon = 'icons/obj/stationobjs.dmi' icon_state = "signpost" - anchored = 1 + anchored = TRUE density = 1 /obj/structure/signpost/attack_hand(mob/user as mob) @@ -20,7 +20,7 @@ desc = "What?" icon = 'icons/obj/stationobjs.dmi' icon_state = "signpost2" - anchored = 1 + anchored = TRUE density = 0 /obj/structure/respawner @@ -45,7 +45,7 @@ desc = "A structure that draws ethereal attention when active. Use an empty hand to activate." icon = 'icons/obj/lavaland/artefacts.dmi' icon_state = "anomaly_crystal" - anchored = 1 + anchored = TRUE density = 1 var/active = FALSE var/ghost_alert_delay = 30 SECONDS diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 62a3c559d0b..653e180cc23 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -26,37 +26,40 @@ if(in_range(user, src)) . += "[bicon(src)] [src] contains [reagents.total_volume] units of water left." -/obj/structure/mopbucket/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/structure/mopbucket/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/mop)) - var/obj/item/mop/m = W - if(m.reagents.total_volume < m.reagents.maximum_volume) + var/obj/item/mop/mop = W + if(mop.reagents.total_volume < mop.reagents.maximum_volume) add_fingerprint(user) - m.wet_mop(src, user) + mop.wet_mop(src, user) return if(!mymop) add_fingerprint(user) - m.janicart_insert(user, src) + mop.mopbucket_insert(user, src) return to_chat(user, "Theres already a mop in the mopbucket.") return return ..() + /obj/structure/mopbucket/proc/put_in_cart(obj/item/mop/I, mob/user) user.drop_transfer_item_to_loc(I, src) to_chat(user, "You put [I] into [src].") - return + update_icon(UPDATE_OVERLAYS) + /obj/structure/mopbucket/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/structure/mopbucket/update_icon() - overlays.Cut() + +/obj/structure/mopbucket/update_overlays() + . = ..() if(mymop) - overlays += image(icon,"mopbucket_mop") + . += "mopbucket_mop" if(reagents.total_volume > 0) var/image/reagentsImage = image(icon, src, "mopbucket_reagents0") reagentsImage.alpha = 150 - switch((reagents.total_volume/reagents.maximum_volume)*100) + switch((reagents.total_volume / reagents.maximum_volume) * 100) if(1 to 25) reagentsImage.icon_state = "mopbucket_reagents1" if(26 to 50) @@ -66,7 +69,8 @@ if(76 to 100) reagentsImage.icon_state = "mopbucket_reagents4" reagentsImage.icon += mix_color_from_reagents(reagents.reagent_list) - add_overlay(reagentsImage) + . += reagentsImage + /obj/structure/mopbucket/attack_hand(mob/living/user) . = ..() @@ -75,5 +79,5 @@ user.put_in_hands(mymop, ignore_anim = FALSE) to_chat(user, "You take [mymop] from [src].") mymop = null - update_icon() - return + update_icon(UPDATE_OVERLAYS) + diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 4d05534d468..6e4f862393c 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "nboard" density = 0 - anchored = 1 + anchored = TRUE max_integrity = 150 var/notices = 0 @@ -25,6 +25,7 @@ break . += image(src.icon, icon_state = "[src.icon_state][I]") + //attaching papers!! /obj/structure/noticeboard/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/paper)) diff --git a/code/game/objects/structures/pit.dm b/code/game/objects/structures/pit.dm index 99b778479b3..9b6ca752a84 100644 --- a/code/game/objects/structures/pit.dm +++ b/code/game/objects/structures/pit.dm @@ -45,9 +45,11 @@ return ..() -/obj/structure/pit/update_icon() + +/obj/structure/pit/update_icon_state() icon_state = "pit[open][icon_floor_type]" + /obj/structure/pit/Initialize(mapload) . = ..() if(mapload && !open) @@ -64,12 +66,13 @@ icon_floor_type = "sand" if(istype(loc, /turf/simulated/floor/grass)) icon_floor_type = "mud" - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/pit/proc/take_contents() var/itemcount = 0 for(var/atom/movable/A in loc) - if(A.density || A.anchored || A == src || open) continue + if(A.density || A.anchored || A == src || open) + continue A.forceMove(src) itemcount += 1 if(itemcount >= storage_capacity) @@ -87,7 +90,7 @@ if(istype(A, /obj/structure/closet)) for(var/mob/living/carbon/M in A.contents) M.update_tint() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/pit/proc/close(var/user) name = "mound" @@ -108,7 +111,7 @@ if(istype(A, /obj/structure/closet)) for(var/mob/living/carbon/M in A.contents) M.overlay_fullscreen("tint", /obj/screen/fullscreen/blind) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/pit/remove_air(amount) return 0 diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index a5bd33c304f..6b4ad0d2721 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "plasticflaps" density = 0 - anchored = 1 + anchored = TRUE layer = 4 armor = list(melee = 100, bullet = 80, laser = 80, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 50, acid = 50) var/state = PLASTIC_FLAPS_NORMAL diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index a93cb5e7cca..c39bf139cd5 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/stock_parts.dmi' icon_state = "box_0" desc = "A frame to create a reflector.\nUse 5 sheets of glass to create a 1 way reflector.\nUse 10 sheets of reinforced glass to create a 2 way reflector.\nUse 1 diamond to create a reflector cube." - anchored = 0 + anchored = FALSE density = 1 layer = 3 var/finished = 0 diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 06cd6627178..f2f64492a6e 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -112,7 +112,8 @@ GLOBAL_LIST_EMPTY(safes) /obj/structure/safe/examine_status(mob/user) return -/obj/structure/safe/update_icon() + +/obj/structure/safe/update_icon_state() if(open) if(broken) icon_state = "[initial(icon_state)]-open-broken" @@ -124,17 +125,15 @@ GLOBAL_LIST_EMPTY(safes) else icon_state = initial(icon_state) - var/list/overlays_to_cut = list(drill_overlay) - if(!drill_timer) - overlays_to_cut += progress_bar - - cut_overlay(overlays_to_cut) +/obj/structure/safe/update_overlays() + . = ..() if(istype(drill, /obj/item/thermal_drill)) var/drill_icon = istype(drill, /obj/item/thermal_drill/diamond_drill) ? "d" : "h" var/state = "[initial(icon_state)]_[drill_icon]-drill-[drill_timer ? "on" : "off"]" drill_overlay = image(icon = 'icons/effects/drill.dmi', icon_state = state, pixel_x = drill_x_offset, pixel_y = drill_y_offset) - add_overlay(drill_overlay) + . += drill_overlay + /obj/structure/safe/attack_ghost(mob/user) if(..() || drill) @@ -376,7 +375,7 @@ GLOBAL_LIST_EMPTY(safes) hide(T.intact) /obj/structure/safe/floor/hide(intact) - invisibility = intact ? INVISIBILITY_ABSTRACT : 0 + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 /** * # Safe Internals diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index c841de19414..40e72b92172 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -1,12 +1,32 @@ /obj/structure/sign icon = 'icons/obj/decals.dmi' - anchored = 1 + anchored = TRUE opacity = 0 density = 0 layer = 3.5 max_integrity = 100 + blocks_emissive = EMISSIVE_BLOCK_GENERIC + var/does_emissive = FALSE armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + +/obj/structure/sign/Initialize(mapload) + . = ..() + if(does_emissive) + update_icon(UPDATE_OVERLAYS) + set_light(1, LIGHTING_MINIMUM_POWER) + + +/obj/structure/sign/update_overlays() + . = ..() + + underlays.Cut() + if(!does_emissive) + return + + underlays += emissive_appearance(icon,"[icon_state]_lightmask") + + /obj/structure/sign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) @@ -17,6 +37,7 @@ if(BURN) playsound(loc, 'sound/items/welder.ogg', 80, TRUE) + /obj/structure/sign/screwdriver_act(mob/user, obj/item/I) if(istype(src, /obj/structure/sign/double)) return @@ -42,33 +63,36 @@ resistance_flags = FLAMMABLE var/sign_state = "" -/obj/item/sign/attackby(obj/item/tool as obj, mob/user as mob) //construction - if(istype(tool, /obj/item/screwdriver) && isturf(user.loc)) - var/direction = input("In which direction?", "Select direction.") in list("North", "East", "South", "West", "Cancel") - if(direction == "Cancel") - return - if(QDELETED(src)) - return - var/obj/structure/sign/S = new(user.loc) - switch(direction) - if("North") - S.pixel_y = 32 - if("East") - S.pixel_x = 32 - if("South") - S.pixel_y = -32 - if("West") - S.pixel_x = -32 - else - return - S.name = name - S.desc = desc - S.icon_state = sign_state - src.transfer_fingerprints_to(S) - to_chat(user, "You fasten \the [S] with your [tool].") - qdel(src) - else - return ..() + +/obj/item/sign/screwdriver_act(mob/living/user, obj/item/I) + if(!isturf(loc)) + return + + var/direction = input("In which direction?", "Select direction.") in list("North", "East", "South", "West", "Cancel") + if(direction == "Cancel") + return TRUE // These gotta be true or we stab the sign + if(QDELETED(src)) + return TRUE // Unsure about this, but stabbing something that doesnt exist seems like a bad idea + + var/obj/structure/sign/sign = new(loc) + switch(direction) + if("North") + sign.pixel_y = 32 + if("East") + sign.pixel_x = 32 + if("South") + sign.pixel_y = -32 + if("West") + sign.pixel_x = -32 + else + return TRUE // We dont want to stab it or place it, so we return + sign.name = name + sign.desc = desc + sign.icon_state = sign_state + to_chat(user, span_notice("You fasten [sign] with your [I].")) + qdel(src) + return TRUE + /obj/structure/sign/double/map name = "station map" @@ -212,11 +236,15 @@ name = "\improper barber shop sign" desc = "A spinning sign indicating a barbershop is near." icon_state = "barber" + does_emissive = TRUE + blocks_emissive = FALSE /obj/structure/sign/chinese name = "\improper chinese restaurant sign" desc = "A glowing dragon invites you in." icon_state = "chinese" + does_emissive = TRUE + blocks_emissive = FALSE /obj/structure/sign/science name = "\improper SCIENCE!" diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm index e72f4760089..cd241fec97b 100644 --- a/code/game/objects/structures/spirit_board.dm +++ b/code/game/objects/structures/spirit_board.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "spirit_board" density = 1 - anchored = 1 + anchored = TRUE var/used = FALSE var/cooldown = 0 var/planchette = "А" diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 8ad8842a508..ca64315fbcb 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/statue.dmi' icon_state = "" density = 1 - anchored = 0 + anchored = FALSE max_integrity = 100 var/oreAmount = 5 var/material_drop_type = /obj/item/stack/sheet/metal @@ -376,7 +376,7 @@ icon = 'icons/obj/statuelarge.dmi' icon_state = "frank" max_integrity = 2000 - anchored = 1 + anchored = TRUE layer = EDGED_TURF_LAYER /obj/structure/statue/dude @@ -385,7 +385,7 @@ icon = 'icons/obj/statuelarge.dmi' icon_state = "dude" max_integrity = 2000 - anchored = 1 + anchored = TRUE layer = EDGED_TURF_LAYER /obj/structure/statue/death @@ -394,7 +394,7 @@ icon = 'icons/obj/statuebig.dmi' icon_state = "death" max_integrity = 2000 - anchored = 1 + anchored = TRUE bound_width = 64 layer = EDGED_TURF_LAYER @@ -404,20 +404,16 @@ icon = 'icons/obj/statuebig.dmi' icon_state = "unknown" max_integrity = 2000 - anchored = 1 + anchored = TRUE bound_width = 64 var/lit = 0 layer = EDGED_TURF_LAYER -/obj/structure/statue/unknown/Destroy() - return ..() -/obj/structure/statue/unknown/update_icon() - if(lit) - lit = 1 - icon_state = "unknown_lit" - else - icon_state = "unknown" +/obj/structure/statue/unknown/update_icon_state() + icon_state = "unknown[lit ? "_lit" : ""]" + + /obj/structure/statue/unknown/attackby(obj/item/W, mob/user, params) if(is_hot(W)) @@ -425,29 +421,33 @@ return return ..() + /obj/structure/statue/unknown/welder_act(mob/user, obj/item/I) . = TRUE if(I.tool_use_check(user, 0)) light(span_notice("[user] casually lights the [name] with [I], what a badass.")) + /obj/structure/statue/unknown/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) if(!lit) light() return ..() + /obj/structure/statue/unknown/proc/light(show_message) if(!lit) - lit = 1 + lit = TRUE if(show_message) usr.visible_message(show_message) set_light(CANDLE_LUM) - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/structure/statue/unknown/attack_hand(mob/user) if(lit) user.visible_message(span_notice("[user] snuffs out [src].")) - lit = 0 - update_icon() + lit = FALSE + update_icon(UPDATE_ICON_STATE) set_light(0) //////////////////////////////// diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index eaeabd374a5..5f44986b557 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -149,16 +149,18 @@ forceMove(RH) RH.held = src -/obj/structure/bed/roller/MouseDrop(over_object, src_location, over_location) - ..() - if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src))) - if(!ishuman(usr) || usr.incapacitated()) - return - if(has_buckled_mobs()) - return 0 - usr.visible_message("[usr] collapses \the [name].", "You collapse \the [name].") + +/obj/structure/bed/roller/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(!has_buckled_mobs() && over_object == usr && ishuman(usr) && !usr.incapacitated() && usr.Adjacent(src)) + usr.visible_message( + span_notice("[usr] collapses [src]."), + span_notice("You collapse [src]."), + ) new folded(get_turf(src)) qdel(src) + return FALSE + return ..() + /obj/item/roller/holo name = "holo stretcher" diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index c7895e40f5c..2723eb5c760 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -73,11 +73,9 @@ new buildstacktype(loc, buildstackamount) ..() -/obj/structure/chair/MouseDrop(over_object, src_location, over_location) - . = ..() - if(over_object == usr && Adjacent(usr)) - if(!item_chair || has_buckled_mobs() || anchored) - return + +/obj/structure/chair/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(over_object == usr && ishuman(usr) && item_chair && !anchored && !has_buckled_mobs() && usr.Adjacent(src)) if(usr.incapacitated()) to_chat(usr, span_warning("You can't do that right now!")) return @@ -87,13 +85,18 @@ if(usr.get_active_hand() && usr.get_inactive_hand()) to_chat(usr, span_warning("You try to grab the chair, but your hands are already full!")) return - if(!ishuman(usr)) - return - usr.visible_message(span_notice("[usr] grabs \the [src]."), span_notice("You grab \the [src].")) - var/C = new item_chair(drop_location()) - usr.put_in_hands(C, ignore_anim = FALSE) - transfer_fingerprints_to(C) + usr.visible_message( + span_notice("[usr] grabs [src]."), + span_notice("You grab [src]."), + ) + var/new_chair = new item_chair(drop_location()) + transfer_fingerprints_to(new_chair) + usr.put_in_hands(new_chair, ignore_anim = FALSE) qdel(src) + return FALSE + + return ..() + /obj/structure/chair/attack_tk(mob/user) if(!anchored || has_buckled_mobs() || !isturf(user.loc)) @@ -101,53 +104,65 @@ else rotate() + /obj/structure/chair/proc/handle_rotation(direction) handle_layer() if(has_buckled_mobs()) - for(var/m in buckled_mobs) - var/mob/living/buckled_mob = m + for(var/mob/living/buckled_mob as anything in buckled_mobs) buckled_mob.setDir(direction) + /obj/structure/chair/proc/handle_layer() if(has_buckled_mobs() && dir == NORTH) layer = ABOVE_MOB_LAYER else layer = OBJ_LAYER + /obj/structure/chair/post_buckle_mob(mob/living/M) . = ..() handle_layer() + /obj/structure/chair/post_unbuckle_mob() . = ..() handle_layer() + /obj/structure/chair/setDir(newdir) ..() handle_rotation(newdir) -/obj/structure/chair/verb/rotate() - set name = "Rotate Chair" - set category = "Object" - set src in oview(1) - if(CONFIG_GET(flag/ghost_interaction)) - add_fingerprint(usr) - setDir(turn(dir, 90)) - handle_rotation() - return +/obj/structure/chair/examine(mob/user) + . = ..() + . += span_info("You can Alt-Click [src] to rotate it.") - if(usr.incapacitated()) - return - add_fingerprint(usr) +/obj/structure/chair/proc/rotate(mob/living/user) + if(user) + if(isobserver(user)) + if(!CONFIG_GET(flag/ghost_interaction)) + return FALSE + else if(!isliving(user) || user.incapacitated() || !Adjacent(user)) + return FALSE + setDir(turn(dir, 90)) handle_rotation() + return TRUE + + +/obj/structure/chair/AltClick(mob/living/user) + rotate(user) + + +/obj/structure/chair/verb/rotate_chair() + set name = "Rotate Chair" + set category = "Object" + set src in oview(1) + + rotate(usr) -/obj/structure/chair/AltClick(mob/user) - if(!Adjacent(user)) - return - rotate() // CHAIR TYPES @@ -288,7 +303,7 @@ anchored = TRUE item_chair = null comfort = 0.6 - var/image/armrest = null + var/mutable_appearance/armrest /obj/structure/chair/sofa/Initialize(mapload) armrest = GetArmrest() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 186ec4ea419..9364329513e 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -34,52 +34,72 @@ var/buildstackamount = 1 var/framestackamount = 2 var/deconstruction_ready = TRUE - var/flipped = 0 + var/flip_sound = 'sound/machines/wooden_closet_close.ogg' + var/flipped = FALSE + /// Can this table be flipped? + var/can_be_flipped = TRUE + /obj/structure/table/Initialize(mapload) . = ..() if(flipped) - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/structure/table/examine(mob/user) . = ..() . += deconstruction_hints(user) + if(can_be_flipped) + if(flipped) + . += span_info("Alt-Shift-Click to right the table again.") + else + . += span_info("Alt-Shift-Click to flip over the table.") + /obj/structure/table/proc/deconstruction_hints(mob/user) return "The top is screwed on, but the main bolts are also visible." -/obj/structure/table/update_icon() + +/obj/structure/table/update_icon(updates = ALL) + . = ..() + update_smoothing() + + +/obj/structure/table/update_icon_state() if(smooth && !flipped) icon_state = "" - queue_smooth(src) - queue_smooth_neighbors(src) if(flipped) - clear_smooth_overlays() - var/type = 0 var/subtype = null for(var/direction in list(turn(dir,90), turn(dir,-90)) ) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - if(T && T.flipped) + var/obj/structure/table/other_table = locate(/obj/structure/table,get_step(src,direction)) + if(other_table?.flipped) type++ if(type == 1) subtype = direction == turn(dir,90) ? "-" : "+" var/base = "table" if(istype(src, /obj/structure/table/wood)) base = "wood" - if(istype(src, /obj/structure/table/reinforced)) + else if(istype(src, /obj/structure/table/reinforced)) base = "rtable" - if(istype(src, /obj/structure/table/wood/poker)) + else if(istype(src, /obj/structure/table/wood/poker)) base = "poker" - if(istype(src, /obj/structure/table/wood/fancy)) + else if(istype(src, /obj/structure/table/wood/fancy)) base = "fancy" - if(istype(src, /obj/structure/table/wood/fancy/black)) + else if(istype(src, /obj/structure/table/wood/fancy/black)) base = "fancyblack" - icon_state = "[base]flip[type][type == 1 ? subtype : ""]" - return 1 + +/obj/structure/table/proc/update_smoothing() + if(smooth) + queue_smooth(src) + queue_smooth_neighbors(src) + + if(flipped) + clear_smooth_overlays() + /obj/structure/table/narsie_act() new /obj/structure/table/wood(loc) @@ -117,28 +137,29 @@ var/mob/living/user = AM clumse_stuff(user) + /obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0) if(height == 0) - return 1 + return TRUE if(istype(mover,/obj/item/projectile)) - return (check_cover(mover,target)) + return check_cover(mover,target) if(ismob(mover)) - var/mob/M = mover + var/mob/living/M = mover if(M.flying) - return 1 + return TRUE if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 + return TRUE if(mover.throwing) - return 1 + return TRUE + if(length(get_atoms_of_type(get_turf(mover), /obj/structure/table) - mover)) + var/obj/structure/table/other_table = locate(/obj/structure/table) in get_turf(mover) + if(!other_table.flipped) + return TRUE if(flipped) if(get_dir(loc, target) == dir) return !density - else - return 1 - var/obj/structure/table/S = locate(/obj/structure/table) in get_turf(mover) - if(S?.flipped == 0) - return 1 - return 0 + return TRUE + return FALSE /obj/structure/table/CanPathfindPass(obj/item/card/id/ID, dir, caller, no_id = FALSE) @@ -157,53 +178,48 @@ * * from - Where the projectile is located. */ /obj/structure/table/proc/check_cover(obj/item/projectile/P, turf/from) - var/turf/cover = flipped ? get_turf(src) : get_step(loc, get_dir(from, loc)) - if(get_dist(P.starting, loc) <= 1) //Tables won't help you if people are THIS close - return 1 - if(get_turf(P.original) == cover) - var/chance = 20 - if(ismob(P.original)) - var/mob/M = P.original - if(M.lying) - chance += 20 //Lying down lets you catch less bullets - if(flipped) - if(get_dir(loc, from) == dir) //Flipped tables catch mroe bullets - chance += 20 - else - return 1 //But only from one side - if(prob(chance)) - obj_integrity -= P.damage/2 - if(obj_integrity > 0) - visible_message("[P] hits \the [src]!") - return 0 - else - visible_message("[src] breaks down!") - deconstruct(FALSE) - return 1 - return 1 - -/obj/structure/table/CheckExit(atom/movable/O, turf/target) - if(istype(O) && O.checkpass(PASSTABLE)) - return 1 - if(flipped) - if(get_dir(loc, target) == dir) - return !density - else - return 1 - return 1 + . = TRUE -/obj/structure/table/MouseDrop_T(obj/O, mob/user) - ..() - if((!( istype(O, /obj/item) ) || user.get_active_hand() != O)) - return + if(!flipped) + return . + + if(in_range(P.starting, loc)) // Tables won't help you if people are THIS close + return . + + var/proj_dir = get_dir(from, loc) + var/block_dir = get_dir(get_step(loc, dir), loc) + var/full_protection = (proj_dir & block_dir) + var/half_protection = ((proj_dir == get_clockwise_dir(block_dir)) || (proj_dir == get_anticlockwise_dir(block_dir))) + + if(!full_protection && !half_protection) // Back/side shots may pass + return . + + if(prob(half_protection ? 40 : 60)) + return FALSE // Blocked + + +/obj/structure/table/CheckExit(atom/movable/mover, turf/target) + if(istype(mover) && mover.checkpass(PASSTABLE)) + return TRUE + if(flipped && get_dir(loc, target) == dir) + return !density + return TRUE + + +/obj/structure/table/MouseDrop_T(obj/dropping, mob/user, params) + if(..()) + return TRUE + if(!isitem(dropping) || user.get_active_hand() != dropping) + return FALSE if(isrobot(user)) - return - if(!user.drop_from_active_hand()) - return - if(O.loc != src.loc) + return FALSE + if(!user.drop_item_ground(dropping)) + return FALSE + if(dropping.loc != loc) add_fingerprint(user) - step(O, get_dir(O, src)) - return + step(dropping, get_dir(dropping, src)) + return TRUE + /obj/structure/table/proc/tablepush(obj/item/grab/G, mob/user) if(HAS_TRAIT(user, TRAIT_PACIFISM) || GLOB.pacifism_after_gt) @@ -232,6 +248,7 @@ return TRUE qdel(G) + /obj/structure/table/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/grab)) add_fingerprint(user) @@ -269,6 +286,7 @@ deconstruct(TRUE) TOOL_DISMANTLE_SUCCESS_MESSAGE + /obj/structure/table/wrench_act(mob/user, obj/item/I) if(flags & NODECONSTRUCT) return @@ -282,6 +300,7 @@ deconstruct(TRUE, 1) TOOL_DISMANTLE_SUCCESS_MESSAGE + /obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) if(!(flags & NODECONSTRUCT)) var/turf/T = get_turf(src) @@ -292,119 +311,113 @@ new framestack(T, framestackamount) qdel(src) + /obj/structure/table/proc/straight_table_check(direction) - var/obj/structure/table/T - for(var/angle in list(-90,90)) - T = locate() in get_step(loc,turn(direction,angle)) - if(T && !T.flipped) - return 0 - T = locate() in get_step(loc,direction) - if(!T || T.flipped) - return 1 - if(istype(T,/obj/structure/table/reinforced/)) - if(!T.deconstruction_ready) - return 0 - return T.straight_table_check(direction) + var/obj/structure/table/check_table + for(var/angle in list(-90, 90)) + check_table = locate() in get_step(loc, turn(direction, angle)) + if(check_table && !check_table.flipped) + return FALSE + check_table = locate() in get_step(loc, direction) + if(!check_table || check_table.flipped) + return TRUE + if(istype(check_table, /obj/structure/table/reinforced) && !check_table.deconstruction_ready) + return FALSE + return check_table.straight_table_check(direction) -/obj/structure/table/verb/do_flip() - set name = "Flip table" - set desc = "Flips a non-reinforced table" - set category = null - set src in oview(1) - if(!can_touch(usr) || ismouse(usr)) - return +/obj/structure/table/AltShiftClick(mob/user) + actual_flip(user) - if(!flip(get_cardinal_dir(usr,src))) - to_chat(usr, "It won't budge.") - return - add_fingerprint(usr) - usr.visible_message("[usr] flips \the [src]!") +/obj/structure/table/verb/do_flip() + set name = "Flip/Unflip table" + set desc = "Flips or unflips a table" + set category = null + set src in oview(1) + actual_flip(usr) - if(climbable) - structure_shaken() - return +/obj/structure/table/proc/actual_flip(mob/living/user) + if(!can_be_flipped || !can_touch(user)) + return FALSE -/obj/structure/table/proc/do_put() - set name = "Put table back" - set desc = "Puts flipped table back" - set category = "Object" - set src in oview(1) + if(!flipped) + if(!flip(get_cardinal_dir(user, src))) + to_chat(user, span_notice("It won't budge.")) + return - if(!can_touch(usr) || ismouse(usr)) - return + user.visible_message("[user] flips \the [src]!") - if(!unflip()) - to_chat(usr, "It won't budge.") - return + if(climbable) + structure_shaken() + else + if(!unflip()) + to_chat(user, span_notice("It won't budge.")) /obj/structure/table/proc/flip(direction) if(flipped) - return 0 + return FALSE - if( !straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90)) ) - return 0 - - verbs -=/obj/structure/table/verb/do_flip - verbs +=/obj/structure/table/proc/do_put + if(!straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90))) + return FALSE var/list/targets = list(get_step(src,dir),get_step(src,turn(dir, 45)),get_step(src,turn(dir, -45))) - for(var/atom/movable/A in get_turf(src)) - if(!A.anchored) - spawn(0) - A.throw_at(pick(targets),1,1) + for(var/atom/movable/thing in get_turf(src)) + if(!thing.anchored) + INVOKE_ASYNC(thing, TYPE_PROC_REF(/atom/movable, throw_at), pick(targets), 1, 1) dir = direction if(dir != NORTH) layer = 5 - flipped = 1 + flipped = TRUE smooth = SMOOTH_FALSE flags |= ON_BORDER - for(var/D in list(turn(direction, 90), turn(direction, -90))) - if(locate(/obj/structure/table,get_step(src,D))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D)) - T.flip(direction) - update_icon() + playsound(loc, flip_sound, 100, TRUE) + + for(var/check_dir in list(turn(direction, 90), turn(direction, -90))) + var/obj/structure/table/other_table = locate(/obj/structure/table, get_step(src, check_dir)) + if(other_table) + other_table.flip(direction) + update_icon(UPDATE_ICON_STATE) creates_cover = FALSE if(isturf(loc)) REMOVE_TRAIT(loc, TRAIT_TURF_COVERED, UNIQUE_TRAIT_SOURCE(src)) - return 1 + return TRUE + /obj/structure/table/proc/unflip() if(!flipped) - return 0 + return FALSE - var/can_flip = 1 - for(var/mob/A in oview(src,0))//loc) - if(istype(A)) - can_flip = 0 + var/can_flip = TRUE + for(var/mob/check in oview(src, 0)) + can_flip = FALSE + break if(!can_flip) - return 0 - - verbs -=/obj/structure/table/proc/do_put - verbs +=/obj/structure/table/verb/do_flip + return FALSE layer = initial(layer) - flipped = 0 + flipped = FALSE smooth = initial(smooth) flags &= ~ON_BORDER - for(var/D in list(turn(dir, 90), turn(dir, -90))) - if(locate(/obj/structure/table,get_step(src,D))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D)) - T.unflip() + playsound(loc, flip_sound, 100, TRUE) + + for(var/check_dir in list(turn(dir, 90), turn(dir, -90))) + var/obj/structure/table/other_table = locate(/obj/structure/table, get_step(src, check_dir)) + if(other_table) + other_table.unflip() dir = initial(dir) - update_icon() + update_icon(UPDATE_ICON_STATE) creates_cover = TRUE if(isturf(loc)) ADD_TRAIT(loc, TRAIT_TURF_COVERED, UNIQUE_TRAIT_SOURCE(src)) - return 1 + return TRUE /* @@ -433,25 +446,30 @@ qdel(i) . = ..() + /obj/structure/table/glass/Crossed(atom/movable/AM, oldloc) . = ..() if(flags & NODECONSTRUCT) return if(!isliving(AM)) return + + var/mob/living/check = AM + if(check.incorporeal_move || check.flying || check.floating) + return + // Don't break if they're just flying past if(AM.throwing) addtimer(CALLBACK(src, PROC_REF(throw_check), AM), 5) else check_break(AM) + /obj/structure/table/glass/proc/throw_check(mob/living/M) if(M.loc == get_turf(src)) check_break(M) /obj/structure/table/glass/proc/check_break(mob/living/M) - if(M.flying || M.incorporeal_move) - return if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL) table_shatter(M) @@ -628,9 +646,8 @@ /obj/structure/table/reinforced/flip(direction) if(!deconstruction_ready) - return 0 - else - return ..() + return FALSE + return ..() /obj/structure/table/reinforced/welder_act(mob/user, obj/item/I) . = TRUE @@ -683,15 +700,15 @@ icon_state = "tray" buildstack = /obj/item/stack/sheet/mineral/titanium buildstackamount = 2 + can_be_flipped = FALSE var/list/typecache_can_hold = list(/mob, /obj/item) var/list/held_items = list() /obj/structure/table/tray/Initialize() . = ..() - verbs -= /obj/structure/table/verb/do_flip typecache_can_hold = typecacheof(typecache_can_hold) for(var/atom/movable/held in get_turf(src)) - if(is_type_in_typecache(held, typecache_can_hold)) + if(!held.anchored && held.move_resist != INFINITY && is_type_in_typecache(held, typecache_can_hold)) held_items += held.UID() /obj/structure/table/tray/Move(NewLoc, direct) @@ -717,10 +734,26 @@ continue held.forceMove(NewLoc) + +/obj/structure/table/tray/can_be_pulled(user, force, show_message) + var/atom/movable/puller = user + if(loc != puller.loc) + held_items -= puller.UID() + if(isliving(user)) + var/mob/living/M = user + if(M.UID() in held_items) + return FALSE + return ..() + + /obj/structure/table/tray/item_placed(atom/movable/item) . = ..() if(is_type_in_typecache(item, typecache_can_hold)) held_items += item.UID() + if(isliving(item)) + var/mob/living/M = item + if(M.pulling == src) + M.stop_pulling() /obj/structure/table/tray/deconstruct(disassembled = TRUE, wrench_disassembly = 0) if(!(flags & NODECONSTRUCT)) @@ -758,17 +791,17 @@ . = ..() . += "It's held together by a couple of bolts." + /obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0) if(height==0) - return 1 - if(density == 0) //Because broken racks -Agouri |TODO: SPRITE!| - return 1 + return TRUE + if(!density) //Because broken racks -Agouri |TODO: SPRITE!| + return TRUE if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 + return TRUE if(mover.throwing) - return 1 - else - return 0 + return TRUE + return FALSE /obj/structure/rack/CanPathfindPass(obj/item/card/id/ID, dir, caller, no_id = FALSE) @@ -778,23 +811,25 @@ . = . || mover.checkpass(PASSTABLE) -/obj/structure/rack/MouseDrop_T(obj/item/O, mob/user) - if((!(istype(O)) || user.get_active_hand() != O)) - return +/obj/structure/rack/MouseDrop_T(obj/item/dropping, mob/user, params) + . = FALSE + if((!isitem(dropping)) || user.get_active_hand() != dropping) + return . if(isrobot(user)) - return - if(O.loc != src.loc) - if(user.transfer_item_to_loc(O, src.loc)) - add_fingerprint(user) + return . + if(dropping.loc != loc && user.transfer_item_to_loc(dropping, src.loc)) + add_fingerprint(user) + return TRUE + -/obj/structure/rack/attackby(obj/item/W, mob/user, params) +/obj/structure/rack/attackby(obj/item/I, mob/user, params) if(isrobot(user)) return if(user.a_intent == INTENT_HARM) return ..() - if(!(W.flags & ABSTRACT)) - if(user.transfer_item_to_loc(W, src.loc)) - add_fingerprint(user) + if(!(I.flags & ABSTRACT) && user.transfer_item_to_loc(I, loc)) + add_fingerprint(user) + /obj/structure/rack/wrench_act(mob/user, obj/item/I) . = TRUE @@ -842,46 +877,45 @@ desc = "A gun rack for storing guns." icon_state = "gunrack" -/obj/structure/rack/gunrack/MouseDrop_T(obj/O, mob/user) - if(isrobot(user)) - return - if(!user.drop_from_active_hand()) - return - if(!(istype(O, /obj/item/gun))) - to_chat(user, "This item doesn't fit!") - return - if(O.loc != src.loc) - add_fingerprint(user) - var/obj/item/gun/our_gun = O - our_gun.reset_direction() - our_gun.place_on_rack() - our_gun.do_drop_animation(src) - our_gun.Move(loc) -/obj/structure/rack/gunrack/attackby(obj/item/W, mob/user, params) +/obj/structure/rack/gunrack/proc/place_gun(obj/item/gun/our_gun, mob/user, params) + . = FALSE if(!ishuman(user)) - return - if(user.a_intent == INTENT_HARM) - return ..() - if(!(istype(W, /obj/item/gun))) - to_chat(user, "This item doesn't fit!") - return - if(!(W.flags & ABSTRACT) && user.drop_from_active_hand()) + return . + if(!(istype(our_gun))) + to_chat(user, span_warning("This item doesn't fit!")) + return . + if(our_gun.flags & ABSTRACT) + return . + if(!user.drop_item_ground(our_gun)) + return . + if(our_gun.loc != loc) add_fingerprint(user) - var/obj/item/gun/our_gun = W + our_gun.reset_direction() our_gun.place_on_rack() our_gun.do_drop_animation(src) our_gun.Move(loc) var/list/click_params = params2list(params) //Center the icon where the user clicked. if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) - return + return . //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - W.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - W.pixel_y = 0 - else + our_gun.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + our_gun.pixel_y = 0 + return TRUE + + +/obj/structure/rack/gunrack/MouseDrop_T(obj/item/gun/our_gun, mob/user, params) + return place_gun(our_gun, user, params) + + +/obj/structure/rack/gunrack/attackby(obj/item/I, mob/user, params) + if(!ishuman(user)) return - return + if(user.a_intent == INTENT_HARM) + return ..() + place_gun(I, user, params) + /obj/structure/rack/gunrack/wrench_act(mob/user, obj/item/I) . = TRUE @@ -889,13 +923,15 @@ return deconstruct(TRUE) + /obj/structure/rack/gunrack/Initialize(mapload) . = ..() - if(mapload) - for(var/obj/item/I in loc.contents) - if(istype(I, /obj/item/gun)) - var/obj/item/gun/to_place = I - to_place.place_on_rack() + if(!mapload) + return + + for(var/obj/item/gun/gun in loc) + gun.place_on_rack() + /obj/structure/rack/gunrack/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index e773b66baf2..8e33df0e985 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "dispenser" density = 1 - anchored = 1.0 + anchored = TRUE var/starting_oxygen_tanks = MAX_TANK_STORAGE // The starting amount of oxygen tanks the dispenser gets when it's spawned var/starting_plasma_tanks = MAX_TANK_STORAGE // Starting amount of plasma tanks var/list/stored_oxygen_tanks = list() // List of currently stored oxygen tanks @@ -21,7 +21,7 @@ /obj/structure/dispenser/Initialize(mapload) . = ..() initialize_tanks() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/dispenser/Destroy() QDEL_LIST(stored_plasma_tanks) @@ -37,21 +37,23 @@ var/obj/item/tank/internals/oxygen/O = new(src) stored_oxygen_tanks.Add(O) -/obj/structure/dispenser/update_icon() - cut_overlays() + +/obj/structure/dispenser/update_overlays() + . = ..() var/oxy_tank_amount = LAZYLEN(stored_oxygen_tanks) switch(oxy_tank_amount) if(1 to 3) - overlays += "oxygen-[oxy_tank_amount]" + . += "oxygen-[oxy_tank_amount]" if(4 to INFINITY) - overlays += "oxygen-4" + . += "oxygen-4" var/pla_tank_amount = LAZYLEN(stored_plasma_tanks) switch(pla_tank_amount) if(1 to 4) - overlays += "plasma-[pla_tank_amount]" + . += "plasma-[pla_tank_amount]" if(5 to INFINITY) - overlays += "plasma-5" + . += "plasma-5" + /obj/structure/dispenser/attack_hand(mob/user) if(..()) @@ -100,14 +102,14 @@ try_insert_tank(user, stored_plasma_tanks, I) return - if(istype(I, /obj/item/wrench)) + if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) if(anchored) to_chat(user, "You lean down and unwrench [src].") - anchored = 0 + anchored = FALSE else to_chat(user, "You wrench [src] into place.") - anchored = 1 + anchored = TRUE return return ..() @@ -116,14 +118,14 @@ if(!LAZYLEN(tank_list)) return // There are no tanks left to withdraw. - var/obj/item/tank/internals/T = tank_list[1] - tank_list.Remove(T) + var/obj/item/tank/internals/tank = tank_list[1] + tank_list.Remove(tank) - T.forceMove_turf() - user.put_in_hands(T) + tank.forceMove_turf() + user.put_in_hands(tank, ignore_anim = FALSE) - to_chat(user, "You take [T] out of [src].") - update_icon() + to_chat(user, "You take [tank] out of [src].") + update_icon(UPDATE_OVERLAYS) /// Called when the user clicks on the dispenser with a tank. Tries to insert the tank into the dispenser, and updates the UI if successful. /obj/structure/dispenser/proc/try_insert_tank(mob/living/user, list/tank_list, obj/item/tank/T) @@ -137,7 +139,7 @@ add_fingerprint(user) tank_list.Add(T) - update_icon() + update_icon(UPDATE_OVERLAYS) to_chat(user, "You put [T] in [src].") SStgui.update_uis(src) diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 12e14dcf80d..7ebd461fd7e 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -1,15 +1,14 @@ #define CLOSE_DURATION 6 #define OPEN_DURATION 6 -#define LAUNCH_COOLDOWN 50 - - +#define LAUNCH_COOLDOWN 30 // A place where tube pods stop, and people can get in or out. -// Mappers: use "Generate Instances from Directions" for this -// one. +// Mappers: use "Generate Instances from Directions" for this one. /obj/structure/transit_tube/station name = "station tube station" + desc = "The lynchpin of the transit system." icon = 'icons/obj/pipes_and_stuff/not_atmos/transit_tube_station.dmi' - icon_state = "closed" + icon_state = "closed_station0" + base_icon_state = "station0" exit_delay = 1 enter_delay = 2 var/pod_moving = FALSE @@ -18,6 +17,8 @@ var/hatch_state = TRANSIT_TUBE_CLOSED var/list/disallowed_mobs = list(/mob/living/silicon/ai) + /// Direction by which you can board the tube + var/boarding_dir /obj/structure/transit_tube/station/Initialize(mapload) . = ..() @@ -27,26 +28,32 @@ STOP_PROCESSING(SSobj, src) return ..() -// Stations which will send the tube in the opposite direction after their stop. -/obj/structure/transit_tube/station/reverse - reverse_launch = TRUE +/obj/structure/transit_tube/station/init_tube_dirs() + // Tube station directions are simply 90 to either side of + // the exit. + switch(dir) + if(NORTH) + tube_dirs = list(EAST, WEST) + if(SOUTH) + tube_dirs = list(EAST, WEST) + if(EAST) + tube_dirs = list(NORTH, SOUTH) + if(WEST) + tube_dirs = list(NORTH, SOUTH) + boarding_dir = reverse_direction(dir) /obj/structure/transit_tube/station/should_stop_pod(pod, from_dir) return TRUE -/obj/structure/transit_tube/station/Bumped(atom/movable/moving_atom) - if(!pod_moving && hatch_state == TRANSIT_TUBE_OPEN && isliving(moving_atom) && !is_type_in_list(moving_atom, disallowed_mobs)) - var/failed = FALSE +/obj/structure/transit_tube/station/Bumped(mob/living/L) + if(!pod_moving && L.dir == boarding_dir && hatch_state == TRANSIT_TUBE_OPEN && isliving(L) && !is_type_in_list(L, disallowed_mobs)) for(var/obj/structure/transit_tube_pod/pod in loc) - if(pod.contents.len) - failed = TRUE - else if(!pod.moving && (pod.dir in directions())) - pod.move_into(moving_atom) + if(length(pod.contents)) + to_chat(L, "The pod is already occupied.") + return + if(!pod.moving && ((pod.dir in directions()) || (reverse_launch && (turn(pod.dir, 180) in directions())))) + pod.move_into(L) return - if(failed) - to_chat(moving_atom, "The pod is already occupied.") - - /obj/structure/transit_tube/station/attack_hand(mob/user) if(pod_moving) @@ -66,9 +73,7 @@ "You start emptying [pod]'s contents onto the floor.", "You hear a loud noise! As if somebody is throwing stuff on the floor!") if(!do_after(user, 20, target = pod)) return - add_fingerprint(user) for(var/atom/movable/AM in pod) - AM.add_fingerprint(user) pod.eject(AM) if(isliving(AM)) var/mob/living/L = AM @@ -82,7 +87,7 @@ if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE) var/mob/living/GM = G.affecting for(var/obj/structure/transit_tube_pod/pod in loc) - pod.visible_message("[user] starts putting [GM] into the [pod]!") + pod.visible_message("[user] starts putting [GM] into [pod]!") if(do_after(user, 30, target = GM) && GM && G && G.affecting == GM) GM.add_fingerprint(user) GM.Weaken(10 SECONDS) @@ -92,31 +97,36 @@ /obj/structure/transit_tube/station/proc/open_hatch() if(hatch_state == TRANSIT_TUBE_CLOSED) - icon_state = "opening" + icon_state = "opening_[base_icon_state]" hatch_state = TRANSIT_TUBE_OPENING - addtimer(CALLBACK(src, PROC_REF(open_hatch_callback)), OPEN_DURATION) - -/obj/structure/transit_tube/station/proc/open_hatch_callback() - if(hatch_state == TRANSIT_TUBE_OPENING) - icon_state = "open" - hatch_state = TRANSIT_TUBE_OPEN - - + addtimer(CALLBACK(src, PROC_REF(finish_animation)), OPEN_DURATION) /obj/structure/transit_tube/station/proc/close_hatch() if(hatch_state == TRANSIT_TUBE_OPEN) - icon_state = "closing" + icon_state = "closing_[base_icon_state]" hatch_state = TRANSIT_TUBE_CLOSING - addtimer(CALLBACK(src, PROC_REF(close_hatch_calllback)), CLOSE_DURATION) + addtimer(CALLBACK(src, PROC_REF(finish_animation)), CLOSE_DURATION) -/obj/structure/transit_tube/station/proc/close_hatch_calllback() - if(hatch_state == TRANSIT_TUBE_CLOSING) - icon_state = "closed" - hatch_state = TRANSIT_TUBE_CLOSED +/obj/structure/transit_tube/station/proc/finish_animation() + switch(hatch_state) + if(TRANSIT_TUBE_OPENING) + icon_state = "open_[base_icon_state]" + hatch_state = TRANSIT_TUBE_OPEN + for(var/obj/structure/transit_tube_pod/pod in loc) + for(var/thing in pod) + if(ismob(thing)) + var/mob/mob_content = thing + if(mob_content.client && mob_content.stat < UNCONSCIOUS) + continue // Let the mobs with clients decide what they want to do themselves. + var/atom/movable/movable_content = thing + movable_content.forceMove(loc) //Everything else is moved out of. + if(TRANSIT_TUBE_CLOSING) + icon_state = "closed_[base_icon_state]" + hatch_state = TRANSIT_TUBE_CLOSED /obj/structure/transit_tube/station/proc/launch_pod() for(var/obj/structure/transit_tube_pod/pod in loc) - if(!pod.moving && (pod.dir in directions())) + if(!pod.moving && ((pod.dir in directions()) || (reverse_launch && (turn(pod.dir, 180) in directions())))) addtimer(CALLBACK(src, PROC_REF(launch_pod_callback), pod), 5) return @@ -135,7 +145,7 @@ if(!nexttube) pod.dir = turn(pod.dir, 180) - if(hatch_state == TRANSIT_TUBE_CLOSED && pod) + if(hatch_state == TRANSIT_TUBE_CLOSED && pod && pod.loc == loc) pod.follow_tube() pod_moving = FALSE @@ -146,6 +156,7 @@ /obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir) pod_moving = TRUE + pod.stop_following() addtimer(CALLBACK(src, PROC_REF(pod_stopped_callback), pod), 5) /obj/structure/transit_tube/station/proc/pod_stopped_callback(obj/structure/transit_tube_pod/pod) @@ -156,10 +167,99 @@ pod_moving = FALSE pod.mix_air() -// Tube station directions are simply 90 to either side of -// the exit. -/obj/structure/transit_tube/station/init_dirs() - tube_dirs = list(turn(dir, 90), turn(dir, -90)) +/obj/structure/transit_tube/station/flipped + icon_state = "closed_station1" + base_icon_state = "station1" + +/obj/structure/transit_tube/station/flipped/init_tube_dirs() + ..() + boarding_dir = dir + +// Stations which will send the tube in the opposite direction after their stop. +/obj/structure/transit_tube/station/reverse + icon_state = "closed_terminus0" + base_icon_state = "terminus0" + reverse_launch = TRUE + +/obj/structure/transit_tube/station/reverse/init_tube_dirs() + tube_dirs = list(turn(dir, -90)) + boarding_dir = reverse_direction(dir) + +/obj/structure/transit_tube/station/reverse/flipped + icon_state = "closed_terminus1" + base_icon_state = "terminus1" + +/obj/structure/transit_tube/station/reverse/flipped/init_tube_dirs() + ..() + boarding_dir = dir + +//special dispenser station, it creates a pod for you to enter when you bump into it. + +/obj/structure/transit_tube/station/dispenser + name = "station tube pod dispenser" + icon_state = "open_dispenser0" + desc = "The lynchpin of a GOOD transit system." + enter_delay = 1 + base_icon_state = "dispenser0" + hatch_state = TRANSIT_TUBE_OPEN + +/obj/structure/transit_tube/station/dispenser/examine(mob/user) + . = ..() + . += "This station will create a pod for you to ride, no need to wait for one." + . += "Any pods arriving at this station will be reclaimed." + +/obj/structure/transit_tube/station/dispenser/close_hatch() + . = ..() + return + +/obj/structure/transit_tube/station/dispenser/launch_pod() + for(var/obj/structure/transit_tube_pod/pod in loc) + if(!pod.moving) + pod_moving = TRUE + pod.follow_tube() + pod_moving = FALSE + return TRUE + return FALSE + +/obj/structure/transit_tube/station/dispenser/Bumped(mob/living/L) + if(!(istype(L) && L.dir == boarding_dir) || L.anchored) + return + if(isliving(L) && !is_type_in_list(L, disallowed_mobs)) + var/obj/structure/transit_tube_pod/dispensed/pod = new(loc) + L.visible_message("[pod] forms around [L].", "[pod] materializes around you.") + playsound(src, 'sound/weapons/emitter2.ogg', 50, TRUE) + pod.dir = turn(dir, -90) + pod.move_into(L) + launch_pod() + +/obj/structure/transit_tube/station/dispenser/pod_stopped(obj/structure/transit_tube_pod/pod) + playsound(src, 'sound/machines/ding.ogg', 50, TRUE) + qdel(pod) + +/obj/structure/transit_tube/station/dispenser/flipped + icon_state = "open_dispenser1" + base_icon_state = "dispenser1" + +/obj/structure/transit_tube/station/dispenser/flipped/init_tube_dirs() + ..() + boarding_dir = dir +/obj/structure/transit_tube/station/dispenser/reverse + reverse_launch = TRUE + icon_state = "open_terminusdispenser0" + base_icon_state = "terminusdispenser0" + +/obj/structure/transit_tube/station/dispenser/reverse/init_tube_dirs() + tube_dirs = list(turn(dir, 90)) + boarding_dir = reverse_direction(dir) + +/obj/structure/transit_tube/station/dispenser/reverse/flipped + icon_state = "open_terminusdispenser1" + base_icon_state = "terminusdispenser1" + +/obj/structure/transit_tube/station/dispenser/reverse/flipped/init_tube_dirs() + ..() + boarding_dir = dir + #undef CLOSE_DURATION #undef OPEN_DURATION diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index 476ce469492..584c8136eeb 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -4,38 +4,50 @@ // Mappers: you can use "Generate Instances from Icon-states" // to get the different pieces. /obj/structure/transit_tube + name = "transit tube" + desc = "A pneumatic tube that brings you from here to there." icon = 'icons/obj/pipes_and_stuff/not_atmos/transit_tube.dmi' - icon_state = "E-W" - density = 1 + icon_state = "straight" + density = TRUE layer = 3.1 - anchored = 1.0 + anchored = TRUE var/list/tube_dirs = null var/exit_delay = 1 var/enter_delay = 0 - // alldirs in global.dm is the same list of directions, but since - // the specific order matters to get a usable icon_state, it is - // copied here so that, in the unlikely case that alldirs is changed, - // this continues to work. - var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) +/obj/structure/transit_tube/Initialize(mapload, new_direction) + . = ..() + if(new_direction) + setDir(new_direction) + // set up our appearance after the initialize in case someone's setting our direction afterwards + // (especially for things like admin spawning) + addtimer(CALLBACK(src, PROC_REF(setup_appearance)), 1) +/obj/structure/transit_tube/proc/setup_appearance() + init_tube_dirs() + update_appearance() + +/obj/structure/transit_tube/Destroy() + for(var/obj/structure/transit_tube_pod/P in loc) + P.empty_pod() + return ..() /obj/structure/transit_tube/CanPass(atom/movable/mover, turf/target) if(istype(mover) && mover.checkpass(PASSGLASS)) - return 1 + return TRUE return !density // When destroyed by explosions, properly handle contents. /obj/structure/transit_tube/ex_act(severity) switch(severity) - if(1.0) + if(EXPLODE_DEVASTATE) for(var/atom/movable/AM in contents) AM.loc = loc AM.ex_act(severity++) qdel(src) return - if(2.0) + if(EXPLODE_HEAVY) if(prob(50)) for(var/atom/movable/AM in contents) AM.loc = loc @@ -43,20 +55,12 @@ qdel(src) return - if(3.0) + if(EXPLODE_LIGHT) return - -/obj/structure/transit_tube/New(loc) - ..(loc) - - if(tube_dirs == null) - init_dirs() - - // Called to check if a pod should stop upon entering this tube. /obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir) - return 0 + return FALSE // Called when a pod stops in this tube section. /obj/structure/transit_tube/proc/pod_stopped(pod, from_dir) @@ -69,27 +73,21 @@ /obj/structure/transit_tube/proc/directions() return tube_dirs - - /obj/structure/transit_tube/proc/has_entrance(from_dir) from_dir = turn(from_dir, 180) for(var/direction in directions()) if(direction == from_dir) - return 1 - - return 0 - + return TRUE + return FALSE /obj/structure/transit_tube/proc/has_exit(in_dir) for(var/direction in directions()) if(direction == in_dir) - return 1 - - return 0 - + return TRUE + return FALSE // Searches for an exit direction within 45 degrees of the // specified dir. Returns that direction, or 0 if none match. @@ -110,7 +108,6 @@ return near_dir - // Return how many BYOND ticks to wait before entering/exiting // the tube section. Default action is to return the value of // a var, which wouldn't need a proc, but it makes it possible @@ -122,194 +119,157 @@ /obj/structure/transit_tube/proc/enter_delay(pod, to_dir) return enter_delay +/obj/structure/transit_tube/proc/init_tube_dirs() + switch(dir) + if(NORTH, SOUTH) + tube_dirs = list(NORTH, SOUTH) + if(EAST, WEST) + tube_dirs = list(EAST, WEST) -// Parse the icon_state into a list of directions. -// This means that mappers can use Dream Maker's built in -// "Generate Instances from Icon-states" option to get all -// variations. Additionally, as a separate proc, sub-types -// can handle it more intelligently. -/obj/structure/transit_tube/proc/init_dirs() - if(icon_state == "auto") - // Additional delay, for map loading. - spawn(1) - init_dirs_automatic() - - else - tube_dirs = parse_dirs(icon_state) - - if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass")) - density = 0 - - - - -// Initialize dirs by searching for tubes that do/might connect -// on nearby turfs. Create corner pieces if nessecary. -// Pick two directions, preferring tubes that already connect -// to loc, or other auto tubes if there aren't enough connections. -/obj/structure/transit_tube/proc/init_dirs_automatic() - var/list/connected = list() - var/list/connected_auto = list() - - for(var/direction in tube_dir_list) - var/location = get_step(loc, direction) - for(var/obj/structure/transit_tube/tube in location) - if(tube.directions() == null && tube.icon_state == "auto") - connected_auto += direction - break - - else if(turn(direction, 180) in tube.directions()) - connected += direction - break - - connected += connected_auto - - tube_dirs = select_automatic_dirs(connected) - - if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2])) - tube_dirs.Swap(1, 2) - - generate_automatic_corners(tube_dirs) - select_automatic_icon_state(tube_dirs) - - - -// Given a list of directions, look a pair that forms a 180 or -// 135 degree angle, and return a list containing the pair. -// If none exist, return list(connected[1], turn(connected[1], 180) -/obj/structure/transit_tube/proc/select_automatic_dirs(connected) - if(length(connected) < 1) - return list() - - for(var/i = 1, i <= length(connected), i++) - for(var/j = i + 1, j <= length(connected), j++) - var/d1 = connected[i] - var/d2 = connected[j] - - if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225)) - return list(d1, d2) - - return list(connected[1], turn(connected[1], 180)) - - - -/obj/structure/transit_tube/proc/select_automatic_icon_state(directions) - if(length(directions) == 2) - icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]" - - - -// Look for diagonal directions, generate the decorative corners in each. -/obj/structure/transit_tube/proc/generate_automatic_corners(directions) - for(var/direction in directions) - if(direction == 5 || direction == 6 || direction == 9 || direction == 10) - if(direction & NORTH) - create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3) - - else - create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3) - - if(direction & EAST) - create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12) - - else - create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12) - - - -// Generate a corner, if one doesn't exist for the direction on the turf. -/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction) - var/state = "D-[dir2text_short(direction)]" - - for(var/obj/structure/transit_tube/tube in location) - if(tube.icon_state == state) - return - - var/obj/structure/transit_tube/tube = new(location) - tube.icon_state = state - tube.init_dirs() - - - -// Uses a list() to cache return values. Since they should -// never be edited directly, all tubes with a certain -// icon_state can just reference the same list. In theory, -// reduces memory usage, and improves CPU cache usage. -// In reality, I don't know if that is quite how BYOND works, -// but it is probably safer to assume the existence of, and -// rely on, a sufficiently smart compiler/optimizer. -/obj/structure/transit_tube/proc/parse_dirs(text) - var/global/list/direction_table = list() - - if(text in direction_table) - return direction_table[text] - - var/list/split_text = splittext(text, "-") - - // If the first token is D, the icon_state represents - // a purely decorative tube, and doesn't actually - // connect to anything. - if(split_text[1] == "D") - direction_table[text] = list() - return null - - var/list/directions = list() - - for(var/text_part in split_text) - var/direction = text2dir_extended(text_part) - - if(direction > 0) - directions += direction - - direction_table[text] = directions - return directions - - - -// A copy of text2dir, extended to accept one and two letter -// directions, and to clearly return 0 otherwise. -/obj/structure/transit_tube/proc/text2dir_extended(direction) - switch(uppertext(direction)) - if("NORTH", "N") - return 1 - if("SOUTH", "S") - return 2 - if("EAST", "E") - return 4 - if("WEST", "W") - return 8 - if("NORTHEAST", "NE") - return 5 - if("NORTHWEST", "NW") - return 9 - if("SOUTHEAST", "SE") - return 6 - if("SOUTHWEST", "SW") - return 10 - else - return 0 - - - -// A copy of dir2text, which returns the short one or two letter -// directions used in tube icon states. -/obj/structure/transit_tube/proc/dir2text_short(direction) - switch(direction) - if(1) - return "N" - if(2) - return "S" - if(4) - return "E" - if(8) - return "W" - if(5) - return "NE" - if(6) - return "SE" - if(9) - return "NW" - if(10) - return "SW" +/obj/structure/transit_tube/update_overlays() + . = ..() + for(var/direction in directions()) + if(!IS_DIR_DIAGONAL(direction)) + . += create_tube_overlay(direction) + continue + if(!(direction & NORTH)) + continue + + . += create_tube_overlay(direction ^ (NORTH|SOUTH), NORTH) + if(direction & EAST) + . += create_tube_overlay(direction ^ (EAST|WEST), EAST) else + . += create_tube_overlay(direction ^ (EAST|WEST), WEST) + + +/obj/structure/transit_tube/proc/create_tube_overlay(direction, shift_dir) + // We use image() because a mutable appearance will have its dir mirror the parent which sort of fucks up what we're doing here + var/image/tube_overlay = image(icon, dir = direction) + if(shift_dir) + tube_overlay.icon_state = "decorative_diag" + switch(shift_dir) + if(NORTH) + tube_overlay.pixel_y = 32 + if(SOUTH) + tube_overlay.pixel_y = -32 + if(EAST) + tube_overlay.pixel_x = 32 + if(WEST) + tube_overlay.pixel_x = -32 + else + tube_overlay.icon_state = "decorative" + + tube_overlay.overlays += emissive_blocker(icon, tube_overlay.icon_state, src) + return tube_overlay + +//Some of these are mostly for mapping use +/obj/structure/transit_tube/horizontal + dir = WEST + +/obj/structure/transit_tube/diagonal + icon_state = "diagonal" + +/obj/structure/transit_tube/diagonal/init_tube_dirs() + switch(dir) + if(NORTH) + tube_dirs = list(NORTHEAST, SOUTHWEST) + if(SOUTH) + tube_dirs = list(NORTHEAST, SOUTHWEST) + if(EAST) + tube_dirs = list(NORTHWEST, SOUTHEAST) + if(WEST) + tube_dirs = list(NORTHWEST, SOUTHEAST) + +//mostly for mapping use +/obj/structure/transit_tube/diagonal/topleft + dir = WEST + +/obj/structure/transit_tube/diagonal/crossing + density = FALSE + icon_state = "diagonal_crossing" + +//mostly for mapping use +/obj/structure/transit_tube/diagonal/crossing/topleft + dir = WEST + + +/obj/structure/transit_tube/curved + icon_state = "curved0" + +/obj/structure/transit_tube/curved/init_tube_dirs() + switch(dir) + if(NORTH) + tube_dirs = list(NORTH, SOUTHWEST) + if(SOUTH) + tube_dirs = list(SOUTH, NORTHEAST) + if(EAST) + tube_dirs = list(EAST, NORTHWEST) + if(WEST) + tube_dirs = list(SOUTHEAST, WEST) + +/obj/structure/transit_tube/curved/flipped + icon_state = "curved1" + +/obj/structure/transit_tube/curved/flipped/init_tube_dirs() + switch(dir) + if(NORTH) + tube_dirs = list(NORTH, SOUTHEAST) + if(SOUTH) + tube_dirs = list(SOUTH, NORTHWEST) + if(EAST) + tube_dirs = list(EAST, SOUTHWEST) + if(WEST) + tube_dirs = list(NORTHEAST, WEST) + + +/obj/structure/transit_tube/junction + icon_state = "junction0" + +/obj/structure/transit_tube/junction/init_tube_dirs() + switch(dir) + if(NORTH) + tube_dirs = list(NORTH, SOUTHEAST, SOUTHWEST)//ending with the prefered direction + if(SOUTH) + tube_dirs = list(SOUTH, NORTHWEST, NORTHEAST) + if(EAST) + tube_dirs = list(EAST, SOUTHWEST, NORTHWEST) + if(WEST) + tube_dirs = list(WEST, NORTHEAST, SOUTHEAST) + +/obj/structure/transit_tube/junction/flipped + icon_state = "junction1" + +/obj/structure/transit_tube/junction/flipped/init_tube_dirs() + switch(dir) + if(NORTH) + tube_dirs = list(NORTH, SOUTHWEST, SOUTHEAST)//ending with the prefered direction + if(SOUTH) + tube_dirs = list(SOUTH, NORTHEAST, NORTHWEST) + if(EAST) + tube_dirs = list(EAST, NORTHWEST, SOUTHWEST) + if(WEST) + tube_dirs = list(WEST, SOUTHEAST, NORTHEAST) + + +/obj/structure/transit_tube/crossing + icon_state = "crossing" + density = FALSE + +//mostly for mapping use +/obj/structure/transit_tube/crossing/horizontal + dir = WEST + +// cosmetic "cap" for tubes. Note that tubes can't enter this. +/obj/structure/transit_tube/cap + icon_state = "cap" + +/obj/structure/transit_tube/cap/init_tube_dirs() + tube_dirs = list(turn(dir, 180)) // back the way we came + +/obj/structure/transit_tube/cap/has_entrance(from_dir) + return FALSE + +/obj/structure/transit_tube/cap/create_tube_overlay() + // cap sprites already have overlays return + 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 9ab4942cefd..bd368eb24f9 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -1,3 +1,6 @@ +#define MOVE_ANIMATION_STAGE_ONE 1 +#define MOVE_ANIMATION_STAGE_TWO 2 + /obj/structure/transit_tube_pod icon = 'icons/obj/pipes_and_stuff/not_atmos/transit_tube_pod.dmi' icon_state = "pod" @@ -6,21 +9,47 @@ density = TRUE var/moving = FALSE var/datum/gas_mixture/air_contents = new() - -/obj/structure/transit_tube_pod/New(loc) - ..(loc) + /// The tube we're currently traveling through + var/obj/structure/transit_tube/current_tube = null + /// The direction of our next transit from pipe to pipe. Stored between process calls here. + var/next_dir + /// The location of our next target tube. Stored same as above + var/next_loc + /// How long to wait when entering a new tube + var/enter_delay = 0 + /// How long to wait when exiting a new tube + var/exit_delay + /// The next time we'll be moving + COOLDOWN_DECLARE(move_cooldown) + /// The move animation mode for the next processing tick + var/current_move_anim_mode = MOVE_ANIMATION_STAGE_ONE + /// Icon state in use while we're occupied + var/occupied_icon_state = "pod_occupied" + +/obj/structure/transit_tube_pod/Initialize(mapload) + . = ..() + // Give auto tubes time to align before trying to start moving + spawn(5) air_contents.oxygen = MOLES_O2STANDARD * 2 air_contents.nitrogen = MOLES_N2STANDARD air_contents.temperature = T20C - // Give auto tubes time to align before trying to start moving - spawn(5) - follow_tube() + for(var/obj/structure/transit_tube/tube in loc) + setDir(pick(tube.directions())) + break + follow_tube() + +/obj/structure/transit_tube_pod/update_icon_state() + . = ..() + icon_state = length(contents) ? occupied_icon_state : initial(icon_state) + +/obj/structure/transit_tube_pod/proc/stop_following() + STOP_PROCESSING(SStransit_tube, src) /obj/structure/transit_tube_pod/Destroy() - for(var/atom/movable/AM in contents) - AM.forceMove(get_turf(src)) + empty_pod() + stop_following() return ..() /obj/structure/transit_tube_pod/Process_Spacemove() @@ -28,69 +57,115 @@ return TRUE else return ..() -/obj/structure/transit_tube_pod/proc/follow_tube(var/reverse_launch) +/obj/structure/transit_tube_pod/proc/empty_pod(atom/location) + if(!location) + location = get_turf(src) + for(var/atom/movable/M in contents) + M.forceMove(location) + update_appearance() + +/obj/structure/transit_tube_pod/crowbar_act(mob/living/user, obj/item/I) + . = ..() if(moving) return - moving = TRUE + if(length(contents)) + I.play_tool_sound(src) + user.visible_message("[user] pries [src] open.") + empty_pod() + +/obj/structure/transit_tube_pod/process() + ..() + + if(!COOLDOWN_FINISHED(src, move_cooldown)) + return + + var/move_result = move_animation(current_move_anim_mode) + if(isnull(move_result)) + if(isnull(current_tube) || (!(dir in current_tube.directions()) && !(reverse_direction(dir) in current_tube.directions()))) + outside_tube() + return PROCESS_KILL - spawn() - var/obj/structure/transit_tube/current_tube = null - var/next_dir - var/next_loc - var/last_delay = 0 - var/exit_delay + current_move_anim_mode = move_result - if(reverse_launch) - dir = turn(dir, 180) // Back it up +/obj/structure/transit_tube_pod/proc/outside_tube() + var/list/savedcontents = contents.Copy() + var/saveddir = dir + var/turf/destination = get_edge_target_turf(src, saveddir) + visible_message("[src] ejects its insides out!") + for(var/i in savedcontents) + var/atom/movable/AM = i + AM.throw_at(destination, rand(1, 3), 5) - for(var/obj/structure/transit_tube/tube in loc) - if(tube.has_exit(dir)) + +/obj/structure/transit_tube_pod/proc/move_animation(stage = MOVE_ANIMATION_STAGE_ONE) + if(stage == MOVE_ANIMATION_STAGE_ONE) + next_dir = current_tube.get_exit(dir) + + if(!next_dir) + moving = FALSE + density = TRUE + return + exit_delay = current_tube.exit_delay + next_loc = get_step(src, next_dir) + current_tube = null + for(var/obj/structure/transit_tube/tube in next_loc) + if(tube.has_entrance(next_dir)) current_tube = tube break - while(current_tube) - next_dir = current_tube.get_exit(dir) + if(isnull(current_tube)) + setDir(next_dir) + Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes. + moving = FALSE + density = TRUE + return - if(!next_dir) - break + enter_delay = current_tube.enter_delay(src, next_dir) + if(enter_delay > 0) + COOLDOWN_START(src, move_cooldown, enter_delay) + return MOVE_ANIMATION_STAGE_TWO - exit_delay = current_tube.exit_delay(src, dir) - last_delay += exit_delay + stage = MOVE_ANIMATION_STAGE_TWO - sleep(exit_delay) + if(stage == MOVE_ANIMATION_STAGE_TWO) + setDir(next_dir) + forceMove(next_loc) // When moving from one tube to another, skip collision and such. + density = current_tube.density - next_loc = get_step(loc, next_dir) + if(current_tube?.should_stop_pod(src, next_dir)) + current_tube.pod_stopped(src, dir) + else + COOLDOWN_START(src, move_cooldown, exit_delay) + return MOVE_ANIMATION_STAGE_ONE - current_tube = null - for(var/obj/structure/transit_tube/tube in next_loc) - if(tube.has_entrance(next_dir)) - current_tube = tube - break + density = TRUE + moving = FALSE - if(current_tube == null) - setDir(next_dir) - Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes. - break + return MOVE_ANIMATION_STAGE_ONE - last_delay = current_tube.enter_delay(src, next_dir) - sleep(last_delay) - setDir(next_dir) - forceMove(next_loc) // When moving from one tube to another, skip collision and such. - density = current_tube.density - if(current_tube && current_tube.should_stop_pod(src, next_dir)) - current_tube.pod_stopped(src, dir) - break +/obj/structure/transit_tube_pod/proc/follow_tube(reverse_launch) + if(moving) + return - density = TRUE + moving = TRUE - moving = FALSE + for(var/obj/structure/transit_tube/tube in loc) + if(tube.has_exit(dir)) + current_tube = tube + break + if(current_tube) + START_PROCESSING(SStransit_tube, src) + // move_animation(MOVE_ANIMATION_STAGE_ONE) + else + moving = FALSE // Should I return a copy here? If the caller edits or qdel()s the returned // datum, there might be problems if I don't... /obj/structure/transit_tube_pod/return_air() + RETURN_TYPE(/datum/gas_mixture) var/datum/gas_mixture/GM = new() GM.copy_from(air_contents) return GM @@ -152,9 +227,9 @@ if(!moving) for(var/obj/structure/transit_tube/station/station in loc) - if(dir in station.directions()) + if((dir in station.directions()) || (turn(dir, 180) in station.directions())) if(!station.pod_moving) - if(direction == station.dir) + if(direction == turn(station.boarding_dir, 180)) if(station.hatch_state == TRANSIT_TUBE_OPEN) eject(mob, direction) @@ -173,8 +248,8 @@ return /obj/structure/transit_tube_pod/proc/move_into(atom/movable/A) - icon_state = "pod_occupied" A.forceMove(src) + update_appearance() /obj/structure/transit_tube_pod/proc/eject_mindless(direction) for(var/atom/movable/A in contents) @@ -187,9 +262,24 @@ /obj/structure/transit_tube_pod/proc/eject(atom/movable/A, direction) - icon_state = "pod" A.forceMove(loc) + update_appearance() A.Move(get_step(loc, direction), direction) if(ismob(A)) var/mob/M = A M.reset_perspective(null) + + +/obj/structure/transit_tube_pod/dispensed + name = "temporary transit tube pod" + desc = "Gets you from here to there, and no further." + icon_state = "temppod" + occupied_icon_state = "temppod_occupied" + + +/obj/structure/transit_tube_pod/dispensed/outside_tube() + if(!QDELETED(src)) + qdel(src) + +#undef MOVE_ANIMATION_STAGE_TWO +#undef MOVE_ANIMATION_STAGE_ONE diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index d0769b4cd0a..27febace5d5 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "toilet00" density = 0 - anchored = 1 + anchored = TRUE var/open = 0 //if the lid is up var/cistern = 0 //if the cistern bit is open var/w_items = 0 //the combined w_class of all the items in the cistern @@ -52,7 +52,8 @@ open = !open update_icon() -/obj/structure/toilet/update_icon() + +/obj/structure/toilet/update_icon_state() icon_state = "toilet[open][cistern]" if(!anchored) pixel_x = 0 @@ -129,7 +130,7 @@ user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!", "You hear grinding porcelain.") cistern = !cistern update_icon() - return + /obj/structure/toilet/wrench_act(mob/user, obj/item/I) . = TRUE @@ -156,19 +157,19 @@ if(!loc || !anchored) return user.visible_message("[user] disconnects [src]!", "You disconnect [src]!") - anchored = 0 + anchored = FALSE if("Connect") user.visible_message("[user] starts connecting [src].", "You begin connecting [src]...") if(I.use_tool(src, user, 40, volume = I.tool_volume)) if(!loc || anchored) return user.visible_message("[user] connects [src]!", "You connect [src]!") - anchored = 1 + anchored = TRUE if("Rotate") var/list/dir_choices = list("North" = NORTH, "East" = EAST, "South" = SOUTH, "West" = WEST) var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in dir_choices dir = dir_choices[selected] - update_icon() //is this necessary? probably not + update_icon() /obj/structure/toilet/proc/stash_goods(obj/item/I, mob/user) if(!I) @@ -217,7 +218,7 @@ desc = "Поговаривают, что 7 веков назад у каждого арабского шейха был такой унитаз." icon_state = "gold_toilet00" -/obj/structure/toilet/golden_toilet/update_icon() +/obj/structure/toilet/golden_toilet/update_icon_state() . = ..() icon_state = "gold_toilet[open][cistern]" @@ -226,7 +227,7 @@ desc = "Престижное седалище для престижной персоны. Судя по форме, был идеально подготовлен под седальное место Капитана." icon_state = "captain_toilet00" -/obj/structure/toilet/captain_toilet/update_icon() +/obj/structure/toilet/captain_toilet/update_icon_state() . = ..() icon_state = "captain_toilet[open][cistern]" @@ -236,7 +237,7 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "urinal" density = 0 - anchored = 1 + anchored = TRUE /obj/structure/urinal/attackby(obj/item/I, mob/user, params) @@ -268,7 +269,7 @@ if(!loc || !anchored) return user.visible_message("[user] disconnects [src]!", "You disconnect [src]!") - anchored = 0 + anchored = FALSE pixel_x = 0 pixel_y = 0 else @@ -277,25 +278,32 @@ if(!loc || anchored) return user.visible_message("[user] connects [src]!", "You connect [src]!") - anchored = 1 + anchored = TRUE pixel_x = 0 pixel_y = 32 + +#define SHOWER_FREEZING "freezing" +#define SHOWER_NORMAL "normal" +#define SHOWER_BOILING "boiling" + /obj/machinery/shower name = "shower" desc = "The HS-451. Installed in the 2550s by the Nanotrasen Hygiene Division." icon = 'icons/obj/watercloset.dmi' icon_state = "shower" - density = 0 - anchored = 1 + density = FALSE + anchored = TRUE use_power = NO_POWER_USE - var/on = 0 - var/obj/effect/mist/mymist = null - var/ismist = 0 //needs a var so we can make it linger~ - var/watertemp = "normal" //freezing, normal, or boiling + ///Is the shower on or off? + var/on = FALSE + ///What temperature the shower reagents are set to. + var/current_temperature = SHOWER_NORMAL var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process() + ///What sound will be played on loop when the shower is on and pouring water. var/datum/looping_sound/showering/soundloop + /obj/machinery/shower/New(turf/T, newdir = SOUTH, building = FALSE) ..() soundloop = new(list(src), FALSE) @@ -310,9 +318,12 @@ pixel_y = -5 layer = FLY_LAYER + /obj/machinery/shower/Destroy() - QDEL_NULL(mymist) QDEL_NULL(soundloop) + var/obj/effect/mist/mist = locate() in loc + if(!QDELETED(mist)) + QDEL_IN(mist, 25 SECONDS) return ..() //add heat controls? when emagged, you can freeze to death in it? @@ -321,164 +332,176 @@ name = "mist" icon = 'icons/obj/watercloset.dmi' icon_state = "mist" - layer = MOB_LAYER + 1 - anchored = 1 + layer = FLY_LAYER + anchored = TRUE mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/obj/machinery/shower/attack_hand(mob/M as mob) - add_fingerprint(M) + +/obj/machinery/shower/attack_hand(mob/user) on = !on update_icon() + handle_mist() + add_fingerprint(user) if(on) + START_PROCESSING(SSmachines, src) + process() soundloop.start() - if(M.loc == loc) - wash(M) - check_heat(M) - M.water_act(100, convertHeat(), src) - for(var/atom/movable/G in src.loc) - G.clean_blood() - G.water_act(100, convertHeat(), src) else soundloop.stop() + var/turf/simulated/source_turf = loc + if(istype(source_turf) && !source_turf.density) + source_turf.MakeSlippery(TURF_WET_WATER, 5 SECONDS) + /obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params) if(I.type == /obj/item/analyzer) add_fingerprint(user) - to_chat(user, "The water temperature seems to be [watertemp].") - if(on) - add_fingerprint(user) - I.water_act(100, convertHeat(), src) + to_chat(user, span_notice("The water temperature seems to be [current_temperature].")) return ..() + /obj/machinery/shower/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - to_chat(user, "You begin to adjust the temperature valve with the [I].") - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - switch(watertemp) - if("normal") - watertemp = "freezing" - if("freezing") - watertemp = "boiling" - if("boiling") - watertemp = "normal" - user.visible_message("[user] adjusts the shower with the [I].", "You adjust [src] to [watertemp].") - update_icon() //letsa update whenever we change the temperature, since the mist might need to change + to_chat(user, span_notice("You begin to adjust the temperature valve with [I].")) + if(I.use_tool(src, user, 5 SECONDS)) + switch(current_temperature) + if(SHOWER_NORMAL) + current_temperature = SHOWER_FREEZING + if(SHOWER_FREEZING) + current_temperature = SHOWER_BOILING + if(SHOWER_BOILING) + current_temperature = SHOWER_NORMAL + user.visible_message( + span_notice("[user] adjusts the shower with [I]."), + span_notice("You adjust [src] to [current_temperature] temperature."), + ) + add_hiddenprint(user) + handle_mist() + return TRUE + /obj/machinery/shower/welder_act(mob/user, obj/item/I) . = TRUE if(on) - to_chat(user, "Turn [src] off before you attempt to cut it loose.") + to_chat(user, span_warning("Turn [src] off before you attempt to cut it loose.")) return if(!I.tool_use_check(user, 0)) return - visible_message("[user] begins slicing [src] free...", "You begin slicing [src] free...", "You hear welding.") - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - if(mymist) - qdel(mymist) - user.visible_message("[user] cuts [src] loose!", "You cut [src] loose!") - var/obj/item/mounted/shower/S = new /obj/item/mounted/shower(get_turf(user)) - transfer_fingerprints_to(S) + user.visible_message( + span_notice("[user] begins slicing [src] free..."), + span_notice("You begin slicing [src] free..."), + span_italics("You hear welding."), + ) + if(I.use_tool(src, user, 4 SECONDS, volume = I.tool_volume)) + user.visible_message( + span_notice("[user] cuts [src] loose!"), + span_notice("You cut [src] loose!>"), + ) + var/obj/item/mounted/shower/shower = new /obj/item/mounted/shower(get_turf(user)) + transfer_prints_to(shower, TRUE) qdel(src) -/obj/machinery/shower/update_icon() //this makes the shower mist up or clear mist (depending on water temperature) - overlays.Cut() //once it's been on for a while, in addition to handling the water overlay. - if(on) - overlays += image('icons/obj/watercloset.dmi', src, "water", MOB_LAYER + 1, dir) - var/mist_time = 50 //5 seconds at normal temperature to build up mist - if(watertemp == "freezing") - mist_time = 70 //7 seconds on freezing temperature to disperse existing mist - if(watertemp == "boiling") - mist_time = 20 //2 seconds on boiling temperature to build up mist - addtimer(CALLBACK(src, PROC_REF(update_mist)), mist_time) - else - addtimer(CALLBACK(src, PROC_REF(update_mist)), 250) //25 seconds for mist to disperse after being turned off -/obj/machinery/shower/proc/update_mist() +/obj/machinery/shower/update_overlays() + . = ..() if(on) - if(watertemp == "freezing") - if(mymist) - qdel(mymist) - ismist = 0 - return - if(mymist) - return - ismist = 1 - mymist = new /obj/effect/mist(loc) - else - if(mymist) - qdel(mymist) - ismist = 0 + . += image(icon, icon_state = "water", layer = ABOVE_MOB_LAYER, dir = src.dir) -/obj/machinery/shower/Crossed(atom/movable/O, oldloc) - ..() - wash(O) - if(ismob(O)) - mobpresent += 1 - check_heat(O) - -/obj/machinery/shower/Uncrossed(atom/movable/O) - if(ismob(O)) - mobpresent -= 1 + +/obj/machinery/shower/proc/handle_mist() + // If there is no mist, and the shower was turned on (on a non-freezing temp): make mist in 5 seconds + // If there was already mist, and the shower was turned off (or made cold): remove the existing mist in 25 sec + var/obj/effect/mist/mist = locate() in loc + if(!mist && on && current_temperature != SHOWER_FREEZING) + addtimer(CALLBACK(src, PROC_REF(make_mist)), 5 SECONDS) + + if(mist && (!on || current_temperature == SHOWER_FREEZING)) + addtimer(CALLBACK(src, PROC_REF(clear_mist)), 25 SECONDS) + + +/obj/machinery/shower/proc/make_mist() + var/obj/effect/mist/mist = locate() in loc + if(!mist && on && current_temperature != SHOWER_FREEZING) + new /obj/effect/mist(loc) + + +/obj/machinery/shower/proc/clear_mist() + var/obj/effect/mist/mist = locate() in loc + if(mist && (!on || current_temperature == SHOWER_FREEZING)) + qdel(mist) + + +/obj/machinery/shower/Crossed(atom/movable/AM, oldloc) ..() + if(on) + wash(AM) + /obj/machinery/shower/proc/convertHeat() - switch(watertemp) - if("boiling") + switch(current_temperature) + if(SHOWER_BOILING) return 340.15 - if("normal") + if(SHOWER_NORMAL) return 310.15 - if("freezing") + if(SHOWER_FREEZING) return 230.15 + //Yes, showers are super powerful as far as washing goes. -/obj/machinery/shower/proc/wash(atom/movable/O as obj|mob) - if(!on) return +/obj/machinery/shower/proc/wash(atom/target) + if(!on) + return + + if(isitem(target)) + var/obj/item/item = target + item.extinguish() - if(istype(O, /obj/item)) - var/obj/item/I = O - I.extinguish() + target.water_act(100, convertHeat(), src) - O.water_act(100, convertHeat(), src) + if(isliving(target)) + var/mob/living/l_target = target + l_target.ExtinguishMob() + l_target.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily + to_chat(l_target, span_warning("You've been drenched in water!")) - if(isliving(O)) - var/mob/living/L = O - L.ExtinguishMob() - L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily - to_chat(L, "You've been drenched in water!") - L.clean_blood() + target.clean_blood() - if(isturf(loc)) - var/turf/tile = loc - loc.clean_blood() - for(var/obj/effect/E in tile) - if(E.is_cleanable()) - qdel(E) /obj/machinery/shower/process() - if(!on || !mobpresent) - return - for(var/mob/living/carbon/C in loc) - if(prob(33)) - wash(C) //re-applies water and re-cleans mob while they remain under the shower, 33% chance per process to avoid message spam/quick death - check_heat(C) + if(on) + if(isturf(loc)) + var/turf/tile = loc + tile.water_act(100, convertHeat(), src) + tile.clean_blood() + for(var/obj/effect/effect in tile) + if(effect.is_cleanable()) + qdel(effect) + for(var/thing in loc) + wash(thing) + else + on = FALSE + soundloop.stop() + handle_mist() + update_icon(UPDATE_OVERLAYS) -/obj/machinery/shower/proc/check_heat(mob/M as mob) - if(!on || watertemp == "normal") + +/obj/machinery/shower/proc/check_heat(mob/M) + if(current_temperature == SHOWER_NORMAL) return if(iscarbon(M)) var/mob/living/carbon/C = M - if(watertemp == "freezing") + if(current_temperature == SHOWER_FREEZING) //C.bodytemperature = max(80, C.bodytemperature - 80) to_chat(C, "The water is freezing!") - return - if(watertemp == "boiling") + + else if(current_temperature == SHOWER_BOILING) //C.bodytemperature = min(500, C.bodytemperature + 35) C.adjustFireLoss(5) to_chat(C, "The water is searing!") - return + +#undef SHOWER_FREEZING +#undef SHOWER_NORMAL +#undef SHOWER_BOILING /obj/item/bikehorn/rubberducky @@ -502,7 +525,7 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "sink" desc = "A sink used for washing one's hands and face." - anchored = 1 + anchored = TRUE var/busy = 0 //Something's being washed at the moment var/can_move = 1 //if the sink can be disconnected and moved var/can_rotate = 1 //if the sink can be rotated to face alternate directions @@ -621,10 +644,9 @@ var/list/dir_choices = list("North" = NORTH, "East" = EAST, "South" = SOUTH, "West" = WEST) var/selected = input(user, "Select a direction for the connector.", "Connector Direction") in dir_choices dir = dir_choices[selected] - update_icon() //is this necessary? probably not + update_icon(UPDATE_ICON_STATE) -/obj/structure/sink/update_icon() - ..() +/obj/structure/sink/update_icon_state() layer = OBJ_LAYER if(!anchored) pixel_x = 0 @@ -741,9 +763,9 @@ if(do_after(user, 30, target = user)) user.visible_message("[user] finishes building a new [result_name]!", "You finish building a new [result_name]!") var/obj/structure/S = new result(T) - S.anchored = 0 + S.anchored = FALSE S.dir = user.dir - S.update_icon() + S.update_icon(UPDATE_ICON_STATE) user.temporarily_remove_item_from_inventory(src, force = TRUE) qdel(src) if(prob(50)) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 4a66c4326cd..0c4249e085c 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -50,7 +50,7 @@ setDir(ini_dir) move_update_air(T) -/obj/structure/windoor_assembly/update_icon() +/obj/structure/windoor_assembly/update_icon_state() var/temp_state = state if(temp_state == "03") temp_state = "02" @@ -162,7 +162,7 @@ add_fingerprint(user) //Update to reflect changes(if applicable) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/windoor_assembly/crowbar_act(mob/user, obj/item/I) //Crowbar to complete the assembly, Step 7 complete. if(state != "03") @@ -228,7 +228,7 @@ state = "02" electronics.forceMove(loc) electronics = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/windoor_assembly/wirecutter_act(mob/user, obj/item/I) if(state != "02") @@ -243,7 +243,7 @@ new/obj/item/stack/cable_coil(get_turf(user), 1) state = "01" name = "[(src.secure) ? "secure" : ""] anchored windoor assembly" - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/windoor_assembly/wrench_act(mob/user, obj/item/I) if(state != "01") @@ -274,7 +274,7 @@ to_chat(user, "You loosen bolts on [src].") anchored = FALSE name = "[(src.secure) ? "secure" : ""] windoor assembly" - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/windoor_assembly/welder_act(mob/user, obj/item/I) if(state != "01") @@ -312,7 +312,7 @@ setDir(target_dir) ini_dir = dir - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE /obj/structure/windoor_assembly/AltClick(mob/user) @@ -339,5 +339,5 @@ facing = "l" to_chat(usr, "The windoor will now slide to the left.") - update_icon() - return + update_icon(UPDATE_ICON_STATE) + diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 1d8ea14736a..316cfc4afc9 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 var/cancolor = FALSE - var/image/crack_overlay + var/mutable_appearance/crack_overlay var/list/debris = list() var/real_explosion_block //ignore this, just use explosion_block var/breaksound = "shatter" @@ -325,6 +325,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", if(I.use_tool(src, user, 40, volume = I.tool_volume)) obj_integrity = max_integrity WELDER_REPAIR_SUCCESS_MESSAGE + update_icon(UPDATE_OVERLAYS) /obj/structure/window/proc/check_state(checked_state) if(state == checked_state) @@ -478,23 +479,25 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", //This proc is used to update the icons of nearby windows. /obj/structure/window/proc/update_nearby_icons() - update_icon() + update_icon(UPDATE_OVERLAYS) if(smooth) queue_smooth_neighbors(src) -/obj/structure/window/update_icon() - if(!QDELETED(src)) - if(!fulltile) - return - var/ratio = obj_integrity / max_integrity - ratio = CEILING(ratio*4, 1) * 25 - if(smooth) - queue_smooth(src) - overlays -= crack_overlay - if(ratio > 75) - return - crack_overlay = image('icons/obj/structures.dmi',"damage[ratio]",-(layer+0.1)) - overlays += crack_overlay +/obj/structure/window/update_overlays() + . = ..() + if(QDELETED(src) || !fulltile) + return + + var/ratio = obj_integrity / max_integrity + ratio = CEILING(ratio * 4, 1) * 25 + if(smooth) + queue_smooth(src) + if(ratio > 75) + return + + crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer + 0.01), appearance_flags = RESET_COLOR) + . += crack_overlay + /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() @@ -596,35 +599,38 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", use_power(5) active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) - for(var/obj/structure/window/reinforced/polarized/W in range(src,range)) - if(W.id == src.id || !W.id) - spawn(0) - W.toggle() - return - for(var/obj/machinery/door/airlock/G in range(src,range)) - if(G.id == src.id) - spawn(0) - if(G.glass) - G.airlock_material = null - G.glass = FALSE - G.update_icon() - if(G.density) - G.opacity = 1 - else - G.airlock_material = "glass" - G.glass = TRUE - G.update_icon() - G.opacity = 0 - return + for(var/obj/structure/window/reinforced/polarized/window in range(src,range)) + if(window.id == id || !window.id) + INVOKE_ASYNC(window, TYPE_PROC_REF(/obj/structure/window/reinforced/polarized, toggle)) -/obj/machinery/button/windowtint/power_change() - ..() + for(var/obj/machinery/door/airlock/airlock in range(src,range)) + if(airlock.id == id) + INVOKE_ASYNC(src, PROC_REF(async_update), airlock) + + +/obj/machinery/button/windowtint/proc/async_update(obj/machinery/door/airlock/airlock) + if(airlock.glass) + airlock.airlock_material = null + airlock.glass = FALSE + airlock.update_icon() + if(airlock.density) + airlock.set_opacity(TRUE) + else + airlock.airlock_material = "glass" + airlock.glass = TRUE + airlock.update_icon() + airlock.set_opacity(FALSE) + + +/obj/machinery/button/windowtint/power_change(forced = FALSE) + if(!..()) + return if(active && !powered(power_channel)) toggle_tint() -/obj/machinery/button/windowtint/update_icon() +/obj/machinery/button/windowtint/update_icon_state() icon_state = "light[active]" /obj/structure/window/plasmabasic @@ -900,7 +906,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", /obj/structure/window/reinforced/clockwork/ratvar_act() obj_integrity = max_integrity - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/structure/window/reinforced/clockwork/narsie_act() take_damage(rand(25, 75), BRUTE) diff --git a/code/game/objects/structures/wryn.dm b/code/game/objects/structures/wryn.dm index 5afad33eac2..c10d16b84ae 100644 --- a/code/game/objects/structures/wryn.dm +++ b/code/game/objects/structures/wryn.dm @@ -68,41 +68,29 @@ plane = FLOOR_PLANE icon_state = "wax_floor" max_integrity = 10 + var/current_dir var/static/list/floorImageCache -/obj/structure/wryn/floor/proc/updateOverlays() - - overlays.Cut() - - if(!floorImageCache || !floorImageCache.len) - floorImageCache = list() - floorImageCache.len = 4 - floorImageCache["north"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_n", layer=2.11, pixel_y = -32) - floorImageCache["south"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_s", layer=2.11, pixel_y = 32) - floorImageCache["east"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_e", layer=2.11, pixel_x = -32) - floorImageCache["west"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_w", layer=2.11, pixel_x = 32) - - var/turf/N = get_step(src, NORTH) - var/turf/S = get_step(src, SOUTH) - var/turf/E = get_step(src, EAST) - var/turf/W = get_step(src, WEST) - if(!locate(/obj/structure/wryn) in N.contents) - if(istype(N, /turf/simulated/floor)) - overlays += floorImageCache["south"] - if(!locate(/obj/structure/wryn) in S.contents) - if(istype(S, /turf/simulated/floor)) - overlays += floorImageCache["north"] - if(!locate(/obj/structure/wryn) in E.contents) - if(istype(E, /turf/simulated/floor)) - overlays += floorImageCache["west"] - if(!locate(/obj/structure/wryn) in W.contents) - if(istype(W, /turf/simulated/floor)) - overlays += floorImageCache["east"] + +/obj/structure/wryn/floor/update_overlays() + . = ..() + for(var/check_dir in GLOB.cardinal) + var/turf/check = get_step(src, check_dir) + if(issimulatedturf(check) && !(locate(/obj/structure/wryn) in check)) + . += floorImageCache["[GetOppositeDir(check_dir)]"] /obj/structure/wryn/floor/proc/fullUpdateWeedOverlays() - for(var/obj/structure/wryn/floor/W in range(1,src)) - W.updateOverlays() + if(!length(floorImageCache)) + floorImageCache = list(4) + floorImageCache["[NORTH]"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_n", layer=2.11, pixel_y = -32) + floorImageCache["[SOUTH]"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_s", layer=2.11, pixel_y = 32) + floorImageCache["[EAST]"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_e", layer=2.11, pixel_x = -32) + floorImageCache["[WEST]"] = image('icons/obj/smooth_structures/wryn/floor.dmi', "wax_floor_side_w", layer=2.11, pixel_x = 32) + + for(var/obj/structure/wryn/floor/floor in range(1,src)) + floor.update_icon(UPDATE_OVERLAYS) + /obj/structure/wryn/floor/New(pos) ..() diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index cd9196f7eed..dbcb598f793 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -11,7 +11,7 @@ name = "engine" icon = 'icons/turf/shuttle/misc.dmi' density = 1 - anchored = 1.0 + anchored = TRUE resistance_flags = INDESTRUCTIBLE // То что у нас двигатели ломаются от пары пуль - бред var/list/obj/structure/fillers = list() // Для коллизии более больших двигателей diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 6d15f484e9e..d7859121be4 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -3,6 +3,7 @@ name = "station" var/wet = 0 var/image/wet_overlay = null + var/mutable_appearance/melting_olay var/thermite = 0 oxygen = MOLES_O2STANDARD @@ -83,7 +84,7 @@ switch(src.wet) if(TURF_WET_WATER) if(!(M.slip("the wet floor", WATER_WEAKEN_TIME, tilesSlipped = 0, walkSafely = 1))) - M.inertia_dir = 0 + M.inertia_dir = NONE return if(TURF_WET_LUBE) //lube @@ -92,7 +93,7 @@ if(TURF_WET_ICE) // Ice if(M.slip("the icy floor", 4 SECONDS, tilesSlipped = 0, walkSafely = 0)) - M.inertia_dir = 0 + M.inertia_dir = NONE if(prob(5)) var/obj/item/organ/external/affected = M.get_organ(BODY_ZONE_HEAD) if(affected) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index b5c04cb2031..9f5842de11d 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -125,12 +125,11 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama /turf/simulated/floor/blob_act(obj/structure/blob/B) return -/turf/simulated/floor/update_icon() +/turf/simulated/floor/update_overlays() + . = ..() update_visuals() - overlays -= current_overlay if(current_overlay) - overlays.Add(current_overlay) - return 1 + . += current_overlay /turf/simulated/floor/proc/break_tile_to_plating() var/turf/simulated/floor/plating/T = make_plating(FALSE) diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index d44b6ecb80c..b3dcf69dee9 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -114,7 +114,7 @@ . = ..() update_icon() -/turf/simulated/floor/grass/update_icon() +/turf/simulated/floor/grass/update_icon_state() icon_state = "grass[pick("1","2","3","4")]" /turf/simulated/floor/grass/attackby(obj/item/C, mob/user, params) @@ -159,13 +159,13 @@ . = ..() update_icon() + /turf/simulated/floor/carpet/broken_states() return list("damaged") -/turf/simulated/floor/carpet/update_icon() - if(!..()) - return - dir = 0 //Prevents wrong smoothing + +/turf/simulated/floor/carpet/update_icon_state() + dir = NONE //Prevents wrong smoothing if(!broken && !burnt) if(smooth) queue_smooth(src) diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 58e2a708994..53418593002 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -274,7 +274,7 @@ icon = 'icons/turf/floors/seadrop-o.dmi' layer = MOB_LAYER + 0.1 smooth = SMOOTH_TRUE - anchored = 1 + anchored = TRUE canSmoothWith = list( /turf/simulated/floor/indestructible/beach/water/drop, /turf/simulated/floor/indestructible/beach/water/drop/dense, /turf/simulated/floor/indestructible/beach/water, /turf/simulated/floor/indestructible/beach/water/dense, diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index dfd63d5ea4c..40851bd4313 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -23,49 +23,52 @@ . = ..() update_icon() + /turf/simulated/floor/light/broken_states() return list("light_broken") -/turf/simulated/floor/light/update_icon() - ..() - if(on) - switch(state) - if(LIGHTFLOOR_ON) - icon_state = "light_on" - set_light(5, null,LIGHT_COLOR_LIGHTBLUE) - if(LIGHTFLOOR_WHITE) - icon_state = "light_on-w" - set_light(5, null,LIGHT_COLOR_WHITE) - if(LIGHTFLOOR_RED) - icon_state = "light_on-r" - set_light(5, null,LIGHT_COLOR_RED) - if(LIGHTFLOOR_GREEN) - icon_state = "light_on-g" - set_light(5, null,LIGHT_COLOR_PURE_GREEN) - if(LIGHTFLOOR_YELLOW) - icon_state = "light_on-y" - set_light(5, null,"#FFFF00") - if(LIGHTFLOOR_BLUE) - icon_state = "light_on-b" - set_light(5, null,LIGHT_COLOR_DARKBLUE) - if(LIGHTFLOOR_PURPLE) - icon_state = "light_on-p" - set_light(5, null,LIGHT_COLOR_PURPLE) - if(LIGHTFLOOR_GENERICCYCLE) - icon_state = "light_on-cycle_all" - set_light(5, null,LIGHT_COLOR_WHITE) - if(LIGHTFLOOR_CYCLEA) - icon_state = "light_on-dancefloor_A" - set_light(5,null,LIGHT_COLOR_RED) - if(LIGHTFLOOR_CYCLEB) - icon_state = "light_on-dancefloor_B" - set_light(5, null,LIGHT_COLOR_DARKBLUE) - else - icon_state = "light_off" - set_light(0) - else + +/turf/simulated/floor/light/update_icon_state() + if(!on) set_light(0) icon_state = "light_off" + return + + switch(state) + if(LIGHTFLOOR_ON) + icon_state = "light_on" + set_light(5, null,LIGHT_COLOR_LIGHTBLUE) + if(LIGHTFLOOR_WHITE) + icon_state = "light_on-w" + set_light(5, null,LIGHT_COLOR_WHITE) + if(LIGHTFLOOR_RED) + icon_state = "light_on-r" + set_light(5, null,LIGHT_COLOR_RED) + if(LIGHTFLOOR_GREEN) + icon_state = "light_on-g" + set_light(5, null,LIGHT_COLOR_PURE_GREEN) + if(LIGHTFLOOR_YELLOW) + icon_state = "light_on-y" + set_light(5, null,"#FFFF00") + if(LIGHTFLOOR_BLUE) + icon_state = "light_on-b" + set_light(5, null,LIGHT_COLOR_DARKBLUE) + if(LIGHTFLOOR_PURPLE) + icon_state = "light_on-p" + set_light(5, null,LIGHT_COLOR_PURPLE) + if(LIGHTFLOOR_GENERICCYCLE) + icon_state = "light_on-cycle_all" + set_light(5, null,LIGHT_COLOR_WHITE) + if(LIGHTFLOOR_CYCLEA) + icon_state = "light_on-dancefloor_A" + set_light(5,null,LIGHT_COLOR_RED) + if(LIGHTFLOOR_CYCLEB) + icon_state = "light_on-dancefloor_B" + set_light(5, null,LIGHT_COLOR_DARKBLUE) + else + icon_state = "light_off" + set_light(0) + /turf/simulated/floor/light/BeforeChange() set_light(0) diff --git a/code/game/turfs/simulated/floor/mineral.dm b/code/game/turfs/simulated/floor/mineral.dm index dd3b20f0b17..4440de90854 100644 --- a/code/game/turfs/simulated/floor/mineral.dm +++ b/code/game/turfs/simulated/floor/mineral.dm @@ -17,12 +17,11 @@ /turf/simulated/floor/mineral/broken_states() return list("[initial(icon_state)]_dam") -/turf/simulated/floor/mineral/update_icon() - if(!..()) - return 0 - if(!broken && !burnt) - if(!(icon_state in icons)) - icon_state = initial(icon_state) + +/turf/simulated/floor/mineral/update_icon_state() + if(!broken && !burnt && !(icon_state in icons)) + icon_state = initial(icon_state) + //PLASMA /turf/simulated/floor/mineral/plasma diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm index 99f943c53e4..366d9d2a12b 100644 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ b/code/game/turfs/simulated/floor/plasteel_floor.dm @@ -8,9 +8,7 @@ /turf/simulated/floor/plasteel/burnt_states() return list("floorscorched1", "floorscorched2") -/turf/simulated/floor/plasteel/update_icon() - if(!..()) - return 0 +/turf/simulated/floor/plasteel/update_icon_state() if(!broken && !burnt) icon_state = icon_regular_floor dir = floor_regular_dir diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 8896f455dda..a37d7d83633 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -32,9 +32,7 @@ . = ..() burn_tile() -/turf/simulated/floor/plating/update_icon() - if(!..()) - return +/turf/simulated/floor/plating/update_icon_state() if(!broken && !burnt) icon_state = icon_plating //Because asteroids are 'platings' too. @@ -191,7 +189,7 @@ /turf/simulated/floor/engine/attackby(obj/item/C, mob/user, params) if(!C || !user) return - if(istype(C, /obj/item/wrench)) + if(C.tool_behaviour == TOOL_WRENCH) to_chat(user, span_notice("You begin removing rods...")) playsound(src, C.usesound, 80, 1) if(do_after(user, 30 * C.toolspeed * gettoolspeedmod(user), target = src)) @@ -227,12 +225,20 @@ /turf/simulated/floor/engine/cult name = "engraved floor" icon_state = "cult" + var/holy = FALSE + /turf/simulated/floor/engine/cult/Initialize(mapload) . = ..() - if(SSticker.mode)//only do this if the round is going..otherwise..fucking asteroid.. - if(!icon_state == "holy") - icon_state = SSticker.cultdat.cult_floor_icon_state + update_icon(UPDATE_ICON_STATE) + + +/turf/simulated/floor/engine/cult/update_icon_state() + if(SSticker?.cultdat && !holy) + icon_state = SSticker.cultdat.cult_floor_icon_state + return + icon_state = initial(icon_state) + /turf/simulated/floor/engine/cult/narsie_act() return @@ -246,6 +252,7 @@ /turf/simulated/floor/engine/cult/holy icon_state = "holy" + holy = TRUE //air filled floors; used in atmos pressure chambers @@ -361,7 +368,7 @@ icon_state = "ironfoam" metal = MFOAM_IRON -/turf/simulated/floor/plating/metalfoam/update_icon() +/turf/simulated/floor/plating/metalfoam/update_icon_state() switch(metal) if(MFOAM_ALUMINUM) icon_state = "metalfoam" @@ -418,14 +425,6 @@ /turf/simulated/floor/plating/metalfoam/proc/smash() ChangeTurf(baseturf) -/turf/simulated/floor/plating/abductor - name = "alien floor" - icon_state = "alienpod1" - -/turf/simulated/floor/plating/abductor/Initialize(mapload) - . = ..() - icon_state = "alienpod[rand(1,9)]" - /turf/simulated/floor/plating/ice name = "ice sheet" desc = "A sheet of solid ice. Looks slippery." diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 4c23b51b895..53f66b42a32 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -104,14 +104,16 @@ else update_icon() -/turf/simulated/mineral/update_icon() + +/turf/simulated/mineral/update_overlays() + . = ..() if(hardness != initial(hardness)) var/amount = hardness var/mutable_appearance/cracks = mutable_appearance('icons/turf/mining.dmi',"rock_cracks_[amount]",ON_EDGED_TURF_LAYER) var/matrix/M = new M.Translate(4,4) cracks.transform = M - add_overlay(cracks) + . += cracks /turf/simulated/mineral/attack_animal(mob/living/simple_animal/user) diff --git a/code/game/turfs/simulated/shuttle.dm b/code/game/turfs/simulated/shuttle.dm index 10c78c46610..5d010f0649c 100644 --- a/code/game/turfs/simulated/shuttle.dm +++ b/code/game/turfs/simulated/shuttle.dm @@ -61,7 +61,7 @@ /turf/simulated/wall/shuttle/try_decon(obj/item/I, mob/user, params) return -/turf/simulated/wall/shuttle/thermitemelt(mob/user as mob, speed) +/turf/simulated/wall/shuttle/thermitemelt(mob/user, time) return /turf/simulated/wall/shuttle/nodiagonal diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 07d46679d71..752889d54f8 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -25,6 +25,8 @@ thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall + var/melting = FALSE //TRUE if wall is currently being melted with thermite + var/can_dismantle_with_welder = TRUE var/hardness = 40 //lower numbers are harder. Used to determine the probability of a hulk smashing through. var/slicing_duration = 100 @@ -71,27 +73,25 @@ if(rotting) . += span_warning("There is fungus growing on [src].") -/turf/simulated/wall/update_icon() + +/turf/simulated/wall/update_overlays() + . = ..() if(!damage_overlays[1]) //list hasn't been populated generate_overlays() queue_smooth(src) if(!damage) - if(damage_overlay) - overlays -= damage_overlays[damage_overlay] - damage_overlay = 0 return - var/overlay = round(damage / damage_cap * damage_overlays.len) + 1 - if(overlay > damage_overlays.len) - overlay = damage_overlays.len + var/overlay = round(damage / damage_cap * length(damage_overlays)) + 1 + if(overlay > length(damage_overlays)) + overlay = length(damage_overlays) if(damage_overlay && overlay == damage_overlay) //No need to update. return - if(damage_overlay) - overlays -= damage_overlays[damage_overlay] - overlays += damage_overlays[overlay] - damage_overlay = overlay + + . += damage_overlays[overlay] + /turf/simulated/wall/proc/generate_overlays() var/alpha_inc = 256 / damage_overlays.len @@ -245,35 +245,87 @@ /turf/simulated/wall/burn_down() if(istype(sheet_type, /obj/item/stack/sheet/mineral/diamond)) return - ChangeTurf(/turf/simulated/floor) + return ChangeTurf(/turf/simulated/floor) + -/turf/simulated/wall/proc/thermitemelt(mob/user as mob, speed) - var/wait = 100 - if(speed) - wait = speed +#define THERMITE_PER_SECOND 2.5 +#define DAMAGE_PER_SECOND 60 + +/** + * Melts down wall into its base turf. + * + * Arguments: + * * user - who used thermite, optional argument used to show message. + * * time - optional override; thermite reagent will not be used for melting, only passed time matters. + */ +/turf/simulated/wall/proc/thermitemelt(mob/user, time) + set waitfor = FALSE + + if(melting) + return if(istype(sheet_type, /obj/item/stack/sheet/mineral/diamond)) return - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "Thermite" - O.desc = "Looks hot." - O.icon = 'icons/effects/fire.dmi' - O.icon_state = "2" - O.anchored = 1 - O.density = 1 - O.layer = 5 + var/obj/effect/overlay/visuals = new(src) + visuals.name = "Thermite" + visuals.desc = "Looks hot." + visuals.icon = 'icons/effects/fire.dmi' + visuals.icon_state = "2" + visuals.anchored = TRUE + visuals.density = TRUE + visuals.layer = FLY_LAYER - src.ChangeTurf(/turf/simulated/floor/plating) - - var/turf/simulated/floor/F = src - F.burn_tile() - F.icon_state = "plating" if(user) - to_chat(user, span_warning("The thermite starts melting through the wall.")) + to_chat(user, span_warning("The thermite starts melting through [src].")) + + if(time) + melting = TRUE + var/sound_timer = 10 + while(time > 0) + if(QDELETED(src)) + return + sound_timer++ + if(sound_timer >= 10) + sound_timer = 0 + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + time = max(0, time - 0.1 SECONDS) + sleep(0.1 SECONDS) + if(QDELETED(src)) + return + var/turf/simulated/floor/our_floor = burn_down() + our_floor.burn_tile() + our_floor.cut_overlay(melting_olay) + if(visuals) + qdel(visuals) + return + + melting = TRUE + + while(reagents.get_reagent_amount("thermite") > 0) + if(QDELETED(src)) + return + reagents.remove_reagent("thermite", THERMITE_PER_SECOND) + if(damage_cap - damage <= DAMAGE_PER_SECOND) + var/turf/simulated/floor/our_floor = burn_down() + our_floor.burn_tile() + break + take_damage(DAMAGE_PER_SECOND) + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + sleep(1 SECONDS) + + if(QDELETED(src)) + return + + if(iswallturf(src)) + melting = FALSE + + cut_overlay(melting_olay) + if(visuals) + qdel(visuals) + +#undef THERMITE_PER_SECOND +#undef DAMAGE_PER_SECOND - spawn(wait) - if(O) qdel(O) - return //Interactions @@ -353,7 +405,7 @@ /turf/simulated/wall/welder_act(mob/user, obj/item/I) . = TRUE - if(thermite && I.use_tool(src, user, volume = I.tool_volume)) + if(reagents?.get_reagent_amount("thermite") && I.use_tool(src, user, volume = I.tool_volume)) thermitemelt(user) return if(rotting) diff --git a/code/game/turfs/simulated/walls_indestructible.dm b/code/game/turfs/simulated/walls_indestructible.dm index 19d8ef7d187..739e68a34fd 100644 --- a/code/game/turfs/simulated/walls_indestructible.dm +++ b/code/game/turfs/simulated/walls_indestructible.dm @@ -59,7 +59,7 @@ /turf/simulated/wall/indestructible/rcd_deconstruct_act() return RCD_NO_ACT -/turf/simulated/wall/indestructible/thermitemelt(mob/user as mob, speed) +/turf/simulated/wall/indestructible/thermitemelt(mob/user, time) return /turf/simulated/wall/indestructible/fakeglass diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm index 5caf1ae9d52..ee8318877f8 100644 --- a/code/game/turfs/simulated/walls_mineral.dm +++ b/code/game/turfs/simulated/walls_mineral.dm @@ -267,7 +267,7 @@ /turf/simulated/wall/mineral/titanium/nodecon/try_decon(obj/item/I, mob/user, params) return -/turf/simulated/wall/mineral/titanium/nodecon/thermitemelt(mob/user as mob, speed) +/turf/simulated/wall/mineral/titanium/nodecon/thermitemelt(mob/user, time) return /turf/simulated/wall/mineral/titanium/nodecon/burn_down() diff --git a/code/game/turfs/simulated/walls_misc.dm b/code/game/turfs/simulated/walls_misc.dm index 037bcda8ef2..b7afc177525 100644 --- a/code/game/turfs/simulated/walls_misc.dm +++ b/code/game/turfs/simulated/walls_misc.dm @@ -8,6 +8,7 @@ sheet_type = /obj/item/stack/sheet/runed_metal sheet_amount = 1 girder_type = /obj/structure/girder/cult + var/holy = FALSE /turf/simulated/wall/cult_fake name = "runed metal wall" @@ -20,12 +21,18 @@ sheet_amount = 1 girder_type = /obj/structure/girder/cult_fake + /turf/simulated/wall/cult/Initialize(mapload) . = ..() - if(SSticker.mode)//game hasn't started offically don't do shit.. - new /obj/effect/temp_visual/cult/turf(src) - if(!icon_state == "holy") - icon_state = SSticker.cultdat.cult_wall_icon_state + update_icon(UPDATE_ICON_STATE) + + +/turf/simulated/wall/cult/update_icon_state() + if(SSticker?.cultdat && !holy) + icon_state = SSticker.cultdat.cult_wall_icon_state + return + icon_state = initial(icon_state) + /turf/simulated/wall/cult_fake/Initialize(mapload) . = ..() @@ -42,6 +49,7 @@ icon_state = "holy" sheet_type = /obj/item/stack/sheet/metal girder_type = /obj/structure/girder + holy = TRUE /turf/simulated/wall/cult/artificer/break_wall() new /obj/effect/temp_visual/cult/turf(get_turf(src)) diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 6739b559b77..2a4ddf66252 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -93,7 +93,7 @@ return ..() /turf/simulated/wall/r_wall/welder_act(mob/user, obj/item/I) - if(thermite && I.use_tool(src, user, volume = I.tool_volume)) + if(reagents?.get_reagent_amount("thermite") && I.use_tool(src, user, volume = I.tool_volume)) thermitemelt(user) return TRUE if(!(d_state in list(RWALL_COVER, RWALL_SUPPORT_RODS, RWALL_CUT_COVER))) @@ -232,9 +232,8 @@ if(prob(30)) dismantle_wall() -/turf/simulated/wall/r_wall/update_icon() - . = ..() +/turf/simulated/wall/r_wall/update_icon_state() if(d_state) icon_state = "r_wall-[d_state]" smooth = SMOOTH_FALSE @@ -243,6 +242,7 @@ smooth = SMOOTH_TRUE icon_state = "" + /turf/simulated/wall/r_wall/devastate_wall() new sheet_type(src, sheet_amount) new /obj/item/stack/sheet/metal(src, 2) diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index e558733e1af..816a23dce65 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -62,9 +62,9 @@ /turf/space/transit/Initialize(mapload) . = ..() - update_icon() + update_icon(UPDATE_ICON_STATE) -/turf/space/transit/update_icon() +/turf/space/transit/update_icon_state() var/p = 9 var/angle = 0 var/state = 1 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 15e049bb4ae..03c09ca7fcc 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -8,6 +8,7 @@ var/slowdown = 0 //negative for faster, positive for slower var/transparent_floor = FALSE //used to check if pipes should be visible under the turf or not + /// Set if the turf should appear on a different layer while in-game and map editing, otherwise use normal layer. var/real_layer = TURF_LAYER layer = MAP_EDITOR_TURF_LAYER @@ -375,19 +376,24 @@ L.Add(T) return L -//Idem, but don't check for ID and goes through open doors -/turf/proc/AdjacentTurfs(list/closed) - var/list/L = new() - var/turf/simulated/T - for(var/dir in GLOB.alldirs2) //arbitrarily ordered list to favor non-diagonal moves in case of ties + +/// Returns the adjacent turfs. Can check for density or cardinal directions only instead of all 8, or just dense turfs entirely. dense_only takes precedence over open_only. +/turf/proc/AdjacentTurfs(open_only = FALSE, cardinal_only = FALSE, dense_only = FALSE) + var/list/L = list() + var/turf/T + var/list/directions = cardinal_only ? GLOB.cardinal : GLOB.alldirs + for(var/dir in directions) T = get_step(src, dir) - if(T in closed) //turf already proceeded by A* + if(!istype(T)) continue - if(istype(T) && !T.density) - if(!CanAtmosPass(T)) - L.Add(T) + if(dense_only && !T.density) + continue + if((open_only && T.density) && !dense_only) + continue + L.Add(T) return L + // check for all turfs, including space ones /turf/proc/AdjacentTurfsSpace(obj/item/card/id/ID = null, list/closed)//check access if one is passed var/list/L = new() @@ -456,7 +462,7 @@ for(var/obj/O in contents) //this is for deleting things like wires contained in the turf if(O.level != 1) continue - if(O.invisibility == INVISIBILITY_MAXIMUM) + if(O.invisibility == INVISIBILITY_MAXIMUM || O.invisibility == INVISIBILITY_ABSTRACT) O.singularity_act() ChangeTurf(baseturf) return 2 diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b2466aafa1b..61f3037598d 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2313,7 +2313,7 @@ if(!P.ico) P.ico = new P.ico += "paper_stamp-[stampvalue]" - P.overlays += stampoverlay + LAZYADD(P.stamp_overlays, stampoverlay) P.stamps += "
    " P.update_icon() P.faxmachineid = fax.UID() @@ -2408,7 +2408,7 @@ if(!P.ico) P.ico = new P.ico += "paper_stamp-[stampvalue]" - P.overlays += stampoverlay + LAZYADD(P.stamp_overlays, stampoverlay) P.stamps += "
    " P.update_icon() fax.receivefax(P) @@ -2620,15 +2620,14 @@ if(!P.stamped) P.stamped = new P.stamped += /obj/item/stamp/centcom - P.overlays += stampoverlay P.stamps += "
    " else if(stamptype == "text") if(!P.stamped) P.stamped = new P.stamped += /obj/item/stamp - P.overlays += stampoverlay P.stamps += "
    [stampvalue]" + LAZYADD(P.stamp_overlays, stampoverlay) if(destination != "All Departments") if(!fax.receivefax(P)) @@ -3647,10 +3646,8 @@ hunter_mob.equipOutfit(O, FALSE) var/obj/item/pinpointer/advpinpointer/N = new /obj/item/pinpointer/advpinpointer(hunter_mob) hunter_mob.equip_to_slot_or_del(N, slot_in_backpack) - N.mode = 3 //MODE_ADV, not defined here N.setting = 2 //SETTING_OBJECT, not defined here - N.target = H - N.pinpoint_at(N.target) + N.pinpoint_at(H) N.modelocked = TRUE if(!locate(/obj/item/implant/dust, hunter_mob)) var/obj/item/implant/dust/D = new /obj/item/implant/dust(hunter_mob) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index c234228a186..f3db9508e82 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -661,7 +661,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) F.active = 1 F.state = 2 F.power = 250 - F.anchored = 1 + F.anchored = TRUE F.warming_up = 3 F.start_fields() F.update_icon() diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm index 7ea997d11b1..bbb27a3be88 100644 --- a/code/modules/admin/verbs/honksquad.dm +++ b/code/modules/admin/verbs/honksquad.dm @@ -97,7 +97,7 @@ GLOBAL_VAR_INIT(sent_clownsequritysquad, 0) new_honksquad.mind.assigned_role = SPECIAL_ROLE_HONKSQUAD new_honksquad.mind.special_role = SPECIAL_ROLE_HONKSQUAD new_honksquad.mind.offstation_role = TRUE - new_honksquad.add_language("Clownish") + new_honksquad.add_language(LANGUAGE_CLOWN) new_honksquad.change_voice() SSticker.mode.traitors |= new_honksquad.mind//Adds them to current traitor list. Which is really the extra antagonist list. new_honksquad.equip_honksquad(honk_leader_selected, rankName) diff --git a/code/modules/antagonists/changeling/changeling_datum.dm b/code/modules/antagonists/changeling/changeling_datum.dm index 8deac41e17f..abcaeda0bf5 100644 --- a/code/modules/antagonists/changeling/changeling_datum.dm +++ b/code/modules/antagonists/changeling/changeling_datum.dm @@ -343,7 +343,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E for(var/datum/language/language in new_languages) if(is_type_in_UID_list(language, absorbed_languages)) continue - owner.current.add_language("[language.name]") + owner.current.add_language(language.name) absorbed_languages += language.UID() @@ -352,8 +352,8 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E */ /datum/antagonist/changeling/proc/update_languages() for(var/lang_UID in absorbed_languages) - var/datum/language/lang = locateUID(lang_UID) - owner.current.add_language("[lang.name]") + var/datum/language/language = locateUID(lang_UID) + owner.current.add_language(language.name) /** @@ -378,10 +378,10 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E ignored_languages += human_user.dna.species.secondary_langs for(var/lang_UID in absorbed_languages) - var/datum/language/lang = locateUID(lang_UID) - if(lang.name in ignored_languages) + var/datum/language/language = locateUID(lang_UID) + if(language.name in ignored_languages) continue - user.remove_language("[lang.name]") + user.remove_language(language.name) /** diff --git a/code/modules/antagonists/changeling/powers/hivemind.dm b/code/modules/antagonists/changeling/powers/hivemind.dm index 4193596a411..113716a6494 100644 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ b/code/modules/antagonists/changeling/powers/hivemind.dm @@ -35,11 +35,11 @@ GLOBAL_LIST_EMPTY(hivemind_bank) linglink.cling = cling linglink.Grant(user)*/ - if(!((GLOB.all_languages["Changeling"] in user.languages)||(GLOB.all_languages["Infiltrated changeling"] in user.languages))) + if(!((GLOB.all_languages[LANGUAGE_HIVE_CHANGELING] in user.languages)||(GLOB.all_languages[LANGUAGE_HIVE_EVENTLING] in user.languages))) if(!cling.evented) - user.add_language("Changeling") + user.add_language(LANGUAGE_HIVE_CHANGELING) else - user.add_language("Infiltrated changeling") + user.add_language(LANGUAGE_HIVE_EVENTLING) /datum/action/changeling/hivemind_pick/Remove(mob/user) @@ -52,10 +52,10 @@ GLOBAL_LIST_EMPTY(hivemind_bank) linglink.Remove(user) QDEL_NULL(linglink)*/ - if(GLOB.all_languages["Changeling"] in user.languages) - user.remove_language("Changeling") - if(GLOB.all_languages["Infiltrated changeling"] in user.languages) - user.remove_language("Infiltrated changeling") + if(GLOB.all_languages[LANGUAGE_HIVE_CHANGELING] in user.languages) + user.remove_language(LANGUAGE_HIVE_CHANGELING) + if(GLOB.all_languages[LANGUAGE_HIVE_EVENTLING] in user.languages) + user.remove_language(LANGUAGE_HIVE_EVENTLING) ..() @@ -67,10 +67,10 @@ GLOBAL_LIST_EMPTY(hivemind_bank) QDEL_NULL(linglink)*/ - if(owner && (GLOB.all_languages["Changeling"] in owner.languages)) - owner.remove_language("Changeling") - if(owner && (GLOB.all_languages["Infiltrated changeling"] in owner.languages)) - owner.remove_language("Infiltrated changeling") + if(owner && (GLOB.all_languages[LANGUAGE_HIVE_CHANGELING] in owner.languages)) + owner.remove_language(LANGUAGE_HIVE_CHANGELING) + if(owner && (GLOB.all_languages[LANGUAGE_HIVE_EVENTLING] in owner.languages)) + owner.remove_language(LANGUAGE_HIVE_EVENTLING) return ..() diff --git a/code/modules/antagonists/changeling/powers/linglink.dm b/code/modules/antagonists/changeling/powers/linglink.dm index 867600317bd..c33cfd6ffa9 100644 --- a/code/modules/antagonists/changeling/powers/linglink.dm +++ b/code/modules/antagonists/changeling/powers/linglink.dm @@ -76,11 +76,11 @@ to_chat(target, "You can now communicate in the changeling hivemind, say \":g message\" to communicate!") for(var/mob/ling in GLOB.mob_list) - if(GLOB.all_languages["Changeling"] in ling.languages) + if(GLOB.all_languages[LANGUAGE_HIVE_CHANGELING] in ling.languages) to_chat(ling, span_changeling("We can sense a foreign presence in the hivemind...")) cling?.is_linking = FALSE - target.add_language("Changeling") + target.add_language(LANGUAGE_HIVE_CHANGELING) target.say(":g AAAAARRRRGGGGGHHHHH!!") target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them @@ -95,7 +95,7 @@ if(QDELETED(target)) return - target.remove_language("Changeling") + target.remove_language(LANGUAGE_HIVE_CHANGELING) to_chat(target, span_userdanger("The link cannot be sustained any longer, your connection to the hivemind has faded!")) if(!QDELETED(user)) diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm index ebaa9518fe9..a7e2f9cf6b4 100644 --- a/code/modules/antagonists/space_dragon/carp_rift.dm +++ b/code/modules/antagonists/space_dragon/carp_rift.dm @@ -92,6 +92,13 @@ return ..() +/obj/structure/carp_rift/update_icon_state() + if(charge_state == CHARGE_COMPLETED) + icon_state = "carp_rift_charged" + return + icon_state = (carp_stored > 0) ? "carp_rift_carpspawn" : "carp_rift" + + /obj/structure/carp_rift/process(seconds_per_tick) // If we're fully charged, just start mass spawning carp. if(charge_state == CHARGE_COMPLETED) @@ -132,7 +139,7 @@ // Can we increase the carp spawn pool size? if(last_carp_inc >= carp_interval) carp_stored += 3 - icon_state = "carp_rift_carpspawn" + update_icon(UPDATE_ICON_STATE) if(light_color != LIGHT_COLOR_PURPLE) light_color = LIGHT_COLOR_PURPLE update_light() @@ -146,7 +153,7 @@ GLOB.command_announcement.Announce("Пространственный объект достиг максимального энергетического заряда в зоне [initial(A.name)]. Пожалуйста, ожидайте.", "Отдел Изучения Дикой Природы") max_integrity = INFINITY obj_integrity = INFINITY - icon_state = "carp_rift_charged" + update_icon(UPDATE_ICON_STATE) light_color = LIGHT_COLOR_YELLOW update_light() armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) @@ -210,7 +217,7 @@ to_chat(newcarp, span_boldwarning("Вы прибыли, чтобы помочь космическому дракону защищать разломы. Следуйте поставленной миссии и защитите разлом любой ценой!")) carp_stored-- if(carp_stored <= 0 && charge_state < CHARGE_COMPLETED) - icon_state = "carp_rift" + update_icon(UPDATE_ICON_STATE) light_color = LIGHT_COLOR_BLUE update_light() return TRUE diff --git a/code/modules/antagonists/space_ninja/creeping_widow/creeping_widow_martial_art.dm b/code/modules/antagonists/space_ninja/creeping_widow/creeping_widow_martial_art.dm index 9094a9f4c16..00d7a1f3c83 100644 --- a/code/modules/antagonists/space_ninja/creeping_widow/creeping_widow_martial_art.dm +++ b/code/modules/antagonists/space_ninja/creeping_widow/creeping_widow_martial_art.dm @@ -15,7 +15,12 @@ icon = 'icons/obj/ninjaobjects.dmi' icon_state = "injector" attack_verb = list("poked", "prodded") - var/used = 0 + var/used = FALSE + + +/obj/item/creeping_widow_injector/update_icon_state() + icon_state = "injector[used ? "-used" : ""]" + /obj/item/creeping_widow_injector/attack_self(mob/living/carbon/human/user as mob) if(!used) @@ -26,13 +31,13 @@ var/datum/martial_art/ninja_martial_art/N = new/datum/martial_art/ninja_martial_art(null) N.teach(user) - used = 1 - icon_state = "injector-used" + used = TRUE + update_icon(UPDATE_ICON_STATE) desc = "A strange autoinjector made of a black metal.
    It appears to be used up and empty." - return 0 - else - to_chat(user, "The [src] has been used already!") - return 1 + return FALSE + + to_chat(user, "The [src] has been used already!") + return TRUE // Ninja martial art datum diff --git a/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm b/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm index 3d56278ff8e..8f99583a893 100644 --- a/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm +++ b/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm @@ -26,7 +26,7 @@ /obj/machinery/ninja_mindscan_machine/Initialize() . = ..() - update_state_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/ninja_mindscan_machine/Destroy() if(occupant) @@ -54,7 +54,7 @@ ui_interact(user) /// Сюда вписать код ответственный за пихание оккупанта -/obj/machinery/ninja_mindscan_machine/MouseDrop_T(atom/movable/dropped as mob|obj, mob/user as mob) +/obj/machinery/ninja_mindscan_machine/MouseDrop_T(atom/movable/dropped, mob/user, params) // Только ниндзя умеет работать с этой машиной, но я всё равно оставлю проверки ниже во избежание других проблем. if(!isninja(user)) to_chat(user, span_boldwarning("ERROR!!! UNAUTORISED USER!!!")) @@ -106,6 +106,7 @@ if(!Adjacent(dropped_mob) && !Adjacent(user)) to_chat(user, span_boldnotice("You're not close enough to [src].")) return + . = TRUE if(dropped_mob != user) visible_message("[user] starts putting [dropped_mob] into the [src].") if(do_after(user, 20, target = dropped_mob)) @@ -156,7 +157,7 @@ to_chat(possible_occupant, span_notice("[on_enter_occupant_message]")) occupant = possible_occupant occupant.SetSleeping(120 SECONDS) - update_state_icon() + update_icon(UPDATE_ICON_STATE) desc = "[initial(desc)] ([occupant.name])" if(findtext("[possible_occupant.key]","@",1,2)) var/found_text = replacetext(possible_occupant.key, "@", "") @@ -172,7 +173,7 @@ return occupant.forceMove(get_turf(src)) occupant = null - update_state_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/ninja_mindscan_machine/force_eject_occupant(mob/target) go_out() @@ -190,9 +191,9 @@ new /obj/effect/temp_visual/dir_setting/ninja/phase(teleport_loc, effect_dir) new /obj/item/radio/headset(teleport_loc) //Если парня запрёт в техах, без средства связи... будет не круто, не так ли? to_chat(ninja, "[span_boldnotice("VOID-Shift")] occupant translocation successful") - update_state_icon() + update_icon(UPDATE_ICON_STATE) -/obj/machinery/ninja_mindscan_machine/proc/update_state_icon() +/obj/machinery/ninja_mindscan_machine/update_icon_state() icon_state = occupant ? initial(icon_state) : "[initial(icon_state)]_open" /obj/machinery/ninja_mindscan_machine/proc/get_occupant_icon() diff --git a/code/modules/antagonists/space_ninja/machinery/ninja_teleporter.dm b/code/modules/antagonists/space_ninja/machinery/ninja_teleporter.dm index 17374d85054..3d6749e53fd 100644 --- a/code/modules/antagonists/space_ninja/machinery/ninja_teleporter.dm +++ b/code/modules/antagonists/space_ninja/machinery/ninja_teleporter.dm @@ -4,7 +4,7 @@ desc = "A console used to send a Spider Clan operative long distances rapidly." icon = 'icons/obj/ninjaobjects.dmi' icon_state = "teleconsole" - anchored = 1 + anchored = TRUE density = 0 /obj/structure/ninjatele/attack_hand(mob/user as mob) diff --git a/code/modules/antagonists/space_ninja/ninja_borg_module.dm b/code/modules/antagonists/space_ninja/ninja_borg_module.dm index d3fb2a1ea51..57b5319b055 100644 --- a/code/modules/antagonists/space_ninja/ninja_borg_module.dm +++ b/code/modules/antagonists/space_ninja/ninja_borg_module.dm @@ -26,7 +26,6 @@ /mob/living/silicon/robot/syndicate/saboteur/ninja/New(loc) ..() mmi = new /obj/item/mmi/robotic_brain/ninja(src) - mmi.icon_state = "wanter" /mob/living/silicon/robot/syndicate/saboteur/ninja/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null) . = ..() diff --git a/code/modules/antagonists/space_ninja/ninja_datum.dm b/code/modules/antagonists/space_ninja/ninja_datum.dm index 404504579dc..5d1a77c26b4 100644 --- a/code/modules/antagonists/space_ninja/ninja_datum.dm +++ b/code/modules/antagonists/space_ninja/ninja_datum.dm @@ -222,7 +222,7 @@ var/warning = cell.charge >= check_percentage ? "" : "_warning" hud.ninja_energy_display.icon_state = "ninja_energy_display_[my_suit.color_choice][warning]" hud.ninja_energy_display.maptext = "
    [round(cell.charge)]
    " - hud.ninja_energy_display.invisibility = my_suit.show_charge_UI ? 0 : 100 + hud.ninja_energy_display.invisibility = my_suit.show_charge_UI ? 0 : INVISIBILITY_ABSTRACT // concentration level if(!hud.ninja_focus_display && owner.martial_art && istype(owner.martial_art, /datum/martial_art/ninja_martial_art)) @@ -237,7 +237,7 @@ // martial art update if(creeping_widow && my_suit) hud.ninja_focus_display.icon_state = creeping_widow.has_focus ? "focus_active_[my_suit.color_choice]" : "focus" - hud.ninja_focus_display.invisibility = my_suit.show_concentration_UI ? 0 : 100 + hud.ninja_focus_display.invisibility = my_suit.show_concentration_UI ? 0 : INVISIBILITY_ABSTRACT /** diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm b/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm index 1d7f33f564f..8008622910c 100644 --- a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm +++ b/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm @@ -11,38 +11,41 @@ /// The minimum range for the pinpointer to function properly. var/min_range = 15 /// The first person to have used the item. If this is set already, no one else can use it. - var/mob/owner = null - -/obj/item/pinpointer/crew/contractor/pinpoint_at(atom/target) - if(target && trackable(target)) - // Calc dir - var/turf/T = get_turf(target) - var/turf/L = get_turf(src) - dir = get_dir(L, T) - // Calc dist - var/dist = get_dist(L, T) - if(ISINRANGE(dist, -1, min_range)) - icon_state = icon_direct - else if(ISINRANGE(dist, min_range + 1, min_range + 8)) - icon_state = icon_close - else if(ISINRANGE(dist, min_range + 9, min_range + 16)) - icon_state = icon_medium - else if(ISINRANGE(dist, min_range + 16, INFINITY)) - icon_state = icon_far - else + var/mob/owner + + +/obj/item/pinpointer/crew/contractor/update_icon_state() + if(mode == 0) // MODE_OFF + icon_state = icon_off + return + + if(!target) icon_state = icon_null + return -/obj/item/pinpointer/crew/contractor/trackable(mob/living/carbon/human/H) - var/turf/here = get_turf(src) - var/turf/there = get_turf(H) - return here && there && there.z == here.z + if(ISINRANGE(prev_dist, -1, min_range)) + icon_state = icon_direct + else if(ISINRANGE(prev_dist, min_range + 1, min_range + 8)) + icon_state = icon_close + else if(ISINRANGE(prev_dist, min_range + 9, min_range + 16)) + icon_state = icon_medium + else if(ISINRANGE(prev_dist, min_range + 16, INFINITY)) + icon_state = icon_far -/obj/item/pinpointer/crew/contractor/attack_self(mob/living/user) + +/obj/item/pinpointer/crew/contractor/is_trackable(mob/living/carbon/human/pin_target) + source_turf = get_turf(src) + target_turf = get_turf(pin_target) + return source_turf && target_turf && source_turf.z == target_turf.z + + +/obj/item/pinpointer/crew/contractor/cycle(mob/user, silent = FALSE) if(owner) if(owner != user) - to_chat(user, "[src] refuses to do anything.") + to_chat(user, span_warning("[src] refuses to do anything.")) return else owner = user - to_chat(user, "[src] now recognizes you as its sole user.") + to_chat(user, span_notice("[src] now recognizes you as its sole user.")) return ..() + diff --git a/code/modules/antagonists/vampire/vampire_datum.dm b/code/modules/antagonists/vampire/vampire_datum.dm index 0688594de5f..13cef1a53a1 100644 --- a/code/modules/antagonists/vampire/vampire_datum.dm +++ b/code/modules/antagonists/vampire/vampire_datum.dm @@ -180,9 +180,11 @@ #define BLOOD_GAINED_MODIFIER 0.5 + #define CLOSING_IN_TIME_MOD 0.2 #define GRABBING_TIME_MOD 0.3 #define BITE_TIME_MOD 0.15 + #define STATE_CLOSING_IN 1 #define STATE_GRABBING 2 #define STATE_BITE 3 @@ -291,7 +293,7 @@ else owner.current.set_nutrition(min(NUTRITION_LEVEL_WELL_FED, owner.current.nutrition + (blood / 2))) - stop_sucking(target) + stop_sucking() /datum/antagonist/vampire/proc/getting_closer_animation(mob/living/carbon/human/target, stage, vampire_dir) @@ -338,12 +340,13 @@ owner.current.do_item_attack_animation(target, ATTACK_EFFECT_BITE) -/datum/antagonist/vampire/proc/stop_sucking(mob/living/carbon/human/target) - draining = null - to_chat(owner.current, span_notice("You stop draining [target.name] of blood.")) - owner.current.pixel_x = 0 - owner.current.pixel_y = 0 - owner.current.layer = initial(owner.current.layer) +/datum/antagonist/vampire/proc/stop_sucking() + if(draining) + to_chat(owner.current, span_notice("You stop draining [draining.name] of blood.")) + draining = null + owner.current.pixel_x = 0 + owner.current.pixel_y = 0 + owner.current.layer = initial(owner.current.layer) #undef BLOOD_GAINED_MODIFIER #undef CLOSING_IN_TIME_MOD diff --git a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm index 5b5c5d1f8ea..c9ada5c6435 100644 --- a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm @@ -839,18 +839,6 @@ to_chat(user, span_notice("You pinch arteries on fly and absorb [blood_gained] amount of blood!")) -/obj/effect/proc_holder/spell/vampire/proc/is_path_exist(atom/source, atom/target) - var/obj/dummy = new(source.loc) - dummy.pass_flags |= (PASSTABLE|PASSGRILLE|PASSFENCE|PASSMOB) - for(var/turf/turf in getline(source, target)) - for(var/atom/movable/AM in turf) - if(!AM.CanPass(dummy, turf, 1)) - qdel(dummy) - return FALSE - qdel(dummy) - return TRUE - - /obj/effect/proc_holder/spell/vampire/lunge/on_trophie_update(datum/antagonist/vampire/vampire, trophie_type, force = FALSE) if(trophie_type == INTERNAL_ORGAN_LUNGS || force) var/lungs_amount = vampire.get_trophies(INTERNAL_ORGAN_LUNGS) @@ -1015,6 +1003,7 @@ span_notice("You start to transform into the [vampire_animal]."), \ span_italics("You hear an eerie rustle of many wings...")) + vampire.stop_sucking() original_body = user vampire_animal.status_flags |= GODMODE user.notransform = TRUE diff --git a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm index 1facb14919b..b592f2d3a70 100644 --- a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm @@ -150,7 +150,7 @@ update_vampire_spell_name() -/obj/effect/proc_holder/spell/fireball/demonic_grasp/update_icon() +/obj/effect/proc_holder/spell/fireball/demonic_grasp/update_icon_state() return diff --git a/code/modules/arcade/arcade_base.dm b/code/modules/arcade/arcade_base.dm index 2ecf5ecfd5b..3e65692d86b 100644 --- a/code/modules/arcade/arcade_base.dm +++ b/code/modules/arcade/arcade_base.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/machines/arcade.dmi' icon_state = "clawmachine_on" density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 40 var/tokens = 0 @@ -35,7 +35,7 @@ else . += "\The [src.name] has [tokens] play credits!" -/obj/machinery/arcade/attack_hand(mob/user as mob) +/obj/machinery/arcade/attack_hand(mob/user) if(..()) if(in_use && src == user.machine) //this one checks if they fell down/died and closes the game src.close_game() @@ -44,7 +44,7 @@ return interact(user) -/obj/machinery/arcade/interact(mob/user as mob) +/obj/machinery/arcade/interact(mob/user) if(stat & BROKEN || panel_open) return if(!tokens && !freeplay) @@ -60,12 +60,6 @@ return /obj/machinery/arcade/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver) && anchored) - playsound(src.loc, I.usesound, 50, 1) - panel_open = !panel_open - to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") - update_icon() - return if(!freeplay) if(I.GetID()) if(pay_with_card(user, token_price, name)) @@ -76,15 +70,25 @@ if(pay_with_cash(cash, user, token_price, name)) tokens += 1 return - if(panel_open && component_parts && istype(I, /obj/item/crowbar)) - default_deconstruction_crowbar(user, I) - return return ..() -/obj/machinery/arcade/update_icon() - return -/obj/machinery/arcade/proc/start_play(mob/user as mob) +/obj/machinery/arcade/screwdriver_act(mob/living/user, obj/item/I) + if(!anchored) + return FALSE + default_deconstruction_screwdriver(user, icon_state, icon_state, I) + update_icon(UPDATE_ICON_STATE) + return TRUE + + +/obj/machinery/arcade/crowbar_act(mob/living/user, obj/item/I) + if(!component_parts || !panel_open) + return FALSE + default_deconstruction_crowbar(user, I) + return TRUE + + +/obj/machinery/arcade/proc/start_play(mob/user) user.set_machine(src) if(!freeplay) tokens -= 1 diff --git a/code/modules/arcade/arcade_prize.dm b/code/modules/arcade/arcade_prize.dm index fa669d5212b..0c84662dc14 100644 --- a/code/modules/arcade/arcade_prize.dm +++ b/code/modules/arcade/arcade_prize.dm @@ -7,20 +7,27 @@ desc = "A toy is a toy, but a prize ball could be anything! It could even be a toy!" icon = 'icons/obj/machines/arcade.dmi' icon_state = "prizeball_1" - var/opening = 0 + var/choose_icon_state + var/opening = FALSE var/possible_contents = list(/obj/random/carp_plushie, /obj/random/plushie, /obj/random/figure, /obj/item/toy/eight_ball, /obj/item/stack/tickets) -/obj/item/toy/prizeball/New() - ..() - icon_state = pick("prizeball_1","prizeball_2","prizeball_3") +/obj/item/toy/prizeball/Initialize(mapload) + . = ..() + choose_icon_state = pick("prizeball_1","prizeball_2","prizeball_3") + update_icon(UPDATE_ICON_STATE) -/obj/item/toy/prizeball/attack_self(mob/user as mob) + +/obj/item/toy/prizeball/update_icon_state() + icon_state = opening ? "prizeconfetti" : choose_icon_state + + +/obj/item/toy/prizeball/attack_self(mob/user) if(opening) return - opening = 1 + opening = TRUE + update_icon(UPDATE_ICON_STATE) playsound(loc, 'sound/items/bubblewrap.ogg', 30, TRUE) - icon_state = "prizeconfetti" - src.color = pick(GLOB.random_color_list) + color = pick(GLOB.random_color_list) var/prize_inside = pick(possible_contents) spawn(10) user.temporarily_remove_item_from_inventory(src) @@ -72,14 +79,10 @@ /obj/item/stack/tickets/five amount = 5 -/obj/item/stack/tickets/New(var/loc, var/amount=null) - ..() - update_icon() - -/obj/item/stack/tickets/attack_self(mob/user as mob) +/obj/item/stack/tickets/attack_self(mob/user) return -/obj/item/stack/tickets/update_icon() +/obj/item/stack/tickets/update_icon_state() switch(get_amount()) if(1 to 3) icon_state = "tickets_1" // One ticket diff --git a/code/modules/arcade/claw_game.dm b/code/modules/arcade/claw_game.dm index 6cbc35c4ebc..60117788f6c 100644 --- a/code/modules/arcade/claw_game.dm +++ b/code/modules/arcade/claw_game.dm @@ -20,7 +20,7 @@ GLOBAL_VAR(claw_game_html) /obj/machinery/arcade/claw/New() ..() machine_image = pick("_1", "_2") - update_icon() + update_icon(UPDATE_ICON_STATE) component_parts = list() component_parts += new /obj/item/circuitboard/clawgame(null) @@ -39,7 +39,7 @@ GLOBAL_VAR(claw_game_html) bin_upgrades = B.rating bonus_prize_chance = bin_upgrades * 5 //equals +5% chance per matter bin rating level (+20% with rating 4) -/obj/machinery/arcade/claw/update_icon() +/obj/machinery/arcade/claw/update_icon_state() if(stat & BROKEN) icon_state = "clawmachine[machine_image]_broken" else if(panel_open) @@ -58,7 +58,7 @@ GLOBAL_VAR(claw_game_html) atom_say("ПОБЕДИТЕЛЬ!") new /obj/item/toy/prizeball(get_turf(src)) playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 10) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_ICON_STATE), 1 SECONDS) /obj/machinery/arcade/claw/start_play(mob/user as mob) ..() diff --git a/code/modules/arcade/mob_hunt/battle_computer.dm b/code/modules/arcade/mob_hunt/battle_computer.dm index 32c0cb292af..c88cb9b91d4 100644 --- a/code/modules/arcade/mob_hunt/battle_computer.dm +++ b/code/modules/arcade/mob_hunt/battle_computer.dm @@ -6,7 +6,7 @@ icon_screen = null icon_keyboard = null density = 0 - anchored = 1 + anchored = TRUE var/obj/item/nanomob_card/card var/datum/mob_hunt/mob_info var/obj/effect/landmark/battle_mob_point/avatar_point @@ -32,12 +32,14 @@ ..() check_connection() -/obj/machinery/computer/mob_battle_terminal/update_icon() - if(card) - icon_state = "mob_battle_loaded" - else - icon_state = "mob_battle_empty" - ..() + +/obj/machinery/computer/mob_battle_terminal/update_icon_state() + icon_state = "mob_battle_[card ? "loaded" : "empty"]" + + +/obj/machinery/computer/mob_battle_terminal/update_overlays() + . = list() + /obj/machinery/computer/mob_battle_terminal/Destroy() eject_card(1) @@ -286,7 +288,7 @@ icon_screen = null icon_keyboard = null density = 0 - anchored = 1 + anchored = TRUE dir = EAST /obj/machinery/computer/mob_healer_terminal/attackby(obj/item/O, mob/user) diff --git a/code/modules/arcade/mob_hunt/mob_avatar.dm b/code/modules/arcade/mob_hunt/mob_avatar.dm index eafd03beff9..283f137905b 100644 --- a/code/modules/arcade/mob_hunt/mob_avatar.dm +++ b/code/modules/arcade/mob_hunt/mob_avatar.dm @@ -4,7 +4,7 @@ desc = "A wild Nano-Mob appeared! Hit it with your PDA with the game open to attempt to capture it!" invisibility = INVISIBILITY_ABSTRACT alpha = 128 - anchored = 1 //just in case + anchored = TRUE //just in case density = 0 icon = 'icons/effects/mob_hunt.dmi' var/state_name diff --git a/code/modules/arcade/prize_counter.dm b/code/modules/arcade/prize_counter.dm index fa75b35bded..5093bc2cedb 100644 --- a/code/modules/arcade/prize_counter.dm +++ b/code/modules/arcade/prize_counter.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/machines/arcade.dmi' icon_state = "prize_counter-on" density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 40 var/tickets = 0 @@ -20,7 +20,8 @@ component_parts += new /obj/item/stack/sheet/glass(null) RefreshParts() -/obj/machinery/prize_counter/update_icon() + +/obj/machinery/prize_counter/update_icon_state() if(stat & BROKEN) icon_state = "prize_counter-broken" else if(panel_open) @@ -29,9 +30,9 @@ icon_state = "prize_counter-off" else icon_state = "prize_counter-on" - return -/obj/machinery/prize_counter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + +/obj/machinery/prize_counter/attackby(obj/item/O, var/mob/user, params) if(istype(O, /obj/item/stack/tickets)) var/obj/item/stack/tickets/T = O if(user.temporarily_remove_item_from_inventory(T)) //Because if you can't drop it for some reason, you shouldn't be increasing the tickets var @@ -40,29 +41,37 @@ else to_chat(user, "\The [T] seems stuck to your hand!") return - if(istype(O, /obj/item/screwdriver) && anchored) - playsound(src.loc, O.usesound, 50, 1) - panel_open = !panel_open - to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") - update_icon() - return if(panel_open) - if(istype(O, /obj/item/wrench)) - default_unfasten_wrench(user, O) - if(component_parts && istype(O, /obj/item/crowbar)) + if(component_parts && O.tool_behaviour == TOOL_CROWBAR) if(tickets) //save the tickets! print_tickets() default_deconstruction_crowbar(user, O) return return ..() -/obj/machinery/prize_counter/attack_hand(mob/user as mob) + +/obj/machinery/prize_counter/screwdriver_act(mob/living/user, obj/item/I) + if(!anchored) + return FALSE + default_deconstruction_screwdriver(user, icon_state, icon_state, I) + update_icon(UPDATE_ICON_STATE) + return TRUE + + +/obj/machinery/snow_machine/wrench_act(mob/user, obj/item/I) + . = TRUE + if(!panel_open) + return . + default_unfasten_wrench(user, I) + + +/obj/machinery/prize_counter/attack_hand(mob/user) if(..()) return add_fingerprint(user) interact(user) -/obj/machinery/prize_counter/interact(mob/user as mob) +/obj/machinery/prize_counter/interact(mob/user) user.set_machine(src) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index e1fa3b31a54..40733745909 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -1,8 +1,8 @@ -#define WIRE_RECEIVE (1<<0) //Allows pulse(0) to call Activate() -#define WIRE_PULSE (1<<1) //Allows pulse(0) to act on the holder -#define WIRE_PULSE_SPECIAL (1<<2) //Allows pulse(0) to act on the holders special assembly -#define WIRE_RADIO_RECEIVE (1<<3) //Allows pulse(1) to call Activate() -#define WIRE_RADIO_PULSE (1<<4) //Allows pulse(1) to send a radio message +#define WIRE_RECEIVE (1<<0) //Allows pulse(FALSE) to call Activate() +#define WIRE_PULSE (1<<1) //Allows pulse(FALSE) to act on the holder +#define WIRE_PULSE_SPECIAL (1<<2) //Allows pulse(FALSE) to act on the holders special assembly +#define WIRE_RADIO_RECEIVE (1<<3) //Allows pulse(TRUE) to call Activate() +#define WIRE_RADIO_PULSE (1<<4) //Allows pulse(TRUE) to send a radio message /obj/item/assembly name = "assembly" @@ -30,54 +30,45 @@ var/wires = WIRE_RECEIVE | WIRE_PULSE var/datum/wires/connected = null // currently only used by timer/signaler -/obj/item/assembly/proc/activate() //What the device does when turned on - return -/obj/item/assembly/proc/pulsed(radio = FALSE) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs - return +/obj/item/assembly/Destroy() + if(istype(loc, /obj/item/assembly_holder) || istype(holder)) + var/obj/item/assembly_holder/A = loc + if(A.a_left == src) + A.a_left = null + else if(A.a_right == src) + A.a_right = null + holder = null + return ..() -/obj/item/assembly/proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here - return -/obj/item/assembly/proc/attach_assembly(obj/A, mob/user) //Called when an assembly is attacked by another +/// Called when the holder is moved +/obj/item/assembly/proc/holder_movement(mob/user) return -/obj/item/assembly/proc/process_cooldown() //Called via spawn(10) to have it count down the cooldown var - return -/obj/item/assembly/proc/holder_movement(mob/user) //Called when the holder is moved +/// Called when attack_self is called +/obj/item/assembly/interact(mob/user) return -/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc) - return "The trigger assembly looks broken!" -/obj/item/assembly/interact(mob/user) //Called when attack_self is called - return - -/obj/item/assembly/process_cooldown() - cooldown-- - if(cooldown <= 0) +/// Called via 1 SECONDS to have it count down the cooldown var +/obj/item/assembly/proc/process_cooldown() + if(cooldown-- <= 0) return FALSE - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) + addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 1 SECONDS) return TRUE -/obj/item/assembly/Destroy() - if(istype(loc, /obj/item/assembly_holder) || istype(holder)) - var/obj/item/assembly_holder/A = loc - if(A.a_left == src) - A.a_left = null - else if(A.a_right == src) - A.a_right = null - holder = null - return ..() -/obj/item/assembly/pulsed(radio = FALSE) +/// Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs +/obj/item/assembly/proc/pulsed(radio = FALSE) if(holder && (wires & WIRE_RECEIVE)) activate() if(radio && (wires & WIRE_RADIO_RECEIVE)) activate() return TRUE + /* Called when this device attempts to act on another device, * var/radio determines if it was sent via radio or direct * var/mob/user for logging @@ -87,61 +78,72 @@ connected.pulse_assembly(src) return TRUE if(holder && (wires & WIRE_PULSE)) - holder.process_activation(src, 1, 0, user) + holder.process_activation(src, TRUE, FALSE, user) if(holder && (wires & WIRE_PULSE_SPECIAL)) - holder.process_activation(src, 0, 1, user) + holder.process_activation(src, FALSE, TRUE, user) if(istype(loc, /obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu var/obj/item/grenade/G = loc G.prime(user) // Adios, muchachos return TRUE -/obj/item/assembly/activate() + +/// What the device does when turned on +/obj/item/assembly/proc/activate() if(!secured || cooldown > 0) return FALSE cooldown = 2 addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) return TRUE -/obj/item/assembly/toggle_secure() + +/// Code that has to happen when the assembly is un\secured goes here +/obj/item/assembly/proc/toggle_secure() secured = !secured update_icon() return secured -/obj/item/assembly/attach_assembly(obj/item/assembly/A, mob/user) - holder = new /obj/item/assembly_holder(get_turf(src)) - if(holder.attach(A, src, user)) - to_chat(user, "You attach [A] to [src]!") + +/// Called when an assembly is attacked by another +/obj/item/assembly/proc/attach_assembly(obj/item/assembly/assembly, mob/user) + holder = new /obj/item/assembly_holder(drop_location()) + user?.put_in_hands(holder, ignore_anim = FALSE) + if(holder.attach(assembly, src, user)) + to_chat(user, span_notice("You attach [assembly] to [src]!")) return TRUE return FALSE + /obj/item/assembly/attackby(obj/item/W, mob/user, params) if(isassembly(W)) var/obj/item/assembly/A = W if(!A.secured && !secured) attach_assembly(A, user) return - return ..() + /obj/item/assembly/screwdriver_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return if(toggle_secure()) - to_chat(user, "[src] is ready!") + to_chat(user, span_notice("[src] is ready!")) else - to_chat(user, "[src] can now be attached!") + to_chat(user, span_notice("[src] can now be attached!")) + /obj/item/assembly/process() - STOP_PROCESSING(SSobj, src) + return PROCESS_KILL + /obj/item/assembly/examine(mob/user) . = ..() - if(in_range(src, user) || loc == user) + if(in_range(src, user)) if(secured) - . += "[src] is ready!" + . += span_notice("[src] need to be secured!") else - . += "[src] can be attached!" + . += span_notice("[src] can be attached!") + /obj/item/assembly/attack_self(mob/user) if(!user) @@ -150,5 +152,3 @@ interact(user) return TRUE -/obj/item/assembly/interact(mob/user) - return diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 9189df8560f..60efca14515 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -12,21 +12,29 @@ var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank origin_tech = "materials=1;engineering=1" + /obj/item/onetankbomb/ComponentInitialize() . = ..() AddComponent(/datum/component/proximity_monitor) + /obj/item/onetankbomb/examine(mob/user) . = ..() . += bombtank.examine(user) -/obj/item/onetankbomb/update_icon() + +/obj/item/onetankbomb/update_icon_state() if(bombtank) icon_state = bombtank.icon_state + + +/obj/item/onetankbomb/update_overlays() + . = ..() if(bombassembly) - overlays += bombassembly.icon_state - overlays += bombassembly.overlays - overlays += "bomb_assembly" + . += bombassembly.icon_state + . += bombassembly.overlays + . += "bomb_assembly" + /obj/item/onetankbomb/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/analyzer)) @@ -34,13 +42,14 @@ return return ..() + /obj/item/onetankbomb/wrench_act(mob/user, obj/item/I) //This is basically bomb assembly code inverted. apparently it works. if(status) return . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return - to_chat(user, "You disassemble [src].") + to_chat(user, span_notice("You disassemble [src].")) bombassembly.loc = user.loc bombassembly.master = null bombassembly = null @@ -49,6 +58,7 @@ bombtank = null qdel(src) + /obj/item/onetankbomb/welder_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, volume = I.tool_volume)) @@ -56,6 +66,7 @@ if(!status) status = TRUE investigate_log("[key_name_log(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) + log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]") to_chat(user, "A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.") add_attack_logs(user, src, "welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW) else @@ -70,9 +81,10 @@ 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. visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") - sleep(10) + sleep(1 SECONDS) if(!src) return if(status) @@ -80,26 +92,32 @@ else bombtank.release() + /obj/item/onetankbomb/HasProximity(atom/movable/AM) if(bombassembly) bombassembly.HasProximity(AM) + /obj/item/onetankbomb/Crossed(atom/movable/AM, oldloc) //for mousetraps if(bombassembly) bombassembly.Crossed(AM, oldloc) + /obj/item/onetankbomb/on_found(mob/finder) //for mousetraps if(bombassembly) bombassembly.on_found(finder) + /obj/item/onetankbomb/hear_talk(mob/living/M, list/message_pieces) if(bombassembly) bombassembly.hear_talk(M, message_pieces) + /obj/item/onetankbomb/hear_message(mob/living/M, msg) if(bombassembly) bombassembly.hear_message(M, msg) + // ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- /obj/item/tank/proc/bomb_assemble(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb @@ -126,6 +144,7 @@ R.update_icon() return + /obj/item/tank/proc/detonate() //This happens when a bomb is told to explode var/fuel_moles = air_contents.toxins + air_contents.oxygen/6 var/strength = 1 @@ -175,6 +194,7 @@ qdel(master) qdel(src) + /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/simulated/T = get_turf(src) @@ -182,3 +202,4 @@ return T.assume_air(removed) air_update_turf() + diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 0372ed7d2e6..641e559ae7c 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -1,3 +1,6 @@ +#define MAX_HEALTH_ACTIVATE 0 +#define MIN_HEALTH_ACTIVATE -90 + /obj/item/assembly/health name = "health sensor" desc = "Used for scanning and monitoring health." @@ -6,10 +9,12 @@ origin_tech = "magnets=1;biotech=1" secured = FALSE + /// Are we scanning our user's health? var/scanning = FALSE - var/health_scan - var/alarm_health = 0 - + /// Our user's health + var/user_health + /// The health amount on which to activate + var/alarm_health = MAX_HEALTH_ACTIVATE /obj/item/assembly/health/activate() @@ -18,47 +23,51 @@ toggle_scan() return FALSE + /obj/item/assembly/health/toggle_secure() secured = !secured if(secured && scanning) START_PROCESSING(SSobj, src) else scanning = FALSE + user_health = null // Clear out the user data, we're no longer scanning STOP_PROCESSING(SSobj, src) update_icon() return secured + /obj/item/assembly/health/multitool_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return - if(alarm_health == 0) - alarm_health = -90 + if(alarm_health == MAX_HEALTH_ACTIVATE) + alarm_health = MIN_HEALTH_ACTIVATE user.show_message("You toggle [src] to \"detect death\" mode.") else - alarm_health = 0 + alarm_health = MAX_HEALTH_ACTIVATE user.show_message("You toggle [src] to \"detect critical state\" mode.") + /obj/item/assembly/health/process() if(!scanning || !secured) + STOP_PROCESSING(SSobj, src) // It should never reach here, but if it somehow does stop processing return - var/atom/A = src - if(connected && connected.holder) - A = connected.holder - - for(A, A && !ismob(A), A=A.loc); - // like get_turf(), but for mobs. - var/mob/living/M = A + var/atom/our_source = src + if(connected?.holder) + our_source = connected.holder - if(M) - health_scan = M.health - if(health_scan <= alarm_health) - pulse(FALSE, M) - audible_message("[bicon(src)] *beep* *beep*") - toggle_scan() + if(!get(our_source, /mob/living)) + user_health = null // We aint on a living thing, remove the previous data return - return + + var/mob/living/user = our_source + user_health = user.health + if(user_health <= alarm_health) // Its a health detector, not a death detector + pulse(FALSE, user) + audible_message("[bicon(src)] *beep* *beep*") + toggle_scan() + /obj/item/assembly/health/proc/toggle_scan() if(!secured) @@ -67,40 +76,44 @@ if(scanning) START_PROCESSING(SSobj, src) else + user_health = null // Clear out the user data, we're no longer scanning STOP_PROCESSING(SSobj, src) - return + /obj/item/assembly/health/interact(mob/user)//TODO: Change this to the wires thingy if(!secured) - user.show_message("The [name] is unsecured!") + user.show_message(span_warning("The [name] is unsecured!")) return FALSE var/dat = text({"Health Sensor [scanning?"On":"Off"]"}) - if(scanning && health_scan) - dat += "
    Health: [health_scan]" + if(scanning && user_health) + dat += "
    Health: [user_health]" var/datum/browser/popup = new(user, "hscan", name, 400, 400, src) popup.set_content(dat) popup.open() - return /obj/item/assembly/health/Topic(href, href_list) ..() - if(!ismob(usr)) + if(!isliving(usr)) return - var/mob/user = usr + var/mob/living/user = usr - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=hscan") - onclose(usr, "hscan") + if(user.incapacitated() || user.restrained() || !in_range(loc, user)) + user << browse(null, "window=hscan") + onclose(user, "hscan") return if(href_list["scanning"]) toggle_scan() if(href_list["close"]) - usr << browse(null, "window=hscan") + user << browse(null, "window=hscan") return attack_self(user) - return + + +#undef MAX_HEALTH_ACTIVATE +#undef MIN_HEALTH_ACTIVATE + diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 7a27cf88768..1c48989a0a5 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -13,11 +13,6 @@ var/obj/item/assembly/a_left = null var/obj/item/assembly/a_right = null -/obj/item/assembly_holder/proc/attach(obj/item/D, obj/item/D2, mob/user) - return - -/obj/item/assembly_holder/proc/process_activation(var/obj/item/D) - return /obj/item/assembly_holder/Destroy() if(a_left) @@ -26,7 +21,8 @@ a_right.holder = null return ..() -/obj/item/assembly_holder/attach(obj/item/D, obj/item/D2, mob/user) + +/obj/item/assembly_holder/proc/attach(obj/item/D, obj/item/D2, mob/user) if(!D || !D2) return FALSE if(!isassembly(D) || !isassembly(D2)) @@ -50,35 +46,52 @@ if(has_prox_sensors()) AddComponent(/datum/component/proximity_monitor) name = "[A1.name]-[A2.name] assembly" - update_icon() + update_icon(UPDATE_OVERLAYS) return TRUE + /obj/item/assembly_holder/proc/has_prox_sensors() if(istype(a_left, /obj/item/assembly/prox_sensor) || istype(a_right, /obj/item/assembly/prox_sensor)) return TRUE return FALSE -/obj/item/assembly_holder/update_icon() - overlays.Cut() + +/obj/item/assembly_holder/proc/process_activation(obj/D, normal = TRUE, special = TRUE, mob/user) + if(!D) + return FALSE + if(normal && a_right && a_left) + if(a_right != D) + a_right.pulsed() + if(a_left != D) + a_left.pulsed() + if(master) + var/datum/signal/signal = new + signal.source = src + signal.user = user + master.receive_signal(signal) + return TRUE + + +/obj/item/assembly_holder/update_overlays() + . = ..() if(a_left) - overlays += "[a_left.icon_state]_left" + . += "[a_left.icon_state]_left" for(var/O in a_left.attached_overlays) - overlays += "[O]_l" + . += "[O]_l" if(a_right) - overlays += "[a_right.icon_state]_right" + . += "[a_right.icon_state]_right" for(var/O in a_right.attached_overlays) - overlays += "[O]_r" - if(master) - master.update_icon() + . += "[O]_r" + master?.update_icon() /obj/item/assembly_holder/examine(mob/user) . = ..() - if(in_range(src, user) || loc == user) + if(in_range(src, user)) if(secured) - . += "[src] is ready!" + . += span_notice("[src] can be attached!") else - . += "[src] can be attached!" + . += span_notice("[src] need to be secured!") /obj/item/assembly_holder/HasProximity(atom/movable/AM) @@ -94,6 +107,7 @@ if(a_right) a_right.Crossed(AM, oldloc) + /obj/item/assembly_holder/on_found(mob/finder) if(a_left) a_left.on_found(finder) @@ -107,26 +121,31 @@ if(a_right) a_right.hear_talk(M, message_pieces) + /obj/item/assembly_holder/hear_message(mob/living/M, msg) if(a_left) a_left.hear_message(M, msg) if(a_right) a_right.hear_message(M, msg) + /obj/item/assembly_holder/proc/process_movement(mob/user) // infrared beams and prox sensors if(a_left && a_right) a_left.holder_movement(user) a_right.holder_movement(user) + /obj/item/assembly_holder/Move() . = ..() process_movement() return + /obj/item/assembly_holder/pickup(mob/user) . = ..() process_movement(user) + /obj/item/assembly_holder/Bump(atom/A) ..() var/triggered @@ -138,6 +157,7 @@ triggered = AM process_movement(triggered) + /obj/item/assembly_holder/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) // called when a throw stops ..() var/triggered @@ -145,16 +165,17 @@ triggered = throwing.thrower process_movement(triggered) + /obj/item/assembly_holder/attack_hand(mob/user)//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess if(a_left && a_right) a_left.holder_movement(user) a_right.holder_movement(user) ..() - return + /obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/I) if(!a_left || !a_right) - to_chat(user, "BUG:Assembly part missing, please report this!") + to_chat(user, span_warning("BUG:Assembly part missing, please report this!")) return . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -163,16 +184,17 @@ a_right.toggle_secure() secured = !secured if(secured) - to_chat(user, "[src] is ready!") + to_chat(user, span_notice("[src] can now be attached!")) else - to_chat(user, "[src] can now be taken apart!") + to_chat(user, span_notice("[src] can now be taken apart!")) update_icon() + /obj/item/assembly_holder/attack_self(mob/user) add_fingerprint(user) if(secured) if(!a_left || !a_right) - to_chat(user, "Assembly part missing!") + to_chat(user, span_warning("Assembly part missing!")) return if(istype(a_left, a_right.type))//If they are the same type it causes issues due to window code switch(alert("Which side would you like to use?",,"Left","Right")) @@ -190,24 +212,11 @@ return FALSE if(a_left) a_left.holder = null - a_left.loc = T + a_left.forceMove(T) + user.put_in_hands(a_left, ignore_anim = FALSE) if(a_right) a_right.holder = null - a_right.loc = T + a_right.forceMove(T) + user.put_in_hands(a_left, ignore_anim = FALSE) qdel(src) - -/obj/item/assembly_holder/process_activation(obj/D, normal = TRUE, special = TRUE, mob/user) - if(!D) - return FALSE - if(normal && a_right && a_left) - if(a_right != D) - a_right.pulsed(0) - if(a_left != D) - a_left.pulsed(0) - if(master) - var/datum/signal/signal = new - signal.source = src - signal.user = user - master.receive_signal(signal) - return TRUE diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index b81acbbe2b0..0389339efb7 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -4,42 +4,62 @@ icon_state = "igniter" materials = list(MAT_METAL=500, MAT_GLASS=50) origin_tech = "magnets=1" - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect_system/spark_spread/sparks -/obj/item/assembly/igniter/New() - ..() - sparks.set_up(2, 0, src) + +/obj/item/assembly/igniter/Initialize(mapload) + . = ..() + sparks = new /datum/effect_system/spark_spread + sparks.set_up(2, FALSE, src) sparks.attach(src) + /obj/item/assembly/igniter/Destroy() QDEL_NULL(sparks) return ..() -/obj/item/assembly/igniter/describe() - return "The igniter is [secured ? "secured." : "unsecured."]" +/obj/item/assembly/igniter/examine(mob/user) + . = ..() + . += span_notice("The igniter is [secured ? "secured." : "unsecured."]") /obj/item/assembly/igniter/activate() if(!..()) - return FALSE//Cooldown check + return FALSE //Cooldown check + var/turf/location = get_turf(loc) if(location) - location.hotspot_expose(1000,1000) + location.hotspot_expose(1000, 1000) + + sparks.start() + if(istype(loc, /obj/item/assembly_holder)) - if(istype(loc.loc, /obj/structure/reagent_dispensers/fueltank)) - var/obj/structure/reagent_dispensers/fueltank/tank = loc.loc + var/locloc = loc.loc + if(istype(locloc, /obj/structure/reagent_dispensers/fueltank)) + var/obj/structure/reagent_dispensers/fueltank/tank = locloc if(tank) - tank.boom(TRUE) - if(istype(loc.loc, /obj/item/reagent_containers/glass/beaker)) - var/obj/item/reagent_containers/glass/beaker/beakerbomb = loc.loc + tank.boom(TRUE) // this qdel's `src` + + if(istype(locloc, /obj/item/onetankbomb)) + var/obj/item/onetankbomb/bomb = locloc + if(bomb?.bombtank) + bomb.bombtank.detonate() + + else if(istype(locloc, /obj/item/reagent_containers/glass/beaker)) + var/obj/item/reagent_containers/glass/beaker/beakerbomb = locloc if(beakerbomb) beakerbomb.heat_beaker() - sparks.start() + + else if(istype(locloc, /obj/item/grenade/chem_grenade)) + var/obj/item/grenade/chem_grenade/CG = locloc + CG.prime() + return TRUE /obj/item/assembly/igniter/attack_self(mob/user) - activate() + if(!istype(loc, /obj/item/assembly_holder)) + activate() add_fingerprint(user) - return + diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 7211b74d433..01506870ac0 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -7,7 +7,7 @@ bomb_name = "tripwire mine" - secured = FALSE // toggle_secure()'ed in New() for correct adding to processing_objects, won't work otherwise + secured = FALSE // toggle_secure()'ed in Initialize() for correct adding to processing_objects, won't work otherwise dir = EAST var/on = FALSE var/visible = TRUE @@ -18,6 +18,13 @@ var/emission_cycles = 0 var/emission_cap = 20 + +/obj/item/assembly/infra/Initialize(mapload) + . = ..() + if(!secured) + toggle_secure() + + /obj/item/assembly/infra/Destroy() if(first) QDEL_NULL(first) @@ -25,12 +32,12 @@ fire_location = null return ..() -/obj/item/assembly/infra/describe() - return "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]." /obj/item/assembly/infra/examine(mob/user) . = ..() - . += describe() + . += span_notice("The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"].") + . += span_info("Alt-Click to rotate it.") + /obj/item/assembly/infra/activate() if(!..()) @@ -39,6 +46,7 @@ update_icon() return TRUE + /obj/item/assembly/infra/toggle_secure() secured = !secured if(secured) @@ -51,25 +59,22 @@ update_icon() return secured -/obj/item/assembly/infra/New() - ..() - if(!secured) - toggle_secure() -/obj/item/assembly/infra/proc/arm() // Forces the device to arm no matter its current state. +/// Forces the device to arm no matter its current state. +/obj/item/assembly/infra/proc/arm() if(!secured) // Checked because arm() might be called sometime after the object is spawned. toggle_secure() - on = 1 + on = TRUE -/obj/item/assembly/infra/update_icon() - overlays.Cut() + +/obj/item/assembly/infra/update_overlays() + . = ..() attached_overlays = list() if(on) - overlays += "infrared_on" + . += "infrared_on" attached_overlays += "infrared_on" + holder?.update_icon() - if(holder) - holder.update_icon() /obj/item/assembly/infra/process() var/turf/T = get_turf(src) @@ -89,7 +94,7 @@ emission_cycles = 0 var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(T) I.master = src - I.density = 1 + I.density = TRUE I.dir = dir I.update_icon() first = I @@ -100,30 +105,36 @@ I.limit = 8 I.process() + /obj/item/assembly/infra/attack_hand() qdel(first) ..() -/obj/item/assembly/infra/Move() - var/t = dir + +/obj/item/assembly/infra/Move(atom/newloc, direct = 0, movetime) + var/prev_dir = dir . = ..() - dir = t + dir = prev_dir qdel(first) + /obj/item/assembly/infra/holder_movement() if(!holder) return FALSE qdel(first) return TRUE + /obj/item/assembly/infra/equipped(mob/user, slot, initial) qdel(first) return ..() + /obj/item/assembly/infra/pickup(mob/user) qdel(first) return ..() + /obj/item/assembly/infra/proc/trigger_beam(atom/movable/AM) var/mob/triggered if(AM.throwing?.thrower) @@ -132,15 +143,17 @@ triggered = AM if(!secured || !on || cooldown > 0) return FALSE + cooldown = 2 + pulse(FALSE, triggered) audible_message("[bicon(src)] *beep* *beep*", hearing_distance = 3) if(first) qdel(first) - cooldown = 2 - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) - pulse(FALSE, triggered) + addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 1 SECONDS) + /obj/item/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel - if(!secured) return + if(!secured) + return user.set_machine(src) var/dat = {"Infrared Laser Status: [on ? "On" : "Off"]
    @@ -153,6 +166,7 @@ popup.set_content(dat) popup.open() + /obj/item/assembly/infra/Topic(href, href_list) ..() if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) @@ -167,38 +181,51 @@ if(first) first.vis_spread(visible) if(href_list["rotate"]) - rotate() + rotate(usr) if(href_list["close"]) usr << browse(null, "window=infra") return if(usr) attack_self(usr) -/obj/item/assembly/infra/verb/rotate()//This could likely be better + +/obj/item/assembly/infra/AltClick(mob/user) + if(!Adjacent(user)) + return ..() + rotate(user) + + +/obj/item/assembly/infra/verb/rotate_verb() set name = "Rotate Infrared Laser" set category = "Object" set src in usr - if(usr.stat || !usr.canmove || usr.restrained()) + rotate(usr) + + +/obj/item/assembly/infra/proc/rotate(mob/living/user = usr) + if(!isliving(user) || user.incapacitated() || user.restrained()) return dir = turn(dir, 90) - if(usr.machine == src) - interact(usr) + if(user.machine == src) + interact(user) if(first) qdel(first) +/obj/item/assembly/infra/armed/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, PROC_REF(delayed_arm)), 0.3 SECONDS) + + +/obj/item/assembly/infra/armed/proc/delayed_arm() + if(holder?.master) + dir = holder.master.dir + arm() -/obj/item/assembly/infra/armed/New() - ..() - spawn(3) - if(holder) - if(holder.master) - dir = holder.master.dir - arm() /obj/item/assembly/infra/armed/stealth visible = FALSE @@ -222,19 +249,31 @@ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSFENCE +/obj/effect/beam/i_beam/Destroy() + if(master && master.first == src) + master.first = null + QDEL_NULL(next) + if(previous) + previous.next = null + master?.last = previous + return ..() + + /obj/effect/beam/i_beam/proc/hit(atom/movable/AM) - if(master) - master.trigger_beam(AM) + master?.trigger_beam(AM) qdel(src) -/obj/effect/beam/i_beam/proc/vis_spread(v) - visible = v + +/obj/effect/beam/i_beam/proc/vis_spread(new_visibility) + visible = new_visibility if(next) - next.vis_spread(v) + next.vis_spread(new_visibility) + -/obj/effect/beam/i_beam/update_icon() +/obj/effect/beam/i_beam/update_icon_state() transform = turn(matrix(), dir2angle(dir)) + /obj/effect/beam/i_beam/process() life_cycles++ if(loc.density || !master || life_cycles >= life_cap) @@ -242,18 +281,15 @@ return if(left > 0) left-- - if(left < 1) - if(!(visible)) - invisibility = INVISIBILITY_ABSTRACT - else - invisibility = FALSE + if(left < 1 && !visible) + invisibility = INVISIBILITY_ABSTRACT else - invisibility = FALSE + invisibility = 0 if(!next && (limit > 0)) var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(loc) I.master = master - I.density = 1 + I.density = TRUE I.dir = dir I.update_icon() I.previous = src @@ -266,12 +302,15 @@ master.last = I I.process() + /obj/effect/beam/i_beam/Bump() qdel(src) + /obj/effect/beam/i_beam/Bumped(atom/movable/moving_atom) hit(moving_atom) + /obj/effect/beam/i_beam/Crossed(atom/movable/AM, oldloc) if(!isobj(AM) && !isliving(AM)) return @@ -279,11 +318,3 @@ return hit(AM) -/obj/effect/beam/i_beam/Destroy() - if(master.first == src) - master.first = null - QDEL_NULL(next) - if(previous) - previous.next = null - master.last = previous - return ..() diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index dde6183ca6f..01a1b6734a6 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -8,133 +8,165 @@ bomb_name = "contact mine" + /obj/item/assembly/mousetrap/examine(mob/user) . = ..() if(armed) - . += "It looks like it's armed." + . += span_warning("It looks like it's armed.") + . += span_info("Alt-Click to hide it.") + /obj/item/assembly/mousetrap/activate() - if(..()) - armed = !armed - if(!armed) - if(ishuman(usr)) - var/mob/living/carbon/human/user = usr - if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50)) - to_chat(user, "Your hand slips, setting off the trigger.") - pulse(0, user) - update_icon() - if(usr) - playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) - -/obj/item/assembly/mousetrap/describe() - return "The pressure switch is [armed ? "primed" : "safe"]." - -/obj/item/assembly/mousetrap/update_icon() - if(armed) - icon_state = "mousetraparmed" - else - icon_state = "mousetrap" + if(!..()) + return + + armed = !armed + if(!armed && ishuman(usr)) + var/mob/living/carbon/human/user = usr + if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50)) + to_chat(user, "Your hand slips, setting off the trigger.") + pulse(FALSE, user) + + update_icon() + + if(usr) + playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) + + +/obj/item/assembly/mousetrap/update_icon_state() + icon_state = "mousetrap[armed ? "armed": ""]" if(holder) holder.update_icon() + /obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet") if(!armed) return + var/obj/item/organ/external/affecting = null + if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(PIERCEIMMUNE in H.dna.species.species_traits) + var/mob/living/carbon/human/h_target = target + if(h_target.dna && (PIERCEIMMUNE in h_target.dna.species.species_traits)) playsound(src, 'sound/effects/snap.ogg', 50, TRUE) armed = FALSE update_icon() - pulse(FALSE, target) + pulse(FALSE, h_target) return FALSE + switch(type) if("feet") - if(!H.shoes) - affecting = H.get_organ(pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) - H.Weaken(6 SECONDS) + if(!h_target.shoes) + affecting = h_target.get_organ(pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) + h_target.Weaken(6 SECONDS) + if(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND) - if(!H.gloves) - affecting = H.get_organ(type) - H.Stun(6 SECONDS) + if(!h_target.gloves) + affecting = h_target.get_organ(type) + h_target.Stun(6 SECONDS) + if(affecting) affecting.receive_damage(1, 0) - else if(ismouse(target)) - var/mob/living/simple_animal/mouse/M = target - visible_message("SPLAT!") - M.apply_damage(5, "brute") - if (M.stat == DEAD) - M.splat(item = src) - playsound(loc, 'sound/effects/snap.ogg', 50, 1) + + else if(ismouse(target) && target.stat != DEAD) + var/mob/living/simple_animal/mouse/mouse = target + visible_message(span_danger("SPLAT!")) + mouse.death() + mouse.splat(src) + + playsound(loc, 'sound/effects/snap.ogg', 50, TRUE) layer = MOB_LAYER - 0.2 armed = FALSE update_icon() - pulse(0, target) + pulse(FALSE, target) + /obj/item/assembly/mousetrap/attack_self(mob/living/user) if(!armed) - to_chat(user, "You arm [src].") + to_chat(user, span_notice("You arm [src].")) else if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50)) triggered(user, user.hand ? BODY_ZONE_PRECISE_L_HAND : BODY_ZONE_PRECISE_R_HAND) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", \ - "You accidentally trigger [src]!") + user.visible_message( + span_warning("[user] accidentally sets off [src], breaking [user.p_their()] fingers."), + span_warning("You accidentally trigger [src]!"), + ) return - to_chat(user, "You disarm [src].") + to_chat(user, span_notice("You disarm [src].")) armed = !armed update_icon() - playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) + playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) + /obj/item/assembly/mousetrap/attack_hand(mob/living/user) - if(armed) - if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50)) - triggered(user, user.hand ? BODY_ZONE_PRECISE_L_HAND : BODY_ZONE_PRECISE_R_HAND) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", \ - "You accidentally trigger [src]!") - return + if(armed && (user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50)) + triggered(user, user.hand ? BODY_ZONE_PRECISE_L_HAND : BODY_ZONE_PRECISE_R_HAND) + user.visible_message( + span_warning("[user] accidentally sets off [src], breaking [user.p_their()] fingers."), + span_warning("You accidentally trigger [src]!"), + ) + return ..() + /obj/item/assembly/mousetrap/Crossed(atom/movable/AM, oldloc) if(armed) if(ishuman(AM)) - var/mob/living/carbon/H = AM - if(H.m_intent == MOVE_INTENT_RUN) - triggered(H) - H.visible_message("[H] accidentally steps on [src].", \ - "You accidentally step on [src]") + var/mob/living/carbon/h_target = AM + if(h_target.m_intent == MOVE_INTENT_RUN) + triggered(h_target) + h_target.visible_message( + span_warning("[h_target] accidentally steps on [src]."), + span_warning("You accidentally step on [src]!"), + ) else if(ismouse(AM)) triggered(AM) else if(AM.density) // For mousetrap grenades, set off by anything heavy triggered(AM) ..() + /obj/item/assembly/mousetrap/on_found(mob/finder) if(armed) - finder.visible_message("[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.", \ - "You accidentally trigger [src]!") + finder.visible_message( + span_warning("[finder] accidentally sets off [src], breaking [finder.p_their()] fingers."), + span_warning("You accidentally trigger [src]!"), + ) triggered(finder, finder.hand ? BODY_ZONE_PRECISE_L_HAND : BODY_ZONE_PRECISE_R_HAND) return TRUE //end the search! return FALSE + /obj/item/assembly/mousetrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(!armed) return ..() - visible_message("[src] is triggered by [AM].") - triggered(null) + visible_message(span_warning("[src] is triggered by [AM].")) + triggered() + /obj/item/assembly/mousetrap/armed icon_state = "mousetraparmed" - armed = 1 + armed = TRUE -/obj/item/assembly/mousetrap/verb/hide_under() +/obj/item/assembly/mousetrap/AltClick(mob/user) + if(!Adjacent(user)) + return ..() + hide_under(user) + + +/obj/item/assembly/mousetrap/verb/hide_under_verb() set src in oview(1) set name = "Hide" set category = "Object" - if(usr.stat) + hide_under(usr) + + +/obj/item/assembly/mousetrap/proc/hide_under(mob/user = usr) + if(!isliving(user) || user.incapacitated() || user.restrained()) return - layer = TURF_LAYER+0.2 - to_chat(usr, "You hide [src].") + layer = TURF_LAYER + 0.2 + to_chat(user, span_notice("You hide [src].")) + diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index cce1f06410f..671c69b23be 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -5,22 +5,27 @@ materials = list(MAT_METAL = 800, MAT_GLASS = 200) origin_tech = "magnets=1;engineering=1" - secured = 0 + secured = FALSE bomb_name = "proximity mine" - var/scanning = 0 - var/timing = 0 + var/scanning = FALSE + var/timing = FALSE var/time = 10 + /obj/item/assembly/prox_sensor/ComponentInitialize() . = ..() AddComponent(/datum/component/proximity_monitor) -/obj/item/assembly/prox_sensor/describe() + +/obj/item/assembly/prox_sensor/examine(mob/user) + . = ..() if(timing) - return "The proximity sensor is arming." - return "The proximity sensor is [scanning ? "armed" : "disarmed"]." + . += span_notice("The proximity sensor is arming.") + else + . += span_notice("The proximity sensor is [scanning ? "armed" : "disarmed"].") + /obj/item/assembly/prox_sensor/activate() if(!..()) @@ -29,17 +34,19 @@ update_icon() return FALSE + /obj/item/assembly/prox_sensor/toggle_secure() secured = !secured if(secured) START_PROCESSING(SSobj, src) else - scanning = 0 - timing = 0 + scanning = FALSE + timing = FALSE STOP_PROCESSING(SSobj, src) update_icon() return secured + /obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM) if(!isobj(AM) && !isliving(AM)) return @@ -48,6 +55,7 @@ if(AM.move_speed < 12) sense(AM) + /obj/item/assembly/prox_sensor/proc/sense(atom/movable/AM) var/mob/triggered if(ismob(AM)) @@ -55,23 +63,24 @@ if(!secured || !scanning || cooldown > 0) return FALSE cooldown = 2 - visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) pulse(FALSE, triggered) + visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") + addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 1 SECONDS) + /obj/item/assembly/prox_sensor/process() if(timing && (time >= 0)) time-- if(timing && time <= 0) - timing = 0 + timing = FALSE toggle_scan() time = 10 + /obj/item/assembly/prox_sensor/dropped(mob/user, silent = FALSE) - ..() - spawn(0) - sense(user) - return + . = ..() + INVOKE_ASYNC(src, PROC_REF(sense), user) + /obj/item/assembly/prox_sensor/proc/toggle_scan() if(!secured) @@ -79,28 +88,31 @@ scanning = !scanning update_icon() -/obj/item/assembly/prox_sensor/update_icon() - overlays.Cut() + +/obj/item/assembly/prox_sensor/update_overlays() + . = ..() attached_overlays = list() if(timing) - overlays += "prox_timing" + . += "prox_timing" attached_overlays += "prox_timing" if(scanning) - overlays += "prox_scanning" + . += "prox_scanning" attached_overlays += "prox_scanning" - if(holder) - holder.update_icon() + holder?.update_icon() -/obj/item/assembly/prox_sensor/Move() + +/obj/item/assembly/prox_sensor/Move(atom/newloc, direct = NONE, movetime) . = ..() sense() + /obj/item/assembly/prox_sensor/holder_movement(user) sense(user) + /obj/item/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy if(!secured) - user.show_message("The [name] is unsecured!") + user.show_message(span_warning("The [name] is unsecured!")) return FALSE var/second = time % 60 var/minute = (time - second) / 60 @@ -112,6 +124,7 @@ popup.set_content(dat) popup.open() + /obj/item/assembly/prox_sensor/Topic(href, href_list) ..() if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) @@ -137,3 +150,4 @@ if(usr) attack_self(usr) + diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 4c1e8ae6d1b..e2ccef0b2bc 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -9,26 +9,27 @@ w_class = WEIGHT_CLASS_HUGE flags = CONDUCT + /obj/item/assembly/shock_kit/Destroy() QDEL_NULL(part1) QDEL_NULL(part2) return ..() -/obj/item/assembly/shock_kit/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wrench) && !status) - var/turf/T = loc - if(ismob(T)) - T = T.loc - part1.loc = T - part2.loc = T - part1.master = null - part2.master = null - part1 = null - part2 = null - qdel(src) - return + +/obj/item/assembly/shock_kit/wrench_act(mob/living/user, obj/item/I) + . = TRUE + if(!status) + return . add_fingerprint(user) - return + var/drop_loc = drop_location() + part1.forceMove(drop_loc) + part2.forceMove(drop_loc) + part1.master = null + part2.master = null + part1 = null + part2 = null + qdel(src) + /obj/item/assembly/shock_kit/screwdriver_act(mob/user, obj/item/I) . = TRUE @@ -36,18 +37,19 @@ return status = !status if(status) - to_chat(user, "[src] is now ready to be attached to a chair!") + to_chat(user, span_notice("[src] is now ready to be attached to a chair!")) else - to_chat(user, "[src] is now ready!") + to_chat(user, span_notice("[src] is now ready!")) + -/obj/item/assembly/shock_kit/attack_self(mob/user as mob) +/obj/item/assembly/shock_kit/attack_self(mob/user) part1.attack_self(user, status) part2.attack_self(user, status) add_fingerprint(user) - return + /obj/item/assembly/shock_kit/receive_signal() if(istype(loc, /obj/structure/chair/e_chair)) - var/obj/structure/chair/e_chair/C = loc - C.shock() - return + var/obj/structure/chair/e_chair/chair = loc + chair.shock() + diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 406f70f17c0..9d0f1b830e4 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -7,7 +7,7 @@ origin_tech = "magnets=1;bluespace=1" wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE - secured = 1 + secured = TRUE var/receiving = FALSE bomb_name = "remote-control bomb" @@ -18,24 +18,32 @@ var/datum/radio_frequency/radio_connection var/airlock_wire = null -/obj/item/assembly/signaler/New() - ..() - if(SSradio) - set_frequency(frequency) /obj/item/assembly/signaler/Initialize() - ..() + . = ..() if(SSradio) set_frequency(frequency) + /obj/item/assembly/signaler/Destroy() if(SSradio) SSradio.remove_object(src, frequency) radio_connection = null return ..() -/obj/item/assembly/signaler/describe() - return "[src]'s power light is [receiving ? "on" : "off"]" + +/obj/item/assembly/signaler/examine(mob/user) + . = ..() + . += span_notice("The power light is [receiving ? "on" : "off"].") + . += span_info("Alt+Click to send a signal.") + + +/obj/item/assembly/signaler/AltClick(mob/user) + if(!isliving(user) || user.incapacitated() || user.restrained() || !Adjacent(user)) + return ..() + to_chat(user, span_notice("You activate [src].")) + activate() + /obj/item/assembly/signaler/activate() if(cooldown > 0) @@ -46,10 +54,10 @@ signal() return TRUE -/obj/item/assembly/signaler/update_icon() - if(holder) - holder.update_icon() - return + +/obj/item/assembly/signaler/update_icon_state() + holder?.update_icon() + /obj/item/assembly/signaler/interact(mob/user, flag1) var/t1 = "-------" @@ -81,13 +89,14 @@ "} var/datum/browser/popup = new(user, "radio", name, 400, 400) popup.set_content(dat) - popup.open(0) + popup.open(FALSE) onclose(user, "radio") + /obj/item/assembly/signaler/Topic(href, href_list) ..() - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) + if(usr.incapacitated() || usr.restrained() || !Adjacent(usr)) usr << browse(null, "window=radio") onclose(usr, "radio") return @@ -103,16 +112,17 @@ code = round(code) code = min(100, code) code = max(1, code) + if(href_list["receive"]) receiving = !receiving if(href_list["send"]) - spawn( 0 ) - signal() + INVOKE_ASYNC(src, PROC_REF(signal)) if(usr) attack_self(usr) + /obj/item/assembly/signaler/proc/signal() if(!radio_connection) return @@ -129,6 +139,7 @@ if(usr) GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") + /obj/item/assembly/signaler/receive_signal(datum/signal/signal) if(!receiving || !signal) return FALSE @@ -140,15 +151,15 @@ return FALSE pulse(1, signal.user) - for(var/mob/O in hearers(1, loc)) - O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) + for(var/mob/hearer in hearers(1, loc)) + hearer.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) return TRUE + /obj/item/assembly/signaler/proc/set_frequency(new_frequency) - if(!SSradio) - sleep(20) if(!SSradio) return SSradio.remove_object(src, frequency) frequency = new_frequency radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT) + diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index c4393ce999f..6084f4cd5ec 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -15,10 +15,18 @@ var/set_time = 10 var/mob/user // for logging -/obj/item/assembly/timer/describe() + +/obj/item/assembly/timer/Destroy() + user = null + return ..() + +/obj/item/assembly/timer/examine(mob/user) + . = ..() if(timing) - return "The timer is counting down from [time]!" - return "The timer is set for [time] seconds." + . += span_notice("The timer is counting down from [time]!") + else + . += span_notice("The timer is set for [time] seconds.") + /obj/item/assembly/timer/activate() if(!..()) @@ -27,6 +35,7 @@ update_icon() return FALSE + /obj/item/assembly/timer/toggle_secure() secured = !secured if(secured) @@ -37,13 +46,17 @@ update_icon() return secured + /obj/item/assembly/timer/proc/timer_end() if(!secured || cooldown > 0) return FALSE - visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") cooldown = 2 - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) pulse(FALSE, user) + update_icon() + if(loc) + loc.visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") + addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) + /obj/item/assembly/timer/process() if(timing && (time > 0)) @@ -53,18 +66,19 @@ timer_end() time = set_time -/obj/item/assembly/timer/update_icon() - overlays.Cut() + +/obj/item/assembly/timer/update_overlays() + . = ..() attached_overlays = list() if(timing) - overlays += "timer_timing" + . += "timer_timing" attached_overlays += "timer_timing" - if(holder) - holder.update_icon() + holder?.update_icon() + -/obj/item/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires +/obj/item/assembly/timer/interact(mob/user)//TODO: Have this use the wires if(!secured) - user.show_message("The [name] is unsecured!") + user.show_message(span_warning("The [name] is unsecured!")) return FALSE var/second = time % 60 var/minute = (time - second) / 60 @@ -90,9 +104,10 @@ popup.set_content(dat) popup.open() + /obj/item/assembly/timer/Topic(href, href_list) ..() - if(usr.incapacitated() || !in_range(loc, usr)) + if(usr.incapacitated() || usr.restrained() || !Adjacent(usr)) usr << browse(null, "window=timer") onclose(usr, "timer") return diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 7dc382cde69..61b965b8c23 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -4,38 +4,48 @@ icon_state = "voice" materials = list(MAT_METAL=500, MAT_GLASS=50) origin_tech = "magnets=1;engineering=1" - var/listening = 0 + var/listening = FALSE var/recorded = null //the activation message var/recorded_type = 0 // 0 for say, 1 for emote bomb_name = "voice-activated bomb" -/obj/item/assembly/voice/describe() + +/obj/item/assembly/voice/examine(mob/user) + . = ..() if(recorded || listening) - return "A meter on [src] flickers with every nearby sound." + . += span_notice("A meter on it flickers with every nearby sound.") else - return "[src] is deactivated." + . += span_notice("It is deactivated.") -/obj/item/assembly/voice/hear_talk(mob/living/M as mob, list/message_pieces) + +/obj/item/assembly/voice/hear_talk(mob/living/M, list/message_pieces) hear_input(M, multilingual_to_message(message_pieces), 0) -/obj/item/assembly/voice/hear_message(mob/living/M as mob, msg) + +/obj/item/assembly/voice/hear_message(mob/living/M, msg) hear_input(M, msg, 1) -/obj/item/assembly/voice/proc/hear_input(mob/living/M as mob, msg, type) + +/obj/item/assembly/voice/proc/hear_input(mob/living/M, msg, type) if(!istype(M,/mob/living)) return if(listening) + if(findtext(msg, "
    ")) + recorded = strip_html_properly(msg) + else + recorded = msg recorded = msg recorded_type = type - listening = 0 + listening = FALSE var/turf/T = get_turf(src) //otherwise it won't work in hand T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"") else if(findtext(msg, recorded) && type == recorded_type) var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[bicon(src)] beeps!") + T.visible_message(span_warning("[bicon(src)] beeps!")) pulse(0, M) + /obj/item/assembly/voice/activate() return // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way. @@ -52,7 +62,8 @@ /obj/item/assembly/voice/toggle_secure() . = ..() - listening = 0 + listening = FALSE + /obj/item/assembly/voice/noise name = "noise sensor" @@ -62,16 +73,22 @@ origin_tech = "magnets=1;engineering=1" bomb_name = "noise-activated bomb" + /obj/item/assembly/voice/noise/attack_self(mob/user) return -/obj/item/assembly/voice/noise/describe() - return "[src] does not appear to have any controls." -/obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, list/message_pieces) +/obj/item/assembly/voice/noise/examine(mob/user) + . = ..() + . += span_notice("It does not appear to have any controls.") + + +/obj/item/assembly/voice/noise/hear_talk(mob/living/M, list/message_pieces) return -/obj/item/assembly/voice/noise/hear_message(mob/living/M as mob, msg) + +/obj/item/assembly/voice/noise/hear_message(mob/living/M, msg) pulse(0, M) var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[bicon(src)] beeps!") + T.visible_message(span_warning("[bicon(src)] beeps!")) + diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index eaf849d8a00..c4049335180 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -4,74 +4,74 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations." icon = 'icons/obj/machines/gateway.dmi' icon_state = "off" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/active = 0 + var/active = FALSE + /obj/machinery/gateway/Initialize() ..() - update_icon() + update_icon(UPDATE_ICON_STATE) update_density_from_dir() -/obj/machinery/gateway/proc/update_density_from_dir() - if(dir == 2) - density = 0 +/obj/machinery/gateway/proc/update_density_from_dir() + if(dir == SOUTH) + density = FALSE -/obj/machinery/gateway/update_icon() - if(active) - icon_state = "on" - return - icon_state = "off" +/obj/machinery/gateway/update_icon_state() + icon_state = active ? "on" : "off" //this is da important part wot makes things go /obj/machinery/gateway/centerstation - density = 1 icon_state = "offcenter" use_power = IDLE_POWER_USE //warping vars var/list/linked = list() - var/ready = 0 //have we got all the parts for a gateway? + var/ready = FALSE //have we got all the parts for a gateway? var/wait = 0 //this just grabs world.time at world start var/obj/machinery/gateway/centeraway/awaygate = null + /obj/machinery/gateway/centerstation/New() ..() if(!GLOB.the_gateway) GLOB.the_gateway = src -/obj/machinery/gateway/centerstation/Initialize() - ..() - update_icon() + +/obj/machinery/gateway/centerstation/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) wait = world.time + CONFIG_GET(number/gateway_delay) return INITIALIZE_HINT_LATELOAD -/obj/machinery/gateway/centerstation/LateInitialize() - awaygate = locate(/obj/machinery/gateway/centeraway) in GLOB.machines - -/obj/machinery/gateway/centerstation/update_density_from_dir() - return /obj/machinery/gateway/centerstation/Destroy() if(GLOB.the_gateway == src) GLOB.the_gateway = null return ..() -/obj/machinery/gateway/centerstation/update_icon() - if(active) - icon_state = "oncenter" - return - icon_state = "offcenter" + +/obj/machinery/gateway/centerstation/LateInitialize() + awaygate = locate(/obj/machinery/gateway/centeraway) in GLOB.machines + + +/obj/machinery/gateway/centerstation/update_density_from_dir() + return +/obj/machinery/gateway/centerstation/update_icon_state() + icon_state = active ? "oncenter" : "offcenter" + /obj/machinery/gateway/centerstation/process() if(stat & (NOPOWER)) - if(active) toggleoff() + if(active) + toggleoff() return if(active) @@ -90,18 +90,18 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) continue //this is only done if we fail to find a part - ready = 0 + ready = FALSE toggleoff() break - if(linked.len == 8) - ready = 1 + if(length(linked) == 8) + ready = TRUE -/obj/machinery/gateway/centerstation/proc/toggleon(mob/user as mob) +/obj/machinery/gateway/centerstation/proc/toggleon(mob/user) if(!ready) return - if(linked.len != 8) + if(length(linked) != 8) return if(!powered()) return @@ -115,21 +115,21 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) return for(var/obj/machinery/gateway/G in linked) - G.active = 1 + G.active = TRUE G.update_icon() - active = 1 - update_icon() + active = TRUE + update_icon(UPDATE_ICON_STATE) /obj/machinery/gateway/centerstation/proc/toggleoff() for(var/obj/machinery/gateway/G in linked) - G.active = 0 - G.update_icon() - active = 0 - update_icon() + G.active = FALSE + G.update_icon(UPDATE_ICON_STATE) + active = FALSE + update_icon(UPDATE_ICON_STATE) -/obj/machinery/gateway/centerstation/attack_hand(mob/user as mob) +/obj/machinery/gateway/centerstation/attack_hand(mob/user) add_fingerprint(user) if(!ready) detect() @@ -152,17 +152,16 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) moving_atom.forceMove(get_step(awaygate.loc, SOUTH)) moving_atom.dir = SOUTH return - else - var/obj/effect/landmark/dest = pick(GLOB.awaydestinations) - if(dest) - moving_atom.forceMove(dest.loc) - moving_atom.dir = SOUTH - use_power(5000) - return + + var/obj/effect/landmark/dest = pick(GLOB.awaydestinations) + if(dest) + moving_atom.forceMove(dest.loc) + moving_atom.dir = SOUTH + use_power(5000) -/obj/machinery/gateway/centerstation/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/multitool)) +/obj/machinery/gateway/centerstation/attackby(obj/item/W, mob/user, params) + if(ismultitool(W)) add_fingerprint(user) to_chat(user, "The gate is already calibrated, there is no work for you to do here.") return @@ -172,13 +171,12 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) /obj/machinery/gateway/centeraway - density = 1 icon_state = "offcenter" use_power = NO_POWER_USE var/calibrating_on_activating = FALSE - var/calibrated = 1 + var/calibrated = TRUE var/list/linked = list() //a list of the connected gateway chunks - var/ready = 0 + var/ready = FALSE var/obj/machinery/gateway/centeraway/stationgate = null @@ -191,11 +189,9 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) /obj/machinery/gateway/centeraway/update_density_from_dir() return -/obj/machinery/gateway/centeraway/update_icon() - if(active) - icon_state = "oncenter" - return - icon_state = "offcenter" + +/obj/machinery/gateway/centeraway/update_icon_state() + icon_state = active ? "oncenter" : "offcenter" /obj/machinery/gateway/centeraway/proc/detect() @@ -210,18 +206,18 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) continue //this is only done if we fail to find a part - ready = 0 + ready = FALSE toggleoff() break - if(linked.len == 8) - ready = 1 + if(length(linked) == 8) + ready = TRUE -/obj/machinery/gateway/centeraway/proc/toggleon(mob/user as mob) +/obj/machinery/gateway/centeraway/proc/toggleon(mob/user) if(!ready) return - if(linked.len != 8) + if(length(linked) != 8) return if(!stationgate) stationgate = locate(/obj/machinery/gateway/centerstation) in GLOB.machines @@ -232,21 +228,21 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) calibrated = TRUE for(var/obj/machinery/gateway/G in linked) - G.active = 1 - G.update_icon() - active = 1 - update_icon() + G.active = TRUE + G.update_icon(UPDATE_ICON_STATE) + active = TRUE + update_icon(UPDATE_ICON_STATE) /obj/machinery/gateway/centeraway/proc/toggleoff() for(var/obj/machinery/gateway/G in linked) - G.active = 0 - G.update_icon() - active = 0 - update_icon() + G.active = FALSE + G.update_icon(UPDATE_ICON_STATE) + active = FALSE + update_icon(UPDATE_ICON_STATE) -/obj/machinery/gateway/centeraway/attack_hand(mob/user as mob) +/obj/machinery/gateway/centeraway/attack_hand(mob/user) add_fingerprint(user) if(!ready) detect() @@ -285,21 +281,24 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null) if(M.client) M.client.move_delay = max(world.time + 5, M.client.move_delay) -/obj/machinery/gateway/centeraway/proc/exilecheck(var/mob/living/carbon/M) - for(var/obj/item/implant/exile/E in M)//Checking that there is an exile implant in the contents - if(E.imp_in == M)//Checking that it's actually implanted vs just in their pocket - to_chat(M, "The station gate has detected your exile implant and is blocking your entry.") - return 1 - return 0 -/obj/machinery/gateway/centeraway/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/multitool)) +/obj/machinery/gateway/centeraway/proc/exilecheck(mob/living/carbon/user) + for(var/obj/item/implant/exile/imp in user)//Checking that there is an exile implant in the contents + if(imp.imp_in == user)//Checking that it's actually implanted vs just in their pocket + to_chat(user, "The station gate has detected your exile implant and is blocking your entry.") + return TRUE + return FALSE + + +/obj/machinery/gateway/centeraway/attackby(obj/item/W, mob/user, params) + if(ismultitool(W)) if(calibrated) to_chat(user, "The gate is already calibrated, there is no work for you to do here.") return else add_fingerprint(user) to_chat(user, "Recalibration successful!: This gate's systems have been fine tuned. Travel to this gate will now be on target.") - calibrated = 1 + calibrated = TRUE return return ..() + diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm index 6e3a8e82e3a..30edb32fcb4 100644 --- a/code/modules/awaymissions/map_rng.dm +++ b/code/modules/awaymissions/map_rng.dm @@ -3,7 +3,7 @@ icon = 'icons/mob/screen_gen.dmi' icon_state = "x2" invisibility = INVISIBILITY_ABSTRACT - anchored = 1 + anchored = TRUE density = 0 opacity = 0 var/template_name = null diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm index 3e488ba1edc..065b2749f7d 100644 --- a/code/modules/awaymissions/mission_code/academy.dm +++ b/code/modules/awaymissions/mission_code/academy.dm @@ -44,191 +44,6 @@ icon_state = "monocle" item_state = "headset" -// Die of Fate -/obj/item/dice/d20/fate - name = "\improper Die of Fate" - desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky." - icon_state = "d20" - var/reusable = TRUE - var/used = FALSE - -/obj/item/dice/d20/fate/stealth - name = "d20" - desc = "A die with twenty sides. The preferred die to throw at the GM." - -/obj/item/dice/d20/fate/one_use - reusable = FALSE - -/obj/item/dice/d20/fate/one_use/stealth - name = "d20" - desc = "A die with twenty sides. The preferred die to throw at the GM." - -/obj/item/dice/d20/fate/cursed - name = "cursed Die of Fate" - desc = "A die with twenty sides. You feel that rolling this is a REALLY bad idea." - color = "#00BB00" - - rigged = DICE_TOTALLY_RIGGED - rigged_value = 1 - -/obj/item/dice/d20/fate/diceroll(mob/user) - . = ..() - if(!used) - if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards)) - to_chat(user, "You feel the magic of the dice is restricted to ordinary humans!") - return - - if(!reusable) - used = TRUE - - var/turf/T = get_turf(src) - T.visible_message("[src] flares briefly.") - - addtimer(CALLBACK(src, PROC_REF(effect), user, .), 1 SECONDS) - -/obj/item/dice/d20/fate/equipped(mob/user, slot, initial) - . = ..() - - if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards)) - to_chat(user, "You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.") - user.drop_item_ground(src) - -/obj/item/dice/d20/fate/proc/create_smoke(amount) - var/datum/effect_system/smoke_spread/smoke = new - smoke.set_up(amount, 0, drop_location()) - smoke.start() - -/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user, roll) - var/turf/T = get_turf(src) - switch(roll) - if(1) - //Dust - T.visible_message("[user] turns to dust!") - user.dust() - if(2) - //Death - T.visible_message("[user] suddenly dies!") - user.death() - if(3) - //Swarm of creatures - T.visible_message("A swarm of creatures surround [user]!") - for(var/direction in GLOB.alldirs) - new /mob/living/simple_animal/hostile/netherworld(get_step(get_turf(user),direction)) - if(4) - //Destroy Equipment - T.visible_message("Everything [user] is holding and wearing disappears!") - for(var/obj/item/I in user) - if(istype(I, /obj/item/implant) || istype(I, /obj/item/organ)) - continue - qdel(I) - if(5) - //Monkeying - T.visible_message("[user] transforms into a monkey!") - user.monkeyize() - if(6) - //Cut speed - T.visible_message("[user] starts moving slower!") - var/datum/species/S = user.dna.species - S.speed_mod += 1 - if(7) - //Throw - T.visible_message("Unseen forces throw [user]!") - user.Stun(12 SECONDS) - user.adjustBruteLoss(50) - var/throw_dir = GLOB.cardinal - var/atom/throw_target = get_edge_target_turf(user, throw_dir) - user.throw_at(throw_target, 200, 4) - if(8) - //Fueltank Explosion - T.visible_message("An explosion bursts into existence around [user]!") - explosion(get_turf(user),-1,0,2, flame_range = 2, cause = src) - if(9) - //Cold - T.visible_message("[user] looks a little under the weather!") - var/datum/disease/virus/cold/D = new - D.Contract(user) - if(10) - //Nothing - T.visible_message("Nothing seems to happen.") - if(11) - //Cookie - T.visible_message("A cookie appears out of thin air!") - var/obj/item/reagent_containers/food/snacks/cookie/C = new(drop_location()) - create_smoke(2) - C.name = "Cookie of Fate" - if(12) - //Healing - T.visible_message("[user] looks very healthy!") - user.revive() - if(13) - //Mad Dosh - T.visible_message("Mad dosh shoots out of [src]!") - var/turf/Start = get_turf(src) - for(var/direction in GLOB.alldirs) - var/turf/dirturf = get_step(Start,direction) - if(rand(0,1)) - new /obj/item/stack/spacecash/c1000(dirturf) - else - var/obj/item/storage/bag/money/M = new(dirturf) - for(var/i in 1 to rand(5,50)) - new /obj/item/coin/gold(M) - if(14) - //Free Gun - T.visible_message("An impressive gun appears!") - create_smoke(2) - new /obj/item/gun/projectile/revolver/mateba(drop_location()) - if(15) - //Random One-use spellbook - T.visible_message("A magical looking book drops to the floor!") - create_smoke(2) - new /obj/item/spellbook/oneuse/random(drop_location()) - if(16) - //Servant & Servant Summon - T.visible_message("A Dice Servant appears in a cloud of smoke!") - var/mob/living/carbon/human/H = new(drop_location()) - create_smoke(2) - - H.equipOutfit(/datum/outfit/butler) - var/datum/mind/servant_mind = new /datum/mind() - var/datum/objective/O = new - O.owner = servant_mind - O.target = user.mind - O.explanation_text = "Serve [user.real_name]." - servant_mind.objectives += O - servant_mind.transfer_to(H) - - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 30 SECONDS, source = H) - if(LAZYLEN(candidates)) - var/mob/dead/observer/C = pick(candidates) - message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") - H.key = C.key - to_chat(H, "You are a servant of [user.real_name]. You must do everything in your power to follow their orders.") - - var/obj/effect/proc_holder/spell/summonmob/S = new - S.target_mob = H - user.mind.AddSpell(S) - - if(17) - //Tator Kit - T.visible_message("A suspicious box appears!") - new /obj/item/storage/box/syndicate(drop_location()) - create_smoke(2) - if(18) - //Captain ID - T.visible_message("A golden identification card appears!") - new /obj/item/card/id/captains_spare(drop_location()) - create_smoke(2) - if(19) - //Instrinct Resistance - T.visible_message("[user] looks very robust!") - var/datum/species/S = user.dna.species - S.brute_mod *= 0.5 - S.burn_mod *= 0.5 - - if(20) - //Free wizard! - T.visible_message("Magic flows out of [src] and into [user]!") - user.mind.make_Wizard() // Butler outfit /datum/outfit/butler diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm index 26017e4c37c..f57e3ce7ae9 100644 --- a/code/modules/awaymissions/mission_code/beach.dm +++ b/code/modules/awaymissions/mission_code/beach.dm @@ -5,7 +5,7 @@ opacity = 0 mouse_opacity = MOUSE_OPACITY_TRANSPARENT density = 0 - anchored = 1 + anchored = TRUE invisibility = INVISIBILITY_ABSTRACT var/water_frequency = 15 diff --git a/code/modules/awaymissions/mission_code/blackmarketpackers.dm b/code/modules/awaymissions/mission_code/blackmarketpackers.dm index 37f1ef8b212..dec17fd5ae8 100644 --- a/code/modules/awaymissions/mission_code/blackmarketpackers.dm +++ b/code/modules/awaymissions/mission_code/blackmarketpackers.dm @@ -188,7 +188,7 @@ icon_state = "destroyed_target_prism" /obj/machinery/broken/porta_turret/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/crowbar)) + if(I.tool_behaviour == TOOL_CROWBAR) to_chat(user, "You begin prying the metal coverings off.") if(do_after(user, 20 * I.toolspeed * gettoolspeedmod(user), target = src)) if(prob(70)) @@ -206,8 +206,7 @@ /obj/machinery/firealarm/triggered_nosignals report_fire_alarms = FALSE show_alert_level = FALSE - triggered = TRUE - icon_state = "fire1" + //Spieder spawner diff --git a/code/modules/awaymissions/mission_code/challenge.dm b/code/modules/awaymissions/mission_code/challenge.dm index 49662238100..7de2e5b8bc0 100644 --- a/code/modules/awaymissions/mission_code/challenge.dm +++ b/code/modules/awaymissions/mission_code/challenge.dm @@ -27,7 +27,7 @@ desc = "A heavy duty industrial laser" icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "emitter" - anchored = 1 + anchored = TRUE density = 1 use_power = NO_POWER_USE diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm index db62708fbbb..f067c68b895 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm @@ -100,9 +100,9 @@ /datum/outfit/oldstation/post_equip(mob/living/carbon/human/H) . = ..() - H.remove_language("Galactic Common") - H.set_default_language(GLOB.all_languages["Sol Common"]) - H.dna.species.default_language = "Sol Common" + H.remove_language(LANGUAGE_GALACTIC_COMMON) + H.set_default_language(GLOB.all_languages[LANGUAGE_SOL_COMMON]) + H.dna.species.default_language = LANGUAGE_SOL_COMMON /datum/outfit/oldstation/officer name = "Old station officer" diff --git a/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm b/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm index 1f8cfc6ff85..76ea3476529 100644 --- a/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm +++ b/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm @@ -342,7 +342,7 @@ /////////////////// Paper notes /obj/item/paper/gorky17 - language = "Neo-Russkiya" + language = LANGUAGE_NEO_RUSSIAN /obj/item/paper/gorky17/talisman name = "Проклятый талисман" info = "

    НЕ ТРОГАЙ ЭТУ ХРЕНЬ ИЗ ЯЩИКА!
    \ diff --git a/code/modules/awaymissions/mission_code/ruins/graveyard.dm b/code/modules/awaymissions/mission_code/ruins/graveyard.dm index cfd23a2cac0..f6da0b0e414 100644 --- a/code/modules/awaymissions/mission_code/ruins/graveyard.dm +++ b/code/modules/awaymissions/mission_code/ruins/graveyard.dm @@ -36,11 +36,10 @@ icon_state = "case-0" allowed_books = list(/obj/item/storage/funeral_urn) -/obj/structure/bookcase/ashframe/update_icon() - if(contents.len < 5) - icon_state = "case-[contents.len]" - else - icon_state = "case-5" + +/obj/structure/bookcase/ashframe/update_icon_state() + icon_state = "case-[min(length(contents), 5)]" + /obj/structure/bookcase/ashframe/random diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index 59480303a93..c75ca6f45d7 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -104,7 +104,7 @@ // Papers /obj/item/paper/fluff/ruins/oldstation name = "Cryo Awakening Alert" - language = "Sol Common" + language = LANGUAGE_SOL_COMMON info = "**WARNING**

    Catastrophic damage sustained to station. Powernet exhausted to reawaken crew.

    Immediate Objectives

    1: Activate emergency power generator
    2: Lift station lockdown on the bridge

    Please locate the 'Damage Report' on the bridge for a detailed situation report." /obj/item/paper/fluff/ruins/oldstation/damagereport @@ -152,7 +152,7 @@ *eep th* *e**l of **m..

    The last words completly faded." // yep, the temperature overheat, some players set power to 5 and make the gen to blow up, rip oldstation. /obj/item/paper/ruins/oldstation - language = "Sol Common" + language = LANGUAGE_SOL_COMMON /obj/item/paper/ruins/oldstation/protoinventory name = "Theta RnD Prototype Inventory Secure Storage" diff --git a/code/modules/awaymissions/mission_code/spacebattle.dm b/code/modules/awaymissions/mission_code/spacebattle.dm index 90958a14048..afa9d8f43b8 100644 --- a/code/modules/awaymissions/mission_code/spacebattle.dm +++ b/code/modules/awaymissions/mission_code/spacebattle.dm @@ -231,11 +231,11 @@ /obj/effect/landmark/awaymissions/spacebattle/mine_spawner icon = 'icons/obj/spacebattle.dmi' icon_state = "spawner_mine" - canmove = 0 + canmove = FALSE var/id = null - var/triggered = 0 + var/triggered = FALSE var/faction = null - var/safety_z_check = 1 + var/safety_z_check = TRUE /obj/effect/landmark/awaymissions/spacebattle/mob_spawn name = "spawner" @@ -260,7 +260,7 @@ continue if(S.id == id) new S.syndi_mob(get_turf(S)) - triggered = 1 + triggered = TRUE qdel(src) /mob/living/proc/spawn_alert(atom/A) // Вызывает появление восклицательного знака над головой при наступании на маркер @@ -689,26 +689,33 @@ shoes = /obj/item/clothing/shoes/black suit = /obj/item/clothing/suit/storage/labcoat/science + /obj/item/clothing/suit/space/hardsuit/syndi/damaged name = "damaged blood-red hardsuit" desc = "Damaged advanced hardsuit designed for work in special operations. There are a many patches visible on the suit. Its mode switcher system looks damaged and forced in travel mode. Property of Gorlex Marauders." armor = list("melee" = 30, "bullet" = 40, "laser" = 20, "energy" = 20, "bomb" = 30, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) w_class = WEIGHT_CLASS_NORMAL - on = 1 + icon_state = "hardsuit1-syndi" + on = TRUE helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged actions_types = list(/datum/action/item_action/toggle_helmet) -/obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged/attack_self(mob/user) //Toggle Helmet - if(!on) - to_chat(user, "You cant switch your hardsuit to combat mode.") - playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1) - .=..() /obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged - on = 1 icon_state = "hardsuit1-syndi" item_state = "syndie_helm" actions_types = list(/datum/action/item_action/toggle_helmet_light) + on = TRUE + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged/update_icon_state() + return + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged/adjust_headgear(mob/living/carbon/human/user, toggle = FALSE) + if(user) + to_chat(user, span_notice("You cant switch your hardsuit to combat mode.")) + playsound(user, 'sound/machines/buzz-two.ogg', 50, TRUE) + return + ..() -/obj/item/clothing/head/helmet/space/hardsuit/syndi/damaged/update_icon() - icon_state = "hardsuit1-syndi" diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm index 8b67115ae0e..fdc64fa78c2 100644 --- a/code/modules/awaymissions/mission_code/spacehotel.dm +++ b/code/modules/awaymissions/mission_code/spacehotel.dm @@ -144,8 +144,7 @@ return 1 return 0 -/obj/machinery/door/unpowered/hotel_door/update_icon() - overlays.Cut() +/obj/machinery/door/unpowered/hotel_door/update_icon_state() if(density) icon_state = "door_closed" else @@ -193,7 +192,7 @@ icon = 'icons/mob/screen_gen.dmi' icon_state = "x" invisibility = INVISIBILITY_ABSTRACT - anchored = 1 + anchored = TRUE density = 0 opacity = 0 var/list/room_doors[0] // assoc list of [room id]=hotel_door diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index c37899eba9f..02b57d03a95 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -69,8 +69,8 @@ //Syndicate sub-machine guns. /obj/item/gun/projectile/automatic/c20r/sc_c20r -/obj/item/gun/projectile/automatic/c20r/sc_c20r/New() - ..() +/obj/item/gun/projectile/automatic/c20r/sc_c20r/Initialize(mapload) + . = ..() for(var/ammo in magazine.stored_ammo) if(prob(95)) //95% chance magazine.stored_ammo -= ammo @@ -78,8 +78,8 @@ //Barman's shotgun /obj/item/gun/projectile/shotgun/sc_pump -/obj/item/gun/projectile/shotgun/sc_pump/New() - ..() +/obj/item/gun/projectile/shotgun/sc_pump/Initialize(mapload) + . = ..() for(var/ammo in magazine.stored_ammo) if(prob(95)) //95% chance magazine.stored_ammo -= ammo @@ -178,7 +178,7 @@ GLOBAL_VAR_INIT(sc_safecode5, "[rand(0,9)]") if(prob(25)) mezzer() -/obj/singularity/narsie/sc_Narsie/consume(var/atom/A) +/obj/singularity/narsie/sc_Narsie/consume(atom/A) if(!A.simulated) return FALSE if(is_type_in_list(A, uneatable)) @@ -196,7 +196,7 @@ GLOBAL_VAR_INIT(sc_safecode5, "[rand(0,9)]") for(var/obj/O in T.contents) if(O.level != 1) continue - if(O.invisibility == INVISIBILITY_ABSTRACT) + if(O.invisibility == INVISIBILITY_MAXIMUM || O.invisibility == INVISIBILITY_ABSTRACT) src.consume(O) T.ChangeTurf(T.baseturf) return diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 39e068ef64b..deb58adf9d3 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -43,7 +43,7 @@ icon = 'icons/obj/device.dmi' icon_state = "syndbeacon" - anchored = 1 + anchored = TRUE density = 1 use_power = NO_POWER_USE @@ -128,7 +128,7 @@ name = "Meat Grinder" desc = "What is that thing?" density = 1 - anchored = 1 + anchored = TRUE layer = 3 icon = 'icons/mob/blob.dmi' icon_state = "blobpod" diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm index ffbb188ada2..77e3f053ef1 100644 --- a/code/modules/awaymissions/pamphlet.dm +++ b/code/modules/awaymissions/pamphlet.dm @@ -34,5 +34,5 @@ environs." //we don't want the silly text overlay! -/obj/item/paper/pamphlet/update_icon() +/obj/item/paper/pamphlet/update_icon_state() return diff --git a/code/modules/awaymissions/zvis.dm b/code/modules/awaymissions/zvis.dm index 5dd78cc4772..c0dcd99c93c 100644 --- a/code/modules/awaymissions/zvis.dm +++ b/code/modules/awaymissions/zvis.dm @@ -155,7 +155,7 @@ icon = 'icons/mob/screen_gen.dmi' icon_state = "x2" invisibility = INVISIBILITY_ABSTRACT - anchored = 1 + anchored = TRUE var/id = null // id of other portal turf we connect to diff --git a/code/modules/buildmode/buttons.dm b/code/modules/buildmode/buttons.dm index 9f74ac9aeff..ac6ded10777 100644 --- a/code/modules/buildmode/buttons.dm +++ b/code/modules/buildmode/buttons.dm @@ -26,7 +26,7 @@ update_icon() return TRUE -/obj/screen/buildmode/mode/update_icon() +/obj/screen/buildmode/mode/update_icon_state() icon_state = bd.mode.get_button_iconstate() /obj/screen/buildmode/help @@ -43,7 +43,7 @@ screen_loc = "NORTH,WEST+2" name = "Change Dir" -/obj/screen/buildmode/bdir/update_icon() +/obj/screen/buildmode/bdir/update_icon_state() dir = bd.build_dir /obj/screen/buildmode/bdir/Click() diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e2028b4ea82..95c8c0da5d4 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -10,6 +10,7 @@ //I would just like the code ready should it ever need to be used. #define SUGGESTED_CLIENT_VERSION 514 // only integers (e.g: 513, 514) are useful here. This is the part BEFORE the ".", IE 513 out of 513.1536 #define SUGGESTED_CLIENT_BUILD 1568 // only integers (e.g: 1536, 1539) are useful here. This is the part AFTER the ".", IE 1536 out of 513.1536 +#define MINIMUM_FPS_VERSION 511 // used as check, if you can update fps or not #define SSD_WARNING_TIMER 30 // cycles, not seconds, so 30=60s @@ -310,6 +311,7 @@ prefs = GLOB.preferences_datums[ckey] if(!prefs) prefs = new /datum/preferences(src) + set_macros() GLOB.preferences_datums[ckey] = prefs else prefs.parent = src @@ -321,10 +323,10 @@ prefs.init_keybindings(prefs.keybindings_overrides) //The earliest sane place to do it where prefs are not null, if they are null you can't do crap at lobby prefs.last_ip = address //these are gonna be used for banning prefs.last_id = computer_id //these are gonna be used for banning - if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps) + if(world.byond_version >= MINIMUM_FPS_VERSION && byond_version >= MINIMUM_FPS_VERSION && prefs.clientfps) fps = prefs.clientfps - if(world.byond_version >= 511 && byond_version >= 511 && !prefs.clientfps) + if(world.byond_version >= MINIMUM_FPS_VERSION && byond_version >= MINIMUM_FPS_VERSION && !prefs.clientfps) fps = CONFIG_GET(number/clientfps) // Check if the client has or has not accepted TOS @@ -977,33 +979,40 @@ /client/proc/activate_darkmode() ///// BUTTONS ///// /* Rpane */ - winset(src, "rpane.fullscreenb", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.textb", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.infob", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.wikib", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.forumb", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.rulesb", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "rpane.githubb", "background-color=#40628a;text-color=#FFFFFF") + winset(src, "rpane.fullscreenb", "background-color=#494949;text-color=#a4bad6") + winset(src, "rpane.textb", "background-color=#494949;text-color=#a4bad6") + winset(src, "rpane.infob", "background-color=#494949;text-color=#a4bad6") + winset(src, "rpane.wikib", "background-color=#494949;text-color=#a4bad6") + winset(src, "rpane.rulesb", "background-color=#494949;text-color=#a4bad6") + winset(src, "rpane.githubb", "background-color=#494949;text-color=#a4bad6") winset(src, "rpane.webmap", "background-color=#494949;text-color=#a4bad6") - /* Mainwindow */ - winset(src, "mainwindow.saybutton", "background-color=#40628a;text-color=#FFFFFF") - winset(src, "mainwindow.mebutton", "background-color=#40628a;text-color=#FFFFFF") + /* Outputwindow */ + winset(src, "outputwindow.saybutton", "background-color=#494949;text-color=#a4bad6") + winset(src, "outputwindow.mebutton", "background-color=#494949;text-color=#a4bad6") + ///// UI ELEMENTS ///// /* Mainwindow */ - winset(src, "mainwindow", "background-color=#272727") - winset(src, "mainwindow.mainvsplit", "background-color=#272727") - winset(src, "mainwindow.tooltip", "background-color=#272727") + winset(src, "mainwindow", "background-color=#171717") + winset(src, "mainwindow.mainvsplit", "background-color=#202020") + winset(src, "mainwindow.tooltip", "background-color=#171717") /* Outputwindow */ - winset(src, "outputwindow.browseroutput", "background-color=#272727") + winset(src, "outputwindow", "background-color=#202020") + winset(src, "outputwindow.input", "text-color=#a4bad6;background-color=#202020") + winset(src, "outputwindow.browseroutput", "background-color=#202020") /* Rpane */ - winset(src, "rpane", "background-color=#272727") - winset(src, "rpane.rpanewindow", "background-color=#272727") + winset(src, "rpane", "background-color=#202020") + winset(src, "rpane.rpanewindow", "background-color=#202020") /* Browserwindow */ - winset(src, "browserwindow", "background-color=#272727") - winset(src, "browserwindow.browser", "background-color=#272727") + + //winset(src, "browserwindow", "background-color=#272727") + //winset(src, "browserwindow.browser", "background-color=#272727") /* Infowindow */ - winset(src, "infowindow", "background-color=#272727;text-color=#FFFFFF") - winset(src, "infowindow.info", "background-color=#272727;text-color=#FFFFFF;highlight-color=#009900;tab-text-color=#FFFFFF;tab-background-color=#272727") + winset(src, "infowindow", "background-color=#202020;text-color=#a4bad6") + winset(src, "infowindow.info", "background-color=#171717;text-color=#a4bad6;highlight-color=#009900;tab-text-color=#a4bad6;tab-background-color=#202020") + //Macros + winset(src, "default-Tab", "parent=default;name=Tab;command=\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[COLOR_DARK_INPUT_ENABLED]\\\"\"") + winset(src, "legacy-Tab", "parent=legacy;name=Tab;command=\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[COLOR_DARK_INPUT_DISABLED]\\\"\"") + // NOTIFY USER to_chat(src, "Darkmode Enabled") @@ -1014,29 +1023,36 @@ winset(src, "rpane.textb", "background-color=none;text-color=#000000") winset(src, "rpane.infob", "background-color=none;text-color=#000000") winset(src, "rpane.wikib", "background-color=none;text-color=#000000") - winset(src, "rpane.forumb", "background-color=none;text-color=#000000") + //winset(src, "rpane.forumb", "background-color=none;text-color=#000000") winset(src, "rpane.rulesb", "background-color=none;text-color=#000000") winset(src, "rpane.githubb", "background-color=none;text-color=#000000") - winset(src, "rpane.webmap", "background-color=#494949;text-color=#a4bad6") - /* Mainwindow */ - winset(src, "mainwindow.saybutton", "background-color=none;text-color=#000000") - winset(src, "mainwindow.mebutton", "background-color=none;text-color=#000000") + winset(src, "rpane.webmap", "background-color=none;text-color=#000000") + /* Outputwindow */ + winset(src, "outputwindow.saybutton", "background-color=none;text-color=#000000") + winset(src, "outputwindow.mebutton", "background-color=none;text-color=#000000") + ///// UI ELEMENTS ///// /* Mainwindow */ winset(src, "mainwindow", "background-color=none") winset(src, "mainwindow.mainvsplit", "background-color=none") winset(src, "mainwindow.tooltip", "background-color=none") /* Outputwindow */ + winset(src, "outputwindow", "background-color=none") + winset(src, "outputwindow.input", "text-color=none; background-color=#F0F0F0") winset(src, "outputwindow.browseroutput", "background-color=none") /* Rpane */ winset(src, "rpane", "background-color=none") winset(src, "rpane.rpanewindow", "background-color=none") /* Browserwindow */ - winset(src, "browserwindow", "background-color=none") - winset(src, "browserwindow.browser", "background-color=none") + //winset(src, "browserwindow", "background-color=none") + //winset(src, "browserwindow.browser", "background-color=none") /* Infowindow */ winset(src, "infowindow", "background-color=none;text-color=#000000") winset(src, "infowindow.info", "background-color=none;text-color=#000000;highlight-color=#007700;tab-text-color=#000000;tab-background-color=none") + //Macros + winset(src, "default-Tab", "parent=default;name=Tab;command=\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"") + winset(src, "legacy-Tab", "parent=legacy;name=Tab;command=\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"") + ///// NOTIFY USER ///// to_chat(src, "Darkmode Disabled") // what a sick fuck @@ -1347,7 +1363,14 @@ log_adminwarn("[key] has just connected with BYOND v[byond_version].[byond_build] for the first time. BYOND account registered on [byondacc_date] ([byondacc_age] days old)") /client/proc/show_update_notice() - to_chat(src, "Your BYOND client (v: [byond_version].[byond_build]) is out of date. This can cause glitches. We highly suggest you download the latest client from byond.com before playing. You can also update via the BYOND launcher application.") + var/list/msg = list({""}) + msg += "Ваша версия BYOND устарела:
    " + msg += "Это может привести к проблемам, таким как к неправильному отображением вещей или лагам.

    " + msg += "Ваша версия: [byond_version].[byond_build]
    " + msg += "Требуемая версия, чтобы убрать это окно: [SUGGESTED_CLIENT_VERSION].[SUGGESTED_CLIENT_BUILD] или выше
    " + msg += "Посетите сайт BYOND, чтобы скачать последнюю версию.
    " + src << browse(msg.Join(""), "window=warning_popup") + to_chat(src, span_userdanger("Ваш клиент BYOND (версия: [byond_version].[byond_build]) устарел. Это может вызвать лаги. Мы крайне рекомендуем скачать последнюю версию с byond.com Прежде чем играть. Также можете обновиться через приложение BYOND.")) /client/proc/update_ambience_pref() @@ -1401,7 +1424,7 @@ /// Returns the biggest number from client.view so we can do easier maths /client/proc/maxview() var/list/screensize = getviewsize(view) - return max(screensize[1], screensize[2]) + return round(max(screensize[1], screensize[2]) / 2) #undef LIMITER_SIZE diff --git a/code/modules/client/preference/loadout/loadout_donor.dm b/code/modules/client/preference/loadout/loadout_donor.dm index 338ecaa832a..bc1229a279c 100644 --- a/code/modules/client/preference/loadout/loadout_donor.dm +++ b/code/modules/client/preference/loadout/loadout_donor.dm @@ -3,6 +3,18 @@ sort_category = "Donor" subtype_path = /datum/gear/donor +/datum/gear/donor/ussptracksuit_black + donator_tier = 1 + cost = 1 + display_name = "track suit (black)" + path = /obj/item/clothing/under/ussptracksuit_black + +/datum/gear/donor/ussptracksuit_white + donator_tier = 1 + cost = 1 + display_name = "track suit (white)" + path = /obj/item/clothing/under/ussptracksuit_white + /datum/gear/donor/kittyears display_name = "Kitty ears" path = /obj/item/clothing/head/kitty diff --git a/code/modules/client/preference/loadout/loadout_glasses.dm b/code/modules/client/preference/loadout/loadout_glasses.dm index a84af914c49..b53c8bd360e 100644 --- a/code/modules/client/preference/loadout/loadout_glasses.dm +++ b/code/modules/client/preference/loadout/loadout_glasses.dm @@ -22,3 +22,8 @@ /datum/gear/glasses/prescription display_name = "Prescription glasses" path = /obj/item/clothing/glasses/regular + +/datum/gear/glasses/sectacticool + display_name = "Security tactical glasses" + path = /obj/item/clothing/glasses/hud/security/sunglasses/tacticool + allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot") diff --git a/code/modules/client/preference/loadout/loadout_hat.dm b/code/modules/client/preference/loadout/loadout_hat.dm index 3844d89b851..8e08be9c49c 100644 --- a/code/modules/client/preference/loadout/loadout_hat.dm +++ b/code/modules/client/preference/loadout/loadout_hat.dm @@ -202,3 +202,8 @@ /datum/gear/hat/capsolgov display_name = "cap, Sol Gov" path = /obj/item/clothing/head/soft/solgov + +/datum/gear/hat/lwhelmet + display_name = "security lightweight helmet" + path = /obj/item/clothing/head/helmet/lightweighthelmet + allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot") diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm index 2016a37c03b..025838ff869 100644 --- a/code/modules/client/preference/loadout/loadout_uniform.dm +++ b/code/modules/client/preference/loadout/loadout_uniform.dm @@ -442,3 +442,13 @@ display_name = "hawaiian shirt (orange)" description = "Come one step closer and I will knock his teeth out!" path = /obj/item/clothing/under/orangehawaiianshirt + +/datum/gear/uniform/ussptracksuit_red + display_name = "track suit (red)" + description = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + path = /obj/item/clothing/under/ussptracksuit_red + +/datum/gear/uniform/ussptracksuit_blue + display_name = "track suit (blue)" + description = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + path = /obj/item/clothing/under/ussptracksuit_blue diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index cb0827a3c31..0f4169430a5 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -140,7 +140,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/e_colour = "#000000" //Eye color var/alt_head = "None" //Alt head style. var/species = "Human" - var/language = "None" //Secondary language + var/language = "None" //Secondary language for choise. var/autohiss_mode = AUTOHISS_FULL //Species autohiss level. OFF, BASIC, FULL. var/tts_seed = null @@ -196,6 +196,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/med_record = "" var/sec_record = "" var/gen_record = "" + var/exploit_record = "" var/disabilities = 0 var/nanotrasen_relation = "Neutral" @@ -245,6 +246,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/list/keybindings_overrides = null /// View range preference for this client var/viewrange = DEFAULT_CLIENT_VIEWSIZE + /// How dark things are if client is a ghost, 0-255 + var/ghost_darkness_level = LIGHTING_PLANE_ALPHA_VISIBLE /// Minigames notification about their end, start and etc. var/minigames_notifications = TRUE @@ -253,7 +256,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts /datum/preferences/New(client/C) parent = C b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") - parent?.set_macros() max_gear_slots = CONFIG_GET(number/max_loadout_points) var/loaded_preferences_successfully = FALSE if(istype(C)) @@ -307,13 +309,12 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts species = initial(species) S = GLOB.all_species[species] random_character() - dat += "

    " dat += "
    " dat += "Name: " dat += "[real_name]" dat += "(Randomize)" - dat += "(Always Randomize)
    " + dat += "(Always Randomize)
    " dat += "
    " dat += "
    " dat += "Slot [default_slot][saved ? "" : " (empty)"]
    " @@ -748,13 +749,13 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/list/html = list() html += "" if(!length(SSjobs.occupations)) - html += "The Jobs subsystem is not yet finished creating jobs, please try again later" - html += "
    Done

    " // Easier to press up here. + html += "Подсистема вакансий ещё не успела создать вакансии, пожалуйста, повторите попытку позже" + html += "
    Принять

    " // Easier to press up here. else html += "
    " - html += "Choose occupation chances
    Unavailable occupations are crossed out.

    " - html += "
    Save

    " // Easier to press up here. - html += "
    Left-click to raise an occupation preference, right-click to lower it.
    " + html += "Выберите предпочитаемые должности
    Определите приоритет на получение желаемой работы.

    " + html += "
    Сохранить

    " // Easier to press up here. + html += "
    Левый клик - для повышения предпочтения профессии, правый - для понижения.
    " html += "" html += "
    " // Table within a table for alignment, also allows you to easily add more colomns. html += "" @@ -788,95 +789,96 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts html += "
    " index = 0 + var/color + color = "dark" + if(job.admin_only) + color = "light" html += "" + html += "[rank]" continue if(jobban_isbanned(user, job.title)) - html += "[rank]" + html += "[rank]" continue var/available_in_playtime = job.available_in_playtime(user.client) if(available_in_playtime) - html += "[rank]" + html += "[rank]" continue if(job.barred_by_disability(user.client)) - html += "[rank]" + html += "[rank]" continue if(!job.player_old_enough(user.client)) var/available_in_days = job.available_in_days(user.client) - html += "[rank]" + html += "[rank]" continue if(!job.character_old_enough(user.client)) - html += "[rank]" - continue - if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian")) - html += "[rank]" + html += "[rank]" continue if((job.title in GLOB.command_positions) || (job.title == "AI"))//Bold head jobs - html += "[rank]" + html += "[rank]" else - html += "[rank]" + html += "[rank]" + if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian")) + html += "" + continue html += "" + index += 1 + html += "" continue - /* - if(GetJobDepartment(job, 1) & job.flag) - HTML += " \[High]" - else if(GetJobDepartment(job, 2) & job.flag) - HTML += " \[Medium]" - else if(GetJobDepartment(job, 3) & job.flag) - HTML += " \[Low]" + + if(prefLowerLevel>1) + html += "[prefLevelLabel]" else - HTML += " \[NEVER]" - */ - html += "[prefLevelLabel]" + html += "[prefLevelLabel]" html += "" + index += 1 for(var/i in 1 to limit - index) // Finish the column so it is even html += "" @@ -885,22 +887,23 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts switch(alternate_option) if(GET_RANDOM_JOB) - html += "

    Get random job if preferences unavailable

    " + html += "

    Получить случайную работу, если предпочитаемая работа недоступна

    " if(BE_ASSISTANT) - html += "

    Be a civilian if preferences unavailable

    " + html += "

    Стать гражданским, если предпочитаемая работа недоступна

    " if(RETURN_TO_LOBBY) - html += "

    Return to lobby if preferences unavailable

    " + html += "

    Вернуться в лобби, если предпочитаемая работа недоступна

    " - html += "
    Reset
    " - html += "

    Learn About Job Selection
    " + html += "
    Сброс
    " + html += "

    Узнать о \"Выборе должности\"
    " html += "" user << browse(null, "window=preferences") // user << browse(HTML, "window=mob_occupation;size=[width]x[height]") - var/datum/browser/popup = new(user, "mob_occupation", "
    Occupation Preferences
    ", width, height) + var/datum/browser/popup = new(user, "mob_occupation", "
    Предпочитаемые должности
    ", width, height) popup.set_window_options("can_close=0") var/html_string = html.Join() popup.set_content(html_string) + popup.add_stylesheet("bootstrap.min.css", 'html/browser/bootstrap.min.css') popup.open(0) return @@ -921,6 +924,15 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts parent?.update_active_keybindings() return keybindings +/datum/preferences/proc/null_longtextfix(raw) + var/text + if(raw) + try + text = raw + catch + text = "" + return text + /datum/preferences/proc/capture_keybinding(mob/user, datum/keybinding/KB, old) var/HTML = {"
    Keybinding: [KB.name]

    Press any key to change
    Press ESC to clear
    @@ -1104,11 +1116,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts HTML += "
    Security Records
    " if(length(sec_record) <= 40) - HTML += "[sec_record]
    " + HTML += "[sec_record]" else - HTML += "[copytext_char(sec_record, 1, 37)]...
    " + HTML += "[copytext_char(sec_record, 1, 37)]..." + + HTML += "
    Exploitable Records
    " - HTML += "\[Done\]" + if(length(exploit_record) <= 40) + HTML += "[exploit_record]" + else + HTML += "[copytext_char(exploit_record, 1, 37)]..." + + HTML += "

    \[Done\]" HTML += "" var/datum/browser/popup = new(user, "records", "
    Character Records
    ", 350, 300) @@ -1365,6 +1384,15 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts gen_record = genmsg SetRecords(user) + if(href_list["task"] == "exploit_record") + var/expmsg = input(usr,"Set your exploitable notes here. This info is available to traitors only.","Exploitable Records",html_decode(exploit_record)) as message + + if(expmsg != null) + expmsg = copytext(expmsg, 1, MAX_PAPER_MESSAGE_LEN) + expmsg = html_encode(expmsg) + + exploit_record = expmsg + SetRecords(user) if(href_list["preference"] == "gear") if(href_list["toggle_gear"]) @@ -1518,6 +1546,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts species = tgui_input_list(user, "Please select a species", "Character Generation", sortTim(new_species, cmp = /proc/cmp_text_asc)) if(!species) + species = prev_species return var/datum/species/NS = GLOB.all_species[species] if(!istype(NS)) //The species was invalid. Notify the user and fail out. @@ -1585,7 +1614,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts alt_head = "None" //No alt heads on species that don't have them. speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks. - + language = LANGUAGE_NONE body_accessory = null //no vulptail on humans damnit body_accessory = random_body_accessory(NS.name, NS.optional_body_accessory) @@ -1612,14 +1641,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts alert(user, "There are not currently any available secondary languages.") else */ - for(var/L in GLOB.all_languages) - var/datum/language/lang = GLOB.all_languages[L] - if(!(lang.flags & RESTRICTED)) - new_languages += lang.name - - language = tgui_input_list(user, "Please select a secondary language", "Character Generation", sortTim(new_languages, cmp = /proc/cmp_text_asc)) - if(!language) + for(var/language_name in GLOB.all_languages) + var/datum/language/lang = GLOB.all_languages[language_name] + if(lang.flags & UNIQUE) + if(language_name in S.secondary_langs) + new_languages += language_name + else if(!(lang.flags & RESTRICTED)) + new_languages += language_name + + var/new_language = tgui_input_list(user, "Please select a secondary language", "Character Generation", sortTim(new_languages, cmp = /proc/cmp_text_asc)) + if(!new_language) return + language = new_language if("autohiss_mode") if(S.autohiss_basic_map) @@ -2200,14 +2233,14 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts if("clientfps") var/version_message - if(user.client && user.client.byond_version < 511) - version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" - if(world.byond_version < 511) + if(user.client && user.client.byond_version < MINIMUM_FPS_VERSION) + version_message = "\nYou need to be using byond version [MINIMUM_FPS_VERSION] or later to take advantage of this feature, your version of [user.client.byond_version] is too low" + if(world.byond_version < MINIMUM_FPS_VERSION) version_message += "\nThis server does not currently support client side fps. You can set now for when it does." var/desiredfps = input(user, "Выберите желаемый FPS.[version_message]\n 0 = значение по умолчанию ([CONFIG_GET(number/clientfps)]) < РЕКОМЕНДОВАНО\n -1 = синхронизировано с сервером ([world.fps])\n30 = Может помочь при проблемах с плавностью.", "Настройка персонажа", clientfps) as null|num if(!isnull(desiredfps)) clientfps = desiredfps - if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511) + if(world.byond_version >= MINIMUM_FPS_VERSION && user.client && user.client.byond_version >= MINIMUM_FPS_VERSION) if(clientfps) parent.fps = clientfps else @@ -2585,6 +2618,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts else if(firstspace == name_length) real_name += "[character.gender==FEMALE ? pick(GLOB.last_names_female) : pick(GLOB.last_names)]" + character.add_language(language) @@ -2596,6 +2630,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts character.med_record = med_record character.sec_record = sec_record character.gen_record = gen_record + character.exploit_record = exploit_record character.change_gender(gender) character.age = age diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index b71da792be3..27ed97fce51 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -20,7 +20,8 @@ discord_id, discord_name, keybindings, - viewrange + viewrange, + ghost_darkness_level FROM [format_table_name("player")] WHERE ckey=:ckey"}, list( "ckey" = C.ckey @@ -53,6 +54,7 @@ discord_name = query.item[18] keybindings = init_keybindings(raw = query.item[19]) viewrange = query.item[20] + ghost_darkness_level = query.item[21] qdel(query) @@ -105,7 +107,8 @@ clientfps=:clientfps, parallax=:parallax, keybindings=:keybindings, - viewrange=:viewrange + viewrange=:viewrange, + ghost_darkness_level=:ghost_darkness_level WHERE ckey=:ckey"}, list( // OH GOD THE PARAMETERS "ooccolour" = ooccolor, @@ -125,7 +128,8 @@ "parallax" = parallax, "keybindings" = json_encode(keybindings_overrides), "viewrange" = viewrange, - "ckey" = C.ckey + "ghost_darkness_level" = ghost_darkness_level, + "ckey" = C.ckey, ) ) @@ -202,6 +206,7 @@ med_record, sec_record, gen_record, + exploit_record, disabilities, player_alt_titles, organ_data, @@ -279,6 +284,7 @@ med_record = query.item[42] sec_record = query.item[43] gen_record = query.item[44] + exploit_record = null_longtextfix(query.item[45]) // Apparently, the preceding vars weren't always encoded properly... if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags! flavor_text = html_encode(flavor_text) @@ -288,31 +294,33 @@ sec_record = html_encode(sec_record) if(findtext(gen_record, "<")) gen_record = html_encode(gen_record) - disabilities = text2num(query.item[45]) - player_alt_titles = params2list(query.item[46]) - organ_data = params2list(query.item[47]) - rlimb_data = params2list(query.item[48]) - nanotrasen_relation = query.item[49] - speciesprefs = text2num(query.item[50]) + if(findtext(exploit_record, "<")) + exploit_record = html_encode(exploit_record) + disabilities = text2num(query.item[46]) + player_alt_titles = params2list(query.item[47]) + organ_data = params2list(query.item[48]) + rlimb_data = params2list(query.item[49]) + nanotrasen_relation = query.item[50] + speciesprefs = text2num(query.item[51]) //socks - socks = query.item[51] - body_accessory = query.item[52] - loadout_gear = params2list(query.item[53]) - autohiss_mode = text2num(query.item[54]) - uplink_pref = query.item[55] + socks = query.item[52] + body_accessory = query.item[53] + loadout_gear = params2list(query.item[54]) + autohiss_mode = text2num(query.item[55]) + uplink_pref = query.item[56] // TTS - tts_seed = query.item[56] + tts_seed = query.item[57] //Emotes - custom_emotes_tmp = query.item[57] + custom_emotes_tmp = query.item[58] // Gradient - h_grad_style = query.item[58] - h_grad_offset_x = query.item[59] // parsed down below - h_grad_colour = query.item[60] - h_grad_alpha = query.item[61] + h_grad_style = query.item[59] + h_grad_offset_x = query.item[60] // parsed down below + h_grad_colour = query.item[61] + h_grad_alpha = query.item[62] saved = TRUE @@ -472,6 +480,7 @@ med_record=:med_record, sec_record=:sec_record, gen_record=:gen_record, + exploit_record=:exploit_record, player_alt_titles=:playertitlelist, disabilities=:disabilities, organ_data=:organlist, @@ -536,6 +545,7 @@ "med_record" = med_record, "sec_record" = sec_record, "gen_record" = gen_record, + "exploit_record" = exploit_record, "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it! "disabilities" = disabilities, "organlist" = (organlist ? organlist : ""), @@ -592,6 +602,7 @@ med_record, sec_record, gen_record, + exploit_record, player_alt_titles, disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs, socks, body_accessory, gear, autohiss, hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, uplink_pref, tts_seed, custom_emotes) @@ -620,6 +631,7 @@ :med_record, :sec_record, :gen_record, + :exploit_record, :playertitlelist, :disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs, :socks, :body_accessory, :gearlist, :autohiss_mode, :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :uplink_pref, :tts_seed, :custom_emotes) @@ -672,6 +684,7 @@ "med_record" = med_record, "sec_record" = sec_record, "gen_record" = gen_record, + "exploit_record" = exploit_record, "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it! "disabilities" = disabilities, "organlist" = (organlist ? organlist : ""), diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index a0022fb206b..6c4bdf0aa11 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -22,19 +22,22 @@ var/alt_desc = null var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect - var/up = 0 //but seperated to allow items to protect but not impair vision, like space helmets - - var/visor_flags = 0 //flags that are added/removed when an item is adjusted up/down - var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv - var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW //what to toggle when toggled with weldingvisortoggle() - - var/toggle_message = null - var/alt_toggle_message = null - var/active_sound = null - var/toggle_sound = null - var/toggle_cooldown = null + var/tint_up = 0 // tint when its up + var/up = FALSE //but seperated to allow items to protect but not impair vision, like space helmets + + var/visor_flags = NONE //flags that are added/removed when an item is adjusted up/down + var/visor_flags_inv = NONE //same as visor_flags, but for flags_inv + var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW | VISOR_FULL_HUD + //what to toggle when toggled with weldingvisortoggle() + + var/can_toggle = FALSE + var/toggle_on_message + var/toggle_off_message + var/active_sound + var/toggle_sound + var/toggle_cooldown = 0 var/cooldown = 0 - var/species_disguise = null + var/species_disguise var/magical = FALSE var/dyeable = FALSE var/heal_bodypart = null //If a bodypart or an organ is specified here, it will slowly regenerate while the clothes are worn. Currently only implemented for eyes, though. @@ -42,44 +45,49 @@ w_class = WEIGHT_CLASS_SMALL -/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc. - if(!can_use(user)) +/obj/item/clothing/update_icon_state() + if(!can_toggle) return FALSE + // Done as such to not break chameleon gear since you can't rely on initial states + icon_state = "[replacetext("[icon_state]", "_up", "")][up ? "_up" : ""]" + return TRUE - visor_toggling() - to_chat(user, "You adjust \the [src] [up ? "up" : "down"].") +/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc. + if(!can_use(user)) + return FALSE - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_head(src, forced = TRUE) - if(H.wear_mask == src) - H.wear_mask_update(src, FALSE) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + visor_toggling(user) + to_chat(user, span_notice("You adjust [src] [up ? "up" : "down"].")) + update_equipped_item() return TRUE + /obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags + if(!can_toggle) + return FALSE + + . = TRUE up = !up flags ^= visor_flags flags_inv ^= visor_flags_inv flags_cover ^= initial(flags_cover) - icon_state = "[initial(icon_state)][up ? "up" : ""]" if(visor_vars_to_toggle & VISOR_FLASHPROTECT) flash_protect ^= initial(flash_protect) if(visor_vars_to_toggle & VISOR_TINT) - tint ^= initial(tint) + tint = up ? tint_up : initial(tint) + update_icon(UPDATE_ICON_STATE) + // Aurora forensics port. /obj/item/clothing/clean_blood() . = ..() gunshot_residue = null + /obj/item/clothing/proc/can_use(mob/user) - if(user && ismob(user)) - if(!user.incapacitated()) - return TRUE + if(isliving(user) && !user.incapacitated()) + return TRUE return FALSE @@ -95,7 +103,7 @@ return FALSE -/obj/item/clothing/proc/refit_for_species(var/target_species) +/obj/item/clothing/proc/refit_for_species(target_species) //Set species_restricted list switch(target_species) if("Human", "Skrell") //humanoid bodytypes @@ -158,6 +166,7 @@ var/list/color_view = null//overrides client.color while worn var/prescription = FALSE var/prescription_upgradable = FALSE + var/over_hat = FALSE var/over_mask = FALSE //Whether or not the eyewear is rendered above the mask. Purely cosmetic. strip_delay = 20 // but seperated to allow items to protect but not impair vision, like space helmets put_on_delay = 25 @@ -180,6 +189,12 @@ SEE_PIXELS// if an object is located on an unlit area, but some of its pixels ar BLIND // can't see anything */ + +/obj/item/clothing/glasses/update_icon_state() + if(..()) + item_state = "[replacetext("[item_state]", "_up", "")][up ? "_up" : ""]" + + /obj/item/clothing/glasses/verb/adjust_eyewear() //Adjust eyewear to be worn above or below the mask. set name = "Adjust Eyewear" set category = "Object" @@ -230,20 +245,29 @@ BLIND // can't see anything return 0 // return 1 to cancel attack_hand() /obj/item/clothing/gloves/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour == TOOL_WIRECUTTER) if(!clipped) playsound(src.loc, W.usesound, 100, 1) user.visible_message("[user] snips the fingertips off [src].","You snip the fingertips off [src].") - clipped = 1 - name = "mangled [name]" - desc = "[desc] They have had the fingertips cut off of them." - update_icon() + clipped = TRUE + update_appearance() else to_chat(user, "[src] have already been clipped!") return else return ..() + +/obj/item/clothing/gloves/update_name(updates = ALL) + . = ..() + name = clipped ? "mangled [initial(name)]" : initial(name) + + +/obj/item/clothing/gloves/update_desc(updates = ALL) + . = ..() + desc = clipped ? "[initial(desc)] They have had the fingertips cut off of them." : initial(desc) + + /obj/item/clothing/under/proc/set_sensors(mob/living/user) if(user.stat || user.restrained()) return @@ -333,8 +357,6 @@ BLIND // can't see anything var/see_in_dark = 0 var/lighting_alpha - var/can_toggle = null - sprite_sheets = list( "Monkey" = 'icons/mob/clothing/species/monkey/head.dmi', "Farwa" = 'icons/mob/clothing/species/monkey/head.dmi', @@ -343,10 +365,51 @@ BLIND // can't see anything "Stok" = 'icons/mob/clothing/species/monkey/head.dmi' ) -///obj/item/clothing/head/equipped(var/mob/living/carbon/human/lesser/monkey/user, var/slot) //Смещаем шапки у обезьян -// ..() -// if(!issmall(user)) -// return + +/obj/item/clothing/head/update_icon_state() + if(..()) + item_state = "[replacetext("[item_state]", "_up", "")][up ? "_up" : ""]" + + +/obj/item/clothing/head/attack_self(mob/user) + adjust_headgear(user) + + +/obj/item/clothing/head/proc/adjust_headgear(mob/living/carbon/human/user) + if(!can_toggle || user.incapacitated() || world.time < cooldown + toggle_cooldown) + return FALSE + + . = TRUE + + cooldown = world.time + up = !up + update_icon(UPDATE_ICON_STATE) + if(user.head == src) + user.update_head(src, forced = TRUE) + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + else + update_equipped_item() + + if(up && toggle_on_message) + to_chat(user, span_notice("[toggle_on_message] [src]")) + else if(!up && toggle_off_message) + to_chat(user, span_notice("[toggle_off_message] [src]")) + + if(active_sound) + INVOKE_ASYNC(src, PROC_REF(headgear_loop_sound)) + + if(toggle_sound) + playsound(loc, toggle_sound, 100, FALSE, 4) + + +/obj/item/clothing/head/proc/headgear_loop_sound() + set waitfor = FALSE + + while(up) + playsound(loc, active_sound, 100, FALSE, 4) + sleep(1.5 SECONDS) + //Mask /obj/item/clothing/mask @@ -354,7 +417,6 @@ BLIND // can't see anything icon = 'icons/obj/clothing/masks.dmi' body_parts_covered = HEAD slot_flags = SLOT_MASK - var/mask_adjusted = 0 var/adjusted_flags = null strip_delay = 40 put_on_delay = 40 @@ -368,16 +430,22 @@ BLIND // can't see anything ) //Proc that moves gas/breath masks out of the way -/obj/item/clothing/mask/proc/adjustmask(var/mob/user) +/obj/item/clothing/mask/proc/adjustmask(mob/user) var/mob/living/carbon/human/H = usr //Used to check if the mask is on the head, to check if the hands are full, and to turn off internals if they were on when the mask was pushed out of the way. - if(user.incapacitated()) //This check allows you to adjust your masks while you're buckled into chairs or beds. - return - if(mask_adjusted) - icon_state = initial(icon_state) + if(!can_toggle || user.incapacitated()) //This check allows you to adjust your masks while you're buckled into chairs or beds. + return FALSE + if(is_obscured_for_unEquip(H)) + return FALSE + + . = TRUE + + up = !up + update_icon(UPDATE_ICON_STATE) + + if(!up) gas_transfer_coefficient = initial(gas_transfer_coefficient) permeability_coefficient = initial(permeability_coefficient) - to_chat(user, "You push \the [src] back into place.") - mask_adjusted = 0 + to_chat(user, span_notice("You push \the [src] back into place.")) slot_flags = initial(slot_flags) if(flags_inv != initial(flags_inv)) if(initial(flags_inv) & HIDENAME) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again. @@ -388,18 +456,11 @@ BLIND // can't see anything if(flags_cover != initial(flags_cover)) if(initial(flags_cover) & MASKCOVERSMOUTH) //If the mask covers the mouth when it's down and can be adjusted yet lost that trait when it was adjusted, make it cover the mouth again. flags_cover |= MASKCOVERSMOUTH - if(H.head == src && flags_inv == HIDENAME) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. - if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. - user.drop_item_ground(src) - else //Otherwise, put it in an available hand, the active one preferentially. - user.drop_item_ground(src) - user.put_in_hands(src) + else - icon_state += "_up" - to_chat(user, "You push \the [src] out of the way.") + to_chat(user, span_notice("You push \the [src] out of the way.")) gas_transfer_coefficient = null permeability_coefficient = null - mask_adjusted = 1 if(adjusted_flags) slot_flags = adjusted_flags if(ishuman(user) && H.internal && !H.get_organ_slot(INTERNAL_ORGAN_BREATHING_TUBE) && user.wear_mask == src) /*If the user was wearing the mask providing internals on their face at the time it was adjusted, turn off internals. @@ -413,18 +474,13 @@ BLIND // can't see anything flags_cover &= ~MASKCOVERSMOUTH if(flags & AIRTIGHT) //If the mask was airtight, it won't be anymore since you just pushed it off your face. flags &= ~AIRTIGHT - if(user.wear_mask == src && initial(flags_inv) == HIDENAME) //Means that you won't have to take off and put back on simple things like breath masks which, realistically, can just be pulled down off your face. - if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. - user.drop_item_ground(src) - else //Otherwise, put it in an available hand, the active one preferentially. - user.drop_item_ground(src) - user.put_in_hands(src) - H.wear_mask_update(src, toggle_off = mask_adjusted) - usr.update_inv_wear_mask() - usr.update_inv_head() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + + if(H?.wear_mask == src) + H.wear_mask_update(src, toggle_off = up) + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + else + update_equipped_item() // Changes the speech verb when wearing a mask if a value is returned /obj/item/clothing/mask/proc/change_speech_verb() @@ -436,9 +492,9 @@ BLIND // can't see anything icon = 'icons/obj/clothing/shoes.dmi' desc = "Comfortable-looking shoes." gender = PLURAL //Carn: for grammatically correct text-parsing - var/chained = 0 - var/can_cut_open = 0 - var/cut_open = 0 + //var/chained = 0 + var/can_cut_open = FALSE + var/cut_open = FALSE body_parts_covered = FEET slot_flags = SLOT_FEET pickup_sound = 'sound/items/handling/shoes_pickup.ogg' @@ -476,29 +532,44 @@ BLIND // can't see anything M.dropped() return - if(istype(I, /obj/item/wirecutters)) + if(I.tool_behaviour == TOOL_WIRECUTTER) if(can_cut_open) if(!cut_open) playsound(src.loc, I.usesound, 100, 1) user.visible_message("[user] cuts open the toes of [src].","You cut open the toes of [src].") - cut_open = 1 - icon_state = "[icon_state]_opentoe" - item_state = "[item_state]_opentoe" - name = "mangled [name]" - desc = "[desc] They have had their toes opened up." - update_icon() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.shoes == src) - user.update_inv_shoes() + cut_open = TRUE + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) else to_chat(user, "[src] have already had [p_their()] toes cut open!") return else return ..() + +/obj/item/clothing/shoes/update_name() + . = ..() + if(!cut_open) + return + name = "mangled [initial(name)]" + + +/obj/item/clothing/shoes/update_desc() + . = ..() + if(!cut_open) + return + desc = "[initial(desc)] They have had their toes opened up." + + +/obj/item/clothing/shoes/update_icon_state() + if(!cut_open) + return + icon_state = "[icon_state]_opentoe" + item_state = "[item_state]_opentoe" + update_equipped_item() + + /obj/item/proc/negates_gravity() - return 0 + return //Suit /obj/item/clothing/suit @@ -511,9 +582,8 @@ BLIND // can't see anything pickup_sound = 'sound/items/handling/cloth_pickup.ogg' slot_flags = SLOT_OCLOTHING var/blood_overlay_type = "suit" - var/suittoggled = FALSE - var/suit_adjusted = 0 - var/ignore_suitadjust = 1 + var/suit_adjusted = FALSE + var/ignore_suitadjust = TRUE var/adjust_flavour = null var/list/hide_tail_by_species = null max_integrity = 400 @@ -524,58 +594,59 @@ BLIND // can't see anything "Farwa" = 'icons/mob/clothing/species/monkey/suit.dmi', "Wolpin" = 'icons/mob/clothing/species/monkey/suit.dmi', "Neara" = 'icons/mob/clothing/species/monkey/suit.dmi', - "Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi' - //"Stok" = 'icons/mob/clothing/species/monkey/suit.dmi' + "Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi', + "Stok" = 'icons/mob/clothing/species/monkey/suit.dmi' ) //Proc that opens and closes jackets. -/obj/item/clothing/suit/proc/adjustsuit(var/mob/user) - if(!ignore_suitadjust) - if(!user.incapacitated()) - if(!(HULK in user.mutations)) - if(suit_adjusted) - var/flavour = "close" - icon_state = copytext(icon_state, 1, findtext(icon_state, "_open")) /*Trims the '_open' off the end of the icon state, thus avoiding a case where jackets that start open will - end up with a suffix of _open_open if adjusted twice, since their initial state is _open. */ - item_state = copytext(item_state, 1, findtext(item_state, "_open")) - if(adjust_flavour) - flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. - to_chat(user, "You [flavour] \the [src].") - suit_adjusted = 0 //Suit is no longer adjusted. - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - else - var/flavour = "open" - icon_state += "_open" - item_state += "_open" - if(adjust_flavour) - flavour = "[adjust_flavour]" - to_chat(user, "You [flavour] \the [src].") - suit_adjusted = 1 //Suit's adjusted. - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - else - if(user.can_unEquip(src)) //Checks to see if the item can be unequipped. If so, lets shred. Otherwise, struggle and fail. - if(contents) //If the suit's got any storage capability... - for(var/obj/item/O in contents) //AVOIDING ITEM LOSS. Check through everything that's stored in the jacket and see if one of the items is a pocket. - if(istype(O, /obj/item/storage/internal)) //If it's a pocket... - if(O.contents) //Check to see if the pocket's got anything in it. - for(var/obj/item/I in O.contents) //Dump the pocket out onto the floor below the user. - user.drop_item_ground(I, force = TRUE) - - user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] [user.p_their()] jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!") - user.temporarily_remove_item_from_inventory(src) - qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket. - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) - else - to_chat(user, "You yank and pull at \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")], however you are unable to change its state!")//Yep, that's all they get. Avoids having to snowflake in a cooldown. - - return - user.update_inv_wear_suit() +/obj/item/clothing/suit/proc/adjustsuit(mob/user) + if(ignore_suitadjust) + to_chat(user, span_notice("You attempt to button up the velcro on [src], before promptly realising how foolish you are.")) + return + if(user.incapacitated()) + return + + if((HULK in user.mutations)) + if(user.can_unEquip(src)) //Checks to see if the item can be unequipped. If so, lets shred. Otherwise, struggle and fail. + for(var/obj/item/thing in src) //AVOIDING ITEM LOSS. Check through everything that's stored in the jacket and see if one of the items is a pocket. + if(istype(thing, /obj/item/storage/internal)) //If it's a pocket... + for(var/obj/item/pocket_thing in thing) //Dump the pocket out onto the floor below the user. + user.drop_item_ground(pocket_thing, force = TRUE) + + user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] [user.p_their()] jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!") + user.temporarily_remove_item_from_inventory(src) + qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket. + user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) + else + to_chat(user, "You yank and pull at \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")], however you are unable to change its state!")//Yep, that's all they get. Avoids having to snowflake in a cooldown. + return + + update_icon(UPDATE_ICON_STATE) + update_equipped_item() + + if(suit_adjusted) + var/flavour = "close" + if(adjust_flavour) + flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. + to_chat(user, "You [flavour] [src].") else - to_chat(user, "You attempt to button up the velcro on \the [src], before promptly realising how foolish you are.") + var/flavour = "open" + if(adjust_flavour) + flavour = "[adjust_flavour]" + to_chat(user, "You [flavour] [src].") + + suit_adjusted = !suit_adjusted + + +/obj/item/clothing/suit/update_icon_state() + // Trims the '_open' off the end of the icon state, thus avoiding a case where jackets that start open will + // end up with a suffix of _open_open if adjusted twice, since their initial state is _open + var/base_icon_state = copytext(icon_state, 1, findtext(icon_state, "_open")) + var/base_item_state = copytext(item_state, 1, findtext(item_state, "_open")) + + icon_state = suit_adjusted ? base_icon_state : "[base_icon_state]_open" + item_state = suit_adjusted ? base_item_state : "[base_item_state]_open" + // Proc used to check if suit storage is limited by item weight // Allows any suit to have their own weight limit for items that can be equipped into suit storage @@ -657,10 +728,10 @@ BLIND // can't see anything var/obj/item/tank/jetpack/suit/jetpack = null -/obj/item/clothing/suit/space/New() +/obj/item/clothing/suit/space/Initialize(mapload) + . = ..() if(jetpack && ispath(jetpack)) jetpack = new jetpack(src) - ..() /obj/item/clothing/suit/space/screwdriver_act(mob/user, obj/item/I) @@ -679,22 +750,18 @@ BLIND // can't see anything to_chat(user, span_notice("You successfully remove the jetpack from [src].")) -/obj/item/clothing/suit/space/equipped(mob/user, slot, initial) +/obj/item/clothing/suit/space/equipped(mob/user, slot, initial = FALSE) . = ..() - - if(jetpack) - if(slot == slot_wear_suit) - for(var/X in jetpack.actions) - var/datum/action/A = X - A.Grant(user) + if(jetpack && slot == slot_wear_suit) + for(var/datum/action/action as anything in jetpack.actions) + action.Grant(user) /obj/item/clothing/suit/space/dropped(mob/user, silent = FALSE) - ..() + . = ..() if(jetpack) - for(var/X in jetpack.actions) - var/datum/action/A = X - A.Remove(user) + for(var/datum/action/action as anything in jetpack.actions) + action.Remove(user) /obj/item/clothing/suit/space/attackby(obj/item/I, mob/user, params) @@ -736,8 +803,8 @@ BLIND // can't see anything "Monkey" = 'icons/mob/clothing/species/monkey/uniform.dmi', "Farwa" = 'icons/mob/clothing/species/monkey/uniform.dmi', "Wolpin" = 'icons/mob/clothing/species/monkey/uniform.dmi', - "Neara" = 'icons/mob/clothing/species/monkey/uniform.dmi' - //"Stok" = 'icons/mob/clothing/species/monkey/uniform.dmi' - стоки слишком жирные для маленькой одежды + "Neara" = 'icons/mob/clothing/species/monkey/uniform.dmi', + "Stok" = 'icons/mob/clothing/species/monkey/uniform.dmi' ) var/has_sensor = TRUE//For the crew computer 2 = unable to change mode @@ -755,10 +822,12 @@ BLIND // can't see anything var/list/accessories = list() var/basecolor -/obj/item/clothing/under/rank/New() + +/obj/item/clothing/under/rank/Initialize(mapload) + . = ..() if(random_sensor) sensor_mode = pick(SENSOR_OFF, SENSOR_LIVING, SENSOR_VITALS, SENSOR_COORDS) - ..() + /obj/item/clothing/under/Destroy() QDEL_LIST(accessories) diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 9a44815a53e..8f602caf51c 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -1,40 +1,78 @@ -/obj/item/clothing/glasses/New() +/obj/item/clothing/glasses/Initialize(mapload) . = ..() if(prescription_upgradable && prescription) // Pre-upgraded upgradable glasses - name = "prescription [name]" + upgrade_prescription() -/obj/item/clothing/glasses/attackby(obj/item/O, mob/user) - if(user.stat || user.restrained() || !ishuman(user)) + +/obj/item/clothing/glasses/attackby(obj/item/I, mob/living/carbon/human/user, params) + if(!prescription_upgradable || user.incapacitated() || !ishuman(user)) return ..() - var/mob/living/carbon/human/H = user - if(prescription_upgradable) - if(istype(O, /obj/item/clothing/glasses/regular)) - if(prescription) - to_chat(H, "You can't possibly imagine how adding more lenses would improve \the [name].") - return - H.drop_transfer_item_to_loc(O, src) // Store the glasses for later removal - to_chat(H, "You fit \the [name] with lenses from \the [O].") - prescription = TRUE - name = "prescription [name]" - if(H.glasses == src) - H.update_nearsighted_effects() - return - if(prescription && istype(O, /obj/item/screwdriver)) - var/obj/item/clothing/glasses/regular/G = locate() in src - if(!G) - G = new(get_turf(H)) - to_chat(H, "You salvage the prescription lenses from \the [name].") - prescription = FALSE - name = initial(name) - H.put_in_hands(G) - if(H.glasses == src) - H.update_nearsighted_effects() - return - return ..() + + + if(!istype(I, /obj/item/clothing/glasses/regular)) + return ..() + + if(prescription) + to_chat(user, span_warning("You can't possibly imagine how adding more lenses would improve [src].")) + return + + if(!user.drop_transfer_item_to_loc(I, src)) // Store the glasses for later removal + return + + upgrade_prescription(I, user) + + +/obj/item/clothing/glasses/update_name(updates = ALL) + . = ..() + name = prescription ? "prescription [initial(name)]" : initial(name) + + +/obj/item/clothing/glasses/proc/upgrade_prescription(obj/item/I, mob/living/carbon/human/user) + if(!I) + new /obj/item/clothing/glasses/regular(src) + else if(I.loc != src) + I.forceMove(src) + prescription = TRUE + update_appearance(UPDATE_NAME) + if(user) + to_chat(user, span_notice("You fit [src] with lenses from [I].")) + if(user.glasses == src) + user.update_nearsighted_effects() + + +/obj/item/clothing/glasses/proc/remove_prescription(mob/living/carbon/human/user) + var/obj/item/clothing/glasses/regular/prescription_glasses = locate() in src + + if(!prescription_glasses) + return + + prescription = FALSE + update_appearance(UPDATE_NAME) + + prescription_glasses.forceMove(drop_location()) + + if(user) + to_chat(user, span_notice("You salvage the prescription lenses from [src].")) + user.put_in_hands(prescription_glasses, ignore_anim = FALSE) + if(user.glasses == src) + user.update_nearsighted_effects() + + +/obj/item/clothing/glasses/screwdriver_act(mob/living/user, obj/item/I) + if(!prescription) + to_chat(user, span_notice("There are no prescription lenses in [src].")) + return FALSE + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return TRUE + remove_prescription(user) + return TRUE + /obj/item/clothing/glasses/visor_toggling() - ..() + . = ..() + if(!.) + return . if(visor_vars_to_toggle & VISOR_VISIONFLAGS) vision_flags ^= initial(vision_flags) if(visor_vars_to_toggle & VISOR_DARKNESSVIEW) @@ -42,15 +80,6 @@ if(visor_vars_to_toggle & VISOR_INVISVIEW) invis_view ^= initial(invis_view) -/obj/item/clothing/glasses/weldingvisortoggle(mob/user) - . = ..() - if(. && user) - if(ishuman(user)) - var/mob/living/carbon/human/human = user - human.wear_glasses_update(src) - else - user.update_sight() - user.update_inv_glasses() /obj/item/clothing/glasses/meson name = "Optical Meson Scanner" @@ -440,6 +469,7 @@ actions_types = list(/datum/action/item_action/toggle) flash_protect = 2 tint = 2 + can_toggle = TRUE visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', @@ -449,8 +479,8 @@ "Farwa" = 'icons/mob/clothing/species/monkey/eyes.dmi', "Wolpin" = 'icons/mob/clothing/species/monkey/eyes.dmi', "Neara" = 'icons/mob/clothing/species/monkey/eyes.dmi', - "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi' - ) + "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi', + ) /obj/item/clothing/glasses/welding/attack_self(mob/user) weldingvisortoggle(user) @@ -559,6 +589,7 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE resistance_flags = LAVA_PROOF | FIRE_PROOF HUDType = DATA_HUD_MEDICAL_ADVANCED + var/double_eye = FALSE sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi', @@ -570,20 +601,34 @@ "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi' ) + +/obj/item/clothing/glasses/hud/godeye/update_icon_state() + icon_state = "[double_eye ? "double" : ""]godeye" + item_state = "[double_eye ? "double" : ""]godeye" + + +/obj/item/clothing/glasses/hud/godeye/update_desc(updates = ALL) + . = ..() + if(!double_eye) + desc = initial(desc) + return + desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you." + + /obj/item/clothing/glasses/hud/godeye/attackby(obj/item/W, mob/user, params) - if(istype(W, src) && W != src && W.loc == user) - if(W.icon_state == "godeye") - W.icon_state = "doublegodeye" - W.item_state = "doublegodeye" - W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you." - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.update_inv_wear_mask() - else + if(istype(W, type) && W != src && W.loc == user && !double_eye) + if(double_eye) to_chat(user, span_notice("The eye winks at you and vanishes into the abyss, you feel really unlucky.")) - qdel(src) + qdel(src) + return + + double_eye = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + user.wear_glasses_update(src) + return ..() + /obj/item/clothing/glasses/tajblind name = "embroidered veil" desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes." @@ -591,6 +636,7 @@ item_state = "tajblind" flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) + tint = 3 sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', @@ -610,26 +656,20 @@ item_state = "tajblind_engi" vision_flags = SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + flash_protect = 2 + var/flash_protect_up = 0 + /obj/item/clothing/glasses/tajblind/eng/sunglasses - flash_protect = 1 - tint = 1 + flash_protect_up = 1 + tint_up = 1 + /obj/item/clothing/glasses/tajblind/eng/toggle_veil(mob/user) - if(user.canmove && !user.incapacitated()) - if(up) - up = !up - tint = initial(tint) - flash_protect = initial(flash_protect) - to_chat(user, "You activate [src], allowing you to see.") - else - up = !up - tint = 3 - flash_protect = 2 - to_chat(user, "You deactivate [src], obscuring your vision.") - var/mob/living/carbon/user1 = user - user1.update_tint() - user1.update_inv_glasses() + . = ..() + if(.) + flash_protect = up ? flash_protect_up : initial(flash_protect) + /obj/item/clothing/glasses/tajblind/sci name = "hi-tech veil" @@ -641,7 +681,7 @@ /obj/item/clothing/glasses/tajblind/sci/sunglasses flash_protect = 1 - tint = 1 + tint_up = 1 /obj/item/clothing/glasses/tajblind/cargo name = "khaki veil" @@ -654,24 +694,23 @@ /obj/item/clothing/glasses/tajblind/cargo/sunglasses flash_protect = 1 - tint = 1 + tint_up = 1 + /obj/item/clothing/glasses/tajblind/attack_self(mob/user) toggle_veil(user) -/obj/item/clothing/glasses/proc/toggle_veil(mob/user) - if(user.canmove && !user.incapacitated()) - if(up) - up = !up - tint = initial(tint) - to_chat(user, "You activate [src], allowing you to see.") - else - up = !up - tint = 3 - to_chat(user, "You deactivate [src], obscuring your vision.") - var/mob/living/carbon/user1 = user - user1.update_tint() - user1.update_inv_glasses() + +/obj/item/clothing/glasses/proc/toggle_veil(mob/living/carbon/human/user) + if(user.incapacitated()) + return FALSE + . = TRUE + up = !up + tint = up ? tint_up : initial(tint) + if(user.glasses == src) + to_chat(user, span_notice("[up ? "You deactivate [src], obscuring your vision." : "You activate [src], allowing you to see."]")) + user.wear_glasses_update(src) + /obj/item/clothing/glasses/sunglasses/blindfold/cucumbermask desc = "A simple pair of two cucumber slices. Medically proven to be able to heal your eyes over time." @@ -679,3 +718,4 @@ heal_bodypart = INTERNAL_ORGAN_EYES icon_state = "cucumbermask" item_state = "cucumbermask" + diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index fb5b7dbc8d7..803f76fa03a 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -7,7 +7,7 @@ /// The visual icons granted by wearing these glasses. var/HUDType = null /// List of things added to examine text, like security or medical records. - var/list/examine_extensions = null + var/examine_extensions = 0 /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot, initial) @@ -31,6 +31,24 @@ emagged = TRUE desc = desc + " The display flickers slightly." +/obj/item/clothing/glasses/hud/visor_toggling(mob/living/carbon/human/user) + . = ..() + if(!.) + return + if(visor_vars_to_toggle & VISOR_EXAM_EXTENTIONS) + examine_extensions ^= initial(examine_extensions) + + if(visor_vars_to_toggle & VISOR_HUDTYPE) + HUDType ^= initial(HUDType) + + var/datum/atom_hud/H = GLOB.huds[initial(HUDType)] + if(istype(user) && src == user.glasses) + if(HUDType) + H.add_hud_to(user) + + else + H.remove_hud_from(user) + /* MEDICAL */ @@ -41,7 +59,7 @@ MEDICAL icon_state = "healthhud" origin_tech = "magnets=3;biotech=2" HUDType = DATA_HUD_MEDICAL_ADVANCED - examine_extensions = list(EXAMINE_HUD_MEDICAL) + examine_extensions = EXAMINE_HUD_MEDICAL sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', @@ -78,6 +96,7 @@ MEDICAL icon_state = "tajblind_med" item_state = "tajblind_med" flags_cover = GLASSESCOVERSEYES + tint = 3 actions_types = list(/datum/action/item_action/toggle) sprite_sheets = list( @@ -94,7 +113,7 @@ MEDICAL /obj/item/clothing/glasses/hud/health/tajblind/sunglasses see_in_dark = 1 flash_protect = 1 - tint = 1 + tint_up = 1 /obj/item/clothing/glasses/hud/health/tajblind/attack_self(mob/user) toggle_veil(user) @@ -152,12 +171,13 @@ DIAGNOSTIC icon_state = "tajblind_diagnostic" item_state = "tajblind_diagnostic" flags_cover = GLASSESCOVERSEYES + tint = 3 actions_types = list(/datum/action/item_action/toggle) /obj/item/clothing/glasses/hud/diagnostic/tajblind/sunglasses see_in_dark = 1 flash_protect = 1 - tint = 1 + tint_up = 1 /obj/item/clothing/glasses/hud/diagnostic/tajblind/attack_self(mob/user) toggle_veil(user) @@ -173,7 +193,7 @@ SECURITY origin_tech = "magnets=3;combat=2" var/global/list/jobs[0] HUDType = DATA_HUD_SECURITY_ADVANCED - examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE) + examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', @@ -187,7 +207,7 @@ SECURITY ) /obj/item/clothing/glasses/hud/security/read_only - examine_extensions = list(EXAMINE_HUD_SECURITY_READ) + examine_extensions = EXAMINE_HUD_SECURITY_READ /obj/item/clothing/glasses/hud/security/night name = "\improper Night Vision Security HUD" @@ -218,8 +238,33 @@ SECURITY "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi' ) +/obj/item/clothing/glasses/hud/security/sunglasses/tacticool + name = "security tactical glasses" + desc = "Ballistic glasses with a security HUD. Gives you tacticool protection and selfish increase. The elastic band allows it to be worn over a helmet." + icon_state = "secgoggles-g" + item_state = "secgoggles-g" + over_mask = TRUE + over_hat = TRUE + can_toggle = TRUE + visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_DARKNESSVIEW | VISOR_FULL_HUD + actions_types = list(/datum/action/item_action/toggle) + + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', + "Drask" = 'icons/mob/clothing/species/drask/eyes.dmi', + "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi', + "Monkey" = 'icons/mob/clothing/species/monkey/eyes.dmi', + "Farwa" = 'icons/mob/clothing/species/monkey/eyes.dmi', + "Wolpin" = 'icons/mob/clothing/species/monkey/eyes.dmi', + "Neara" = 'icons/mob/clothing/species/monkey/eyes.dmi', + "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi' + ) + +/obj/item/clothing/glasses/hud/security/sunglasses/tacticool/attack_self(mob/user) + weldingvisortoggle(user) + /obj/item/clothing/glasses/hud/security/sunglasses/read_only - examine_extensions = list(EXAMINE_HUD_SECURITY_READ) + examine_extensions = EXAMINE_HUD_SECURITY_READ /obj/item/clothing/glasses/hud/security/sunglasses/prescription prescription = TRUE @@ -243,6 +288,8 @@ SECURITY icon_state = "tajblind_sec" item_state = "tajblind_sec" flags_cover = GLASSESCOVERSEYES + tint_up = 1 + tint = 3 actions_types = list(/datum/action/item_action/toggle) sprite_sheets = list( @@ -258,7 +305,7 @@ SECURITY toggle_veil(user) /obj/item/clothing/glasses/hud/security/sunglasses/tajblind/read_only - examine_extensions = list(EXAMINE_HUD_SECURITY_READ) + examine_extensions = EXAMINE_HUD_SECURITY_READ /* HYDROPONIC @@ -269,7 +316,7 @@ HYDROPONIC desc = "A heads-up display capable of analyzing the health and status of plants growing in hydro trays and soil." icon_state = "hydroponichud" HUDType = DATA_HUD_HYDROPONIC - examine_extensions = list(DATA_HUD_HYDROPONIC) + examine_extensions = EXAMINE_HUD_BOTANY sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi', "Drask" = 'icons/mob/clothing/species/drask/eyes.dmi', @@ -304,12 +351,13 @@ HYDROPONIC desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. There is botanical hud in it." icon_state = "tajblind_bot" item_state = "tajblind_bot" + tint = 3 actions_types = list(/datum/action/item_action/toggle) /obj/item/clothing/glasses/hud/hydroponic/tajblind/sunglasses see_in_dark = 1 flash_protect = 1 - tint = 1 + tint_up = 1 /obj/item/clothing/glasses/hud/hydroponic/tajblind/attack_self(mob/user) toggle_veil(user) @@ -324,7 +372,7 @@ SKILLS icon_state = "skill" item_state = "glasses" HUDType = DATA_HUD_SECURITY_BASIC - examine_extensions = list(EXAMINE_HUD_SKILLS) + examine_extensions = EXAMINE_HUD_SKILLS sprite_sheets = list( "Drask" = 'icons/mob/clothing/species/drask/eyes.dmi', "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi', @@ -361,12 +409,13 @@ SKILLS icon_state = "tajblind_skill" item_state = "tajblind_skill" flags_cover = GLASSESCOVERSEYES + tint = 3 actions_types = list(/datum/action/item_action/toggle) /obj/item/clothing/glasses/hud/skills/tajblind/sunglasses see_in_dark = 1 flash_protect = 1 - tint = 1 + tint_up = 1 /obj/item/clothing/glasses/hud/skills/tajblind/attack_self(mob/user) toggle_veil(user) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index a8525be2633..25f78c6eddb 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -102,8 +102,8 @@ /obj/item/clothing/gloves/color/black/thief pickpocket = 1 -/obj/item/clothing/gloves/color/black/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wirecutters)) +/obj/item/clothing/gloves/color/black/attackby(obj/item/W, mob/user, params) + if(W.tool_behaviour == TOOL_WIRECUTTER) if(can_be_cut && icon_state == initial(icon_state))//only if not dyed var/confirm = alert("Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.","Cut tips?","Yes","No") if(get_dist(user, src) > 1) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 98b76d8646a..85220c7a610 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -99,9 +99,9 @@ /obj/item/clothing/gloves/color/yellow/stun/get_cell() return cell -/obj/item/clothing/gloves/color/yellow/stun/New() - ..() - update_icon() +/obj/item/clothing/gloves/color/yellow/stun/Initialize(mapload) + . = ..() + update_icon(UPDATE_OVERLAYS) /obj/item/clothing/gloves/color/yellow/stun/Destroy() QDEL_NULL(cell) @@ -132,12 +132,13 @@ return TRUE return FALSE -/obj/item/clothing/gloves/color/yellow/stun/update_icon() - ..() - overlays.Cut() - overlays += "gloves_wire" + +/obj/item/clothing/gloves/color/yellow/stun/update_overlays() + . = ..() + . += "gloves_wire" if(cell) - overlays += "gloves_cell" + . += "gloves_cell" + /obj/item/clothing/gloves/color/yellow/stun/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/stock_parts/cell)) @@ -147,7 +148,7 @@ return cell = W to_chat(user, "You attach [W] to [src].") - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(user, "[src] already has a cell.") else @@ -161,7 +162,7 @@ to_chat(user, "You cut [cell] away from [src].") cell.forceMove(get_turf(loc)) cell = null - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/clothing/gloves/color/yellow/stun/emp_act() if(!ishuman(loc)) diff --git a/code/modules/clothing/gloves/rings.dm b/code/modules/clothing/gloves/rings.dm index 3b9e4eadab8..f5bcbbd698e 100644 --- a/code/modules/clothing/gloves/rings.dm +++ b/code/modules/clothing/gloves/rings.dm @@ -14,11 +14,11 @@ var/stud = 0 var/ring_color = "iron" -/obj/item/clothing/gloves/ring/New() - ..() - update_icon() +/obj/item/clothing/gloves/ring/Initialize(mapload) + . = ..() + update_icon(UPDATE_ICON_STATE) -/obj/item/clothing/gloves/ring/update_icon() +/obj/item/clothing/gloves/ring/update_icon_state() icon_state = "[stud ? "d_" : ""][ring_color]ring" /obj/item/clothing/gloves/ring/examine(mob/user) @@ -28,7 +28,7 @@ if(stud) . += "It is adorned with a single gem." -/obj/item/clothing/gloves/ring/attackby(obj/item/I as obj, mob/user as mob, params) +/obj/item/clothing/gloves/ring/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/stack/sheet/mineral/diamond)) var/obj/item/stack/sheet/mineral/diamond/D = I if(stud) @@ -76,10 +76,10 @@ icon_state = "redring" ring_color = "red" -/obj/item/clothing/gloves/ring/plastic/random/New() +/obj/item/clothing/gloves/ring/plastic/random/Initialize(mapload) ring_color = pick("white","blue","red") name = "[ring_color] plastic ring" - ..() + . = ..() // weird /obj/item/clothing/gloves/ring/glass diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 45d0984d685..99db59689fe 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -24,24 +24,21 @@ /obj/item/clothing/head/hardhat/attack_self() toggle_helmet_light() + /obj/item/clothing/head/hardhat/proc/toggle_helmet_light() on = !on if(on) turn_on() else turn_off() - update_icon() + update_icon(UPDATE_ICON_STATE) + -/obj/item/clothing/head/hardhat/update_icon() +/obj/item/clothing/head/hardhat/update_icon_state() icon_state = "hardhat[on]_[item_color]" item_state = "hardhat[on]_[item_color]" - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_head() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - ..() + update_equipped_item() + /obj/item/clothing/head/hardhat/proc/turn_on() set_light(brightness_on) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 298a86c5c38..5323bc59fbf 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -28,25 +28,12 @@ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/helmet.dmi' ) -/obj/item/clothing/head/helmet/attack_self(mob/user) - if(can_toggle && !user.incapacitated()) - if(world.time > cooldown + toggle_cooldown) - cooldown = world.time - up = !up - flags ^= visor_flags - flags_inv ^= visor_flags_inv - icon_state = "[initial(icon_state)][up ? "up" : ""]" - to_chat(user, "[up ? alt_toggle_message : toggle_message] \the [src]") - - user.update_inv_head() - - if(active_sound) - while(up) - playsound(src.loc, "[active_sound]", 100, 0, 4) - sleep(15) - if(toggle_sound) - playsound(src.loc, "[toggle_sound]", 100, 0, 4) +/obj/item/clothing/head/helmet/adjust_headgear(mob/user) + . = ..() + if(.) + flags ^= visor_flags + flags_inv ^= visor_flags_inv /obj/item/clothing/head/helmet/visor name = "visor helmet" @@ -122,10 +109,10 @@ name = "helmet of justice" desc = "WEEEEOOO. WEEEEEOOO. WEEEEOOOO." icon_state = "justice" - toggle_message = "You turn off the lights on" - alt_toggle_message = "You turn on the lights on" + toggle_on_message = "You turn off the lights on" + toggle_off_message = "You turn on the lights on" actions_types = list(/datum/action/item_action/toggle_helmet_light) - can_toggle = 1 + can_toggle = TRUE toggle_cooldown = 20 active_sound = 'sound/items/weeoo1.ogg' dog_fashion = null @@ -134,8 +121,8 @@ name = "alarm helmet" desc = "WEEEEOOO. WEEEEEOOO. STOP THAT MONKEY. WEEEOOOO." icon_state = "justice2" - toggle_message = "You turn off the light on" - alt_toggle_message = "You turn on the light on" + toggle_on_message = "You turn off the light on" + toggle_off_message = "You turn on the light on" /obj/item/clothing/head/helmet/swat @@ -214,10 +201,10 @@ flags = BLOCKHAIR item_state = "gladiator" flags_inv = HIDEMASK|HIDEHEADSETS|HIDEGLASSES - toggle_message = "You attach the face shield to the" - alt_toggle_message = "You remove the face shield from the" + toggle_on_message = "You attach the face shield to the" + toggle_off_message = "You remove the face shield from the" actions_types = list(/datum/action/item_action/toggle_helmet_mode) - can_toggle = 1 + can_toggle = TRUE toggle_cooldown = 20 toggle_sound = 'sound/items/zippoclose.ogg' dog_fashion = null @@ -421,3 +408,24 @@ see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE species_restricted = list("Human", "Slime People", "Skeleton", "Nucleation", "Machine") + +/obj/item/clothing/head/helmet/lightweighthelmet + name = "lightweight helmet" + desc = "Standard Security gear. Protects the head from impacts." + icon_state = "lightweighthelmet" + item_state = "lightweighthelmet" + flags_inv = HIDEHEADSETS + strip_delay = 60 + flags = BLOCKHEADHAIR + flags_cover = null + dog_fashion = null + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/helmet.dmi', + "Drask" = 'icons/mob/clothing/species/drask/helmet.dmi', + "Grey" = 'icons/mob/clothing/species/grey/helmet.dmi', + "Monkey" = 'icons/mob/clothing/species/monkey/head.dmi', + "Farwa" = 'icons/mob/clothing/species/monkey/head.dmi', + "Wolpin" = 'icons/mob/clothing/species/monkey/head.dmi', + "Neara" = 'icons/mob/clothing/species/monkey/head.dmi', + "Stok" = 'icons/mob/clothing/species/monkey/head.dmi' + ) diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index f875c19e718..e87a1509def 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -21,6 +21,7 @@ materials = list(MAT_METAL=1750, MAT_GLASS=400) flash_protect = 2 tint = 2 + can_toggle = TRUE armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 60) flags_inv = HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME actions_types = list(/datum/action/item_action/toggle) @@ -44,9 +45,6 @@ "Stok" = 'icons/mob/clothing/species/monkey/head.dmi' ) -/obj/item/clothing/head/welding/attack_self(mob/user) - weldingvisortoggle(user) - /obj/item/clothing/head/welding/flamedecal name = "flame decal welding helmet" desc = "A welding helmet adorned with flame decals, and several cryptic slogans of varying degrees of legibility." @@ -62,8 +60,8 @@ desc = "A white welding helmet with a character written across it." icon_state = "welding_white" -/obj/item/clothing/head/welding/attack_self() - toggle() +/obj/item/clothing/head/welding/attack_self(mob/user) + weldingvisortoggle(user) /obj/item/clothing/head/welding/attackby(obj/item/I, mob/living/user) if(istype(I, /obj/item/toy/crayon/spraycan)) @@ -98,40 +96,6 @@ return ..() -/obj/item/clothing/head/welding/proc/toggle() - if(up) - up = !up - flags_cover |= (HEADCOVERSEYES | HEADCOVERSMOUTH) - flags_inv |= (HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME) - if(paint) - icon_state = paint - else - icon_state = initial(icon_state) - to_chat(usr, "You flip the [src] down to protect your eyes.") - flash_protect = 2 - tint = 2 - else - up = !up - flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH) - flags_inv &= ~(HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME) - if(paint) - icon_state = "[paint]up" - else - icon_state = "[initial(icon_state)]up" - to_chat(usr, "You push the [src] up out of your face.") - flash_protect = 0 - tint = 0 - var/mob/living/carbon/user = usr - user.update_tint() - user.update_inv_head() //so our mob-overlays update - user.update_inv_wear_mask() - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - - /* * Cakehat */ @@ -139,40 +103,55 @@ name = "cake-hat" desc = "It's tasty looking!" icon_state = "cake0" + base_icon_state = "cake" flags_cover = HEADCOVERSEYES armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) - var/onfire = 0.0 - var/status = 0 - var/fire_resist = T0C+1300 //this is the max temp it can stand before you start to cook. although it might not burn away, you take damage - var/processing = 0 //I dont think this is used anywhere. + var/on_fire = FALSE + /obj/item/clothing/head/cakehat/process() - if(!onfire) - STOP_PROCESSING(SSobj, src) - return + if(!on_fire) + return PROCESS_KILL + + var/turf/cake_turf = loc + if(is_equipped(include_pockets = TRUE, include_hands = TRUE)) + cake_turf = loc.loc + + if(isturf(cake_turf)) + cake_turf.hotspot_expose(700, 1) + + +/obj/item/clothing/head/cakehat/attack_self(mob/user) + toggle_cake_light(user) - var/turf/location = src.loc - if(istype(location, /mob/)) - var/mob/living/carbon/human/M = location - if(M.l_hand == src || M.r_hand == src || M.head == src) - location = M.loc - - if(istype(location, /turf)) - location.hotspot_expose(700, 1) - -/obj/item/clothing/head/cakehat/attack_self(mob/user as mob) - if(status > 1) return - src.onfire = !( src.onfire ) - if(src.onfire) - src.force = 3 - src.damtype = "fire" - src.icon_state = "cake1" + +/obj/item/clothing/head/cakehat/proc/toggle_cake_light(mob/user) + on_fire = !on_fire + update_icon(UPDATE_ICON_STATE) + user?.visible_message( + span_notice("[user] [on_fire ? "lights up" : "extinguishes"] [src]."), + span_notice("You [on_fire ? "lighted up" : "extinguished"] [src]."), + ) + if(on_fire) + set_light(1.5, 1, LIGHT_COLOR_YELLOW) + force = 3 + damtype = BURN START_PROCESSING(SSobj, src) else - src.force = null - src.damtype = "brute" - src.icon_state = "cake0" - return + set_light(0) + force = 0 + damtype = BRUTE + STOP_PROCESSING(SSobj, src) + + +/obj/item/clothing/head/cakehat/update_icon_state() + icon_state = "[base_icon_state][on_fire]" + + +/obj/item/clothing/head/cakehat/extinguish_light(force = FALSE) + if(!force || !on_fire) + return + toggle_cake_light() /* @@ -181,12 +160,16 @@ /obj/item/clothing/head/ushanka name = "ushanka" desc = "Perfect for winter in Siberia, da?" - icon_state = "ushankadown" - item_state = "ushankadown" + icon_state = "ushanka" + item_state = "ushanka" flags_inv = HIDEHEADSETS cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT dog_fashion = /datum/dog_fashion/head/ushanka + actions_types = list(/datum/action/item_action/toggle_helmet_mode) + can_toggle = TRUE + toggle_on_message = "You raise the ear flaps on" + toggle_off_message = "You lower the ear flaps on" sprite_sheets = list( "Grey" = 'icons/mob/clothing/species/grey/head.dmi', "Monkey" = 'icons/mob/clothing/species/monkey/head.dmi', @@ -196,16 +179,6 @@ "Stok" = 'icons/mob/clothing/species/monkey/head.dmi' ) -/obj/item/clothing/head/ushanka/attack_self(mob/user as mob) - if(src.icon_state == "ushankadown") - src.icon_state = "ushankaup" - src.item_state = "ushankaup" - to_chat(user, "You raise the ear flaps on the ushanka.") - else - src.icon_state = "ushankadown" - src.item_state = "ushankadown" - to_chat(user, "You lower the ear flaps on the ushanka.") - /obj/item/clothing/head/sovietsidecap name = "\improper Soviet side cap" desc = "A simple military cap with a Soviet star on the front. What it lacks in protection it makes up for in revolutionary spirit." @@ -280,43 +253,42 @@ name = "kitty ears" desc = "A pair of kitty ears. Meow!" icon_state = "kitty" - var/icon/mob dog_fashion = /datum/dog_fashion/head/kitty + var/mob/living/carbon/human/previous_owner + var/outer_state = "kitty" + var/inner_state = "kittyinner" -/obj/item/clothing/head/kitty/update_icon(var/mob/living/carbon/human/user) - if(!istype(user)) return - var/obj/item/organ/external/head/head_organ = user.get_organ(BODY_ZONE_HEAD) - mob = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "kitty") - mob.Blend(head_organ.hair_colour, ICON_ADD) +/obj/item/clothing/head/kitty/mouse + name = "mouse ears" + desc = "A pair of mouse ears. Squeak!" + icon_state = "mousey" + outer_state = "mousey" + inner_state = "mouseyinner" - var/icon/earbit = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "kittyinner") - mob.Blend(earbit, ICON_OVERLAY) - icon_override = mob +/obj/item/clothing/head/kitty/Destroy() + previous_owner = null + return ..() -/obj/item/clothing/head/kitty/equipped(mob/M, slot, initial) - . = ..() - - if(ishuman(M) && slot == slot_head) - update_icon(M) +/obj/item/clothing/head/kitty/equipped(mob/user, slot, initial) + . = ..() + if(. && slot == slot_head) + update_look(user) -/obj/item/clothing/head/kitty/mouse - name = "mouse ears" - desc = "A pair of mouse ears. Squeak!" - icon_state = "mousey" -/obj/item/clothing/head/kitty/mouse/update_icon(var/mob/living/carbon/human/user) - if(!istype(user)) return +/obj/item/clothing/head/kitty/proc/update_look(mob/living/carbon/human/user) + if(!ishuman(user) || user == previous_owner) + return + previous_owner = user var/obj/item/organ/external/head/head_organ = user.get_organ(BODY_ZONE_HEAD) - mob = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "mousey") - mob.Blend(head_organ.hair_colour, ICON_ADD) - - var/icon/earbit = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "mouseyinner") - mob.Blend(earbit, ICON_OVERLAY) + var/icon/new_look = icon('icons/mob/clothing/head.dmi', outer_state) + new_look.Blend(head_organ.hair_colour, ICON_ADD) + new_look.Blend(icon('icons/mob/clothing/head.dmi', inner_state), ICON_OVERLAY) + icon_override = new_look + user.update_inv_head() - icon_override = mob /obj/item/clothing/head/cardborg name = "cardborg helmet" @@ -338,19 +310,18 @@ ) -/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot, initial) +/obj/item/clothing/head/cardborg/equipped(mob/living/carbon/human/user, slot, initial) . = ..() + if(ishuman(user) && slot == slot_head && istype(user.wear_suit, /obj/item/clothing/suit/cardborg)) + var/obj/item/clothing/suit/cardborg/user_suit = user.wear_suit + user_suit.disguise(user, src) - if(ishuman(user) && slot == slot_head) - var/mob/living/carbon/human/H = user - if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) - var/obj/item/clothing/suit/cardborg/CB = H.wear_suit - CB.disguise(user, src) /obj/item/clothing/head/cardborg/dropped(mob/living/user, silent = FALSE) - ..() + . = ..() user.remove_alt_appearance("standard_borg_disguise") + /* * Head Mirror */ diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 34e2b64ec12..2cf395d7c33 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -4,7 +4,7 @@ icon_state = "cargosoft" item_state = "helmet" item_color = "cargo" - var/flipped = 0 + var/flipped = FALSE actions_types = list(/datum/action/item_action/flip_cap) dog_fashion = /datum/dog_fashion/head/cargo_tech sprite_sheets = list( @@ -17,27 +17,30 @@ ) dyeable = TRUE + +/obj/item/clothing/head/soft/update_icon_state() + icon_state = flipped ? "[item_color]soft_flipped" : "[item_color]soft" + update_equipped_item() + + /obj/item/clothing/head/soft/dropped(mob/user, silent = FALSE) - icon_state = "[item_color]soft" - flipped = 0 - ..() + . = ..() + if(flipped) + flipped = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/item/clothing/head/soft/attack_self(mob/user) flip(user) + /obj/item/clothing/head/soft/proc/flip(mob/user) flipped = !flipped + update_icon(UPDATE_ICON_STATE) if(flipped) - icon_state = "[item_color]soft_flipped" - to_chat(usr, "You flip the hat backwards.") + to_chat(user, span_notice("You flip the hat backwards.")) else - icon_state = "[item_color]soft" - to_chat(user, "You flip the hat back in normal position.") - user.update_inv_head() //so our mob-overlays update - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + to_chat(user, span_notice("You flip the hat back in normal position.")) /obj/item/clothing/head/soft/red name = "red cap" diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index cac4042c6e9..6295c77592a 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -6,6 +6,7 @@ flags = BLOCKHAIR flags_inv = HIDENAME w_class = WEIGHT_CLASS_SMALL + can_toggle = TRUE actions_types = list(/datum/action/item_action/adjust) adjusted_flags = SLOT_HEAD @@ -26,12 +27,24 @@ "Stok" = 'icons/mob/clothing/species/monkey/mask.dmi' ) -/obj/item/clothing/mask/balaclava/attack_self(var/mob/user) +/obj/item/clothing/mask/balaclava/attack_self(mob/user) adjustmask(user) -/obj/item/clothing/mask/balaclava/adjustmask(user) - ..() - flags = mask_adjusted ? null : initial(flags) +/obj/item/clothing/mask/balaclava/adjustmask(mob/user) + . = ..() + if(!.) + return + var/mob/living/carbon/human/H = usr + if(H.l_hand && H.r_hand) + user.drop_item_ground(src) + else + user.drop_item_ground(src) + user.put_in_hands(src) + + if(!up) + flags |= BLOCKHAIR + else + flags &= ~BLOCKHAIR /obj/item/clothing/mask/luchador name = "Luchador Mask" diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index 7603c354d17..9712a8cdc10 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -10,6 +10,7 @@ permeability_coefficient = 0.50 actions_types = list(/datum/action/item_action/adjust) resistance_flags = NONE + can_toggle = TRUE sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', "Vox Armalis" = 'icons/mob/clothing/species/armalis/mask.dmi', @@ -29,7 +30,7 @@ "Stok" = 'icons/mob/clothing/species/monkey/mask.dmi' ) -/obj/item/clothing/mask/breath/attack_self(var/mob/user) +/obj/item/clothing/mask/breath/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/breath/AltClick(mob/living/user) @@ -57,7 +58,7 @@ species_restricted = list("Vox", "Vox Armalis") //These should fit the "Mega Vox" just fine. actions_types = null -/obj/item/clothing/mask/breath/vox/attack_self(var/mob/user) +/obj/item/clothing/mask/breath/vox/attack_self(mob/user) return /obj/item/clothing/mask/breath/vox/AltClick(mob/user) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index ecd69b85e3f..f36c1724294 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -38,6 +38,7 @@ materials = list(MAT_METAL=4000, MAT_GLASS=2000) flash_protect = 2 tint = 2 + can_toggle = TRUE armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 55) origin_tech = "materials=2;engineering=3" actions_types = list(/datum/action/item_action/toggle) @@ -46,9 +47,15 @@ visor_flags_inv = HIDEGLASSES resistance_flags = FIRE_PROOF + /obj/item/clothing/mask/gas/welding/attack_self(mob/user) weldingvisortoggle(user) + +/obj/item/clothing/mask/gas/welding/adjustmask(mob/user) + return + + /obj/item/clothing/mask/gas/explorer name = "explorer gas mask" desc = "A military-grade gas mask that can be connected to an air supply." @@ -56,6 +63,7 @@ actions_types = list(/datum/action/item_action/adjust) armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40) resistance_flags = FIRE_PROOF + can_toggle = TRUE sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', @@ -74,16 +82,32 @@ "Stok" = 'icons/mob/clothing/species/monkey/mask.dmi' ) + /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) adjustmask(user) -/obj/item/clothing/mask/gas/explorer/adjustmask(user) - ..() - w_class = mask_adjusted ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL -/obj/item/clothing/mask/gas/explorer/folded/Initialize() +/obj/item/clothing/mask/gas/explorer/adjustmask(mob/user) . = ..() - adjustmask() + if(.) + w_class = up ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL + + +/obj/item/clothing/mask/gas/explorer/folded/Initialize(mapload) + . = ..() + force_adjust_mask() + + +/obj/item/clothing/mask/gas/explorer/folded/proc/force_adjust_mask() + up = !up + update_icon(UPDATE_ICON_STATE) + gas_transfer_coefficient = null + permeability_coefficient = null + flags_cover &= ~MASKCOVERSMOUTH + flags_inv &= ~HIDENAME + flags &= ~AIRTIGHT + w_class = WEIGHT_CLASS_SMALL + //Bane gas mask /obj/item/clothing/mask/banemask @@ -288,9 +312,12 @@ desc = "A standard issue Security gas mask with integrated 'Compli-o-nator 3000' device, plays over a dozen pre-recorded compliance phrases designed to get scumbags to stand still whilst you taze them. Do not tamper with the device." icon_state = "sechailer" item_state = "sechailer" + flags_inv = HIDENAME + flags_cover = MASKCOVERSMOUTH var/phrase = 1 var/aggressiveness = 1 var/safety = 1 + can_toggle = TRUE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/adjust, /datum/action/item_action/selectphrase) var/phrase_list = list( @@ -329,6 +356,7 @@ icon_state = "hosmask" aggressiveness = 3 phrase = 12 + can_toggle = FALSE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase) /obj/item/clothing/mask/gas/sechailer/warden @@ -337,6 +365,7 @@ icon_state = "wardenmask" aggressiveness = 3 phrase = 12 + can_toggle = FALSE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase) @@ -346,6 +375,7 @@ icon_state = "officermask" aggressiveness = 3 phrase = 12 + can_toggle = FALSE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase) /obj/item/clothing/mask/gas/sechailer/blue @@ -355,6 +385,7 @@ item_state = "blue_sechailer" aggressiveness = 3 phrase = 12 + can_toggle = FALSE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase) /obj/item/clothing/mask/gas/sechailer/cyborg @@ -362,6 +393,7 @@ desc = "A set of recognizable pre-recorded messages for cyborgs to use when apprehending criminals." icon = 'icons/obj/device.dmi' icon_state = "taperecorder_idle" + can_toggle = FALSE actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase) /obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, actiontype) @@ -401,8 +433,14 @@ else to_chat(user, "It's broken.") + var/datum/action/item_action/halt/halt_action = locate() in actions + if(halt_action) + halt_action.name = "[uppertext(key)]!" + halt_action.UpdateButtonIcon() + + /obj/item/clothing/mask/gas/sechailer/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/screwdriver)) + if(W.tool_behaviour == TOOL_SCREWDRIVER) switch(aggressiveness) if(1) to_chat(user, "You set the aggressiveness restrictor to the second position.") @@ -422,7 +460,7 @@ phrase = 1 if(5) to_chat(user, "You adjust the restrictor but nothing happens, probably because its broken.") - else if(istype(W, /obj/item/wirecutters)) + else if(W.tool_behaviour == TOOL_WIRECUTTER) if(aggressiveness != 5) to_chat(user, "You broke it!") aggressiveness = 5 diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 3ad5c475930..eb9b12ed201 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -23,7 +23,7 @@ ) // Clumsy folks can't take the mask off themselves. -/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob) +/obj/item/clothing/mask/muzzle/attack_hand(mob/user) if(user.wear_mask == src && !user.IsAdvancedToolUser()) return 0 else if(security_lock && locked) @@ -207,7 +207,7 @@ return loc return FALSE -/obj/item/clothing/mask/muzzle/safety/shock/proc/process_activation(var/obj/D, var/normal = 1, var/special = 1) +/obj/item/clothing/mask/muzzle/safety/shock/proc/process_activation(obj/D, normal = 1, special = 1) visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") var/mob/living/L = can_shock(loc) if(!L) @@ -224,11 +224,11 @@ trigger.HasProximity(AM) -/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M as mob, list/message_pieces) +/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M, list/message_pieces) if(trigger) trigger.hear_talk(M, message_pieces) -/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M as mob, msg) +/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M, msg) if(trigger) trigger.hear_message(M, msg) @@ -243,6 +243,7 @@ flags_cover = MASKCOVERSMOUTH gas_transfer_coefficient = 0.90 permeability_coefficient = 0.01 + can_toggle = TRUE armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 25, "rad" = 0, "fire" = 0, "acid" = 0) actions_types = list(/datum/action/item_action/adjust) @@ -264,7 +265,7 @@ ) -/obj/item/clothing/mask/surgical/attack_self(var/mob/user) +/obj/item/clothing/mask/surgical/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/fakemoustache @@ -332,19 +333,6 @@ w_class = WEIGHT_CLASS_SMALL gas_transfer_coefficient = 0.90 -/* -------------------------------- - * Хрен знает зачем у нас тут шарф у которого даже спрайта нет. И который ещё и маска... - * Я пожалуй оставлю, но закоменчу этот код. -/obj/item/clothing/mask/ninjascarf - name = "ninja scarf" - desc = "A stealthy, dark scarf." - icon_state = "ninja_scarf" - item_state = "ninja_scarf" - flags_cover = MASKCOVERSMOUTH - w_class = WEIGHT_CLASS_SMALL - gas_transfer_coefficient = 0.90 -*/ - /obj/item/clothing/mask/pig name = "pig mask" desc = "A rubber pig mask." @@ -534,7 +522,7 @@ adjusted_flags = SLOT_HEAD icon_state = "bandbotany" dyeable = TRUE - + can_toggle = TRUE sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', @@ -553,9 +541,18 @@ ) actions_types = list(/datum/action/item_action/adjust) -/obj/item/clothing/mask/bandana/attack_self(var/mob/user) +/obj/item/clothing/mask/bandana/attack_self(mob/user) adjustmask(user) +/obj/item/clothing/mask/bandana/adjustmask(mob/user) + ..() + var/mob/living/carbon/human/H = usr + if(H.l_hand && H.r_hand) + user.drop_item_ground(src) + else + user.drop_item_ground(src) + user.put_in_hands(src) + /obj/item/clothing/mask/bandana/red name = "red bandana" icon_state = "bandred" @@ -663,3 +660,39 @@ /obj/item/clothing/mask/gas/voice_modulator/change_speech_verb() if(voice_modulator.active) return pick("modulates", "drones", "hums", "buzzes") + +//sec scarf + +/obj/item/clothing/mask/secscarf + name = "security scarf" + desc = "Bleck security snood. Excellent replacement for a balaclava." + icon_state = "secscarf" + item_state = "secscarf" + icon = 'icons/obj/clothing/masks.dmi' + flags_inv = HIDENAME + flags = BLOCKFACIALHAIR + flags_cover = MASKCOVERSMOUTH + can_toggle = TRUE + strip_delay = 20 + put_on_delay = 20 + armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) + gas_transfer_coefficient = 0.90 + permeability_coefficient = 0.90 + actions_types = list(/datum/action/item_action/adjust) + + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', + "Drask" = 'icons/mob/clothing/species/drask/mask.dmi', + "Grey" = 'icons/mob/clothing/species/grey/mask.dmi', + "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', + "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', + "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi', + "Monkey" = 'icons/mob/clothing/species/monkey/mask.dmi', + "Farwa" = 'icons/mob/clothing/species/monkey/mask.dmi', + "Wolpin" = 'icons/mob/clothing/species/monkey/mask.dmi', + "Neara" = 'icons/mob/clothing/species/monkey/mask.dmi', + "Stok" = 'icons/mob/clothing/species/monkey/mask.dmi' + ) + +/obj/item/clothing/mask/secscarf/attack_self(mob/user) + adjustmask(user) diff --git a/code/modules/clothing/neck/cloaks.dm b/code/modules/clothing/neck/cloaks.dm index efd54786445..a64160f61d7 100644 --- a/code/modules/clothing/neck/cloaks.dm +++ b/code/modules/clothing/neck/cloaks.dm @@ -10,8 +10,8 @@ /obj/item/clothing/neck/cloak/Initialize(mapload) . = ..() + AddComponent(/datum/component/spraycan_paintable) add_atom_colour(colour, FIXED_COLOUR_PRIORITY) - update_icon() /obj/item/clothing/neck/cloak/grey colour = "#535353" @@ -121,20 +121,3 @@ icon_state = "syndadmiral" item_state = "syndadmiral" -/obj/item/clothing/neck/toggle/attack_self(mob/user) - if(icon_state == initial(icon_state)) - icon_state = icon_state + "_t" - item_state = icon_state + "_t" - else - icon_state = initial(icon_state) - item_state = initial(item_state) - user.update_inv_neck() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/clothing/neck/cloak/New() - ..() - AddComponent(/datum/component/spraycan_paintable) - START_PROCESSING(SSobj, src) - update_icon() diff --git a/code/modules/clothing/neck/mantles.dm b/code/modules/clothing/neck/mantles.dm index a5c9a82195a..32285d87202 100644 --- a/code/modules/clothing/neck/mantles.dm +++ b/code/modules/clothing/neck/mantles.dm @@ -82,8 +82,7 @@ desc = "A tweed mantle, worn by the Research Director. Smells like science." icon_state = "rdmantle" -/obj/item/clothing/neck/mantle/New() - ..() +/obj/item/clothing/neck/mantle/Initialize(mapload) + . = ..() AddComponent(/datum/component/spraycan_paintable) - START_PROCESSING(SSobj, src) - update_icon() + diff --git a/code/modules/clothing/neck/ponchos.dm b/code/modules/clothing/neck/ponchos.dm index 59002150fae..be819ebe42a 100644 --- a/code/modules/clothing/neck/ponchos.dm +++ b/code/modules/clothing/neck/ponchos.dm @@ -25,12 +25,8 @@ "Wryn" = 'icons/mob/clothing/species/wryn/neck.dmi' ) -/obj/item/clothing/neck/poncho/update_icon() - . = ..() - if(flipped) - icon_state = "[item_color]poncho_flip" - else - icon_state = "[item_color]poncho" +/obj/item/clothing/neck/poncho/update_icon_state() + icon_state = "[item_color]poncho[flipped ? "_flip" : ""]" /obj/item/clothing/neck/poncho/AltClick(mob/living/carbon/human/user) if(!iscarbon(user)) @@ -57,7 +53,7 @@ ..() if(flipped) flipped = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/clothing/neck/poncho/equipped(mob/user, slot, initial) . = ..() @@ -65,18 +61,17 @@ var/mob/living/carbon/human/human = user if((slot != human.neck) && flipped) flipped = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/clothing/neck/poncho/proc/flip(mob/user) if(user.incapacitated()) to_chat(user, span_warning("You can't do that right now!")) return flipped = !flipped + update_icon(UPDATE_ICON_STATE) if(flipped) - update_icon() to_chat(user, "You flip [src] behind your back.") else - update_icon() to_chat(user, "You flip [src] to its normal position.") user.update_inv_neck() diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 13a72265047..40d8a31f0dc 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -99,18 +99,24 @@ QDEL_NULL(shackles) return ..() + /obj/item/clothing/shoes/orange/attack_self(mob/user) if(shackles) user.put_in_hands(shackles) shackles = null slowdown = SHOES_SLOWDOWN - icon_state = "orange" + update_icon(UPDATE_ICON_STATE) + + +/obj/item/clothing/shoes/orange/update_icon_state() + icon_state = "orange[shackles ? "1" : ""]" + /obj/item/clothing/shoes/orange/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/restraints/handcuffs) && !shackles) - if(user.drop_transfer_item_to_loc(I, src)) - shackles = I - slowdown = 15 - icon_state = "orange1" - return + if(istype(I, /obj/item/restraints/handcuffs) && !shackles && user.drop_transfer_item_to_loc(I, src)) + shackles = I + slowdown = 15 + update_icon(UPDATE_ICON_STATE) + return return ..() + diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 5124a5c2a73..affd6bb1c19 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -4,7 +4,7 @@ icon_state = "magboots0" origin_tech = "materials=3;magnets=4;engineering=4" var/magboot_state = "magboots" - var/magpulse = 0 + var/magpulse = FALSE var/slowdown_active = 2 var/slowdown_passive = SHOES_SLOWDOWN var/magpulse_name = "mag-pulse traction system" @@ -40,21 +40,31 @@ magpulse_name = "anchoring spikes" slowdown_active = 2 -/obj/item/clothing/shoes/magboots/attack_self(mob/user) + +/obj/item/clothing/shoes/magboots/update_icon_state() + icon_state = "[magboot_state][magpulse]" + + +/obj/item/clothing/shoes/magboots/attack_self(mob/user, forced = FALSE) + toggle_magpulse(user, forced) + + +/obj/item/clothing/shoes/magboots/proc/toggle_magpulse(mob/user, forced) if(magpulse) + START_PROCESSING(SSobj, src) //Gravboots flags &= ~NOSLIP slowdown = slowdown_passive else + STOP_PROCESSING(SSobj, src) flags |= NOSLIP slowdown = slowdown_active magpulse = !magpulse - icon_state = "[magboot_state][magpulse]" - to_chat(user, "You [magpulse ? "enable" : "disable"] the [magpulse_name].") - user.update_inv_shoes() //so our mob-overlays update + update_icon(UPDATE_ICON_STATE) + if(!forced) + to_chat(user, "You [magpulse ? "enable" : "disable"] the [magpulse_name].") user.update_gravity(user.mob_has_gravity()) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_equipped_item() + /obj/item/clothing/shoes/magboots/negates_gravity() return flags & NOSLIP @@ -161,7 +171,7 @@ slowdown_active = 0 magboot_state = "gravboots" magpulse_name = "micro gravitational traction system" - var/datum/martial_art/grav_stomp/style = new //Only works with core and cell installed. + var/datum/martial_art/grav_stomp/style var/jumpdistance = 5 var/jumpspeed = 3 var/recharging_rate = 6 SECONDS @@ -171,6 +181,12 @@ var/obj/item/assembly/signaler/anomaly/grav/core = null var/obj/item/stock_parts/cell/cell = null + +/obj/item/clothing/shoes/magboots/gravity/Initialize() + . = ..() + style = new() + + /obj/item/clothing/shoes/magboots/gravity/Destroy() QDEL_NULL(style) QDEL_NULL(cell) @@ -189,7 +205,8 @@ else . += "It is missing a gravitational anomaly core and a power cell." -/obj/item/clothing/shoes/magboots/gravity/attack_self(mob/user) + +/obj/item/clothing/shoes/magboots/gravity/toggle_magpulse(mob/user, forced) if(!cell) to_chat(user, "Your boots do not have a power cell!") return @@ -199,8 +216,8 @@ if(!core) to_chat(user, "There's no core installed!") return + return ..() - ..() /obj/item/clothing/shoes/magboots/gravity/process() if(!cell) //There should be a cell here, but safety first @@ -209,7 +226,7 @@ if(ishuman(loc)) var/mob/living/carbon/human/user = loc to_chat(user, "[src] has ran out of charge, and turned off!") - attack_self(user) + attack_self(user, TRUE) else cell.use(power_consumption_rate) @@ -272,7 +289,7 @@ style.remove(H) if(magpulse) to_chat(user, "As [src] are removed, they deactivate.") - attack_self(user) + attack_self(user, TRUE) /obj/item/clothing/shoes/magboots/gravity/item_action_slot_check(slot) if(slot == slot_shoes) diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index b1eb9def064..9eef7a999aa 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -207,36 +207,44 @@ "Vox Armalis" = 'icons/mob/clothing/species/armalis/feet.dmi' ) -/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user) + +/obj/item/clothing/shoes/magboots/vox/update_icon_state() + return + + +/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user, forced = FALSE) + toggle_magpulse(user, forced) + + +/obj/item/clothing/shoes/magboots/vox/toggle_magpulse(mob/living/user, forced) if(magpulse) flags &= ~NOSLIP - magpulse = 0 - flags |= NODROP - to_chat(user, "You relax your deathgrip on the flooring.") + flags &= ~NODROP + slowdown = slowdown_passive + if(!forced) + to_chat(user, "You relax your deathgrip on the flooring.") else - //make sure these can only be used when equipped. - if(!ishuman(user)) - return - var/mob/living/carbon/human/H = user - if(H.shoes != src) - to_chat(user, "You will have to put on the [src] before you can do that.") - return + flags |= NOSLIP + flags |= NODROP //kinda hard to take off magclaws when you are gripping them tightly. + slowdown = slowdown_active + if(!forced) + to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.") + magpulse = !magpulse + user.update_gravity(user.mob_has_gravity()) - flags |= NOSLIP - magpulse = 1 - flags &= ~NODROP //kinda hard to take off magclaws when you are gripping them tightly. - to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.") - to_chat(user, "It would be hard to take off the [src] without relaxing your grip first.") +/obj/item/clothing/shoes/magboots/vox/item_action_slot_check(slot) + if(slot == slot_shoes) + return TRUE + //In case they somehow come off while enabled. /obj/item/clothing/shoes/magboots/vox/dropped(mob/user, silent = FALSE) - ..() - if(src.magpulse) + . = ..() + if(magpulse) user.visible_message("The [src] go limp as they are removed from [usr]'s feet.", "The [src] go limp as they are removed from your feet.") - flags &= ~NOSLIP - magpulse = 0 - flags &= ~NODROP + toggle_magpulse(user, forced = TRUE) + /obj/item/clothing/shoes/magboots/vox/examine(mob/user) . = ..() diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index b79da33d5bf..7a62cff2630 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -180,7 +180,7 @@ /obj/effect/chronos_cam name = "Chronosuit View" density = 0 - anchored = 1 + anchored = TRUE invisibility = INVISIBILITY_ABSTRACT opacity = 0 mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 2a9bccbb70f..47c0e306c85 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -238,11 +238,11 @@ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi' ) - allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore) + allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore, /obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat) hide_tail_by_species = list("Unathi, Ash Walker, Ash Walker Shaman, Draconid, Tajaran, Vox, Vulpkanin") -/obj/item/clothing/suit/space/hardsuit/ert/paranormal/New() - ..() +/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize(mapload) + . = ..() new /obj/item/nullrod(src) /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor @@ -314,6 +314,11 @@ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/helmet.dmi' ) + +/obj/item/clothing/head/helmet/space/hardsuit/deathsquad/update_icon_state() + return + + /obj/item/clothing/suit/space/hardsuit/deathsquad name = "deathsquad suit" desc = "A heavily armored, advanced space suit that protects against most forms of damage." @@ -338,6 +343,12 @@ "Stok" = 'icons/mob/clothing/species/monkey/suit.dmi', "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi' ) + + +/obj/item/clothing/suit/space/hardsuit/deathsquad/update_icon_state() + return + + /obj/item/clothing/suit/space/ert_eva_amber name = "ERT Amber Spacesuit" icon_state = "ert_eva_amber" diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 252092a5966..3d852b311a1 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -7,14 +7,11 @@ item_state = "eng_helm" armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 15, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75) item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite) - //heat_protection = - //max_heat_protection_temperature = - //resistance_flags = max_integrity = 300 var/basestate = "hardsuit" allowed = list(/obj/item/flashlight) var/brightness_on = 4 //luminosity when on - var/on = FALSE + var/light_on = FALSE var/obj/item/clothing/suit/space/hardsuit/suit actions_types = list(/datum/action/item_action/toggle_helmet_light) @@ -40,57 +37,78 @@ "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi' ) -/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) - toggle_light(user) -/obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(mob/user) - on = !on - icon_state = "[basestate][on]-[item_color]" +/obj/item/clothing/head/helmet/space/hardsuit/Destroy() + suit = null + return ..() - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_head() - if(on) - set_light(brightness_on) - else - set_light(0) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() +/obj/item/clothing/head/helmet/space/hardsuit/update_icon_state() + icon_state = "[basestate][light_on]-[item_color]" + + +/obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot, initial = FALSE) + . = ..() + if(slot != slot_head) + if(suit) + suit.RemoveHelmet() + else + qdel(src) -/obj/item/clothing/head/helmet/space/hardsuit/extinguish_light(force = FALSE) - if(on) - toggle_light() - visible_message(span_danger("[src]'s light fades and turns off.")) /obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user, silent = FALSE) - ..() + . = ..() + if(suit && loc != suit) + forceMove(suit) + else + qdel(src) + + +/obj/item/clothing/head/helmet/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) if(suit) suit.RemoveHelmet() + else + qdel(src) + + +/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) + light_on = !light_on + toggle_light(light_on) + + +/obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(enable = TRUE, update_buttons = TRUE) + light_on = enable + update_icon(UPDATE_ICON_STATE) + update_equipped_item(update_buttons) + + if(light_on) + set_light(brightness_on) + else + set_light(0) + /obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot) if(slot == slot_head) - return 1 - -/obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot, initial) - . = ..() + return TRUE - if(slot != slot_head) - if(suit) - suit.RemoveHelmet() - else - qdel(src) -/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg) +/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(msg) var/mob/wearer = loc if(msg && ishuman(wearer)) - wearer.show_message("[msg]", 1) + wearer.show_message(span_robot("[msg]"), 1) + /obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity) ..() display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!") + +/obj/item/clothing/head/helmet/space/hardsuit/extinguish_light(force = FALSE) + if(light_on) + toggle_light(enable = FALSE) + visible_message(span_danger("[src]'s light fades and turns off.")) + + /obj/item/clothing/suit/space/hardsuit name = "hardsuit" desc = "A special space suit for environments that might pose hazards beyond just the vacuum of space. Provides more protection than a standard space suit." @@ -126,15 +144,116 @@ ) -/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - ..() +/obj/item/clothing/suit/space/hardsuit/Initialize(mapload) + . = ..() + MakeHelmet() + + +/obj/item/clothing/suit/space/hardsuit/Destroy() + if(helmet) + QDEL_NULL(helmet) + QDEL_NULL(jetpack) + return ..() + + +/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet() + if(!helmettype || helmet) + return + + var/obj/item/clothing/head/helmet/space/hardsuit/new_helmet = new helmettype(src) + new_helmet.suit = src + helmet = new_helmet + helmet.update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + + +/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot, initial) + . = ..() + if(suit_adjusted) + RemoveHelmet() + + +/obj/item/clothing/suit/space/hardsuit/dropped(mob/user, silent = FALSE) + . = ..() + if(suit_adjusted) + RemoveHelmet() + + +/obj/item/clothing/suit/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(suit_adjusted) + RemoveHelmet() + return ..() + + +/obj/item/clothing/suit/space/hardsuit/ui_action_click(mob/user) + ToggleHelmet() /obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot) if(slot == slot_wear_suit) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit. return TRUE + +/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) + user.changeNext_move(CLICK_CD_MELEE) + ..() + + +/obj/item/clothing/suit/space/hardsuit/proc/ToggleHelmet() + var/mob/living/carbon/human/user = loc + if(!ishuman(user) || !helmet) + return + if(taser_proof && taser_proof.ert_mindshield_locked) + if(isertmindshielded(user)) + to_chat(user, span_notice("Access granted, identity verified...")) + else + to_chat(user, span_warning("Access denied. The user is not identified!")) + return + if(suit_adjusted) + RemoveHelmet() + return + if(user.wear_suit != src) + to_chat(user, span_warning("You must be wearing [src] to engage the helmet!")) + return + EngageHelmet() + + +/obj/item/clothing/suit/space/hardsuit/proc/EngageHelmet() + if(!helmet) + return FALSE + var/mob/living/carbon/human/user = loc + if(!ishuman(user)) + return FALSE + if(user.head) + to_chat(usr, span_warning("You're already wearing something on your head!")) + return FALSE + if(!user.equip_to_slot(helmet, slot_head)) + return FALSE + . = TRUE + suit_adjusted = TRUE + to_chat(user, span_notice("You engage the helmet on the hardsuit.")) + user.update_head(helmet, TRUE) + user.update_inv_wear_suit() + playsound(user, 'sound/items/rig_deploy.ogg', 110, TRUE) + + +/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet() + if(!helmet) + return FALSE + . = TRUE + suit_adjusted = FALSE + var/mob/living/carbon/human/user = loc + if(helmet.light_on) + helmet.toggle_light(enable = FALSE) + if(ishuman(user)) + user.temporarily_remove_item_from_inventory(helmet, force = TRUE) + user.update_inv_wear_suit() + to_chat(user, span_notice("The helmet on the hardsuit disengages.")) + helmet.forceMove(src) + playsound(user, 'sound/items/rig_retract.ogg', 110, TRUE) + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + + //Engineering hardsuit /obj/item/clothing/head/helmet/space/hardsuit/engine name = "engineering hardsuit helmet" @@ -230,103 +349,137 @@ name = "blood-red hardsuit helmet" desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." alt_desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." - icon_state = "hardsuit1-syndi" + icon_state = "hardsuit0-syndi" item_state = "syndie_helm" armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) item_color = "syndi" - on = 1 + var/on = FALSE var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) visor_flags_inv = HIDEMASK|HIDEGLASSES|HIDENAME|HIDETAIL visor_flags = STOPSPRESSUREDMAGE var/combat_rad = 50 -/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon() + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/Destroy() + linkedsuit = null + return ..() + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon_state() icon_state = "hardsuit[on]-[item_color]" -/obj/item/clothing/head/helmet/space/hardsuit/syndi/New() - ..() - if(istype(loc, /obj/item/clothing/suit/space/hardsuit/syndi)) - linkedsuit = loc -/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) //Toggle Helmet - if(!isturf(user.loc)) - to_chat(user, "You cannot toggle your helmet while in this [user.loc]!" ) +/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_name(updates = ALL) + . = ..() + name = "[initial(name)][on ? "" : " (combat)"]" + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_desc(updates = ALL) + . = ..() + desc = "[initial(desc)][on ? "" : alt_desc]" + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) + adjust_headgear(user) + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/adjust_headgear(mob/living/carbon/human/user, toggle = TRUE) + if(user && !isturf(user.loc)) + to_chat(user, span_warning("You cannot toggle your helmet while in [user.loc]!" )) return - on = !on + if(toggle) + on = !on + toggle_light(enable = on, update_buttons = FALSE) + if(user) + to_chat(user, span_notice("You switch your hardsuit to [on ? "EVA mode, sacrificing speed for space protection." : "combat mode and can now run at full speed."]")) + playsound(loc, 'sound/items/rig_deploy.ogg', 110, TRUE) if(on) - to_chat(user, "You switch your hardsuit to EVA mode, sacrificing speed for space protection.") - name = initial(name) - desc = initial(desc) - set_light(brightness_on) flags |= visor_flags - flags_cover |= HEADCOVERSEYES | HEADCOVERSMOUTH + flags_cover |= (HEADCOVERSEYES|HEADCOVERSMOUTH) flags_inv |= visor_flags_inv cold_protection |= HEAD armor.rad = 100 else - to_chat(user, "You switch your hardsuit to combat mode and can now run at full speed.") - name += " (combat)" - desc = alt_desc - set_light(0) flags &= ~visor_flags - flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH) + flags_cover &= ~(HEADCOVERSEYES|HEADCOVERSMOUTH) flags_inv &= ~visor_flags_inv cold_protection &= ~HEAD armor.rad = combat_rad - update_icon() - playsound(src.loc, 'sound/items/rig_deploy.ogg', 110, 1) - toggle_hardsuit_mode(user) - user.update_inv_head() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_head(src, forced = TRUE) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/toggle_hardsuit_mode(mob/user) //Helmet Toggles Suit Mode - if(linkedsuit) - if(on) - linkedsuit.name = initial(linkedsuit.name) - linkedsuit.desc = initial(linkedsuit.desc) - linkedsuit.slowdown = 1 - linkedsuit.flags |= STOPSPRESSUREDMAGE - linkedsuit.cold_protection |= UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | TAIL - linkedsuit.on = TRUE - linkedsuit.armor.rad = 100 - else - linkedsuit.name += " (combat)" - linkedsuit.desc = linkedsuit.alt_desc - linkedsuit.slowdown = 0 - linkedsuit.flags &= ~STOPSPRESSUREDMAGE - linkedsuit.cold_protection &= ~(UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | TAIL) - linkedsuit.on = FALSE - linkedsuit.armor.rad = combat_rad - - linkedsuit.update_icon() - user.update_inv_wear_suit() - user.update_inv_w_uniform() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + user?.update_head(src) + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + update_linked_hardsuit(user, toggle) + + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/update_linked_hardsuit(mob/user, toggle = TRUE) + if(!linkedsuit) + return + + if(toggle) + linkedsuit.on = !linkedsuit.on + + if(linkedsuit.on) + linkedsuit.slowdown = 1 + linkedsuit.flags |= STOPSPRESSUREDMAGE + linkedsuit.cold_protection |= (UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|TAIL) + linkedsuit.armor.rad = 100 + else + linkedsuit.slowdown = 0 + linkedsuit.flags &= ~STOPSPRESSUREDMAGE + linkedsuit.cold_protection &= ~(UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|TAIL) + linkedsuit.armor.rad = combat_rad + + linkedsuit.update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + user?.update_inv_wear_suit() + user?.update_inv_w_uniform() + /obj/item/clothing/suit/space/hardsuit/syndi name = "blood-red hardsuit" desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." alt_desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." - icon_state = "hardsuit1-syndi" + icon_state = "hardsuit0-syndi" item_state = "syndie_hardsuit" armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) item_color = "syndi" w_class = WEIGHT_CLASS_NORMAL - var/on = 1 + var/on = FALSE actions_types = list(/datum/action/item_action/toggle_hardsuit_mode) allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi jetpack = /obj/item/tank/jetpack/suit -/obj/item/clothing/suit/space/hardsuit/syndi/update_icon() + +/obj/item/clothing/suit/space/hardsuit/syndi/Initialize(mapload) + . = ..() + var/obj/item/clothing/head/helmet/space/hardsuit/syndi/our_helmet = helmet + our_helmet?.linkedsuit = src + our_helmet?.adjust_headgear(toggle = FALSE) + + +/obj/item/clothing/suit/space/hardsuit/syndi/update_icon_state() icon_state = "hardsuit[on]-[item_color]" + +/obj/item/clothing/suit/space/hardsuit/syndi/update_name(updates = ALL) + . = ..() + name = "[initial(name)][on ? "" : " (combat)"]" + + +/obj/item/clothing/suit/space/hardsuit/syndi/update_desc(updates = ALL) + . = ..() + desc = "[initial(desc)][on ? "" : alt_desc]" + + +/obj/item/clothing/suit/space/hardsuit/syndi/EngageHelmet() + . = ..() + if(. && on) + helmet?.toggle_light(enable = TRUE, update_buttons = FALSE) + + //Elite Syndie suit /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite name = "elite syndicate hardsuit helmet" @@ -365,14 +518,14 @@ /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/med name = "Elite medical syndicate hardsuit helmet" desc = "An elite version of the syndicate helmet. This one is made special for medics." - icon_state = "hardsuit1-smedelite" + icon_state = "hardsuit0-smedelite" item_state = "hardsuit0-smedelite" item_color = "smedelite" /obj/item/clothing/suit/space/hardsuit/syndi/elite/med name = "Elite medical syndicate hardsuit helmet" desc = "An elite version of the syndicate hardsuit. This one is made special for medics." - icon_state = "hardsuit1-smedelite" + icon_state = "hardsuit0-smedelite" item_state = "hardsuit0-smedelite" item_color = "smedelite" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/med @@ -398,7 +551,7 @@ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom sprite_sheets = null -/obj/item/clothing/suit/space/hardsuit/syndi/freedom/update_icon() +/obj/item/clothing/suit/space/hardsuit/syndi/freedom/update_icon_state() return /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom @@ -408,7 +561,7 @@ item_state = "griffinhat" sprite_sheets = null -/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon() +/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon_state() return //Soviet hardsuit @@ -562,25 +715,21 @@ armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) item_color = "rd" scan_reagents = TRUE - var/hud_active = TRUE var/explosion_detection_dist = 40 -/obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/user, slot, initial) - . = ..() +/obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/living/carbon/human/user, slot, initial) + . = ..() if(slot == slot_head) GLOB.doppler_arrays += src //Needed to sense the kabooms - if(ishuman(user)) - var/mob/living/carbon/human/U = user - if(istype(U.glasses, /obj/item/clothing/glasses/hud/diagnostic)) // If they are for some reason wearing a diagnostic hud when they put the helmet on - return // already have a hud - hud_active = TRUE + /obj/item/clothing/head/helmet/space/hardsuit/rd/dropped(mob/living/carbon/human/user, silent = FALSE) - ..() - if((user.head == src) && hud_active) + . = ..() + if(!user || user.head != src) GLOB.doppler_arrays -= src + /obj/item/clothing/head/helmet/space/hardsuit/rd/proc/sense_explosion(x0, y0, z0, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) var/turf/T = get_turf(src) diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index ae4c772c0ea..d6612af62e4 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -8,7 +8,7 @@ flash_protect = 2 tint = 2 HUDType = 0 - var/list/examine_extensions = null + var/examine_extensions = 0 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75) resistance_flags = FIRE_PROOF var/brightness_on = 4 //luminosity when the light is on @@ -27,25 +27,27 @@ sprite_sheets = list("Plasmaman" = 'icons/mob/clothing/species/plasmaman/helmet.dmi') var/upgradable = FALSE -/obj/item/clothing/head/helmet/space/plasmaman/New() - ..() + +/obj/item/clothing/head/helmet/space/plasmaman/Initialize(mapload) + . = ..() visor_toggling() update_icon() - cut_overlays() + /obj/item/clothing/head/helmet/space/plasmaman/AltClick(mob/user) if(!user.incapacitated() && Adjacent(user)) toggle_welding_screen(user) + /obj/item/clothing/head/helmet/space/plasmaman/visor_toggling() //handles all the actual toggling of flags up = !up flags ^= visor_flags flags_inv ^= visor_flags_inv - icon_state = "[initial(icon_state)]" if(visor_vars_to_toggle & VISOR_FLASHPROTECT) flash_protect ^= initial(flash_protect) if(visor_vars_to_toggle & VISOR_TINT) - tint ^= initial(tint) + tint = up ? tint_up : initial(tint) + /obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_welding_screen(mob/living/user) if(weldingvisortoggle(user)) @@ -53,73 +55,72 @@ to_chat(user, "Your helmet's torch can't pass through your welding visor!") on = FALSE playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing - update_icon() + update_icon(UPDATE_OVERLAYS) + actions_types = list(/datum/action/item_action/toggle_helmet_light) else playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/clothing/head/helmet/space/plasmaman/update_icon() - cut_overlays() - add_overlay(visor_icon) - ..() - actions_types = list(/datum/action/item_action/toggle_helmet_light) -/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user) +/obj/item/clothing/head/helmet/space/plasmaman/update_icon_state() + if(!upgradable) + icon_state = "[initial(icon_state)][on ? "-light":""]" + item_state = icon_state + return + + switch(armor.getRating(MELEE)) + if(30) + icon_state = "[initial(icon_state)][on ? "-light":""]" + item_state = icon_state + if(40,50) + icon_state = "[initial(icon_state)]_reinf[on ? "-light":""]" + item_state = icon_state + if(60) + icon_state = "[initial(icon_state)]_reinf_full[on ? "-light":""]" + item_state = icon_state + + +/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/living/carbon/human/user) toggle_light(user) + /obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_light(mob/user) on = !on - if(upgradable) - switch(armor.getRating("melee")) - if(30) - icon_state = "[initial(icon_state)][on ? "-light":""]" - item_state = icon_state - if(40,50) - icon_state = "[initial(icon_state)]_reinf[on ? "-light":""]" - item_state = icon_state - if(60) - icon_state = "[initial(icon_state)]_reinf_full[on ? "-light":""]" - item_state = icon_state - else - icon_state = "[initial(icon_state)][on ? "-light":""]" - item_state = icon_state - - var/mob/living/carbon/human/H = user - if(istype(H)) - H.update_inv_head() + update_icon(UPDATE_ICON_STATE) if(on) if(!up) - if(istype(H)) - to_chat(user, "Your helmet's torch can't pass through your welding visor!") + if(user) + to_chat(user, span_notice("Your helmet's torch can't pass through your welding visor!")) set_light(0) else set_light(brightness_on) else set_light(0) - for(var/X in actions) - var/datum/action/A=X - A.UpdateButtonIcon() + update_equipped_item() + /obj/item/clothing/head/helmet/space/plasmaman/extinguish_light(force = FALSE) if(on) toggle_light() update_equipped_item() + /obj/item/clothing/head/helmet/space/plasmaman/equipped(mob/living/carbon/human/user, slot, initial) . = ..() - if(HUDType && slot == slot_head) var/datum/atom_hud/H = GLOB.huds[HUDType] H.add_hud_to(user) + /obj/item/clothing/head/helmet/space/plasmaman/dropped(mob/living/carbon/human/user, silent = FALSE) - ..() + . = ..() if(HUDType && istype(user) && user.head == src) var/datum/atom_hud/H = GLOB.huds[HUDType] H.remove_hud_from(user) + /obj/item/clothing/head/helmet/space/plasmaman/security name = "security plasma envirosuit helmet" desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, alongside other undesirables." @@ -127,7 +128,7 @@ item_state = "security_envirohelm" armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50) HUDType = DATA_HUD_SECURITY_ADVANCED - examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE) + examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE /obj/item/clothing/head/helmet/space/plasmaman/security/dec name = "detective plasma envirosuit helmet" @@ -136,7 +137,7 @@ armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50) scan_reagents = 1 HUDType = DATA_HUD_SECURITY_ADVANCED - examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE) + examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE /obj/item/clothing/head/helmet/space/plasmaman/security/warden name = "warden's plasma envirosuit helmet" @@ -156,7 +157,7 @@ icon_state = "doctor_envirohelm" item_state = "doctor_envirohelm" HUDType = DATA_HUD_MEDICAL_ADVANCED - examine_extensions = list(EXAMINE_HUD_MEDICAL) + examine_extensions = EXAMINE_HUD_MEDICAL /obj/item/clothing/head/helmet/space/plasmaman/cmo name = "chief medical officer's plasma envirosuit helmet" @@ -166,7 +167,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 HUDType = DATA_HUD_MEDICAL_ADVANCED - examine_extensions = list(EXAMINE_HUD_MEDICAL) + examine_extensions = EXAMINE_HUD_MEDICAL scan_reagents = 1 /obj/item/clothing/head/helmet/space/plasmaman/genetics @@ -304,7 +305,7 @@ icon_state = "white_envirohelm" item_state = "white_envirohelm" HUDType = DATA_HUD_SECURITY_ADVANCED - examine_extensions = list(EXAMINE_HUD_SECURITY_READ) + examine_extensions = EXAMINE_HUD_SECURITY_READ /obj/item/clothing/head/helmet/space/plasmaman/nt_rep name = "nanotrasen representative envirosuit helmet" @@ -312,7 +313,7 @@ icon_state = "ntrep_envirohelm" item_state = "ntrep_envirohelm" HUDType = DATA_HUD_SECURITY_BASIC - examine_extensions = list(EXAMINE_HUD_SKILLS) + examine_extensions = EXAMINE_HUD_SKILLS /obj/item/clothing/head/helmet/space/plasmaman/chef name = "chef plasma envirosuit helmet" @@ -335,7 +336,7 @@ item_state = "botany_envirohelm" flags = THICKMATERIAL HUDType = DATA_HUD_HYDROPONIC - examine_extensions = list(DATA_HUD_HYDROPONIC) + examine_extensions = EXAMINE_HUD_BOTANY /obj/item/clothing/head/helmet/space/plasmaman/janitor name = "janitor's plasma envirosuit helmet" @@ -364,7 +365,7 @@ item_state = "hop_envirohelm" armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50) HUDType = DATA_HUD_SECURITY_BASIC - examine_extensions = list(EXAMINE_HUD_SKILLS) + examine_extensions = EXAMINE_HUD_SKILLS /obj/item/clothing/head/helmet/space/plasmaman/captain name = "captain envirosuit helmet" @@ -373,7 +374,7 @@ item_state = "cap_envirohelm" armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50) HUDType = DATA_HUD_SECURITY_BASIC - examine_extensions = list(EXAMINE_HUD_SKILLS) + examine_extensions = EXAMINE_HUD_SKILLS /obj/item/clothing/head/helmet/space/plasmaman/blueshield name = "blueshield envirosuit helmet" @@ -382,7 +383,7 @@ item_state = "bs_envirohelm" armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50) HUDType = DATA_HUD_MEDICAL_ADVANCED - examine_extensions = list(EXAMINE_HUD_MEDICAL) + examine_extensions = EXAMINE_HUD_MEDICAL /obj/item/clothing/head/helmet/space/plasmaman/wizard name = "wizard plasma envirosuit helmet" @@ -410,4 +411,4 @@ icon_state = "centcomm_envirohelm" item_state = "centcomm_envirohelm" HUDType = DATA_HUD_SECURITY_BASIC - examine_extensions = list(EXAMINE_HUD_SKILLS) + examine_extensions = EXAMINE_HUD_SKILLS diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 41e92a995e7..24cb0a4b6b1 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -59,38 +59,47 @@ item_state = "armor" var/obj/item/clothing/accessory/holobadge/attached_badge + +/obj/item/clothing/suit/armor/vest/security/update_icon_state() + icon_state = "armor[attached_badge ? "sec" : ""]" + + +/obj/item/clothing/suit/armor/vest/security/update_desc(updates = ALL) + . = ..() + if(attached_badge) + desc = "An armored vest that protects against some damage. This one has [attached_badge] attached to it." + else + desc = initial(desc) + + /obj/item/clothing/suit/armor/vest/security/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/clothing/accessory/holobadge) && !attached_badge) - if(user.drop_transfer_item_to_loc(I, src)) - add_fingerprint(user) - attached_badge = I - var/datum/action/A = new /datum/action/item_action/remove_badge(src) - A.Grant(user) - icon_state = "armorsec" - user.update_inv_wear_suit() - desc = "An armored vest that protects against some damage. This one has [attached_badge] attached to it." - to_chat(user, "You attach [attached_badge] to [src].") + if(istype(I, /obj/item/clothing/accessory/holobadge) && !attached_badge && user.drop_transfer_item_to_loc(I, src)) + add_fingerprint(user) + attached_badge = I + var/datum/action/item_action/remove_badge/holoaction = new(src) + holoaction.Grant(user) + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + update_equipped_item() + to_chat(user, span_notice("You attach [attached_badge] to [src].")) return ..() + /obj/item/clothing/suit/armor/vest/security/attack_self(mob/user) if(attached_badge) add_fingerprint(user) user.put_in_hands(attached_badge) - for(var/datum/action/item_action/remove_badge/action in actions) LAZYREMOVE(actions, action) action.Remove(user) - - icon_state = "armor" - user.update_inv_wear_suit() - desc = "An armored vest that protects against some damage. This one has a clip for a holobadge." - to_chat(user, "You remove [attached_badge] from [src].") attached_badge = null - + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + update_equipped_item() + to_chat(user, span_notice("You remove [attached_badge] from [src].")) return ..() + /obj/item/clothing/suit/armor/vest/blueshield name = "blueshield security armor" desc = "An armored vest with the badge of a Blueshield Lieutenant." @@ -321,38 +330,45 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF hit_reaction_chance = 50 + +/obj/item/clothing/suit/armor/reactive/update_icon_state() + icon_state = "reactive[active ? "" : "off"]" + item_state = "reactive[active ? "" : "off"]" + + /obj/item/clothing/suit/armor/reactive/attack_self(mob/user) - active = !(active) if(emp_d) - to_chat(user, "[src] is disabled from an electromagnetic pulse!") + to_chat(user, span_warning("[src] is disabled from an electromagnetic pulse!")) return + active = !active + update_icon(UPDATE_ICON_STATE) + add_fingerprint(user) if(active) - to_chat(user, "[src] is now active.") - icon_state = "reactive" - item_state = "reactive" + to_chat(user, span_notice("[src] is now active.")) else - to_chat(user, "[src] is now inactive.") - icon_state = "reactiveoff" - item_state = "reactiveoff" - add_fingerprint(user) - user.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + to_chat(user, span_notice("[src] is now inactive.")) + update_equipped_item() + /obj/item/clothing/suit/armor/reactive/emp_act(severity) active = FALSE emp_d = TRUE - icon_state = "reactiveoff" - item_state = "reactiveoff" - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/C = loc - C.update_inv_wear_suit() - addtimer(CALLBACK(src, PROC_REF(reboot)), 100 / severity) + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, PROC_REF(reboot)), 100 / severity) + if(ishuman(loc)) + var/mob/living/carbon/human/user = loc + to_chat(user, span_warning("[src] starts malfunctioning!")) + update_equipped_item() ..() + /obj/item/clothing/suit/armor/reactive/proc/reboot() emp_d = FALSE + if(ishuman(loc)) + var/mob/living/carbon/human/user = loc + update_equipped_item() + to_chat(user, span_notice("Looks like [src] returns its functionality.")) + //When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!) /obj/item/clothing/suit/armor/reactive/teleport @@ -526,7 +542,7 @@ icon_state = "knight_templar" item_state = "knight_templar" hide_tail_by_species = list("Vox", "Vulpkanin") - allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore) + allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore, /obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat) sprite_sheets = list( "Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi', "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi' @@ -616,6 +632,30 @@ flags = BLOCKHAIR flags_cover = HEADCOVERSEYES +/obj/item/clothing/suit/hooded/goliath/wizard + armor = list("melee" = 60, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 60) + hoodtype = /obj/item/clothing/head/hooded/goliath/wizard + magical = TRUE + +/obj/item/clothing/head/hooded/goliath/wizard + name = "shaman skull" + icon_state = "shamskull" + item_state = "shamskull" + desc = "The skull of a long dead animal bolted to the front of a repurposed pan." + armor = list("melee" = 60, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 60) + magical = TRUE + +//mob_size using for crusher mark +/obj/item/clothing/suit/hooded/goliath/wizard/equipped(mob/living/user, slot, initial) + . = ..() + if(istype(user)) + user.mob_size = MOB_SIZE_LARGE + +/obj/item/clothing/suit/hooded/goliath/wizard/dropped(mob/living/user, silent) + . = ..() + if(istype(user)) + user.mob_size = MOB_SIZE_HUMAN + /obj/item/clothing/suit/armor/bone name = "bone armor" desc = "A tribal armor plate, crafted from animal bone." diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index 2b2e54d9306..ebdd618eae4 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -5,90 +5,138 @@ var/obj/item/clothing/head/hooded/hood var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this + /obj/item/clothing/suit/hooded/Initialize(mapload) . = ..() MakeHood() + /obj/item/clothing/suit/hooded/Destroy() QDEL_NULL(hood) . = ..() + /obj/item/clothing/suit/hooded/proc/MakeHood() item_color = initial(icon_state) if(!hood) - var/obj/item/clothing/head/hooded/W = new hoodtype(src) - W.suit = src - hood = W + var/obj/item/clothing/head/hooded/new_hood = new hoodtype(src) + new_hood.suit = src + hood = new_hood + + +/obj/item/clothing/suit/hooded/attack_self(mob/user) + user.changeNext_move(CLICK_CD_MELEE) + ..() + + +/obj/item/clothing/suit/hooded/update_icon_state() + icon_state = "[item_color][suit_adjusted ? "_hood" : ""]" + /obj/item/clothing/suit/hooded/ui_action_click() ToggleHood() + /obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user) if(slot == slot_wear_suit) - return 1 + return TRUE -/obj/item/clothing/suit/hooded/equipped(mob/user, slot, initial) - . = ..() - if(slot != slot_wear_suit) +/obj/item/clothing/suit/hooded/equipped(mob/user, slot, initial = FALSE) + . = ..() + if(suit_adjusted) RemoveHood() -/obj/item/clothing/suit/hooded/proc/RemoveHood() - if(isnull(hood)) - return - icon_state = item_color - suit_adjusted = 0 - if(ishuman(hood.loc)) - var/mob/living/carbon/H = hood.loc - H.transfer_item_to_loc(hood, src, TRUE) - H.update_inv_wear_suit() - else - hood.forceMove(src) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() /obj/item/clothing/suit/hooded/dropped(mob/user, silent = FALSE) - ..() - RemoveHood() + . = ..() + if(suit_adjusted) + RemoveHood() + + +/obj/item/clothing/suit/hooded/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(suit_adjusted) + RemoveHood() + return ..() + /obj/item/clothing/suit/hooded/proc/ToggleHood() - if(!suit_adjusted) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.wear_suit != src) - to_chat(H,"You must be wearing [src] to put up the hood!") - return - if(H.head) - to_chat(H,"You're already wearing something on your head!") - return - else if(H.equip_to_slot_if_possible(hood, slot_head)) - suit_adjusted = 1 - icon_state = "[item_color]_hood" - H.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - else + var/mob/living/carbon/human/user = loc + if(!ishuman(user) || !hood) + return + if(suit_adjusted) RemoveHood() + return + if(user.wear_suit != src) + to_chat(user, span_warning("You must be wearing [src] to put up the hood!")) + return + EngageHood() + + +/obj/item/clothing/suit/hooded/proc/EngageHood() + if(!hood) + return FALSE + var/mob/living/carbon/human/user = loc + if(!ishuman(user)) + return FALSE + if(user.head) + to_chat(user, span_warning("You're already wearing something on your head!")) + return + if(!user.equip_to_slot(hood, slot_head)) + return FALSE + . = TRUE + suit_adjusted = TRUE + update_icon(UPDATE_ICON_STATE) + to_chat(user, span_notice("You adjust the hood on [src].")) + user.update_head(hood, TRUE) + user.update_inv_wear_suit() + + +/obj/item/clothing/suit/hooded/proc/RemoveHood() + if(!hood) + return FALSE + . = TRUE + suit_adjusted = FALSE + update_icon(UPDATE_ICON_STATE) + var/mob/living/carbon/human/user = loc + if(ishuman(user)) + user.temporarily_remove_item_from_inventory(hood, force = TRUE) + user.update_inv_wear_suit() + to_chat(user, span_notice("The hood fells off from [src].")) + hood.forceMove(src) + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + /obj/item/clothing/head/hooded var/obj/item/clothing/suit/hooded/suit + /obj/item/clothing/head/hooded/Destroy() suit = null return ..() -/obj/item/clothing/head/hooded/dropped(mob/user, silent = FALSE) - ..() - if(suit) - suit.RemoveHood() -/obj/item/clothing/head/hooded/equipped(mob/user, slot, initial) +/obj/item/clothing/head/hooded/equipped(mob/user, slot, initial = FALSE) . = ..() - if(slot != slot_head) if(suit) suit.RemoveHood() else qdel(src) + + +/obj/item/clothing/head/hooded/dropped(mob/user, silent = FALSE) + . = ..() + if(suit && loc != suit) + forceMove(suit) + else + qdel(src) + + +/obj/item/clothing/head/hooded/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) + if(suit) + suit.RemoveHood() + else + qdel(src) + diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index e8c3abe6ef8..9797d891a1f 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -505,11 +505,13 @@ "Grey" = 'icons/mob/clothing/species/grey/suit.dmi' ) + /obj/item/clothing/suit/suspenders/Initialize(mapload) . = ..() if(!color && paintable) color = "#a30e22" - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/item/clothing/suit/suspenders/attackby(obj/D, mob/user, params) . = ..() @@ -519,6 +521,7 @@ color = can.colour update_icon(UPDATE_OVERLAYS) + /obj/item/clothing/suit/suspenders/update_overlays() . = ..() if(color) @@ -527,7 +530,6 @@ var/mutable_appearance/suspenders_clips = mutable_appearance(icon='icons/obj/clothing/belts.dmi', icon_state = "suspenders_clips", appearance_flags = RESET_COLOR) . += suspenders_clips - /obj/item/clothing/suit/suspenders/nodrop flags = NODROP diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index baeb4b05493..8bf89f6ecbb 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -225,8 +225,8 @@ name = "\improper super-hero E-N suit" icon_state = "ensuit" -/obj/item/clothing/suit/corgisuit/super_hero/en/New() - ..() +/obj/item/clothing/suit/corgisuit/super_hero/en/Initialize(mapload) + . = ..() START_PROCESSING(SSobj, src) /obj/item/clothing/suit/corgisuit/super_hero/en/Destroy() @@ -235,14 +235,15 @@ /obj/item/clothing/suit/corgisuit/super_hero/en/process() if(prob(2)) - for(var/obj/M in orange(2,src)) - if(!M.anchored && (M.flags & CONDUCT)) - step_towards(M,src) - for(var/mob/living/silicon/S in orange(2,src)) - if(istype(S, /mob/living/silicon/ai)) continue - step_towards(S,src) - for(var/mob/living/carbon/human/machine/M in orange(2,src)) - step_towards(M,src) + for(var/obj/object in orange(2, src)) + if(!object.anchored && (object.flags & CONDUCT)) + step_towards(object, src) + for(var/mob/living/silicon/robot in orange(2,src)) + if(isAI(robot)) + continue + step_towards(robot, src) + for(var/mob/living/carbon/human/machine/IPC in orange(2,src)) + step_towards(IPC, src) /obj/item/clothing/suit/monkeysuit name = "monkey suit" @@ -1148,7 +1149,6 @@ if(!istype(H) || slot != slot_wear_suit) STOP_PROCESSING(SSobj, src) - return else START_PROCESSING(SSobj, src) diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm index d834e1579eb..e1537044931 100644 --- a/code/modules/clothing/suits/storage.dm +++ b/code/modules/clothing/suits/storage.dm @@ -2,8 +2,8 @@ var/obj/item/storage/internal/pockets w_class = WEIGHT_CLASS_NORMAL //we don't want these to be able to fit in their own pockets. -/obj/item/clothing/suit/storage/New() - ..() +/obj/item/clothing/suit/storage/Initialize(mapload) + . = ..() pockets = new/obj/item/storage/internal(src) pockets.storage_slots = 2 //two slots pockets.max_w_class = WEIGHT_CLASS_SMALL //fit only pocket sized items @@ -13,15 +13,18 @@ QDEL_NULL(pockets) return ..() -/obj/item/clothing/suit/storage/attack_hand(mob/user as mob) - if(pockets.handle_attack_hand(user)) - ..(user) -/obj/item/clothing/suit/storage/MouseDrop(obj/over_object as obj) - if(pockets.handle_mousedrop(usr, over_object)) - ..(over_object) +/obj/item/clothing/suit/storage/attack_hand(mob/user) + if(!pockets || !pockets.handle_attack_hand(user)) + return ..() + + +/obj/item/clothing/suit/storage/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(!pockets || !pockets.handle_mousedrop(usr, over_object)) + return ..() + -/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/suit/storage/attackby(obj/item/W, mob/user, params) . = ..() if(istype(W, /obj/item/radio/spy_spider)) return @@ -35,7 +38,7 @@ pockets.hear_talk(M, message_pieces) ..() -/obj/item/clothing/suit/storage/hear_message(mob/M, var/msg) +/obj/item/clothing/suit/storage/hear_message(mob/M, msg) pockets.hear_message(M, msg) ..() diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm deleted file mode 100644 index 2617619b6c7..00000000000 --- a/code/modules/clothing/suits/toggles.dm +++ /dev/null @@ -1,88 +0,0 @@ -//Hardsuit toggle code -/obj/item/clothing/suit/space/hardsuit/New() - MakeHelmet() - ..() - -/obj/item/clothing/suit/space/hardsuit/Destroy() - if(helmet) - helmet.suit = null - QDEL_NULL(helmet) - QDEL_NULL(jetpack) - return ..() - -/obj/item/clothing/head/helmet/space/hardsuit/Destroy() - if(suit) - suit.helmet = null - return ..() - -/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet() - if(!helmettype) - return - if(!helmet) - var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src) - W.suit = src - helmet = W - -/obj/item/clothing/suit/space/hardsuit/ui_action_click() - ..() - ToggleHelmet() - -/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot, initial) - . = ..() - - if(!helmettype) - return - if(slot != slot_wear_suit) - RemoveHelmet() - -/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet() - if(!helmet) - return - suittoggled = FALSE - if(ishuman(helmet.loc)) - var/mob/living/carbon/H = helmet.loc - if(helmet.on) - helmet.attack_self(H) - H.transfer_item_to_loc(helmet, src, TRUE) - H.update_inv_wear_suit() - to_chat(H, "The helmet on the hardsuit disengages.") - playsound(src.loc, 'sound/items/rig_retract.ogg', 110, 1) - else - helmet.forceMove(src) - -/obj/item/clothing/suit/space/hardsuit/dropped(mob/user, silent = FALSE) - ..() - RemoveHelmet() - -/obj/item/clothing/suit/space/hardsuit/proc/EngageHelmet() - var/mob/living/carbon/human/H = src.loc - if(H.equip_to_slot_if_possible(helmet, slot_head)) - to_chat(H, "You engage the helmet on the hardsuit.") - suittoggled = TRUE - H.update_inv_wear_suit() - playsound(src.loc, 'sound/items/rig_deploy.ogg', 110, 1) - -/obj/item/clothing/suit/space/hardsuit/proc/ToggleHelmet() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(taser_proof && taser_proof.ert_mindshield_locked) - if(isertmindshielded(H)) - to_chat(H, "Access granted, identity verified...") - else - to_chat(H, "Access denied. The user is not identified!") - return - if(!helmettype) - return - if(!helmet) - return - if(!suittoggled) - if(H.wear_suit != src) - to_chat(H, "You must be wearing [src] to engage the helmet!") - return - if(H.head) - to_chat(H, "You're already wearing something on your head!") - return - else - EngageHelmet() - else - RemoveHelmet() diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index b53d4b13383..4dd553949b8 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -78,6 +78,68 @@ dog_fashion = null flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES +/obj/item/clothing/head/wizard/magusdefender + name = "Magus Helm" + desc = "A mysterious helmet that hums with an unearthly power" + icon_state = "magusdefender" + item_state = "magusdefender" + dog_fashion = null + flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES + sprite_sheets = list( + "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi', + "Vox" = 'icons/mob/clothing/species/vox/head.dmi', + "Drask" = 'icons/mob/clothing/species/drask/head.dmi', + "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi', + "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi' + ) + +/obj/item/clothing/head/wizard/necromage + name = "Necronat Mask" + desc = "A mysterious mask made from the skull of the previous owner." + icon_state = "necromage" + item_state = "necromage" + dog_fashion = null + flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES + sprite_sheets = list( + "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi', + "Vox" = 'icons/mob/clothing/species/vox/head.dmi', + "Drask" = 'icons/mob/clothing/species/drask/head.dmi', + "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi', + "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi' + ) + +/obj/item/clothing/head/wizard/artmage + name = "Wizard Sculptor's Beret" + desc = "The classic beret of the followers of the school of sculpture allows you to look like a real artist." + icon_state = "artmage" + item_state = "artmage" + dog_fashion = null + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/head.dmi', + "Drask" = 'icons/mob/clothing/species/drask/head.dmi' + ) + +/obj/item/clothing/head/wizard/visionmage + name = "Golden tiara" + desc = "Golden tiara with a third eye, don't look directly into it." + icon_state = "visionmage" + item_state = "visionmage" + dog_fashion = null + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/head.dmi', + "Drask" = 'icons/mob/clothing/species/drask/head.dmi' + ) + +/obj/item/clothing/head/wizard/healmage + name = "Healer's Hat" + desc = "The magical hat of a healer's robe that protects against leprosy." + icon_state = "healmage" + item_state = "healmage" + dog_fashion = null + sprite_sheets = list( + "Drask" = 'icons/mob/clothing/species/drask/head.dmi' + ) + /obj/item/clothing/head/wizard/amp name = "psychic amplifier" desc = "A crown-of-thorns psychic amplifier. Kind of looks like a tiara having sex with an industrial robot." @@ -167,6 +229,57 @@ "Unathi" = 'icons/mob/clothing/species/unathi/suit.dmi' ) +/obj/item/clothing/suit/wizrobe/magusdefender + name = "Magus Robe" + desc = "A set of armoured robes that seem to radiate a dark power." + icon_state = "magusdefender" + item_state = "magusdefender" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi' + ) + +/obj/item/clothing/suit/wizrobe/necromage + name = "Necronat Robe" + desc = "Black and toxic green robes that seem to radiate a dark power and scent of death." + icon_state = "necromage" + item_state = "necromage" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi' + ) + +/obj/item/clothing/suit/wizrobe/artmage + name = "Wizard Sculptor's Apron" + desc = "A classic apron of followers of the school of sculpture, it protects well from flying clay." + icon_state = "artmage" + item_state = "artmage" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi' + ) + +/obj/item/clothing/suit/wizrobe/visionmage + name = "Dark robe" + desc = "A dark seer's robe woven from otherworldly threads. Emits dark energy." + icon_state = "visionmage" + item_state = "visionmage" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi' + ) + +/obj/item/clothing/suit/wizrobe/healmage + name = "Healer's Robe" + desc = "Magical robe of a healing servant that protects against leprosy." + icon_state = "healmage" + item_state = "healmage" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Unathi" = 'icons/mob/clothing/species/unathi/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi' + ) + /obj/item/clothing/suit/wizrobe/psypurple name = "purple robes" desc = "Heavy, royal purple robes threaded with psychic amplifiers and weird, bulbous lenses. Do not machine wash." diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 138f7662f69..1beecc71651 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -14,8 +14,8 @@ var/image/inv_overlay = null //overlay used when attached to clothing. var/allow_duplicates = TRUE // Allow accessories of the same type. -/obj/item/clothing/accessory/New() - ..() +/obj/item/clothing/accessory/Initialize(mapload) + . = ..() inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") /obj/item/clothing/accessory/Destroy() diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index e1521241bf8..085070e0069 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -188,5 +188,5 @@ /obj/item/clothing/accessory/holster/knives/can_holster(obj/item/I) return is_type_in_list(I, holster_allow, FALSE) -/obj/item/clothing/accessory/holster/attached_examine(mob/user) +/obj/item/clothing/accessory/holster/knives/attached_examine(mob/user) return span_notice("\A [src] with [holstered.len] knives attached to it.") diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm index 6b54e23425c..4b201f7d857 100644 --- a/code/modules/clothing/under/accessories/storage.dm +++ b/code/modules/clothing/under/accessories/storage.dm @@ -12,8 +12,8 @@ actions_types = list(/datum/action/item_action/accessory/storage) w_class = WEIGHT_CLASS_NORMAL // so it doesn't fit in pockets -/obj/item/clothing/accessory/storage/New() - ..() +/obj/item/clothing/accessory/storage/Initialize(mapload) + . = ..() hold = new/obj/item/storage/internal(src) hold.storage_slots = slots @@ -21,22 +21,25 @@ QDEL_NULL(hold) return ..() -/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob) + +/obj/item/clothing/accessory/storage/attack_hand(mob/user) if(has_suit) //if we are part of a suit - hold.open(user) + hold?.open(user) return - if(hold.handle_attack_hand(user)) //otherwise interact as a regular storage item - ..(user) + if(!hold || !hold.handle_attack_hand(user)) //otherwise interact as a regular storage item + return ..() + -/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj) +/obj/item/clothing/accessory/storage/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) if(has_suit) - return + return has_suit.MouseDrop(over_object, src_location, over_location, src_control, over_control, params) + + if(!hold || !hold.handle_mousedrop(usr, over_object)) + return ..() - if(hold.handle_mousedrop(usr, over_object)) - ..(over_object) -/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/accessory/storage/attackby(obj/item/W, mob/user, params) return hold.attackby(W, user, params) /obj/item/clothing/accessory/storage/emp_act(severity) @@ -47,7 +50,7 @@ hold.hear_talk(M, message_pieces, verb) ..() -/obj/item/clothing/accessory/storage/hear_message(mob/M, var/msg, verb, datum/language/speaking) +/obj/item/clothing/accessory/storage/hear_message(mob/M, msg, verb, datum/language/speaking) hold.hear_message(M, msg) ..() @@ -65,7 +68,7 @@ L += G.gift:return_inv() return L -/obj/item/clothing/accessory/storage/attack_self(mob/user as mob) +/obj/item/clothing/accessory/storage/attack_self(mob/user) if(has_suit) //if we are part of a suit hold.open(user) else @@ -112,8 +115,8 @@ item_color = "unathiharness2" slots = 2 -/obj/item/clothing/accessory/storage/knifeharness/New() - ..() +/obj/item/clothing/accessory/storage/knifeharness/Initialize(mapload) + . = ..() hold.max_combined_w_class = 4 hold.can_hold = list(/obj/item/hatchet/unathiknife, /obj/item/kitchen/knife) diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 0ae953fd089..1db6254a7ea 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -3,14 +3,25 @@ dyeable = TRUE -/obj/item/clothing/under/color/random/New() - ..() - var/list/excluded = list(/obj/item/clothing/under/color/random, /obj/item/clothing/under/color/blackf, /obj/item/clothing/under/color/blue/dodgeball, /obj/item/clothing/under/color/orange/prison, /obj/item/clothing/under/color/red/dodgeball, /obj/item/clothing/under/color/red/jersey, /obj/item/clothing/under/color/blue/jersey) - var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - excluded) - name = initial(C.name) - icon_state = initial(C.icon_state) - item_state = initial(C.item_state) - item_color = initial(C.item_color) +/obj/item/clothing/under/color/random/Initialize(mapload) + . = ..() + + var/static/list/excluded = list( + /obj/item/clothing/under/color/random, + /obj/item/clothing/under/color/blackf, + /obj/item/clothing/under/color/blue/dodgeball, + /obj/item/clothing/under/color/orange/prison, + /obj/item/clothing/under/color/red/dodgeball, + /obj/item/clothing/under/color/red/jersey, + /obj/item/clothing/under/color/blue/jersey, + ) + var/static/list/allowed_colors = subtypesof(/obj/item/clothing/under/color) - excluded + var/obj/item/clothing/under/color/new_color = pick(allowed_colors) + name = initial(new_color.name) + icon_state = initial(new_color.icon_state) + item_state = initial(new_color.item_state) + item_color = initial(new_color.item_color) + /obj/item/clothing/under/color/black name = "black jumpsuit" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 9ba82ef12e0..d3a5683cb02 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -1077,3 +1077,36 @@ AddComponent(/datum/component/spraycan_paintable) START_PROCESSING(SSobj, src) update_icon() + + +/obj/item/clothing/under/ussptracksuit_red + name = "red track suit" + desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + icon_state = "ussptracksuit_red" + item_state = "ussptracksuit_red" + item_color = "ussptracksuit_red" + + +/obj/item/clothing/under/ussptracksuit_blue + name = "blue track suit" + desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + icon_state = "ussptracksuit_blue" + item_state = "ussptracksuit_blue" + item_color = "ussptracksuit_blue" + + +/obj/item/clothing/under/ussptracksuit_black + name = "black track suit" + desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + icon_state = "ussptracksuit_black" + item_state = "ussptracksuit_black" + item_color = "ussptracksuit_black" + + +/obj/item/clothing/under/ussptracksuit_white + name = "white track suit" + desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"." + icon_state = "ussptracksuit_white" + item_state = "ussptracksuit_white" + item_color = "ussptracksuit_white" + diff --git a/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm b/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm index f31c73b380c..6b303697e3d 100644 --- a/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm +++ b/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm @@ -1,7 +1,7 @@ /obj/item/clothing/suit/space/hardsuit var/obj/item/hardsuit_shield/shield = null -/obj/item/clothing/suit/space/hardsuit/New() +/obj/item/clothing/suit/space/hardsuit/Initialize(mapload) . = ..() if(shield && ispath(shield)) shield = new shield(src) @@ -21,7 +21,7 @@ shield = new_shield shield.hardsuit = src to_chat(user, "You successfully install the shield upgrade into [src].") - return + /obj/item/clothing/suit/space/hardsuit/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(shield) diff --git a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm index 73981f53808..bcb488973bc 100644 --- a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm +++ b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm @@ -1,7 +1,7 @@ /obj/item/clothing/suit/space/hardsuit var/obj/item/hardsuit_taser_proof/taser_proof = null -/obj/item/clothing/suit/space/hardsuit/New() +/obj/item/clothing/suit/space/hardsuit/Initialize(mapload) . = ..() if(taser_proof && ispath(taser_proof)) taser_proof = new taser_proof(src) diff --git a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm index 50f481c7c1e..8c977b313e0 100644 --- a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm +++ b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm @@ -34,7 +34,7 @@ /obj/item/hardsuit_taser_proof/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(!hardsuit) return FALSE - if(!hardsuit.suittoggled) + if(!hardsuit.suit_adjusted) return FALSE var/obj/item/projectile/P = hitby if(P.shockbull) diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm index 7c0ea71d05f..39d481238f5 100644 --- a/code/modules/crafting/guncrafting.dm +++ b/code/modules/crafting/guncrafting.dm @@ -15,10 +15,25 @@ icon = 'icons/obj/improvised.dmi' icon_state = "riflestock" +/obj/item/weaponcrafting/revolverbarrel + name = "improvised revolver barrel" + desc = "A roughly made revolver barrel." + icon = 'icons/obj/improvised.dmi' + icon_state = "rev_barrel" + w_class = WEIGHT_CLASS_SMALL + var/new_fire_sound = 'sound/weapons/gunshots/1rev257.ogg' + +/obj/item/weaponcrafting/revolverbarrel/steel + name = "steel revolver barrel" + desc = "High quality heavy steel gun barrel to increase stability." + icon = 'icons/obj/improvised.dmi' + icon_state = "s_rev_barrel" + new_fire_sound = 'sound/weapons/gunshots/1rev257S.ogg' + // CRAFTING // -/obj/item/weaponcrafting/receiver/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/weaponcrafting/receiver/attackby(obj/item/W, mob/user, params) if(istype(W,/obj/item/pipe)) to_chat(user, "You attach the shotgun barrel to the receiver. The pins seem loose.") var/obj/item/weaponcrafting/ishotgunconstruction/I = new(drop_location()) @@ -36,13 +51,13 @@ icon = 'icons/obj/improvised.dmi' icon_state = "ishotgunstep1" -/obj/item/weaponcrafting/ishotgunconstruction/attackby(var/obj/item/I, mob/user as mob, params) +/obj/item/weaponcrafting/ishotgunconstruction/attackby(obj/item/I, mob/user, params) ..() - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) var/obj/item/weaponcrafting/ishotgunconstruction2/C = new(drop_location()) user.temporarily_remove_item_from_inventory(src) user.put_in_hands(C, ignore_anim = FALSE) - to_chat(user, "You screw the pins into place, securing the pipe to the receiver.") + to_chat(user, span_notice("You screw the pins into place, securing the pipe to the receiver.")) qdel(src) /obj/item/weaponcrafting/ishotgunconstruction2 @@ -51,7 +66,7 @@ icon = 'icons/obj/improvised.dmi' icon_state = "ishotgunstep1" -/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W, mob/user, params) if(istype(W,/obj/item/weaponcrafting/stock)) to_chat(user, "You attach the stock to the receiver-barrel assembly.") var/obj/item/weaponcrafting/ishotgunconstruction3/I = new(drop_location()) @@ -67,7 +82,7 @@ icon = 'icons/obj/improvised.dmi' icon_state = "ishotgunstep2" -/obj/item/weaponcrafting/ishotgunconstruction3/attackby(var/obj/item/I, mob/user as mob, params) +/obj/item/weaponcrafting/ishotgunconstruction3/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/packageWrap)) var/obj/item/stack/packageWrap/C = I @@ -76,9 +91,8 @@ investigate_log("[key_name_log(user)] crafted [W]", INVESTIGATE_CRAFTING) user.temporarily_remove_item_from_inventory(src) user.put_in_hands(W, ignore_anim = FALSE) - to_chat(user, "You tie the wrapping paper around the stock and the barrel to secure it.") + to_chat(user, span_notice("You tie the wrapping paper around the stock and the barrel to secure it.")) qdel(src) else - to_chat(user, "You need at least five feet of wrapping paper to secure the stock.") + to_chat(user, span_warning("You need at least five feet of wrapping paper to secure the stock.")) return - diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index f26a7f733a3..9ec15f9a8ab 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -200,6 +200,29 @@ subcategory = CAT_WEAPON alert_admins_on_craft = TRUE +/datum/crafting_recipe/revolver_ibullet + name = "Improvised Revolver Shell" + result = /obj/item/ammo_casing/revolver/improvised + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/cable_coil = 1, + /datum/reagent/fuel = 5,) + tools = list(TOOL_SCREWDRIVER) + time = 2 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/revolver_pbullet + name = "Phosphorous Revolver Bullet" + result = /obj/item/ammo_casing/revolver/improvised/phosphorus + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/cable_coil = 1, + /datum/reagent/phosphorus = 5, + /datum/reagent/fuel = 5,) + tools = list(TOOL_SCREWDRIVER) + time = 2 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + /datum/crafting_recipe/pulseslug name = "Pulse Slug Shell" result = /obj/item/ammo_casing/shotgun/pulseslug @@ -255,18 +278,6 @@ category = CAT_WEAPONRY subcategory = CAT_AMMO -/datum/crafting_recipe/improvisedbullet - name = "Improvised Revolver Shell" - result = /obj/item/ammo_casing/revolver/improvised - reqs = list(/obj/item/stack/sheet/metal = 1, - /obj/item/stack/cable_coil = 1, - /datum/reagent/fuel = 5) - tools = list(TOOL_SCREWDRIVER) - time = 2 - category = CAT_WEAPONRY - subcategory = CAT_AMMO - - /datum/crafting_recipe/improvisedslugoverload name = "Overload Improvised Shell" result = /obj/item/ammo_casing/shotgun/improvised/overload @@ -302,8 +313,8 @@ subcategory = CAT_WEAPON /datum/crafting_recipe/irevolver - name = "Improvised revolver" - result = /obj/item/gun/projectile/revolver/improvisedrevolver + name = "Improvised Revolver" + result = /obj/item/gun/projectile/revolver/improvised reqs = list(/obj/item/weaponcrafting/receiver = 1, /obj/item/stack/sheet/wood = 2, /obj/item/stack/sheet/metal = 3, @@ -1339,6 +1350,14 @@ /obj/item/toy/crayon/spraycan = 1) category = CAT_MISC +/datum/crafting_recipe/ntlockerpaint + name = "NT Special Mech Paintkit" + result = /obj/item/paintkit/lockermech_nt + time = 35 + reqs = list(/obj/item/stack/sheet/cardboard = 5, + /obj/item/toy/crayon/spraycan = 1) + category = CAT_MISC + /datum/crafting_recipe/stacklifter name = "The weight stacklifter" result = /obj/structure/weightmachine/stacklifter @@ -1390,7 +1409,7 @@ /datum/crafting_recipe/makeshift_speedloader name = "Makeshift Speedloader" - result = /obj/item/ammo_box/speedloader/improvisedrevolver + result = /obj/item/ammo_box/speedloader/improvised time = 5 SECONDS reqs = list(/obj/item/c_tube = 4, /obj/item/stack/packageWrap = 10, diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 023bb48b9ac..ddc42aa3ae2 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -76,21 +76,20 @@ playsound(src.loc, usesound, 20, 1) used = 1 - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/fluff/tattoo_gun/update_icon() - ..() - overlays.Cut() +/obj/item/fluff/tattoo_gun/update_overlays() + . = ..() if(!used) var/image/ink = image(src.icon, src, "ink_overlay") ink.icon += rgb(tattoo_r, tattoo_g, tattoo_b, 190) - overlays += ink + . += ink /obj/item/fluff/tattoo_gun/New() ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/fluff/tattoo_gun/elliot_cybernetic_tat desc = "A cheap plastic tattoo application pen.
    This one seems heavily used." @@ -314,17 +313,18 @@ var/obj/item/clothing/suit/armor/jacket = target jacket.icon_state = "desolate_coat_open" jacket.icon = 'icons/obj/custom_items.dmi' - jacket.ignore_suitadjust = 0 - jacket.suit_adjusted = 1 + jacket.ignore_suitadjust = FALSE + jacket.suit_adjusted = TRUE + jacket.update_icon(UPDATE_ICON_STATE) + jacket.update_equipped_item(update_buttons = FALSE) var/has_action = FALSE - for(var/datum/action/A in jacket.actions) - if(istype(A, /datum/action/item_action/openclose)) - has_action = TRUE + for(var/datum/action/item_action/openclose/action in jacket.actions) + action.UpdateButtonIcon() + has_action = TRUE if(!has_action) new /datum/action/item_action/openclose(jacket)//this actually works jacket.adjust_flavour = "unbutton" jacket.sprite_sheets = null - user.update_inv_wear_suit() qdel(src) /obj/item/fluff/fei_gasmask_kit //Fei Hazelwood: Tariq Yon-Dale @@ -953,29 +953,27 @@ "Neara" = 'icons/mob/clothing/species/monkey/suit.dmi', "Stok" = 'icons/mob/clothing/species/monkey/suit.dmi' ) - ignore_suitadjust = 0 actions_types = list(/datum/action/item_action/toggle) - suit_adjusted = 0 + suit_adjusted = FALSE + + +/obj/item/clothing/suit/storage/fluff/k3_webbing/update_icon_state() + var/base_icon_state = copytext(icon_state, 1, findtext(icon_state, "_on")) + var/base_item_state = copytext(item_state, 1, findtext(item_state, "_on")) + + icon_state = suit_adjusted ? base_icon_state : "[base_icon_state]_on" + item_state = suit_adjusted ? base_item_state : "[base_item_state]_on" + + +/obj/item/clothing/suit/storage/fluff/k3_webbing/adjustsuit(mob/user) + if(user.incapacitated()) + return + + update_icon(UPDATE_ICON_STATE) + update_equipped_item() + to_chat(user, "You turn the [src]'s lighting system [suit_adjusted ? "off" : "on"].") + suit_adjusted = !suit_adjusted -/obj/item/clothing/suit/storage/fluff/k3_webbing/adjustsuit(var/mob/user) - if(!user.incapacitated()) - var/flavour - if(suit_adjusted) - flavour = "off" - icon_state = copytext(icon_state, 1, findtext(icon_state, "_on")) - item_state = copytext(item_state, 1, findtext(item_state, "_on")) - suit_adjusted = 0 //Lights Off - else - flavour = "on" - icon_state += "_on" - item_state += "_on" - suit_adjusted = 1 //Lights On - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - to_chat(user, "You turn the [src]'s lighting system [flavour].") - user.update_inv_wear_suit() /obj/item/clothing/suit/hooded/hoodie/fluff/xantholne // Xantholne: Meex Zwichsnicrur name = "stripped winter coat" @@ -1326,26 +1324,24 @@ flags = BLOCKHAIR flags_cover = HEADCOVERSEYES actions_types = list(/datum/action/item_action/toggle) - var/adjusted = 0 + var/adjusted = FALSE + /obj/item/clothing/head/fluff/chronx/ui_action_click() adjust() + +/obj/item/clothing/head/fluff/chronx/update_icon_state() + icon_state = adjusted ? initial(icon_state) : "[initial(icon_state)][adjusted ? "" : "_open"]" + item_state = adjusted ? initial(item_state) : "[initial(item_state)][adjusted ? "" : "_open"]" + + /obj/item/clothing/head/fluff/chronx/proc/adjust() - if(adjusted) - icon_state = initial(icon_state) - item_state = initial(item_state) - to_chat(usr, "You untransform \the [src].") - adjusted = 0 - else - icon_state += "_open" - item_state += "_open" - to_chat(usr, "You transform \the [src].") - adjusted = 1 - usr.update_inv_head() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_icon(UPDATE_ICON_STATE) + update_equipped_item() + to_chat(usr, "You untransform [src].") + adjusted = !adjusted + /obj/item/clothing/suit/chaplain_hoodie/fluff/chronx //chronx100: Hughe O'Splash name = "Cthulhu's Robes" @@ -1420,6 +1416,12 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "classic_witch" item_state = "classic_witch" + var/current_state + + +/obj/item/clothing/head/wizard/fluff/dreamy/update_icon_state() + icon_state = current_state ? current_state : initial(icon_state) + /obj/item/clothing/head/wizard/fluff/dreamy/attack_self(mob/user) var/list/options = list() @@ -1439,7 +1441,8 @@ var/choice = tgui_input_list(user, "To what form do you wish to Shapeshift this hat?", "Shapeshift Hat", options) if(choice && !user.stat && in_range(user, src)) - icon_state = options[choice] + current_state = options[choice] + update_icon(UPDATE_ICON_STATE) to_chat(user, "Your strange witch hat has now shapeshifted into it's [choice] form!") return 1 ..() @@ -1647,21 +1650,19 @@ species_restricted = list("Vox") - /obj/item/clothing/gloves/ring/fluff name = "fluff ring" desc = "Someone forgot to set this fluff item's description, notify a coder!" icon = 'icons/obj/custom_items.dmi' fluff_material = TRUE -/obj/item/clothing/gloves/ring/fluff/update_icon() +/obj/item/clothing/gloves/ring/fluff/update_icon_state() return -/obj/item/clothing/gloves/ring/fluff/attackby(obj/item/I as obj, mob/user as mob, params) +/obj/item/clothing/gloves/ring/fluff/attackby(obj/item/I, mob/user, params) return - /obj/item/clothing/gloves/ring/fluff/benjaminfallout //Benjaminfallout: Pretzel Brassheart name = "Pretzel's Ring" desc = "A small platinum ring with a large light blue diamond. Engraved inside the band are the words: 'To my lovely Pristine Princess. Forever yours, Savinien.'" diff --git a/code/modules/detective_work/footprints_and_rag.dm b/code/modules/detective_work/footprints_and_rag.dm index fe9b50547c1..06a7527061b 100644 --- a/code/modules/detective_work/footprints_and_rag.dm +++ b/code/modules/detective_work/footprints_and_rag.dm @@ -21,6 +21,7 @@ flags = NOBLUDGEON container_type = OPENCONTAINER has_lid = FALSE + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/wipespeed = 30 /obj/item/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag) diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index 11c84e1a87e..575c5a0e36b 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/forensics.dmi' icon_state = "dnaopen" layer = BELOW_OBJ_LAYER - anchored = 1 + anchored = TRUE density = 1 var/obj/item/forensics/swab = null @@ -31,7 +31,7 @@ to_chat(user, "Вы вставляете \the [W] в ДНК анализатор.") user.drop_transfer_item_to_loc(W, src) swab = W - update_icon() + update_icon(UPDATE_ICON_STATE) return ..() @@ -41,21 +41,21 @@ to_chat(user, "Сканер пуст!") return add_fingerprint(user) - scanning = 1 - update_icon() + scanning = TRUE + update_icon(UPDATE_ICON_STATE) to_chat(user, "Сканер начинает с жужением анализировать содержимое пробирки \the [swab].") if(!do_after(user, 25, src) || !swab) to_chat(user, "Вы перестали анализировать \the [swab].") - scanning = 0 - update_icon() + scanning = FALSE + update_icon(UPDATE_ICON_STATE) return to_chat(user, "Печать отчета...") var/obj/item/paper/report = new(get_turf(src)) report.stamped = list(/obj/item/stamp) - report.overlays = list("paper_stamped") + LAZYADD(report.stamp_overlays, "paper_stamped") report_num++ if(swab) @@ -73,8 +73,8 @@ report.info += "\nАнализируемый объект:
    [bloodswab.name]
    [bloodswab.desc]

    " + data report.forceMove(src.loc) report.update_icon() - scanning = 0 - update_icon() + scanning = FALSE + update_icon(UPDATE_ICON_STATE) return /obj/machinery/dnaforensics/proc/remove_sample(mob/living/remover) @@ -87,18 +87,18 @@ swab.forceMove_turf() remover.put_in_hands(swab, ignore_anim = FALSE) swab = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/dnaforensics/AltClick() remove_sample(usr) -/obj/machinery/dnaforensics/MouseDrop(atom/other) - if(usr == other) +/obj/machinery/dnaforensics/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(usr == over_object) remove_sample(usr) - else - return ..() + return FALSE + return ..() -/obj/machinery/dnaforensics/update_icon() +/obj/machinery/dnaforensics/update_icon_state() icon_state = "dnaopen" if(swab) icon_state = "dnaclosed" diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm index 20b9dd4638f..14df5adc50f 100644 --- a/code/modules/detectivework/microscope/microscope.dm +++ b/code/modules/detectivework/microscope/microscope.dm @@ -7,7 +7,7 @@ desc = "Высокотехнологичный микроскоп, способный увеличивать изображение до 3000 раз." icon = 'icons/obj/forensics.dmi' icon_state = "microscope" - anchored = 1 + anchored = TRUE density = 1 var/obj/item/sample = null @@ -32,7 +32,7 @@ to_chat(user, "Вы вставили \the [W] в микроскоп.") user.drop_transfer_item_to_loc(W, src) sample = W - update_icon() + update_icon(UPDATE_ICON_STATE) return ..() @@ -53,7 +53,7 @@ to_chat(user, "Печать отчета...") var/obj/item/paper/report = new(get_turf(src)) report.stamped = list(/obj/item/stamp) - report.overlays = list("paper_stamped") + LAZYADD(report.stamp_overlays, "paper_stamped") report_num++ if(istype(sample, /obj/item/forensics/swab)) @@ -109,7 +109,7 @@ sample.forceMove_turf() remover.put_in_hands(sample, ignore_anim = FALSE) sample = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/microscope/proc/is_complete_print(print) return stringpercent(print) <= fingerprint_complete @@ -117,13 +117,13 @@ /obj/machinery/microscope/AltClick() remove_sample(usr) -/obj/machinery/microscope/MouseDrop(atom/other) - if(usr == other) +/obj/machinery/microscope/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(usr == over_object) remove_sample(usr) - else - return ..() + return FALSE + return ..() -/obj/machinery/microscope/update_icon() +/obj/machinery/microscope/update_icon_state() icon_state = "microscope" if(sample) icon_state += "slide" diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm index fc97702a6c3..fe9ddba2c85 100644 --- a/code/modules/detectivework/tools/sample_kits.dm +++ b/code/modules/detectivework/tools/sample_kits.dm @@ -157,19 +157,19 @@ . = ..() -/obj/item/forensics/sample_kit/MouseDrop(atom/over) +/obj/item/forensics/sample_kit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(istype(over, /obj/screen)) + if(istype(over_object, /obj/screen)) return FALSE if(loc != user || user.incapacitated() || !ishuman(user)) return FALSE - afterattack(over, user, TRUE) + afterattack(over_object, user, TRUE) return TRUE diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 90d9aea64b4..91d8ed728ab 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -42,6 +42,7 @@ log transactions /obj/machinery/atm/Initialize() ..() reconnect_database() + update_icon() /obj/machinery/atm/process() if(stat & NOPOWER) @@ -80,6 +81,35 @@ log transactions linked_db = DB break + +/obj/machinery/atm/update_icon_state() + . = ..() + if(stat & NOPOWER) + icon_state = "atm_off" + else + icon_state = "atm" + + +/obj/machinery/atm/power_change(forced = FALSE) + if(!..()) + return + if(stat & NOPOWER) + set_light(0) + else + set_light(1, LIGHTING_MINIMUM_POWER) + update_icon() + + +/obj/machinery/atm/update_overlays() + . = ..() + underlays.Cut() + + if(stat & NOPOWER) + return + + underlays += emissive_appearance(icon, "atm_lightmask") + + /obj/machinery/atm/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card)) if(!powered()) @@ -280,7 +310,7 @@ log transactions if(!R.stamped) R.stamped = new() R.stamped += /obj/item/stamp - R.overlays += stampoverlay + LAZYADD(R.stamp_overlays, stampoverlay) R.stamps += "
    This paper has been stamped by the Automatic Teller Machine." playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, TRUE) diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 0d0b1d317e6..ff59caf8aa7 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(all_money_accounts) if(!R.stamped) R.stamped = new R.stamped += /obj/item/stamp - R.overlays += stampoverlay + LAZYADD(R.stamp_overlays, stampoverlay) R.stamps += "
    This paper has been stamped by the Accounts Database." //add the account diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index 2555ad08253..0f7aaa0a90b 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -39,7 +39,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper_eftpos" -/obj/item/paper/check/update_icon() +/obj/item/paper/check/update_icon_state() return /obj/item/paper/check/AltClick(mob/user, obj/item/I) diff --git a/code/modules/economy/quests/_base_quests.dm b/code/modules/economy/quests/_base_quests.dm index 7022f3a0dd6..419d9b715a2 100644 --- a/code/modules/economy/quests/_base_quests.dm +++ b/code/modules/economy/quests/_base_quests.dm @@ -64,7 +64,7 @@ if(!quest_type) var/list/possible_types = list() if((length(GLOB.clients) < MIN_PLAYERS_FOR_MIX) && (length(current_quests) == 2)) - for(var/datum/cargo_quest/quest in current_quests) + for(var/datum/cargo_quest/quest as anything in current_quests) possible_types += quest.type else for(var/path in subtypesof(/datum/cargo_quest) - /datum/cargo_quest/thing) @@ -75,10 +75,10 @@ possible_types.Remove(customer.cant_order) quest_type = pick(possible_types) - for(var/datum/cargo_quest/quest in current_quests) + for(var/datum/cargo_quest/quest as anything in current_quests) if(quest.type != quest_type) continue - quest.generate_goal(difficultly = quest_difficulty.diff_flag) + quest.add_goal(difficultly = quest_difficulty.diff_flag) quest.update_interface_icon() return @@ -140,10 +140,12 @@ var/datum/cargo_quests_storage/q_storage /// Quest desc, using in interface. var/list/desc = list() - /// Quest interface icons, using in interface. - var/list/interface_icons = list() - /// Quest interface icon states, using in interface. - var/list/interface_icon_states = list() + /// Quest base icon, using in interface. + var/interface_icon + /// Quest base icon state, using in interface. + var/interface_icon_state + /// Quest interface images, using in interface. + var/list/interface_images = list() /// Requested order's item types, unless otherwise specified. var/list/req_items = list() ///possible difficultly @@ -152,18 +154,21 @@ /datum/cargo_quest/New(storage) q_storage = storage - generate_goal(difficultly = q_storage.quest_difficulty.diff_flag) + add_goal(difficultly = q_storage.quest_difficulty.diff_flag) update_interface_icon() -/datum/cargo_quest/proc/generate_goal(difficultly) +/datum/cargo_quest/proc/generate_goal_list(difficultly) return -/datum/cargo_quest/proc/length_quest() +/datum/cargo_quest/proc/add_goal(difficultly) return -/datum/cargo_quest/proc/update_interface_icon() +/datum/cargo_quest/proc/length_quest() return +/datum/cargo_quest/proc/update_interface_icon() + if(interface_icon && interface_icon_state) + interface_images += icon2base64(icon(interface_icon, interface_icon_state, SOUTH, 1)) /datum/cargo_quest/proc/check_required_item(atom/movable/check_item) return diff --git a/code/modules/economy/quests/quest_console.dm b/code/modules/economy/quests/quest_console.dm index 17e213989c6..5627a9942e8 100644 --- a/code/modules/economy/quests/quest_console.dm +++ b/code/modules/economy/quests/quest_console.dm @@ -9,7 +9,7 @@ desc = "Essential for supply requests. Your bread and butter." icon_keyboard = "cargo_quest_key" icon_screen = "cargo_quest" - req_access = list(ACCESS_QM) + req_access = list(ACCESS_CARGO) circuit = /obj/item/circuitboard/supplyquest /// If TRUE you can see only active quests var/for_active_quests = FALSE @@ -71,17 +71,16 @@ /obj/machinery/computer/supplyquest/ui_data(mob/user) var/list/data = list() var/list/quest_storages = list() - for(var/datum/cargo_quests_storage/quest_storage in SScargo_quests.quest_storages) + for(var/datum/cargo_quests_storage/quest_storage as anything in SScargo_quests.quest_storages) if(for_active_quests && !quest_storage.active) continue var/timeleft_sec = round((quest_storage.time_start + quest_storage.quest_time - world.time) / 10) var/list/quests_items = list() for(var/datum/cargo_quest/cargo_quest as anything in quest_storage.current_quests) - var/image_index = rand(1, length(cargo_quest.interface_icons)) quests_items.Add(list(list( "quest_type_name" = cargo_quest.quest_type_name, "desc" = cargo_quest.desc.Join(""), - "image" = "[icon2base64(icon(cargo_quest.interface_icons[image_index], cargo_quest.interface_icon_states[image_index], SOUTH, 1))]", + "image" = "[cargo_quest.interface_images[rand(1, length(cargo_quest.interface_images))]]", ))) quest_storages.Add(list(list( @@ -236,7 +235,6 @@ for_active_quests = TRUE circuit = /obj/item/circuitboard/questcons density = FALSE - req_access = list(ACCESS_CARGO) /obj/machinery/computer/supplyquest/workers/Initialize(mapload) @@ -306,10 +304,10 @@ playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) print_animation() + /obj/machinery/computer/supplyquest/workers/proc/print_animation() - add_overlay(image(icon, icon_state = "print_quest_overlay", layer = overlay_layer)) - spawn(4 SECONDS) // Should change this after merging update_overlays for computers - update_icon() + flick_overlay_view(image(icon, src, "print_quest_overlay", layer + 0.1), 4 SECONDS) + /obj/item/qm_quest_tablet name = "Quartermaster Tablet" diff --git a/code/modules/economy/quests/reagents_quests.dm b/code/modules/economy/quests/reagents_quests.dm index e1b4df1405f..2e6ca37bfdb 100644 --- a/code/modules/economy/quests/reagents_quests.dm +++ b/code/modules/economy/quests/reagents_quests.dm @@ -1,8 +1,8 @@ /datum/cargo_quest/reagents quest_type_name = "Chemical" req_items = list(/obj/item/reagent_containers) - interface_icons = list('icons/obj/chemical.dmi') - interface_icon_states = list("beakerlarge") + interface_icon = 'icons/obj/chemical.dmi' + interface_icon_state = "beakerlarge" difficultly_flags = (QUEST_DIFFICULTY_EASY) @@ -34,7 +34,7 @@ "growthserum" = list("volume" = 15, "reward" = 55) ) -/datum/cargo_quest/reagents/generate_goal(difficultly) +/datum/cargo_quest/reagents/add_goal(difficultly) var/list/possible_reagents_list = repeated_reagents.Copy() + unique_reagents.Copy() var/our_reagent = pick(possible_reagents_list) required_reagents[our_reagent] += possible_reagents_list[our_reagent] @@ -65,9 +65,6 @@ /datum/cargo_quest/reagents/drinks quest_type_name = "Drink" - interface_icons = list() - interface_icon_states = list() - repeated_reagents = list( "b52" = list("volume" = 30,"reward" = 60), "bacchus_blessing" = list("volume" = 30,"reward" = 100), @@ -101,22 +98,15 @@ "gibbfloats" = list("volume" = 30,"reward" = 40), "nuka_cola" = list("volume" = 30,"reward" = 60), "pumpkin_latte" = list("volume" = 30,"reward" = 40), + "zazafizzy" = list("volume" = 30, "reward" = 20) ) unique_reagents = list() /datum/cargo_quest/reagents/drinks/update_interface_icon() - var/list/new_interface_icons = list() - var/list/new_interface_icon_states = list() - for(var/reagent_id in required_reagents) var/datum/reagent/reagent = GLOB.chemical_reagents_list[reagent_id] if(reagent.drink_icon) - new_interface_icons += 'icons/obj/drinks.dmi' - new_interface_icon_states += reagent.drink_icon + interface_images += icon2base64(icon('icons/obj/drinks.dmi', reagent.drink_icon, SOUTH, 1)) else - new_interface_icons += 'icons/obj/chemical.dmi' - new_interface_icon_states += "beakerlarge" - - interface_icons = new_interface_icons - interface_icon_states = new_interface_icon_states + interface_images += icon2base64(icon('icons/obj/chemical.dmi', "beakerlarge", SOUTH, 1)) diff --git a/code/modules/economy/quests/thing_quests.dm b/code/modules/economy/quests/thing_quests.dm index 99ff36ef3b2..03a34d37c82 100644 --- a/code/modules/economy/quests/thing_quests.dm +++ b/code/modules/economy/quests/thing_quests.dm @@ -8,11 +8,7 @@ var/unique_things = TRUE var/list/current_list -/datum/cargo_quest/thing/generate_goal(difficultly, request_obj, target_reward) - if(request_obj) - req_items += request_obj - q_storage.reward += target_reward - return +/datum/cargo_quest/thing/generate_goal_list(difficultly) var/list/difficult_list switch(difficultly) @@ -28,10 +24,16 @@ if(QUEST_DIFFICULTY_VERY_HARD) difficult_list = very_hard_items + return difficult_list + +/datum/cargo_quest/thing/add_goal(difficultly) + var/list/difficult_list = generate_goal_list(difficultly) var/obj/generated_item = pick(difficult_list) + q_storage.reward += difficult_list[generated_item] if(unique_things) difficult_list.Remove(generated_item) + req_items += generated_item current_list = req_items.Copy() @@ -39,20 +41,15 @@ /datum/cargo_quest/thing/update_interface_icon() - var/list/new_interface_icons = list() - var/list/new_interface_icon_states = list() - + if(interface_icon && interface_icon_state) + interface_images += icon2base64(icon(interface_icon, interface_icon_state, SOUTH, 1)) + return for(var/our_item in req_items) var/obj/obj = our_item if(initial(obj.icon) && initial(obj.icon_state)) - new_interface_icons += initial(obj.icon) - new_interface_icon_states += initial(obj.icon_state) + interface_images += icon2base64(icon(initial(obj.icon), initial(obj.icon_state), SOUTH, 1)) else - new_interface_icons += 'icons/obj/storage.dmi' - new_interface_icon_states += "box" - - interface_icons = new_interface_icons - interface_icon_states = new_interface_icon_states + interface_images += icon2base64(icon('icons/obj/storage.dmi', "box", SOUTH, 1)) /datum/cargo_quest/thing/length_quest() return length(req_items) @@ -124,13 +121,14 @@ /obj/item/organ/internal/heart/cursed = 550, /obj/item/organ/internal/xenos/plasmavessel/hunter = 550, /obj/item/organ/internal/xenos/plasmavessel/drone = 550, - /obj/item/organ/internal/xenos/neurotoxin = 650, + /obj/item/organ/internal/xenos/neurotoxin/sentinel = 650, /obj/item/organ/internal/wryn/glands = 700, /obj/item/organ/internal/xenos/hivenode = 700, /obj/item/organ/internal/heart/plasmaman = 750, /obj/item/organ/internal/xenos/acidgland/sentinel = 750, /obj/item/organ/internal/xenos/acidgland/praetorian = 750, /obj/item/organ/internal/xenos/resinspinner = 750, + /obj/item/organ/internal/xenos/neurotoxin = 850, /obj/item/organ/internal/xenos/acidgland/queen = 900, /obj/item/organ/internal/xenos/plasmavessel/queen = 900 ) @@ -148,6 +146,7 @@ /obj/item/reagent_containers/food/snacks/amanitajelly = 50, /obj/item/reagent_containers/food/snacks/donut/chaos = 50, /obj/item/reagent_containers/food/snacks/sliceable/noel = 50, + /obj/item/reagent_containers/food/snacks/candy/jellybean/purple = 50, /obj/item/reagent_containers/food/snacks/monstermeat/bearmeat = 50, /obj/item/reagent_containers/food/snacks/sashimi = 60, /obj/item/reagent_containers/food/snacks/fishburger = 60, @@ -160,10 +159,27 @@ /obj/item/reagent_containers/food/snacks/monkeysdelight = 60, /obj/item/reagent_containers/food/snacks/aesirsalad = 60, /obj/item/reagent_containers/food/snacks/rofflewaffles = 60, + /obj/item/reagent_containers/food/snacks/muffin = 60, + /obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/human = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/slime = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/skrell = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/tajaran = 60, + /obj/item/reagent_containers/food/snacks/meatsteak/unathi = 60, ) normal_items = list( + /obj/item/reagent_containers/food/snacks/meatsteak/vox = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/wryn = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/kidan = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/diona = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/nian = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/drask = 70, + /obj/item/reagent_containers/food/snacks/meatsteak/grey = 70, /obj/item/reagent_containers/food/snacks/candy/jawbreaker = 70, + /obj/item/reagent_containers/food/snacks/telebacon = 70, + /obj/item/reagent_containers/food/snacks/plov = 70, /obj/item/reagent_containers/food/snacks/weirdoliviersalad = 70, /obj/item/reagent_containers/food/snacks/doner_mushroom = 70, /obj/item/reagent_containers/food/snacks/doner_vegan = 70, @@ -249,19 +265,10 @@ difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD) -/datum/cargo_quest/thing/minerals/generate_goal(difficultly, request_obj, target_reward) - var/list/difficult_list - switch(difficultly) - if(QUEST_DIFFICULTY_EASY) - difficult_list = easy_items - - if(QUEST_DIFFICULTY_NORMAL) - difficult_list = normal_items - - if(QUEST_DIFFICULTY_HARD) - difficult_list = hard_items - +/datum/cargo_quest/thing/minerals/add_goal(difficultly) + var/list/difficult_list = generate_goal_list(difficultly) var/obj/item/generated_mineral = pick(difficult_list) + q_storage.reward += difficult_list[generated_mineral]["reward"] if(!required_minerals[generated_mineral]) required_minerals += generated_mineral @@ -298,16 +305,10 @@ current_list = required_minerals.Copy() /datum/cargo_quest/thing/minerals/update_interface_icon() - var/list/new_interface_icons = list() - var/list/new_interface_icon_states = list() for(var/mineral in required_minerals) var/obj/obj = mineral - new_interface_icons += initial(obj.icon) - new_interface_icon_states += initial(obj.icon_state) - - interface_icons = new_interface_icons - interface_icon_states = new_interface_icon_states + interface_images += icon2base64(icon(initial(obj.icon), initial(obj.icon_state), SOUTH, 1)) /datum/cargo_quest/thing/minerals/length_quest() var/stack_length @@ -396,8 +397,8 @@ /datum/cargo_quest/thing/botanygenes quest_type_name = "Botany Genes on Disks" - interface_icons = list('icons/obj/module.dmi') - interface_icon_states = list("datadisk_hydro") + interface_icon = 'icons/obj/module.dmi' + interface_icon_state = "datadisk_hydro" req_items = list(/obj/item/disk/plantgene) var/list/required_genes = list() easy_items = list( @@ -426,17 +427,9 @@ ) difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD) -/datum/cargo_quest/thing/botanygenes/generate_goal(difficultly, request_obj, target_reward) - - var/list/difficult_list - switch(difficultly) - if(QUEST_DIFFICULTY_EASY) - difficult_list = easy_items - if(QUEST_DIFFICULTY_NORMAL) - difficult_list = normal_items - if(QUEST_DIFFICULTY_HARD) - difficult_list = hard_items +/datum/cargo_quest/thing/botanygenes/add_goal(difficultly) + var/list/difficult_list = generate_goal_list(difficultly) var/datum/plant_gene/generated_gene = pick(difficult_list) q_storage.reward += difficult_list[generated_gene] @@ -448,9 +441,6 @@ desc += "[capitalize(format_text(initial(generated_gene.name)))]
    " -/datum/cargo_quest/thing/botanygenes/update_interface_icon() - return - /datum/cargo_quest/thing/botanygenes/length_quest() return length(required_genes) @@ -473,8 +463,8 @@ /datum/cargo_quest/thing/genes quest_type_name = "DNA Genes" - interface_icons = list('icons/obj/hypo.dmi') - interface_icon_states = list("dnainjector") + interface_icon = 'icons/obj/hypo.dmi' + interface_icon_state = "dnainjector" req_items = list(/obj/item/dnainjector) var/list/required_blocks = list() @@ -528,22 +518,12 @@ ) difficultly_flags = (QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD) -/datum/cargo_quest/thing/genes/update_interface_icon() - return - /datum/cargo_quest/thing/genes/length_quest() return length(required_blocks) -/datum/cargo_quest/thing/genes/generate_goal(difficultly, request_obj, target_reward) +/datum/cargo_quest/thing/genes/add_goal(difficultly) - var/list/difficult_list - switch(difficultly) - if(QUEST_DIFFICULTY_EASY) - difficult_list = easy_items - if(QUEST_DIFFICULTY_NORMAL) - difficult_list = normal_items - if(QUEST_DIFFICULTY_HARD) - difficult_list = hard_items + var/list/difficult_list = generate_goal_list(difficultly) var/generated_gene = pick(difficult_list) q_storage.reward += difficult_list[generated_gene] @@ -585,8 +565,8 @@ #define REQUIRED_BLOOD_AMOUNT 10 /datum/cargo_quest/thing/virus quest_type_name = "Viruses symptoms in vials (10u minimum)" - interface_icons = list('icons/obj/chemical.dmi') - interface_icon_states = list("vial") + interface_icon = 'icons/obj/chemical.dmi' + interface_icon_state = "vial" req_items = list(/obj/item/reagent_containers/glass/beaker/vial) var/list/required_symptoms = list() @@ -638,26 +618,11 @@ ) difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD) -/datum/cargo_quest/thing/virus/update_interface_icon() - return - /datum/cargo_quest/thing/virus/length_quest() return length(required_symptoms) -/datum/cargo_quest/thing/virus/generate_goal(difficultly, request_obj, target_reward) - var/list/difficult_list - switch(difficultly) - if(QUEST_DIFFICULTY_EASY) - difficult_list = easy_items - - if(QUEST_DIFFICULTY_NORMAL) - difficult_list = normal_items - - if(QUEST_DIFFICULTY_HARD) - difficult_list = hard_items - - if(QUEST_DIFFICULTY_VERY_HARD) - difficult_list = very_hard_items +/datum/cargo_quest/thing/virus/add_goal(difficultly) + var/list/difficult_list = generate_goal_list(difficultly) var/datum/symptom/generated_symptom = pick(difficult_list) q_storage.reward += difficult_list[generated_symptom] @@ -705,8 +670,8 @@ /datum/cargo_quest/thing/capsule quest_type_name = "Mob in lazarus capsule" - interface_icons = list('icons/obj/mobcap.dmi') - interface_icon_states = list("mobcap3") + interface_icon = 'icons/obj/mobcap.dmi' + interface_icon_state = "mobcap3" req_items = list(/obj/item/mobcapsule) var/list/required_mobs = list() @@ -726,27 +691,11 @@ ) difficultly_flags = (QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD) -/datum/cargo_quest/thing/capsule/update_interface_icon() - return - /datum/cargo_quest/thing/capsule/length_quest() return length(required_mobs) -/datum/cargo_quest/thing/capsule/generate_goal(difficultly, request_obj, target_reward) - var/list/difficult_list - switch(difficultly) - if(QUEST_DIFFICULTY_EASY) - difficult_list = easy_items - - if(QUEST_DIFFICULTY_NORMAL) - difficult_list = normal_items - - if(QUEST_DIFFICULTY_HARD) - difficult_list = hard_items - - if(QUEST_DIFFICULTY_VERY_HARD) - difficult_list = very_hard_items - +/datum/cargo_quest/thing/capsule/add_goal(difficultly) + var/list/difficult_list = generate_goal_list(difficultly) var/mob/generated_mob = pick(difficult_list) q_storage.reward += difficult_list[generated_mob] if(unique_things) diff --git a/code/modules/events/door_runtime.dm b/code/modules/events/door_runtime.dm index 3e44bf90de9..ea8de1ebf8c 100644 --- a/code/modules/events/door_runtime.dm +++ b/code/modules/events/door_runtime.dm @@ -10,7 +10,7 @@ INVOKE_ASYNC(D, TYPE_PROC_REF(/obj/machinery/door, hostile_lockdown)) addtimer(CALLBACK(D, TYPE_PROC_REF(/obj/machinery/door, disable_lockdown)), 90 SECONDS) addtimer(CALLBACK(src, PROC_REF(reboot)), 90 SECONDS) - post_status("alert", "lockdown") + post_status(STATUS_DISPLAY_ALERT, "lockdown") /datum/event/door_runtime/proc/reboot() GLOB.minor_announcement.Announce("Автоматическая перезагрузка системы завершена. Хорошего вам дня.","ПЕРЕЗАГРУЗКА СЕТИ:") diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index 89cacffb1f4..af5ef381c1b 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -14,7 +14,7 @@ icon = 'icons/obj/meteor.dmi' icon_state = "space_dust" density = 1 - anchored = 1 + anchored = TRUE var/strength = 2 //ex_act severity number var/life = 2 //how many things we hit before qdel(src) var/atom/goal = null diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index e6dce3240bb..a0ab1c3bc12 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -222,7 +222,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ревенант", /datum/event/revenant, 150), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Спавн свармеров", /datum/event/spawn_swarmer, 0, is_one_shot = TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Спавн морфа", /datum/event/spawn_morph, 40, list(ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pulse Demon Infiltration", /datum/event/spawn_pulsedemon, 150, list(ASSIGNMENT_ENGINEER = 10), is_one_shot = TRUE), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pulse Demon Infiltration", /datum/event/spawn_pulsedemon, 0), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Вспышка болезни", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Хедкрабы", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Сбой работы дверей", /datum/event/door_runtime, 50, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_AI = 150), TRUE), diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index 35cf4c70b4c..96047820537 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -27,7 +27,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 icon_state = "immrod" throwforce = 100 density = 1 - anchored = 1 + anchored = TRUE var/z_original = 0 var/destination var/notify = TRUE diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm index 93c498e37bd..3ea7f0aadf0 100644 --- a/code/modules/events/tear.dm +++ b/code/modules/events/tear.dm @@ -25,7 +25,7 @@ icon='icons/effects/tear.dmi' icon_state="tear" density = 0 - anchored = 1 + anchored = TRUE light_range = 3 /obj/effect/tear/Initialize(mapload) diff --git a/code/modules/fish/fish_items.dm b/code/modules/fish/fish_items.dm index e47c5a98942..59d2caab707 100644 --- a/code/modules/fish/fish_items.dm +++ b/code/modules/fish/fish_items.dm @@ -131,7 +131,7 @@ force = 3 /obj/item/fish/shark/attackby(var/obj/item/O, var/mob/user as mob) - if(istype(O, /obj/item/wirecutters)) + if(O.tool_behaviour == TOOL_WIRECUTTER) to_chat(user, "You rip out the teeth of \the [src.name]!") new /obj/item/fish/toothless_shark(get_turf(src)) new /obj/item/shard/shark_teeth(get_turf(src)) diff --git a/code/modules/fish/fish_types.dm b/code/modules/fish/fish_types.dm index 86b87373422..f7c2e6659cc 100644 --- a/code/modules/fish/fish_types.dm +++ b/code/modules/fish/fish_types.dm @@ -63,7 +63,7 @@ /datum/fish/feederfish/special_interact(obj/machinery/fishtank/my_tank) if(!my_tank || !istype(my_tank)) return - if(my_tank.fish_count < 2) + if(my_tank.get_num_fish() < 2) return if(my_tank.food_level <= 5 && prob(25)) my_tank.adjust_food_level(1) diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm index 3b2fca703bf..2c743a77285 100644 --- a/code/modules/fish/fishtank.dm +++ b/code/modules/fish/fishtank.dm @@ -3,7 +3,6 @@ // Fish Tanks // ////////////////////////////// - /obj/machinery/fishtank name = "placeholder tank" desc = "So generic, it might as well have no description at all." @@ -16,12 +15,11 @@ var/tank_type = "" // Type of aquarium, used for icon updating var/water_capacity = 0 // Number of units the tank holds (varies with tank type) var/water_level = 0 // Number of units currently in the tank (new tanks start empty) - var/light_switch = 0 // 0 = off, 1 = on (off by default) + var/light_switch = FALSE var/filth_level = 0 // How dirty the tank is (max 10) - var/lid_switch = 0 // 0 = open, 1 = closed (open by default) + var/lid_switch = FALSE var/max_fish = 0 // How many fish the tank can support (varies with tank type, 1 fish per 50 units sounds reasonable) var/food_level = 0 // Amount of fishfood floating in the tank (max 10) - var/fish_count = 0 // Number of fish in the tank var/list/fish_list = list() // Tracks the current types of fish in the tank var/egg_count = 0 // How many fish eggs can be harvested from the tank (capped at the max_fish value) var/list/egg_list = list() // Tracks the current types of harvestable eggs in the tank @@ -30,6 +28,7 @@ var/leaking = FALSE // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default) var/shard_count = 0 // Number of glass shards to salvage when broken (1 less than the number of sheets to build the tank) + /obj/machinery/fishtank/bowl name = "fish bowl" desc = "A small bowl capable of housing a single fish, commonly found on desks. This one has a tiny treasure chest in it!" @@ -46,6 +45,7 @@ max_integrity = 15 // Not very sturdy shard_count = 0 // No salvageable shards + /obj/machinery/fishtank/tank name = "fish tank" desc = "A large glass tank designed to house aquatic creatures. Contains an integrated water circulation system." @@ -85,68 +85,87 @@ // VERBS & PROCS // ////////////////////////////// +/obj/machinery/fishtank/AltClick(mob/user) + if(!Adjacent(user)) + return ..() + toggle_lid(user) + + +/obj/machinery/fishtank/AltShiftClick(mob/user) + if(!Adjacent(user)) + return ..() + toggle_light(user) + + /obj/machinery/fishtank/verb/toggle_lid_verb() set name = "Toggle Tank Lid" set category = "Object" set src in view(1) + toggle_lid(usr) - toggle_lid() - -/obj/machinery/fishtank/proc/toggle_lid() - lid_switch = !lid_switch - update_icon() /obj/machinery/fishtank/verb/toggle_light_verb() set name = "Toggle Tank Light" set category = "Object" set src in view(1) + toggle_light(usr) - toggle_light() -/obj/machinery/fishtank/proc/toggle_light() +/obj/machinery/fishtank/proc/toggle_lid(mob/user) + if(user.incapacitated() || user.restrained()) + return + lid_switch = !lid_switch + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/fishtank/proc/toggle_light(mob/user) + if(user.incapacitated() || user.restrained()) + return light_switch = !light_switch if(light_switch) set_light(2, 2, "#a0a080") else adjust_tank_light() + ////////////////////////////// -// NEW() PROCS // +// Initialize() PROCS // ////////////////////////////// -/obj/machinery/fishtank/New() - ..() - if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then +/obj/machinery/fishtank/Initialize(mapload) + . = ..() + if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then verbs -= /obj/machinery/fishtank/verb/toggle_lid_verb verbs -= /obj/machinery/fishtank/verb/toggle_light_verb -/obj/machinery/fishtank/tank/New() - ..() - if(prob(5)) //5% chance to get the castle decoration + +/obj/machinery/fishtank/tank/Initialize(mapload) + . = ..() + if(prob(5)) //5% chance to get the castle decoration icon_state = "tank2" + ////////////////////////////// // ICON PROCS // ////////////////////////////// -/obj/machinery/fishtank/update_icon() - cut_overlays() - +/obj/machinery/fishtank/update_overlays() + . = ..() //Update Alert Lights if(has_lid) //Skip the alert lights for aquariums that don't have lids (fishbowls) if(egg_count > 0) //There is at least 1 egg to harvest - add_overlay("over_egg") - if(lid_switch == 1) //Lid is closed, lid status light is red - add_overlay("over_lid_1") + . += "over_egg" + if(lid_switch) //Lid is closed, lid status light is red + . += "over_lid_1" else //Lid is open, lid status light is green - add_overlay("over_lid_0") + . += "over_lid_0" if(food_level > 5) //Food_level is high and isn't a concern yet - add_overlay("over_food_0") + . += "over_food_0" else if(food_level > 2) //Food_level is starting to get low, but still above the breeding threshold - add_overlay("over_food_1") + . += "over_food_1" else //Food_level is below breeding threshold, or fully consumed, feed the fish! - add_overlay("over_food_2") - add_overlay("over_leak_[leaking]") //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak + . += "over_food_2" + . += "over_leak_[leaking]" //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak //Update water overlay if(!water_level) @@ -154,23 +173,25 @@ var/water_type = "_clean" //Default to clean water if(filth_level > 5) water_type = "_dirty" //Show dirty water above filth_level 5 (breeding threshold) if(water_level > (water_capacity * 0.85)) //Show full if the water_level is over 85% of water_capacity - add_overlay("over_[tank_type]_full[water_type]") + . += "over_[tank_type]_full[water_type]" else if(water_level > (water_capacity * 0.35)) //Show half-full if the water_level is over 35% of water_capacity - add_overlay("over_[tank_type]_half[water_type]") + . += "over_[tank_type]_half[water_type]" -/obj/machinery/fishtank/wall/update_icon() - ..() + +/obj/machinery/fishtank/wall/update_overlays() + . = ..() // Update fish overlay for wall tanks var/num_fish = length(fish_list) if(!num_fish) return switch(num_fish) if(1 to 3) - add_overlay("over_tank_fish_33") + . += "over_tank_fish_33" if(4 to 7) - add_overlay("over_tank_fish_66") + . += "over_tank_fish_66" if(7 to INFINITY) - add_overlay("over_tank_fish_100") + . += "over_tank_fish_100" + ////////////////////////////// // PROCESS PROC // @@ -180,23 +201,23 @@ /obj/machinery/fishtank/wall/CanAtmosPass(turf/T) return FALSE + /obj/machinery/fishtank/process() //Start by counting fish in the tank - fish_count = 0 - var/ate_food = 0 - for(var/fish in fish_list) - if(fish) - fish_count++ + var/fish_count = get_num_fish() + var/ate_food = FALSE //Check if the water level can support the current number of fish if((fish_count * 50) > water_level) if(prob(50)) //Not enough water for all the fish, chance to kill one + fish_count-- kill_fish() //Chance passed, kill a random fish adjust_filth_level(2) //Dead fish raise the filth level quite a bit, reflect this //Check filth_level if(filth_level == 10 && fish_count > 0) //This tank is nasty and possibly unsuitable for fish if any are in it if(prob(30)) //Chance for a fish to die each cycle while the tank is this nasty + fish_count-- kill_fish() //Kill a random fish, don't raise filth level since we're at cap already //Check breeding conditions @@ -205,7 +226,7 @@ if(prob(((fish_count - 2) * 5)+10)) //Chances increase with each additional fish, 10% base + 5% per additional fish breed_fish() adjust_food_level(-0.1) //Remove extra food for the breeding process - ate_food = 1 + ate_food = TRUE //Handle standard food and filth adjustments if(food_level > 0 && prob(50)) //Chance for the fish to eat some food @@ -213,7 +234,7 @@ adjust_food_level(fish_count * -0.05) else //Use up the last of the food adjust_food_level(-food_level) - ate_food = 1 + ate_food = TRUE if(water_level > 0) //Don't dirty the tank if it has no water if(fish_count == 0) //If the tank has no fish, algae growth can occur @@ -234,17 +255,23 @@ adjust_water_level(-10) else if(leaking == 1) //At or below 50% health, the tank will lose 1 water_level per cycle (minor leak) adjust_water_level(-1) - update_icon() + update_icon(UPDATE_OVERLAYS) + ////////////////////////////// // SUPPORT PROCS // ////////////////////////////// +/obj/machinery/fishtank/proc/get_num_fish() + return length(fish_list) + + /obj/machinery/fishtank/proc/handle_special_interactions() for(var/datum/fish/fish in fish_list) fish.special_interact(src) adjust_tank_light() + /obj/machinery/fishtank/proc/adjust_tank_light() if(!light_switch) //tank light overrides fish lights var/glo_light = 0 @@ -256,16 +283,20 @@ else set_light(0, 0) + /obj/machinery/fishtank/proc/adjust_water_level(amount = 0) water_level = min(water_capacity, max(0, water_level + amount)) update_icon() + /obj/machinery/fishtank/proc/adjust_filth_level(amount = 0) filth_level = min(10, max(0, filth_level + amount)) + /obj/machinery/fishtank/proc/adjust_food_level(amount = 0) food_level = min(10, max(0, food_level + amount)) + /obj/machinery/fishtank/proc/check_health() //Leaking status check if(obj_integrity <= (max_integrity * 0.25)) //Major leak at or below 25% health (-10 water/cycle) @@ -275,30 +306,31 @@ else //Not leaking above 50% health leaking = 0 + /obj/machinery/fishtank/proc/kill_fish(datum/fish/fish_type = null) //Check if we were passed a fish to kill, otherwise kill a random one if(!fish_type) fish_type = pick(fish_list) fish_list.Remove(fish_type) //Kill a fish of the specified type - fish_count -- //Lower fish_count to reflect the death of a fish, so the everything else works fine if(istype(fish_type, /datum/fish/glofish)) adjust_tank_light() qdel(fish_type) - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/machinery/fishtank/proc/add_fish(datum/fish/fish_type = null) //Check if we were passed a fish type if(fish_type) fish_type = new fish_type fish_list.Add(fish_type) //Add a fish of the specified type - fish_count++ //Increase fish_count to reflect the introduction of a fish, so the everything else works fine //Announce the new fish visible_message("A new [fish_type.fish_name] has hatched in [src]!") - update_icon() + update_icon(UPDATE_OVERLAYS) //Null type fish are dud eggs, give a message to inform the player else to_chat(usr, "The eggs disolve in the water. They were duds!") + /obj/machinery/fishtank/proc/harvest_eggs(mob/user, obj/item/storage/bag/fish/fish_bag) if(!egg_count) //Can't harvest non-existant eggs return @@ -320,42 +352,57 @@ egg_list.Cut() //Destroy any excess eggs, clearing the egg_list if(duds) - to_chat(user, "[duds] egg\s [duds == 1 ? "was a dud" : "were duds"]!") + to_chat(user, span_notice("[duds] egg\s [duds == 1 ? "was a dud" : "were duds"]!")) + /obj/machinery/fishtank/proc/harvest_fish(mob/user) - if(fish_count <= 0) //Can't catch non-existant fish! - to_chat(user, "There are no fish in [src] to catch!") + if(!get_num_fish()) //Can't catch non-existant fish! + to_chat(user, span_warning("There are no fish in [src] to catch!")) return - var/list/fish_types = list() - var/list/fish_types_input = list() + var/list/fish_types = list() // fish sorted by type. Key is type of fish, value is a list of fish of that type + var/list/fish_types_input = list() // The choices given to the player, and the types of fish those choices are for. Key is string shown to player, value is type of fish for(var/datum/fish/F in fish_list) // Group up the fish first fish_types[F.type] += list(F) for(var/key in fish_types) // Then populate the list var/datum/fish/fish_type = key var/count = length(fish_types[key]) - fish_types_input += list("[initial(fish_type.fish_name)][count > 1 ? " (x[count])" : ""]" = fish_types[key]) + var/fish_description = "[initial(fish_type.fish_name)][count > 1 ? " (x[count])" : ""]" + fish_types_input[fish_description] = fish_type var/caught_fish = tgui_input_list(user, "Select a fish to catch.", "Fishing", fish_types_input) //Select a fish from the tank - if(fish_count <= 0) - to_chat(user, "There are no fish in [src] to catch!") + if(!caught_fish) + return + if(!Adjacent(user)) + to_chat(user, span_warning("You are no longer next to [src], so you can't catch fish!")) return - else if(caught_fish) - var/list/fishes_of_type = fish_types_input[caught_fish] - var/datum/fish/fish_to_scoop = pick(fishes_of_type) - // Is the user holding a fish bag? - var/obj/item/storage/bag/fish_bag - if(istype(user.r_hand, /obj/item/storage/bag/fish)) - fish_bag = user.r_hand - else if(istype(user.l_hand, /obj/item/storage/bag/fish)) - fish_bag = user.l_hand - var/fish_name = fish_to_scoop.fish_name - // Move the fish in - var/fish_item = fish_to_scoop.fish_item - if(fish_item) - var/obj/item/I = new fish_item(get_turf(user)) - if(fish_bag?.can_be_inserted(I)) - fish_bag.handle_item_insertion(I) - user.visible_message("[user.name] scoops \a [fish_name] from [src].", "You scoop \a [fish_name] out of [src].") - kill_fish(fish_to_scoop) //Kill the caught fish from the tank + if(!get_num_fish()) + to_chat(user, span_warning("There are no fish in [src] to catch!")) + return + var/fish_type_caught = fish_types_input[caught_fish] + var/list/fishes_of_type = list() + for(var/datum/fish/F in fish_list) + if(F.type == fish_type_caught) + fishes_of_type += list(F) + if(!length(fishes_of_type)) + var/datum/fish/fish_type = fish_type_caught + to_chat(user, span_warning("There are no [fish_type.fish_name] in [src] to catch!")) + return + var/datum/fish/fish_to_scoop = pick(fishes_of_type) + // Is the user holding a fish bag? + var/obj/item/storage/bag/fish_bag + if(istype(user.r_hand, /obj/item/storage/bag/fish)) + fish_bag = user.r_hand + else if(istype(user.l_hand, /obj/item/storage/bag/fish)) + fish_bag = user.l_hand + var/fish_name = fish_to_scoop.fish_name + // Move the fish in + var/fish_item = fish_to_scoop.fish_item + if(fish_item) + var/obj/item/I = new fish_item(get_turf(user)) + if(fish_bag?.can_be_inserted(I)) + fish_bag.handle_item_insertion(I) + user.visible_message("[user.name] scoops \a [fish_name] from [src].", "You scoop \a [fish_name] out of [src].") + kill_fish(fish_to_scoop) //Kill the caught fish from the tank + /obj/machinery/fishtank/proc/spill_water() var/turf/simulated/T = get_turf(src) @@ -366,20 +413,21 @@ if("tank") //Fishtank: Wets it's own tile and the 4 adjacent tiles (cardinal directions) if(istype(T)) T.MakeSlippery() - for(var/turf/simulated/ST in T.CardinalTurfs()) + for(var/turf/simulated/ST in T.AdjacentTurfs(open_only = TRUE, cardinal_only = TRUE)) ST.MakeSlippery() if("wall") //Wall-tank: Wets it's own tile and the surrounding 8 tiles (3x3 square) for(var/turf/simulated/ST in spiral_range_turfs(1, loc)) ST.MakeSlippery() + /obj/machinery/fishtank/proc/breed_fish() var/list/breed_candidates = fish_list.Copy() var/datum/fish/parent1 = pick_n_take(breed_candidates) if(!parent1.crossbreeder) //fish with crossbreed = 0 will only breed with their own species, and only leave duds if they can't breed - var/match_found = 0 + var/match_found = FALSE for(var/datum/fish/possible in breed_candidates) if(parent1.type == possible.type) - match_found = 1 + match_found = TRUE break if(match_found) egg_list.Add(parent1.egg_item) @@ -404,12 +452,14 @@ egg_list.Add(parent2.egg_item) egg_count++ + /obj/machinery/fishtank/welder_act(mob/user, obj/item/I) . = TRUE if(!I.tool_use_check(user, 0)) return default_welder_repair(user, I) + ////////////////////////////// Note from FalseIncarnate: // EXAMINE PROC // This proc is massive, messy, and probably could be handled better. ////////////////////////////// Feel free to try cleaning it up if you think of a better way to do it. @@ -417,6 +467,7 @@ /obj/machinery/fishtank/examine(mob/user) . = ..() var/examine_message = "" + var/fish_count = get_num_fish() //Approximate water level examine_message += "Water level: " @@ -518,85 +569,118 @@ if(leaking == 2) examine_message += "[src] is nearly shattered!" - //Finally, report the full examine_message constructed from the above reports - . += "[examine_message]" + . += span_notice("[examine_message]") + . += span_info("You can Alt-Click [src] to open/close its lid.") + . += span_info("You can Alt-Shift-Click [src] to enable/disable its light.") + ////////////////////////////// // ATACK PROCS // ////////////////////////////// /obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M) + var/fish_count = get_num_fish() if(istype(M, /mob/living/simple_animal/pet/cat)) if(M.a_intent == INTENT_HELP) //Cats can try to fish in open tanks on help intent if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open. - M.visible_message("[M.name] stares at into [src] while sitting perfectly still.", "The lid is closed, so you stare into [src] intently.") + M.visible_message( + span_notice("[M.name] stares at into [src] while sitting perfectly still."), + span_notice("The lid is closed, so you stare into [src] intently."), + ) else if(fish_count) //Tank must actually have fish to try catching one - M.visible_message("[M.name] leaps up onto [src] and attempts to fish through the opening!", "You jump up onto [src] and begin fishing through the opening!") + M.visible_message( + span_warning("[M.name] leaps up onto [src] and attempts to fish through the opening!"), + span_notice("You jump up onto [src] and begin fishing through the opening!"), + ) if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens - M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!") + M.visible_message( + span_notice("[M.name] slipped and got soaked!"), + span_notice("You slipped and got soaked!"), + ) if(istype(M, /mob/living/simple_animal/pet/cat/Syndi)) do_sparks(3, 1, src) else //No water or didn't slip, get that fish! - M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") + M.visible_message( + span_warning("[M.name] catches and devours a live fish!"), + span_notice("You catch and devour a live fish, yum!"), + ) kill_fish() //Kill a random fish M.health = M.maxHealth //Eating fish heals the predator else - to_chat(M, "There are no fish in [src]!") + to_chat(M, span_warning("There are no fish in [src]!")) else return ..() else if(istype(M, /mob/living/simple_animal/hostile/bear)) if(M.a_intent == INTENT_HELP) //Bears can try to fish in open tanks on help intent if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open. - M.visible_message("[M.name] scrapes it's claws along [src]'s lid.", "The lid is closed, so you scrape your claws against [src]'s lid.") + M.visible_message( + span_notice("[M.name] scrapes it's claws along [src]'s lid."), + span_notice("The lid is closed, so you scrape your claws against [src]'s lid."), + ) else if(fish_count) //Tank must actually have fish to try catching one - M.visible_message("[M.name] reaches into [src] and attempts to fish through the opening!", "You reach into [src] and begin fishing through the opening!") + M.visible_message( + span_warning("[M.name] reaches into [src] and attempts to fish through the opening!"), + span_warning("You reach into [src] and begin fishing through the opening!"), + ) if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail - M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!") + M.visible_message( + span_warning("[M.name] swipes at the water!"), + span_notice("You just barely missed that fish!"), + ) else //No water or didn't slip, get that fish! - M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") + M.visible_message( + span_warning("[M.name] catches and devours a live fish!"), + span_notice("You catch and devour a live fish, yum!"), + ) kill_fish() //Kill a random fish M.health = M.maxHealth //Eating fish heals the predator else - to_chat(M, "There are no fish in [src]!") + to_chat(M, span_warning("There are no fish in [src]!")) else return ..() else return ..() + /obj/machinery/fishtank/attack_hand(mob/user) if(isAI(user)) return add_fingerprint(user) user.changeNext_move(CLICK_CD_MELEE) + playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, TRUE) if(user.a_intent == INTENT_HARM) - playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) - user.visible_message("[user.name] bangs against the [name]!", \ - "You bang against the [name]!", \ - "You hear a banging sound.") + user.visible_message( + span_danger("[user] bangs against [src]!"), + span_danger("You bang against [src]!"), + span_italics("You hear a banging sound."), + ) else - playsound(loc, 'sound/effects/glassknock.ogg', 80, 1) - user.visible_message("[user.name] taps on the [name].", \ - "You tap on the [name].", \ - "You hear a knocking sound.") + user.visible_message( + span_notice("[user] taps on [src]."), + span_notice("You tap on [src]."), + span_italics("You hear a knocking sound."), + ) + /obj/machinery/fishtank/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) if(damage_amount) - playsound(src, 'sound/effects/glasshit.ogg', 75, 1) + playsound(src, 'sound/effects/glasshit.ogg', 75, TRUE) else - playsound(src, 'sound/weapons/tap.ogg', 50, 1) + playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) if(BURN) - playsound(src, 'sound/items/welder.ogg', 100, 1) + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + /obj/machinery/fishtank/deconstruct(disassembled = TRUE) if(QDELETED(src)) return if(!disassembled) - playsound(src, "shatter", 70, 1) + playsound(src, "shatter", 70, TRUE) for(var/i in 1 to shard_count) //Produce the appropriate number of glass shards var/obj/item/shard/S = new /obj/item/shard(get_turf(src)) transfer_fingerprints_to(S) @@ -606,6 +690,7 @@ new /obj/item/stack/sheet/glass(get_turf(src), shard_count + 1) //Produce the appropriate number of glass sheets, in a single stack qdel(src) + /obj/machinery/fishtank/attackby(obj/item/O, mob/user) //Open reagent containers add and remove water if(O.is_drainable()) @@ -625,7 +710,7 @@ O.reagents.clear_reagents() else if(water_level == water_capacity) - to_chat(user, "[src] is already full!") + to_chat(user, span_notice("[src] is already full!")) else add_fingerprint(user) message = "The filtration process purifies the water, raising the water level." @@ -636,31 +721,40 @@ message += " You overfilled [src] and some water runs down the side, wasted." O.reagents.clear_reagents() adjust_water_level(water_value) - user.visible_message("[user.name] pours the contents of [O.name] into [src].", "[message]") + user.visible_message( + span_notice("[user.name] pours the contents of [O.name] into [src]."), + span_notice("[message]"), + ) //Empty containers will scoop out water, filling the container as much as possible from the water_level else if(O.is_refillable()) if(!water_level) - to_chat(user, "[src] is empty!") + to_chat(user, span_notice("[src] is empty!")) else add_fingerprint(user) if(water_level >= O.reagents.maximum_volume) //Enough to fill the container completely O.reagents.add_reagent("fishwater", O.reagents.maximum_volume) adjust_water_level(-O.reagents.maximum_volume) - user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [O.name] from [src].") + user.visible_message( + span_notice("[user.name] scoops out some water from [src]."), + span_notice("You completely fill [O.name] from [src]."), + ) else //Fill the container as much as possible with the water_level O.reagents.add_reagent("fishwater", water_level) adjust_water_level(-water_level) - user.visible_message("[user.name] scoops out some water from [src].", "You fill [O.name] with the last of the water in [src].") + user.visible_message( + span_notice("[user.name] scoops out some water from [src]."), + span_notice("You fill [O.name] with the last of the water in [src]."), + ) //Fish eggs else if(istype(O, /obj/item/fish_eggs)) var/obj/item/fish_eggs/egg = O //Don't add eggs if there is no water (they kinda need that to live) if(!water_level) - to_chat(user, "[src] has no water; [egg.name] won't hatch without water!") + to_chat(user, span_warning("[src] has no water; [egg.name] won't hatch without water!")) else //Don't add eggs if the tank already has the max number of fish - if(fish_count >= max_fish) - to_chat(user, "[src] can't hold any more fish.") + if(get_num_fish() >= max_fish) + to_chat(user, span_notice("[src] can't hold any more fish.")) else add_fingerprint(user) add_fish(egg.fish_type) @@ -671,15 +765,21 @@ if(water_level) if(food_level < 10) add_fingerprint(user) - if(fish_count == 0) - user.visible_message("[user.name] shakes some fish food into the empty [src]... How sad.", "You shake some fish food into the empty [src]... If only it had fish.") + if(!get_num_fish()) + user.visible_message( + span_notice("[user.name] shakes some fish food into the empty [src]... How sad."), + span_notice("You shake some fish food into the empty [src]... If only it had fish."), + ) else - user.visible_message("[user.name] feeds the fish in [src]. The fish look excited!", "You feed the fish in [src]. They look excited!") + user.visible_message( + span_notice("[user.name] feeds the fish in [src]. The fish look excited!"), + span_notice("You feed the fish in [src]. They look excited!"), + ) adjust_food_level(10) else - to_chat(user, "[src] already has plenty of food in it. You decide to not add more.") + to_chat(user, span_notice("[src] already has plenty of food in it. You decide to not add more.")) else - to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.") + to_chat(user, span_notice("[src] doesn't have any water in it. You should fill it with water first.")) //Fish egg scoop else if(istype(O, /obj/item/egg_scoop)) add_fingerprint(user) @@ -690,10 +790,16 @@ fish_bag = user.r_hand else if(istype(user.l_hand, /obj/item/storage/bag/fish)) fish_bag = user.l_hand - user.visible_message("[user.name] harvests some fish eggs from [src].", "You scoop the fish eggs out of [src].") + user.visible_message( + span_notice("[user.name] harvests some fish eggs from [src]."), + span_notice("You scoop the fish eggs out of [src]."), + ) harvest_eggs(user, fish_bag) else - user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.") + user.visible_message( + span_notice("[user.name] fails to harvest any fish eggs from [src]."), + span_notice("There are no fish eggs in [src] to scoop out."), + ) //Fish net else if(istype(O, /obj/item/fish_net)) add_fingerprint(user) @@ -701,21 +807,26 @@ //Tank brush else if(istype(O, /obj/item/tank_brush)) if(filth_level == 0) - to_chat(user, "[src] is already spotless!") + to_chat(user, span_warning("[src] is already spotless!")) else add_fingerprint(user) adjust_filth_level(-filth_level) - user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.") + user.visible_message( + span_notice("[user.name] scrubs the inside of [src], cleaning the filth."), + span_notice("You scrub the inside of [src], cleaning the filth."), + ) else return ..() + /obj/machinery/fishtank/wrench_act(mob/user, obj/item/I) //Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process . = TRUE if(water_level) - to_chat(user, "[src] must be empty before you disassemble it!") + to_chat(user, span_warning("[src] must be empty before you disassemble it!")) return if(!I.tool_use_check(user, 0)) return - to_chat(user, "Now disassembling [src].") + to_chat(user, span_notice("Now disassembling [src].")) if(I.use_tool(src, user, 50, volume = I.tool_volume)) deconstruct(TRUE) + diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c4d55fef604..fb28a469d5d 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -593,7 +593,7 @@ GLOBAL_LIST_INIT(major_hallutinations, list("fake"=20,"death"=10,"xeno"=10,"sing name = "" desc = "" density = 0 - anchored = 1 + anchored = TRUE opacity = 0 var/mob/living/carbon/human/my_target = null var/weapon_name = null diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm index 3de68fcce0c..0d02f977481 100644 --- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm +++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm @@ -15,12 +15,12 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "bottler_off" density = 1 - anchored = 1 + anchored = TRUE var/list/slots[3] var/list/datum/bottler_recipe/available_recipes var/list/acceptable_items var/list/containers = list("glass bottle" = 10, "plastic bottle" = 20, "metal can" = 25) - var/bottling = 0 + var/bottling = FALSE /obj/machinery/bottler/New() . = ..() @@ -275,7 +275,8 @@ containers[con_type]-- //select and process a recipe based on inserted ingredients visible_message("[src] hums as it processes the ingredients...") - bottling = 1 + bottling = TRUE + update_icon(UPDATE_ICON_STATE) var/datum/bottler_recipe/recipe_to_use = select_recipe() if(!recipe_to_use) //bad recipe, ruins the drink @@ -293,7 +294,8 @@ flick("bottler_on", src) spawn(45) resetSlots() - bottling = 0 + bottling = FALSE + update_icon(UPDATE_ICON_STATE) drink_container.forceMove(loc) updateUsrDialog() @@ -409,7 +411,7 @@ updateUsrDialog() return -/obj/machinery/bottler/update_icon() +/obj/machinery/bottler/update_icon_state() if(stat & BROKEN) icon_state = "bottler_broken" else if(bottling) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 56022e21541..0206b210962 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -78,10 +78,10 @@ else return -/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over) //CHUG! CHUG! CHUG! - if(!iscarbon(over)) +/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) //CHUG! CHUG! CHUG! + if(!iscarbon(over_object)) return ..() - var/mob/living/carbon/chugger = over + var/mob/living/carbon/chugger = over_object if(!(container_type & DRAINABLE)) to_chat(chugger, "You need to open [src] first!") return @@ -301,11 +301,14 @@ possible_transfer_amounts = null volume = 10 + +/obj/item/reagent_containers/food/drinks/sillycup/update_icon_state() + icon_state = "water_cup[reagents.total_volume ? "" : "_e"]" + + /obj/item/reagent_containers/food/drinks/sillycup/on_reagent_change() - if(reagents.total_volume) - icon_state = "water_cup" - else - icon_state = "water_cup_e" + update_icon(UPDATE_ICON_STATE) + //////////////////////////drinkingglass and shaker// //Note by Darem: This code handles the mixing of drinks. New drinks go in three places: In Chemistry-Reagents.dm (for the drink @@ -398,3 +401,54 @@ /obj/item/reagent_containers/food/drinks/oilcan/full list_reagents = list("oil" = 100) + + +/obj/item/reagent_containers/food/drinks/zaza + name = "Cherry Zaza" + desc = "I possess Zaza!" + icon_state = "zaza_can" + item_state = "zaza_can" + volume = 80 + foodtype = SUGAR + container_type = NONE + list_reagents = list("zaza" = 80) + + +/obj/item/reagent_containers/food/drinks/zaza/on_reagent_change() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/reagent_containers/food/drinks/zaza/update_overlays() + . = ..() + + if(reagents.total_volume) + var/image/filling = image('icons/obj/reagentfillings.dmi', "[icon_state]50") + + switch(round(reagents.total_volume)) + if(1 to 50) + filling.icon_state = "[icon_state]50" + if(51 to 60) + filling.icon_state = "[icon_state]60" + if(61 to 65) + filling.icon_state = "[icon_state]65" + if(66 to 70) + filling.icon_state = "[icon_state]70" + if(71 to 75) + filling.icon_state = "[icon_state]75" + if(76 to INFINITY) + filling.icon_state = "[icon_state]80" + filling.icon += mix_color_from_reagents(reagents.reagent_list) + . += filling + + if(!is_open_container()) + . += "zaza_lid" + + +/obj/item/reagent_containers/food/drinks/zaza/attack_self(mob/user) + if(!is_open_container()) + container_type |= OPENCONTAINER + to_chat(user, span_notice("You put the lid on [src].")) + else + to_chat(user, span_notice("You take the lid off [src].")) + container_type &= ~OPENCONTAINER + update_icon(UPDATE_OVERLAYS) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 35a8a2a1726..1ce01f36217 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -377,17 +377,37 @@ list_reagents = list() var/list/accelerants = list(/datum/reagent/consumable/ethanol,/datum/reagent/fuel,/datum/reagent/clf3,/datum/reagent/phlogiston, /datum/reagent/napalm,/datum/reagent/hellwater,/datum/reagent/plasma,/datum/reagent/plasma_dust) - var/active = 0 + var/active = FALSE + + +/obj/item/reagent_containers/food/drinks/bottle/molotov/update_desc(updates = ALL) + . = ..() + desc = initial(desc) + if(!isGlass) + desc += " You're not sure if making this out of a carton was the brightest idea." + + +/obj/item/reagent_containers/food/drinks/bottle/molotov/update_icon_state() + var/obj/item/reagent_containers/food/drinks/bottle/bottle = locate() in contents + if(bottle) + icon_state = bottle.icon_state + + +/obj/item/reagent_containers/food/drinks/bottle/molotov/update_overlays() + . = ..() + if(active) + . += GLOB.fire_overlay + /obj/item/reagent_containers/food/drinks/bottle/molotov/CheckParts(list/parts_list) ..() - var/obj/item/reagent_containers/food/drinks/bottle/B = locate() in contents - if(B) - icon_state = B.icon_state - B.reagents.copy_to(src, 100) - if(!B.isGlass) - desc += " You're not sure if making this out of a carton was the brightest idea." - isGlass = 0 + var/obj/item/reagent_containers/food/drinks/bottle/bottle = locate() in contents + if(bottle) + bottle.reagents.copy_to(src, 100) + if(!bottle.isGlass) + isGlass = FALSE + update_appearance(UPDATE_DESC|UPDATE_ICON) + /obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/target, datum/thrownthing/throwingdatum) var/firestarter = 0 @@ -402,6 +422,7 @@ new /obj/effect/hotspot(get_turf(target)) ..() + /obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params) if(is_hot(I) && !active) active = 1 @@ -426,11 +447,12 @@ A.fire_act() qdel(src) + /obj/item/reagent_containers/food/drinks/bottle/molotov/attack_self(mob/user) if(active) if(!isGlass) to_chat(user, "The flame's spread too far on it!") return to_chat(user, "You snuff out the flame on \the [src].") - overlays -= GLOB.fire_overlay - active = 0 + active = FALSE + update_icon(UPDATE_OVERLAYS) diff --git a/code/modules/food_and_drinks/drinks/drinks/cans.dm b/code/modules/food_and_drinks/drinks/drinks/cans.dm index 23763ddeef4..44859f6260a 100644 --- a/code/modules/food_and_drinks/drinks/drinks/cans.dm +++ b/code/modules/food_and_drinks/drinks/drinks/cans.dm @@ -185,7 +185,7 @@ name = "non-alcoholic beer" desc = "A favorite thing of all students and those who drive." icon_state = "alcoholfreebeercan" - list_reagents = list("alcohol_free_beer" = 30) + list_reagents = list("noalco_beer" = 30) /obj/item/reagent_containers/food/drinks/cans/adminbooze @@ -289,12 +289,13 @@ desc = "this shouldn't ever be spawned. shame on you" icon_state = "glass_bottle" + /obj/item/reagent_containers/food/drinks/cans/bottler/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/reagent_containers/food/drinks/cans/bottler/update_icon() - overlays.Cut() +/obj/item/reagent_containers/food/drinks/cans/bottler/update_overlays() + . = ..() if(reagents.total_volume) var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") @@ -313,7 +314,8 @@ filling.icon_state = "[icon_state]50" filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling + . += filling + /obj/item/reagent_containers/food/drinks/cans/bottler/glass_bottle name = "glass bottle" diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index b57f6ce792a..59ecbf757de 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -46,22 +46,45 @@ reagents.clear_reagents() extinguish() -/obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change() - overlays.Cut() - if(reagents.reagent_list.len) - var/datum/reagent/R = reagents.get_master_reagent() - name = R.drink_name - desc = R.drink_desc - if(R.drink_icon) - icon_state = R.drink_icon - else - var/image/I = image(icon, "glassoverlay") - I.color = mix_color_from_reagents(reagents.reagent_list) - overlays += I + +/obj/item/reagent_containers/food/drinks/drinkingglass/update_icon_state() + if(length(reagents.reagent_list)) + var/datum/reagent/check = reagents.get_master_reagent() + if(check.drink_icon) + icon_state = check.drink_icon + + +/obj/item/reagent_containers/food/drinks/drinkingglass/update_overlays() + . = ..() + if(length(reagents.reagent_list)) + var/datum/reagent/check = reagents.get_master_reagent() + if(!check.drink_icon) + . += mutable_appearance(icon, "glassoverlay", color = mix_color_from_reagents(reagents.reagent_list)) + else + icon_state = initial(icon_state) + + +/obj/item/reagent_containers/food/drinks/drinkingglass/update_name(updates) + . = ..() + if(length(reagents.reagent_list)) + var/datum/reagent/check = reagents.get_master_reagent() + name = check.drink_name else - icon_state = "glass_empty" - name = "glass" - desc = "Your standard drinking glass." + name = initial(name) + + +/obj/item/reagent_containers/food/drinks/drinkingglass/update_desc(updates) + . = ..() + if(length(reagents.reagent_list)) + var/datum/reagent/check = reagents.get_master_reagent() + desc = check.drink_desc + else + desc = initial(desc) + + +/obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change() + update_appearance() + // for /obj/machinery/vending/sovietsoda /obj/item/reagent_containers/food/drinks/drinkingglass/soda diff --git a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm index af301de5e50..3a3aa6640dc 100644 --- a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm @@ -2,6 +2,7 @@ name = "shot glass" desc = "No glasses were shot in the making of this glass." icon_state = "shotglass" + custom_fire_overlay = "shotglass_fire" amount_per_transfer_from_this = 15 volume = 15 materials = list(MAT_GLASS=100) @@ -12,10 +13,21 @@ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/on_reagent_change() if(!isShotFlammable() && (resistance_flags & ON_FIRE)) extinguish() - update_icon() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_icon() - overlays.Cut() + +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_name() + . = ..() + if(reagents.total_volume) + name = "shot glass of " + reagents.get_master_reagent_name() //No matter what, the glass will tell you the reagent's name. Might be too abusable in the future. + if(resistance_flags & ON_FIRE) + name = "flaming [name]" + else + name = "shot glass" + + +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_overlays() + . = ..() if(reagents.total_volume) var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]1") @@ -28,14 +40,8 @@ if(80 to INFINITY) filling.icon_state = "[icon_state]12" filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling - name = "shot glass of " + reagents.get_master_reagent_name() //No matter what, the glass will tell you the reagent's name. Might be too abusable in the future. - if(resistance_flags & ON_FIRE) - cut_overlay(GLOB.fire_overlay, TRUE) - overlays += "shotglass_fire" - name = "flaming [name]" - else - name = "shot glass" + . += filling + /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/proc/clumsilyDrink(mob/living/carbon/human/user) //Clowns beware if(!(resistance_flags & ON_FIRE)) @@ -59,14 +65,14 @@ ..() set_light(light_intensity, null, light_color) visible_message("[src] begins to burn with a blue hue!") - update_icon() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/extinguish(silent = FALSE) ..() set_light(0) if(!silent) visible_message("The dancing flame on [src] dies out.") - update_icon() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/burn() //Let's override fire deleting the reagents inside the shot return @@ -96,7 +102,7 @@ extinguish() -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/MouseDrop(mob/living/carbon/human/user) +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params) if(!ishuman(user)) return ..() diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 77f936b5956..17ecac08b11 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -304,20 +304,37 @@ reagents.trans_to(target, amount_per_transfer_from_this) qdel(src) -/obj/item/reagent_containers/food/condiment/pack/on_reagent_change() - if(reagents.reagent_list.len > 0) + +/obj/item/reagent_containers/food/condiment/pack/update_desc(updates = ALL) + . = ..() + if(length(reagents.reagent_list)) var/main_reagent = reagents.get_master_reagent_id() if(main_reagent in possible_states) var/list/temp_list = possible_states[main_reagent] - icon_state = temp_list[1] desc = temp_list[3] else - icon_state = "condi_mixed" desc = "A small condiment pack. The label says it contains [originalname]." else - icon_state = "condi_empty" desc = "A small condiment pack. It is empty." + +/obj/item/reagent_containers/food/condiment/pack/update_icon_state() + . = ..() + if(length(reagents.reagent_list)) + var/main_reagent = reagents.get_master_reagent_id() + if(main_reagent in possible_states) + var/list/temp_list = possible_states[main_reagent] + icon_state = temp_list[1] + else + icon_state = "condi_mixed" + else + icon_state = "condi_empty" + + +/obj/item/reagent_containers/food/condiment/pack/on_reagent_change() + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + + //Ketchup /obj/item/reagent_containers/food/condiment/pack/ketchup name = "ketchup pack" diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index dcc622dc441..0feb40259e3 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -1,66 +1,47 @@ +/obj/item/proc/make_custom_food(obj/item/reagent_containers/food/snacks/snack, mob/user, custom_type) + . = TRUE + if(!istype(snack) || !user.can_unEquip(snack)) + return FALSE + + var/obj/item/reagent_containers/food/snacks/customizable/custom_snack = new custom_type(get_turf(src)) + custom_snack.add_ingredient(snack, user) + qdel(src) + + /obj/item/reagent_containers/food/snacks/breadslice/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/sandwich/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) - else - ..() + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/sandwich)) + return ..() + /obj/item/reagent_containers/food/snacks/bun/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/burger/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/burger)) + return ..() + /obj/item/reagent_containers/food/snacks/sliceable/flatdough/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/pizza/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) - else - ..() + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/pizza)) + return ..() /obj/item/reagent_containers/food/snacks/boiledspaghetti/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/pasta/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) - else - ..() + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/pasta)) + return ..() /obj/item/trash/plate/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/fullycustom/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) - else - ..() + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/fullycustom)) + return ..() /obj/item/trash/bowl name = "bowl" desc = "An empty bowl. Put some food in it to start making a soup." - icon = 'icons/obj/food/food.dmi' + icon = 'icons/obj/food/custom.dmi' icon_state = "soup" -/obj/item/trash/bowl/attackby(obj/item/W, mob/user, params) - - if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP)) - var/obj/item/reagent_containers/food/snacks/customizable/soup/S = new(get_turf(user)) - S.attackby(W,user, params) - qdel(src) - else - ..() - -/obj/item/reagent_containers/food/snacks/customizable/sandwich - name = "sandwich" - desc = "A sandwich! A timeless classic." - icon_state = "breadslice" - baseicon = "sandwichcustom" - basename = "sandwich" - toptype = new /obj/item/reagent_containers/food/snacks/breadslice() +/obj/item/trash/bowl/attackby(obj/item/W, mob/user, params) + if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/soup)) + return ..() /obj/item/reagent_containers/food/snacks/customizable @@ -71,24 +52,39 @@ var/baseicon = "sandwichcustom" var/basename = "sandwichcustom" bitesize = 4 - var/top = 1 //Do we have a top? - var/obj/item/toptype - var/snack_overlays = 1 //Do we stack? -// var/offsetstuff = 1 //Do we offset the overlays? - var/sandwich_limit = 40 - var/fullycustom = 0 + var/top = FALSE //Do we have a top? + /// The image of the top + var/image/top_image + var/snack_overlays = FALSE //Do we stack? + var/ingredient_limit = 40 + var/fullycustom = FALSE trash = /obj/item/trash/plate var/list/ingredients = list() list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/customizable/Initialize(mapload) + . = ..() + if(top) + top_image = new(icon, "[baseicon]_top") + add_overlay(top_image) + if(snack_overlays) + layer = ABOVE_ALL_MOB_LAYER // all should see our monstrosity + +/obj/item/reagent_containers/food/snacks/customizable/sandwich + name = "sandwich" + desc = "A sandwich! A timeless classic." + icon_state = "breadslice" + baseicon = "sandwichcustom" + basename = "sandwich" + snack_overlays = TRUE + /obj/item/reagent_containers/food/snacks/customizable/pizza name = "personal pizza" desc = "A personalized pan pizza meant for only one person." icon_state = "personal_pizza" baseicon = "personal_pizza" basename = "personal pizza" - snack_overlays = 0 - top = 0 tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/customizable/pasta @@ -97,17 +93,12 @@ icon_state = "pasta_bot" baseicon = "pasta_bot" basename = "pasta" - snack_overlays = 0 - top = 0 - /obj/item/reagent_containers/food/snacks/customizable/cook/bread name = "bread" desc = "Tasty bread." icon_state = "breadcustom" baseicon = "breadcustom" basename = "bread" - snack_overlays = 0 - top = 0 tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/customizable/cook/pie @@ -116,8 +107,6 @@ icon_state = "piecustom" baseicon = "piecustom" basename = "pie" - snack_overlays = 0 - top = 0 tastes = list("pie" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/cake @@ -126,8 +115,6 @@ icon_state = "cakecustom" baseicon = "cakecustom" basename = "cake" - snack_overlays = 0 - top = 0 tastes = list("cake" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/jelly @@ -136,8 +123,6 @@ icon_state = "jellycustom" baseicon = "jellycustom" basename = "jelly" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/cook/donkpocket name = "donk pocket" @@ -145,8 +130,6 @@ icon_state = "donkcustom" baseicon = "donkcustom" basename = "donk pocket" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/cook/kebab name = "kebab" @@ -154,8 +137,6 @@ icon_state = "kababcustom" baseicon = "kababcustom" basename = "kebab" - snack_overlays = 0 - top = 0 tastes = list("meat" = 3, "metal" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/salad @@ -164,8 +145,6 @@ icon_state = "saladcustom" baseicon = "saladcustom" basename = "salad" - snack_overlays = 0 - top = 0 tastes = list("leaves" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/waffles @@ -174,8 +153,6 @@ icon_state = "wafflecustom" baseicon = "wafflecustom" basename = "waffles" - snack_overlays = 0 - top = 0 tastes = list("waffles" = 1) /obj/item/reagent_containers/food/snacks/customizable/candy/cookie @@ -184,8 +161,6 @@ icon_state = "cookiecustom" baseicon = "cookiecustom" basename = "cookie" - snack_overlays = 0 - top = 0 tastes = list("cookie" = 1) /obj/item/reagent_containers/food/snacks/customizable/candy/cotton @@ -194,8 +169,6 @@ icon_state = "cottoncandycustom" baseicon = "cottoncandycustom" basename = "flavored cotton candy" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/gummybear name = "flavored giant gummy bear" @@ -203,8 +176,6 @@ icon_state = "gummybearcustom" baseicon = "gummybearcustom" basename = "flavored giant gummy bear" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/gummyworm name = "flavored giant gummy worm" @@ -212,8 +183,6 @@ icon_state = "gummywormcustom" baseicon = "gummywormcustom" basename = "flavored giant gummy worm" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/jellybean name = "flavored giant jelly bean" @@ -221,8 +190,6 @@ icon_state = "jellybeancustom" baseicon = "jellybeancustom" basename = "flavored giant jelly bean" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/jawbreaker name = "flavored jawbreaker" @@ -230,8 +197,6 @@ icon_state = "jawbreakercustom" baseicon = "jawbreakercustom" basename = "flavored jawbreaker" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/candycane name = "flavored candy cane" @@ -239,8 +204,6 @@ icon_state = "candycanecustom" baseicon = "candycanecustom" basename = "flavored candy cane" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/gum name = "flavored gum" @@ -248,8 +211,6 @@ icon_state = "gumcustom" baseicon = "gumcustom" basename = "flavored gum" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/donut name = "filled donut" @@ -257,8 +218,6 @@ icon_state = "donutcustom" baseicon = "donutcustom" basename = "filled donut" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/bar name = "flavored chocolate bar" @@ -266,8 +225,6 @@ icon_state = "barcustom" baseicon = "barcustom" basename = "flavored chocolate bar" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/sucker name = "flavored sucker" @@ -275,8 +232,6 @@ icon_state = "suckercustom" baseicon = "suckercustom" basename = "flavored sucker" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/cash name = "flavored chocolate cash" @@ -284,8 +239,6 @@ icon_state = "cashcustom" baseicon = "cashcustom" basename = "flavored cash" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/candy/coin name = "flavored chocolate coin" @@ -293,8 +246,6 @@ icon_state = "coincustom" baseicon = "coincustom" basename = "flavored coin" - snack_overlays = 0 - top = 0 /obj/item/reagent_containers/food/snacks/customizable/fullycustom // In the event you fuckers find something I forgot to add a customizable food for. name = "on a plate" @@ -302,10 +253,8 @@ icon_state = "fullycustom" baseicon = "fullycustom" basename = "on a plate" - snack_overlays = 0 - top = 0 - sandwich_limit = 20 - fullycustom = 1 + ingredient_limit = 20 + fullycustom = TRUE /obj/item/reagent_containers/food/snacks/customizable/soup name = "soup" @@ -313,9 +262,7 @@ icon_state = "soup" baseicon = "soup" basename = "soup" - snack_overlays = 0 trash = /obj/item/trash/bowl - top = 0 tastes = list("soup" = 1) /obj/item/reagent_containers/food/snacks/customizable/burger @@ -324,73 +271,106 @@ icon_state = "burger" baseicon = "burgercustom" basename = "burger" - toptype = new /obj/item/reagent_containers/food/snacks/bun() + top = TRUE + snack_overlays = TRUE tastes = list("bun" = 4) + +/obj/item/reagent_containers/food/snacks/customizable/Destroy() + QDEL_LIST(ingredients) + return ..() + + +/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user) + . = ..() + if(LAZYLEN(ingredients)) + var/whatsinside = pick(ingredients) + . += span_notice("You think you can see [whatsinside] in there.") + + /obj/item/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user, params) - if(contents.len > sandwich_limit) - to_chat(user, "If you put anything else in or on [src] it's going to make a mess.") - return if(!istype(I, /obj/item/reagent_containers/food/snacks)) - to_chat(user, "\The [I] isn't exactly something that you would want to eat.") - return - to_chat(user, "You add [I] to [src].") - if(istype(I, /obj/item/reagent_containers/)) - var/obj/item/reagent_containers/F = I - F.reagents.trans_to(src, F.reagents.total_volume) - if(istype(I, /obj/item/reagent_containers/food/snacks/customizable)) - var/obj/item/reagent_containers/food/snacks/customizable/origin = I - ingredients += origin.ingredients - foodtype |= origin.foodtype - user.drop_transfer_item_to_loc(I, src) - cooktype[basename] = 1 - if(!istype(I, toptype)) - ingredients += I - updateicon() + to_chat(user, span_warning("[I] isn't exactly something that you would want to eat.")) + return ..() + + if(!user.can_unEquip(I)) + return ..() + + if(!add_ingredient(I, user)) + return ..() + + +/** + * Tries to add one ingredient and it's ingredients, if any and applicable, to this snack + * + * Arguments: + * * snack - The ingredient that will be added + * * user - chef + */ +/obj/item/reagent_containers/food/snacks/customizable/proc/add_ingredient(obj/item/reagent_containers/food/snacks/snack, mob/user) + . = FALSE + + if(length(ingredients) > ingredient_limit) + to_chat(user, span_warning("If you put anything else in or on [src] it's going to make a mess.")) + return . + + // Fully custom snacks don't add the ingredients. So no need to check + var/fullycustom_check = !fullycustom && istype(snack, /obj/item/reagent_containers/food/snacks/customizable) + if(fullycustom_check) + var/obj/item/reagent_containers/food/snacks/customizable/origin = snack + if(length(ingredients) + length(origin.ingredients) > ingredient_limit) + to_chat(user, span_warning("Merging [snack] and [src] together is going to make a mess.")) + return . + + . = TRUE + + to_chat(user, span_notice("You add [snack] to [src].")) + user.drop_transfer_item_to_loc(snack, src) + snack.reagents.trans_to(src, snack.reagents.total_volume) + + var/list/added_ingredients = list(snack) + + // Only merge when it is not fullycustom. Else it looks weird + if(fullycustom_check) + var/obj/item/reagent_containers/food/snacks/customizable/origin = snack + added_ingredients += origin.ingredients + origin.ingredients.Cut() + origin.name = initial(origin.name) // Reset the name for the examine text + + cooktype[basename] = TRUE + add_ingredients(added_ingredients) name = newname() -/obj/item/reagent_containers/food/snacks/customizable/proc/updateicon() - overlays = 0 - var/i=0 - for(var/obj/item/O in ingredients) - i++ +/obj/item/reagent_containers/food/snacks/customizable/proc/add_ingredients(list/new_ingredients) + cut_overlay(top_image) // Remove the top image so we can change it again + + var/ingredient_num = length(ingredients) + ingredients += new_ingredients + for(var/obj/item/reagent_containers/food/snacks/food as anything in new_ingredients) + ingredient_num++ + var/image/ingredient_image if(!fullycustom) - var/image/I = new(icon, "[baseicon]_filling") - if(istype(O, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/food = O - if(!food.filling_color == "#FFFFFF") - I.color = food.filling_color - else - I.color = pick("#FF0000","#0000FF","#008000","#FFFF00") + ingredient_image = new(icon, "[baseicon]_filling") + if(!food.filling_color == "#FFFFFF") + ingredient_image.color = food.filling_color else - I.color = pick("#FF0000","#0000FF","#008000","#FFFF00") + ingredient_image.color = pick("#FF0000", "#0000FF", "#008000", "#FFFF00") if(snack_overlays) - I.pixel_x = pick(list(-1,0,1)) - I.pixel_y = (i*2)+1 - overlays += I + ingredient_image.pixel_x = rand(2) - 1 + ingredient_image.pixel_y = ingredient_num * 2 + 1 else - var/image/F = new(O.icon, O.icon_state) - F.pixel_x = pick(list(-1,0,1)) - F.pixel_y = pick(list(-1,0,1)) - overlays += F - overlays += O.overlays + ingredient_image = new(food.icon, food.icon_state) + ingredient_image.pixel_x = rand(2) - 1 + ingredient_image.pixel_y = rand(2) - 1 + add_overlay(food.overlays) - if(top) - var/image/T = new(icon, "[baseicon]_top") - T.pixel_x = pick(list(-1,0,1)) - T.pixel_y = (ingredients.len * 2)+1 - overlays += T - -/obj/item/reagent_containers/food/snacks/customizable/Destroy() - QDEL_LIST(ingredients) - return ..() + add_overlay(ingredient_image) -/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user) - . = ..() - if(LAZYLEN(ingredients)) - var/whatsinside = pick(ingredients) - . += " You think you can see [whatsinside] in there." + if(top_image) + top_image.pixel_x = rand(2) - 1 + top_image.pixel_y = ingredient_num * 2 + 1 + add_overlay(top_image) /obj/item/reagent_containers/food/snacks/customizable/proc/newname() @@ -473,6 +453,7 @@ sendback = "[pick(list("absurd","colossal","enormous","ridiculous","massive","oversized","cardiac-arresting","pipe-clogging","edible but sickening","sickening","gargantuan","mega","belly-burster","chest-burster"))] [basename]" return sendback + /obj/item/reagent_containers/food/snacks/customizable/proc/sortlist(list/unsorted, highest) var/sorted[0] for(var/i = 1, i<= highest, i++) @@ -480,3 +461,4 @@ if(unsorted[it] == i) sorted[it] = i return sorted + diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm index 0ed47a2cfdc..df437c75618 100644 --- a/code/modules/food_and_drinks/food/foods/baked_goods.dm +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -387,6 +387,81 @@ tastes = list("pie" = 1, "meat" = 1) foodtype = GRAIN | MEAT +/obj/item/reagent_containers/food/snacks/meatpie/human + list_reagents = list("nutriment" = 9, "protein" = 3) + tastes = list("pie" = 2, "salty meat" = 1, "human meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/vulpkanin + list_reagents = list("nutriment" = 7, "protein" = 5) + tastes = list("pie" = 2, "salty meat" = 2, "vulpkanin meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/tajaran + list_reagents = list("nutriment" = 9, "protein" = 3) + tastes = list("pie" = 2, "salty meat" = 1, "tajaran meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/unathi + list_reagents = list("nutriment" = 8, "protein" = 3, "zessulblood" = 1) + tastes = list("pie" = 2, "chiken meat" = 1, "unathi meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/drask + list_reagents = list("nutriment" = 7, "protein" = 3, "ice" = 2) + tastes = list("pie" = 2, "salty meat" = 1, "drask meat odor" = 1, "ice" = 2) + +/obj/item/reagent_containers/food/snacks/meatpie/grey + list_reagents = list("nutriment" = 9, "protein" = 2, "mannitol" = 1) + tastes = list("pie" = 2, "salty meat" = 1, "grey meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/skrell + list_reagents = list("nutriment" = 9, "protein" = 2, "water" = 1) + tastes = list("pie" = 2, "watery meat" = 1, "skrell meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/vox + list_reagents = list("nutriment" = 8, "protein" = 3, "toxin" = 1) + tastes = list("pie" = 2, "chiken meat" = 1, "vox meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/slime + list_reagents = list("sugar" = 4, "slimejelly" = 8) + tastes = list("pie" = 2, "sweet jelly" = 1, "slime meat odor" = 1) + foodtype = GRAIN | MEAT | SUGAR + +/obj/item/reagent_containers/food/snacks/meatpie/wryn + list_reagents = list("nutriment" = 8, "protein" = 1, "sugar" = 3) + tastes = list("pie" = 2, "sweet meat" = 1, "wryn meat odor" = 1) + foodtype = GRAIN | MEAT | SUGAR + +/obj/item/reagent_containers/food/snacks/meatpie/kidan + list_reagents = list("nutriment" = 8, "protein" = 3, "blood" = 1) + tastes = list("pie" = 2, "bug meat odor" = 1, "kidan meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/nian + list_reagents = list("nutriment" = 8, "protein" = 1, "phosphorus" = 3) + tastes = list("pie" = 2, "bug meat odor" = 1, "nian meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/diona + list_reagents = list("plantmatter" = 5, "protein" = 3) + tastes = list("pie" = 2, "vegetables" = 1, "stik" = 1, "diona odor" = 1) + foodtype = GRAIN | VEGETABLES + +/obj/item/reagent_containers/food/snacks/meatpie/monkey + list_reagents = list("nutriment" = 5, "protein" = 3) + tastes = list("pie" = 2, "salty meat" = 1, "monkey meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/farwa + list_reagents = list("nutriment" = 5, "protein" = 1) + tastes = list("pie" = 2, "salty meat" = 1, "farwa meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/wolpin + list_reagents = list("nutriment" = 5, "protein" = 3) + tastes = list("pie" = 2, "salty meat" = 1, "wolpin meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/neara + list_reagents = list("nutriment" = 5, "protein" = 1, "water" = 2) + tastes = list("pie" = 2, "watery meat" = 1, "neara meat odor" = 1) + +/obj/item/reagent_containers/food/snacks/meatpie/stok + list_reagents = list("nutriment" = 5, "protein" = 2, "zessulblood" = 1) + tastes = list("pie" = 2, "salty meat" = 1, "chiken meat" = 1, "stok meat odor" = 1) + /obj/item/reagent_containers/food/snacks/tofupie name = "tofu-pie" icon_state = "meatpie" @@ -525,7 +600,7 @@ filling_color = "#FF69B4" . = ..() -/obj/item/reagent_containers/food/snacks/donut/update_icon() +/obj/item/reagent_containers/food/snacks/donut/update_icon_state() return /obj/item/reagent_containers/food/snacks/donut/sprinkles diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm index fc340b29b7f..8d455df01a3 100644 --- a/code/modules/food_and_drinks/food/foods/desserts.dm +++ b/code/modules/food_and_drinks/food/foods/desserts.dm @@ -13,11 +13,9 @@ tastes = list("ice cream" = 1) foodtype = SUGAR | DAIRY -/obj/item/reagent_containers/food/snacks/icecream/update_icon() - cut_overlays() - var/mutable_appearance/filling = mutable_appearance('icons/obj/kitchen.dmi', "icecream_color") - filling.color = mix_color_from_reagents(reagents.reagent_list) - add_overlay(filling) +/obj/item/reagent_containers/food/snacks/icecream/update_overlays() + . = ..() + . += mutable_appearance('icons/obj/kitchen.dmi', "icecream_color", color = mix_color_from_reagents(reagents.reagent_list)) /obj/item/reagent_containers/food/snacks/icecream/icecreamcone name = "ice cream cone" diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm index c4434bc7345..38512905943 100644 --- a/code/modules/food_and_drinks/food/foods/ingredients.dm +++ b/code/modules/food_and_drinks/food/foods/ingredients.dm @@ -198,7 +198,7 @@ tastes = list("dough" = 1, "sugar" = 1) foodtype = GRAIN | SUGAR -/obj/item/reagent_containers/food/snacks/cookiedough/update_icon() +/obj/item/reagent_containers/food/snacks/cookiedough/update_icon_state() if(flat) icon_state = "cookiedough_flat" name = "flat pastry dough" @@ -206,7 +206,6 @@ icon_state = "cookiedough" - // Dough + rolling pin = flat cookie dough // Flat dough + circular cutter = unbaked cookies /obj/item/reagent_containers/food/snacks/cookiedough/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/kitchen/rollingpin) && !flat) diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm index 39bc68ff36c..328d77f4641 100644 --- a/code/modules/food_and_drinks/food/foods/meat.dm +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -27,12 +27,191 @@ name = "synthetic meat" desc = "A synthetic slab of flesh." -/obj/item/reagent_containers/food/snacks/meat/human - name = "-meat" +/obj/item/reagent_containers/food/snacks/meat/humanoid + name = "humanoid meat" var/subjectname = "" var/subjectjob = null tastes = list("salty meat" = 1) +/obj/item/reagent_containers/food/snacks/meat/humanoid/Initialize(mapload, mob/living/carbon/human/victim) + . = ..() + if(victim) + subjectname = victim.real_name + subjectjob = victim.job + victim.reagents.trans_to(src, (victim.reagents.total_volume) / victim.meatleft) + transfer_mob_blood_dna(victim) + + if(!isplasmaman(victim) && !ismachineperson(victim)) + reagents.add_reagent("nutriment", (victim.nutrition / 15) / initial(victim.meatleft)) + +/obj/item/reagent_containers/food/snacks/meat/humanoid/human + name = "human meat" + tastes = list("salty meat" = 1) + +/obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin + name = "vulpkanin meat" + tastes = list("salty meat" = 1) + list_reagents = list("protein" = 5) + icon_state = "meat_vulp" + filling_color = "#850808" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran + name = "tajaran meat" + tastes = list("salty meat" = 1) + list_reagents = list("protein" = 3) + icon_state = "meat_tajara" + filling_color = "#df1919" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/unathi + name = "unathi meat" + tastes = list("chiken meat" = 1) + list_reagents = list("protein" = 3, "zessulblood" = 2) + icon_state = "meat_unathi" + filling_color = "#850808" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/drask + name = "drask meat" + tastes = list("icy meat" = 1) + list_reagents = list("protein" = 3, "ice" = 10) + icon_state = "meat_drask" + filling_color = "#329983" + bitesize = 5 + var/type1 = "meat_drask" + var/type2 = "meat_drask2" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/drask/New() + ..() + icon_state = pick(type1, type2) + +/obj/item/reagent_containers/food/snacks/meat/humanoid/grey + name = "grey meat" + tastes = list("salty meat" = 1) + list_reagents = list("protein" = 2, "mannitol" = 2) + icon_state = "meat_grey" + filling_color = "#8d17a5" + var/type1 = "meat_grey" + var/type2 = "meat_grey2" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/grey/New() + ..() + icon_state = pick(type1, type2) + +/obj/item/reagent_containers/food/snacks/meat/humanoid/skrell + name = "skrell meat" + tastes = list("watery meat" = 1) + list_reagents = list("protein" = 3, "water" = 20) + icon_state = "meat_skrell" + filling_color = "#4d17a5" + bitesize = 10 + +/obj/item/reagent_containers/food/snacks/meat/humanoid/vox + name = "vox meat" + tastes = list("chiken meat" = 1) + list_reagents = list("protein" = 3, "toxin" = 1) + icon_state = "meat_vox" + filling_color = "#0c5ac0" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/slime + name = "slime jelly" + tastes = list("sweet jelly" = 1) + list_reagents = list("sugar" = 5, "slimejelly" = 10) + icon_state = "meat_slime" + filling_color = "#11a0cc" + bitesize = 5 + +/obj/item/reagent_containers/food/snacks/meat/humanoid/wryn + name = "wryn meat" + tastes = list("sweet meat" = 1) + list_reagents = list("protein" = 1, "sugar" = 5) + icon_state = "meat_wryn" + filling_color = "#d1be0d" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/kidan + name = "kidan meat" + tastes = list("bug meat" = 1) + list_reagents = list("protein" = 2, "blood" = 1) + icon_state = "meat_kidan" + filling_color = "#db9808" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/nian + name = "nian meat" + tastes = list("bug meat" = 1) + list_reagents = list("protein" = 2, "phosphorus" = 5) + icon_state = "meat_nian" + filling_color = "#866929" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/diona + name = "diona branch" + tastes = list("crunchy green" = 1) + list_reagents = list("plantmatter" = 5) + icon_state = "branch_diona" + filling_color = "#2d6102" + foodtype = VEGETABLES + +/obj/item/reagent_containers/food/snacks/meat/humanoid/nucleation + name = "nucleation remains" + tastes = list("radioactive dust" = 1) + list_reagents = list("radium" = 30) + icon_state = "dust_nucleation" + filling_color = "#edf5ac" + bitesize = 10 + foodtype = TOXIC + +/obj/item/reagent_containers/food/snacks/meat/humanoid/plasmaman + name = "plasmaman remains" + tastes = list("radioactive dust" = 1) + list_reagents = list("radium" = 10, "plasma" = 10) + icon_state = "dust_plasmaman" + filling_color = "#a502c5" + bitesize = 10 + foodtype = TOXIC + +/obj/item/reagent_containers/food/snacks/meat/humanoid/machine + name = "machine remains" + tastes = list("radioactive dust" = 1) + list_reagents = list("iron" = 3, "aluminum" = 2, "lithium" = 1, "mercury" = 2, "metalicdust" = 1) + icon_state = "dust_machine" + filling_color = "#403e41" + bitesize = 9 + foodtype = TOXIC + +/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey + name = "monkey meat" + tastes = list("salty meat" = 1) + list_reagents = list("protein" = 2) + filling_color = "#FF1C1C" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/farwa + name = "farwa meat" + list_reagents = list("protein" = 1) + tastes = list("salty meat" = 1) + icon_state = "meat_tajara" + filling_color = "#df1919" + +/obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin + name = "wolpin meat" + list_reagents = list("protein" = 3) + tastes = list("salty meat" = 1) + icon_state = "meat_vulp" + filling_color = "#850808" + bitesize = 2 + +/obj/item/reagent_containers/food/snacks/meat/humanoid/neara + name = "neara meat" + list_reagents = list("protein" = 2, "water" = 5) + tastes = list("watery meat" = 1) + icon_state = "meat_skrell" + filling_color = "#4d17a5" + bitesize = 4 + +/obj/item/reagent_containers/food/snacks/meat/humanoid/stok + name = "stok meat" + list_reagents = list("protein" = 2, "zessulblood" = 1) + tastes = list("chiken meat" = 1) + icon_state = "meat_unathi" + filling_color = "#850808" + bitesize = 2 + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct name = "meat product" desc = "A slab of reclaimed and chemically processed meat product." @@ -43,9 +222,6 @@ icon = 'icons/obj/food/food.dmi' icon_state = "birdmeat" -/obj/item/reagent_containers/food/snacks/meat/monkey - name = "lesser meat" - /obj/item/reagent_containers/food/snacks/meat/corgi name = "corgi meat" desc = "Tastes like the Head of Personnel's hopes and dreams" @@ -231,6 +407,119 @@ tastes = list("meat" = 1) foodtype = MEAT +/obj/item/reagent_containers/food/snacks/meatsteak/human + name = "human meat steak" + icon_state = "meatstake_human" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("human meat odor" = 1, "eggplant" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin + name = "vulpkanin meat steak" + icon_state = "meatstake_vulp" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("vulpkanin meat odor" = 1, "chanterelle" = 1, "lemon" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/tajaran + name = "tajaran meat steak" + icon_state = "meatstake_tajara" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("tajaran meat odor" = 1, "nettle" = 1, "soda water" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/unathi + name = "unathi meat steak" + icon_state = "meatstake_unathi" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("unathi meat odor" = 1, "tomato" = 2, "harebell" = 1, "black pepper" = 2, "salt" = 2, "chiken" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/drask + name = "drask meat steak" + desc = "A piece of cold spicy meat." + icon_state = "meatstake_drask" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("drask meat odor" = 1, "garlic" = 1, "chili" = 2, "berries" = 2, "black pepper" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/grey + name = "grey meat steak" + icon_state = "meatstake_grey" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("grey meat odor" = 1, "garlic" = 1, "cabbage" = 1, "tomato" = 2, "salt" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/skrell + name = "skrell meat steak" + icon_state = "meatstake_skrell" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("skrell meat odor" = 1, "banana" = 1, "tomato" = 1, "black pepper" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/vox + name = "vox meat steak" + icon_state = "meatstake_vox" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("vox meat odor" = 1, "garlic" = 1, "herbs" = 1, "chiken" = 1, "sweet potato" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/slime + name = "grilled jelly" + desc = "A piece of hot spicy jelly." + icon_state = "meatstake_slime" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("slime meat odor" = 1, "garlic" = 1, "sugar" = 1, "herbs" = 1, "lemon" = 1, "ambrosia" = 1, "salt" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/wryn + name = "wryn meat steak" + icon_state = "meatstake_wryn" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("wryn meat odor" = 1, "sweetness" = 1, "potato" = 2, "orange" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/kidan + name = "kidan meat steak" + icon_state = "meatstake_kidan" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("kidan meat odor" = 1, "bug odor" = 1, "herbs" = 2, "olives" = 2, "salt" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/nian + name = "nian meat steak" + icon_state = "meatstake_nian" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("nian meat odor" = 1, "bug odor" = 1, "sweetness" = 1, "orange" = 1, "lemon" = 1, "herbs" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/diona + name = "grilled vagetables" + desc = "Hot spicy asparagus." + filling_color = "#548100" + icon_state = "meatstake_diona" + list_reagents = list("plantmatter" = 4, "vitamins" = 5) + tastes = list("diona odor" = 1, "salt" = 2, "herbs" = 1, "garlic" = 1, "lemon" = 1) + foodtype = VEGETABLES + +/obj/item/reagent_containers/food/snacks/meatsteak/monkey + name = "monkey meat steak" + icon_state = "meatstake_monkey" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("monkey meat odor" = 1, "salt" = 2, "herbs" = 1, "lemon" = 1, "chili" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/farwa + name = "farwa meat steak" + icon_state = "meatstake_farwa" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("farwa meat odor" = 1, "poppy" = 2, "grape" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/wolpin + name = "wolpin meat steak" + icon_state = "meatstake_wolpin" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("wolpin meat odor" = 1, "potato" = 1, "onion" = 2) + +/obj/item/reagent_containers/food/snacks/meatsteak/neara + name = "neara meat steak" + icon_state = "meatstake_neara" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("neara meat odor" = 1, "lemon" = 1, "soy" = 2, "herbs" = 1) + +/obj/item/reagent_containers/food/snacks/meatsteak/stok + name = "stok meat steak" + icon_state = "meatstake_stok" + list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3) + tastes = list("stok meat odor" = 1, "chiken" = 1, "cucumber" = 2, "herbs" = 1, "orange" = 1) + /obj/item/reagent_containers/food/snacks/birdsteak name = "Chicken steak" desc = "A piece of hot light bird meat." diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm index d80a1bc4399..0596630c63f 100644 --- a/code/modules/food_and_drinks/food/foods/pizza.dm +++ b/code/modules/food_and_drinks/food/foods/pizza.dm @@ -204,64 +204,70 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "pizzabox1" - var/open = 0 // Is the box open? - var/ismessy = 0 // Fancy mess on the lid + var/open = FALSE // Is the box open? + var/is_messy = FALSE // Fancy mess on the lid var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza var/list/boxes = list() // If the boxes are stacked, they come here - var/boxtag = "" + var/box_tag = "" -/obj/item/pizzabox/update_icon() - overlays = list() - // Set appropriate description +/obj/item/pizzabox/Initialize(mapload) + . = ..() + update_appearance(UPDATE_DESC|UPDATE_ICON) + + +/obj/item/pizzabox/update_desc(updates = ALL) + . = ..() if(open && pizza) desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." - else if(boxes.len > 0) - desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." - var/obj/item/pizzabox/topbox = boxes[boxes.len] - var/toptag = topbox.boxtag - if(toptag != "") - desc = "[desc] The box on top has a tag, it reads: '[toptag]'." + else if(length(boxes)) + desc = "A pile of boxes suited for pizzas. There appears to be [length(boxes) + 1] boxes in the pile." + var/obj/item/pizzabox/top_box = boxes[length(boxes)] + var/top_tag = top_box.box_tag + if(top_tag != "") + desc = "[desc] The box on top has a tag, it reads: '[top_tag]'." else desc = "A box suited for pizzas." - if(boxtag != "") - desc = "[desc] The box has a tag, it reads: '[boxtag]'." + if(box_tag != "") + desc = "[desc] The box has a tag, it reads: '[box_tag]'." + - // Icon states and overlays +/obj/item/pizzabox/update_icon_state() if(open) - if(ismessy) + if(is_messy) icon_state = "pizzabox_messy" else icon_state = "pizzabox_open" - if(pizza) - var/image/pizzaimg = image("food/pizza.dmi", icon_state = pizza.icon_state) - pizzaimg.pixel_y = -3 - overlays += pizzaimg + return + icon_state = "pizzabox[length(boxes) + 1]" + +/obj/item/pizzabox/update_overlays() + . = ..() + if(open && pizza) + . += image("food/pizza.dmi", icon_state = pizza.icon_state, pixel_y = -3) return else // Stupid code because byondcode sucks - var/doimgtag = 0 - if(boxes.len > 0) - var/obj/item/pizzabox/topbox = boxes[boxes.len] - if(topbox.boxtag != "") - doimgtag = 1 + var/set_tag = TRUE + if(length(boxes)) + var/obj/item/pizzabox/top_box = boxes[length(boxes)] + if(top_box.box_tag != "") + set_tag = TRUE else - if(boxtag != "") - doimgtag = 1 - if(doimgtag) - var/image/tagimg = image("food/pizza.dmi", icon_state = "pizzabox_tag") - tagimg.pixel_y = boxes.len * 3 - overlays += tagimg - icon_state = "pizzabox[boxes.len+1]" + if(box_tag != "") + set_tag = TRUE + if(!open && set_tag) + . += image("food/pizza.dmi", icon_state = "pizzabox_tag", pixel_y = length(boxes) * 3) + /obj/item/pizzabox/attack_hand(mob/user) if(open && pizza) pizza.forceMove_turf() user.put_in_hands(pizza, ignore_anim = FALSE) - to_chat(user, "You take the [pizza] out of the [src].") + to_chat(user, span_warning("You take the [pizza] out of the [src].")) pizza = null - update_icon() + update_appearance(UPDATE_DESC|UPDATE_ICON) return if(boxes.len > 0) @@ -272,19 +278,21 @@ boxes -= box box.forceMove_turf() user.put_in_hands(box, ignore_anim = FALSE) - to_chat(user, "You remove the topmost [src] from your hand.") - box.update_icon() - update_icon() + to_chat(user, span_warning("You remove the topmost [src] from your hand.")) + box.update_appearance(UPDATE_DESC|UPDATE_ICON) + update_appearance(UPDATE_DESC|UPDATE_ICON) return ..() + /obj/item/pizzabox/attack_self(mob/user) - if(boxes.len > 0) + if(length(boxes)) return open = !open if(open && pizza) - ismessy = 1 - update_icon() + is_messy = TRUE + update_appearance(UPDATE_DESC|UPDATE_ICON) + /obj/item/pizzabox/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/pizzabox/)) @@ -295,17 +303,17 @@ boxestoadd += box for(var/obj/item/pizzabox/i in box.boxes) boxestoadd += i - if((boxes.len+1) + boxestoadd.len <= 5) + if((length(boxes) + 1) + length(boxestoadd) <= 5) user.drop_transfer_item_to_loc(box, src) box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit boxes.Add(boxestoadd) - box.update_icon() - update_icon() - to_chat(user, "You put the [box] ontop of the [src]!") + box.update_appearance(UPDATE_DESC|UPDATE_ICON) + update_appearance(UPDATE_DESC|UPDATE_ICON) + to_chat(user, span_warning("You put the [box] ontop of the [src]!")) else - to_chat(user, "The stack is too high!") + to_chat(user, span_warning("The stack is too high!")) else - to_chat(user, "Close the [box] first!") + to_chat(user, span_warning("Close the [box] first!")) return if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name @@ -313,46 +321,52 @@ user.drop_transfer_item_to_loc(I, src) pizza = I - update_icon() + update_appearance(UPDATE_DESC|UPDATE_ICON) - to_chat(user, "You put the [I] in the [src]!") + to_chat(user, span_warning("You put the [I] in the [src]!")) else - to_chat(user, "You try to push the [I] through the lid but it doesn't work!") + to_chat(user, span_warning("You try to push the [I] through the lid but it doesn't work!")) return - if(istype(I, /obj/item/pen/)) + if(is_pen(I)) if(open) return var/t = clean_input("Enter what you want to add to the tag:", "Write", null) var/obj/item/pizzabox/boxtotagto = src - if(boxes.len > 0) - boxtotagto = boxes[boxes.len] - boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) - update_icon() + if(length(boxes)) + boxtotagto = boxes[length(boxes)] + boxtotagto.box_tag = copytext("[boxtotagto.box_tag][t]", 1, 30) + update_appearance(UPDATE_DESC|UPDATE_ICON) return ..() -/obj/item/pizzabox/margherita/New() - ..() + +/obj/item/pizzabox/margherita/Initialize(mapload) pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src) - boxtag = "margherita deluxe" + box_tag = "margherita deluxe" + . = ..() -/obj/item/pizzabox/vegetable/New() - ..() + +/obj/item/pizzabox/vegetable/Initialize(mapload) pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) - boxtag = "gourmet vegetable" + box_tag = "gourmet vegetable" + . = ..() -/obj/item/pizzabox/mushroom/New() - ..() + +/obj/item/pizzabox/mushroom/Initialize(mapload) pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) - boxtag = "mushroom special" + box_tag = "mushroom special" + . = ..() -/obj/item/pizzabox/meat/New() - ..() + +/obj/item/pizzabox/meat/Initialize(mapload) pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) - boxtag = "meatlover's supreme" + box_tag = "meatlover's supreme" + . = ..() -/obj/item/pizzabox/hawaiian/New() - ..() + +/obj/item/pizzabox/hawaiian/Initialize(mapload) pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src) - boxtag = "Hawaiian feast" + box_tag = "Hawaiian feast" + . = ..() + diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index af7c17d09b3..f215d64c6ba 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -31,7 +31,7 @@ else ..() -/obj/item/reagent_containers/food/snacks/update_icon() +/obj/item/reagent_containers/food/snacks/update_icon_state() if(!opened) icon_state = "[initial(icon_state)]-closed" else @@ -59,7 +59,7 @@ if(!opened) opened = TRUE to_chat(user, "You open the [src].") - update_icon() + update_icon(UPDATE_ICON_STATE) return ..() else return diff --git a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm index 1bfc7307ace..68b17236b77 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm @@ -3,7 +3,7 @@ desc = "You shouldn't be seeing this!" layer = 2.9 density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 var/on = 0 diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index 085a2c1cfef..12356d32bd4 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -5,10 +5,10 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "grinder" density = 1 - anchored = 1 + anchored = TRUE var/operating = 0 //Is it on? var/dirty = 0 // Does it need cleaning? - var/mob/living/occupant // Mob who has been put inside + var/mob/living/carbon/human/occupant // Mob who has been put inside var/locked = 0 //Used to prevent mobs from breaking the feedin anim var/gib_throw_dir = WEST // Direction to spit meat and gibs in. Defaults to west. @@ -24,17 +24,11 @@ idle_power_usage = 2 active_power_usage = 500 -/obj/machinery/gibber/suicide_act(mob/living/user) - if(occupant || locked) - return FALSE - user.visible_message("[user] climbs into [src] and turns it on!") - user.Stun(20 SECONDS) - user.forceMove(src) - occupant = user - update_icon() - feedinTopanim() - addtimer(CALLBACK(src, PROC_REF(startgibbing), user), 33) - return OBLITERATION + +/obj/machinery/gibber/Initialize(mapload) + . = ..() + update_icon(UPDATE_OVERLAYS) + /obj/machinery/gibber/Destroy() if(contents.len) @@ -47,27 +41,38 @@ /obj/machinery/gibber/RefreshParts() //If you want to make the machine upgradable, this is where you would change any vars basd on its stock parts. return -/obj/machinery/gibber/New() - ..() - overlays += image('icons/obj/kitchen.dmi', "grjam") -/obj/machinery/gibber/update_icon() - overlays.Cut() +/obj/machinery/gibber/update_overlays() + . = ..() if(dirty) - overlays += image('icons/obj/kitchen.dmi', "grbloody") + . += "grbloody" if(stat & (NOPOWER|BROKEN)) return if(!occupant) - overlays += image('icons/obj/kitchen.dmi', "grjam") + . += "grjam" else if(operating) - overlays += image('icons/obj/kitchen.dmi', "gruse") + . += "gruse" else - overlays += image('icons/obj/kitchen.dmi', "gridle") + . += "gridle" + + +/obj/machinery/gibber/suicide_act(mob/living/user) + if(occupant || locked) + return FALSE + user.visible_message("[user] climbs into [src] and turns it on!") + user.Stun(20 SECONDS) + user.forceMove(src) + occupant = user + update_icon() + feedinTopanim() + addtimer(CALLBACK(src, PROC_REF(startgibbing), user), 33) + return OBLITERATION + /obj/machinery/gibber/relaymove(mob/user) if(locked) @@ -115,7 +120,7 @@ return return ..() -/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) +/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user, params) if(user.incapacitated() || !ishuman(user)) return @@ -126,7 +131,7 @@ if(targetl.buckled) return - + . = TRUE add_fingerprint(user) move_into_gibber(user,target) @@ -155,7 +160,7 @@ victim.forceMove(src) occupant = victim - update_icon() + update_icon(UPDATE_OVERLAYS) feedinTopanim() /obj/machinery/gibber/verb/eject() @@ -182,9 +187,8 @@ occupant.forceMove(get_turf(src)) occupant = null - update_icon() + update_icon(UPDATE_OVERLAYS) - return /obj/machinery/gibber/proc/feedinTopanim() if(!occupant) @@ -198,7 +202,7 @@ gibberoverlay.overlays += image('icons/obj/kitchen.dmi', "gridle") var/image/feedee = new - occupant.dir = 2 + occupant.dir = SOUTH feedee.icon = getFlatIcon(occupant, 2) //makes the image a copy of the occupant var/atom/movable/holder = new //holder for occupant image @@ -208,14 +212,14 @@ holder.pixel_x = 2 holder.loc = get_turf(src) holder.layer = MOB_LAYER //simulate mob-like layering - holder.anchored = 1 + holder.anchored = TRUE var/atom/movable/holder2 = new //holder for gibber overlay, used to simulate 3D effect holder2.name = null holder2.overlays += gibberoverlay holder2.loc = get_turf(src) holder2.layer = MOB_LAYER + 0.1 //3D, it's above the mob, rest of the gibber is behind - holder2.anchored = 1 + holder2.anchored = TRUE animate(holder, pixel_y = 16, time = animation_delay) //animate going down @@ -250,33 +254,24 @@ use_power(1000) visible_message("You hear a loud squelchy grinding sound.") - operating = 1 - update_icon() + operating = TRUE + update_icon(UPDATE_OVERLAYS) var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = gibtime * 5) //start shaking - var/slab_name = occupant.name - var/slab_count = 3 - var/slab_type = /obj/item/reagent_containers/food/snacks/meat/human //gibber can only gib humans on paracode, no need to check meat type - var/slab_nutrition = occupant.nutrition / 15 - - slab_nutrition /= slab_count - - for(var/i=1 to slab_count) - var/obj/item/reagent_containers/food/snacks/meat/new_meat = new slab_type(src) - new_meat.name = "[slab_name] [new_meat.name]" - new_meat.reagents.add_reagent("nutriment", slab_nutrition) - - - if(occupant.reagents) - occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count, 1)) + while(occupant.meatleft > 0) + new occupant.dna.species.meat_type(src, occupant) + occupant.meatleft-- if(ishuman(occupant)) var/mob/living/carbon/human/H = occupant var/skinned = H.dna.species.skinned_type + if(ismachineperson(H)) + new /obj/effect/gibspawner/robot(src) + else if(!isplasmaman(H) && !isnucleation(H) && !isgolem(H)) + new /obj/effect/gibspawner(src, H.dna) if(skinned) new skinned(src) - new /obj/effect/decal/cleanable/blood/gibs(src) if(!UserOverride) add_attack_logs(user, occupant, "Gibbed in [src]", !!occupant.ckey ? ATKLOG_FEW : ATKLOG_ALL) @@ -311,8 +306,8 @@ sleep(1) pixel_x = initial(pixel_x) //return to it's spot after shaking - operating = 0 - update_icon() + operating = FALSE + update_icon(UPDATE_OVERLAYS) @@ -369,19 +364,24 @@ victim_targets.Cut() /obj/machinery/gibber/autogibber/proc/force_move_into_gibber(mob/living/carbon/human/victim) - if(!istype(victim)) return 0 + if(!istype(victim)) + return FALSE visible_message("\The [victim.name] gets sucked into \the [src]!") victim.forceMove(src) occupant = victim - update_icon() + update_icon(UPDATE_OVERLAYS) feedinTopanim() - return 1 + return TRUE + /obj/machinery/gibber/autogibber/proc/ejectclothes(mob/living/carbon/human/H) - if(!istype(H)) return 0 - if(H != occupant) return 0 //only using H as a shortcut to typecast + if(!istype(H)) + return + if(H != occupant) + return //only using H as a shortcut to typecast + for(var/obj/O in H) if(istype(O,/obj/item/clothing)) //clothing gets skipped to avoid cleaning out shit continue 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 8edc159e269..664746c1993 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -4,7 +4,7 @@ /obj/machinery/icemachine name = "\improper Cream-Master Deluxe" density = 1 - anchored = 1 + anchored = TRUE icon = 'icons/obj/machines/cooking_machines.dmi' icon_state = "icecream_vat" use_power = IDLE_POWER_USE diff --git a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm index adfed758c15..23a1714f210 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm @@ -5,7 +5,7 @@ icon_state = "juicer1" layer = 2.9 density = 1 - anchored = 0 + anchored = FALSE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 100 @@ -35,9 +35,8 @@ . = ..() beaker = new /obj/item/reagent_containers/glass/beaker/large(src) -/obj/machinery/juicer/update_icon() +/obj/machinery/juicer/update_icon_state() icon_state = "juicer"+num2text(!isnull(beaker)) - return /obj/machinery/juicer/attackby(obj/item/O, mob/user, params) @@ -52,7 +51,7 @@ add_fingerprint(user) beaker = O verbs += /obj/machinery/juicer/verb/detach - update_icon() + update_icon(UPDATE_ICON_STATE) updateUsrDialog() return 0 if(!is_type_in_list(O, allowed_items)) @@ -142,7 +141,7 @@ verbs -= /obj/machinery/juicer/verb/detach beaker.forceMove(loc) beaker = null - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/juicer/proc/get_juice_id(obj/item/reagent_containers/food/snacks/grown/O) for (var/i in allowed_items) diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm index 42f02593cd5..ae91aab6c56 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm @@ -1,16 +1,18 @@ +#define NO_DIRT 0 +#define MAX_DIRT 100 /obj/machinery/kitchen_machine name = "Base Kitchen Machine" desc = "If you are seeing this, a coder/mapper messed up. Please report it." layer = 2.9 density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 100 container_type = OPENCONTAINER - var/operating = 0 // Is it on? - var/dirty = 0 // = {0..100} Does it need cleaning? + var/operating = FALSE // Is it on? + var/dirty = NO_DIRT // = {0..100} Does it need cleaning? var/broken = 0 // ={0,1,2} How broken is it??? var/efficiency = 0 var/list/cook_verbs = list("Cooking") @@ -63,21 +65,21 @@ if(operating) add_fingerprint(user) return - if(!broken && dirty < 100) + if(!broken && dirty < MAX_DIRT) if(default_deconstruction_screwdriver(user, open_icon, off_icon, O)) add_fingerprint(user) return if(exchange_parts(user, O)) return - if(!broken && istype(O, /obj/item/wrench)) + if(!broken && O.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) playsound(src, O.usesound, 50, 1) if(anchored) - anchored = 0 + anchored = FALSE to_chat(user, "\The [src] can now be moved.") return else if(!anchored) - anchored = 1 + anchored = TRUE to_chat(user, "\The [src] is now secured.") return @@ -85,33 +87,33 @@ return if(broken > 0) - if(broken == 2 && istype(O, /obj/item/screwdriver)) // If it's broken and they're using a screwdriver + if(broken == 2 && O.tool_behaviour == TOOL_SCREWDRIVER) // If it's broken and they're using a screwdriver user.visible_message("[user] starts to fix part of [src].", "You start to fix part of [src].") if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src)) add_fingerprint(user) user.visible_message("[user] fixes part of [src].", "You have fixed part of \the [src].") broken = 1 // Fix it a bit - else if(broken == 1 && istype(O, /obj/item/wrench)) // If it's broken and they're doing the wrench + else if(broken == 1 && O.tool_behaviour == TOOL_WRENCH) // If it's broken and they're doing the wrench user.visible_message("[user] starts to fix part of [src].", "You start to fix part of [src].") if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src)) add_fingerprint(user) user.visible_message("[user] fixes [src].", "You have fixed [src].") - icon_state = off_icon broken = 0 // Fix it! - dirty = 0 // just to be sure + dirty = NO_DIRT // just to be sure + update_icon(UPDATE_ICON_STATE) container_type = OPENCONTAINER else to_chat(user, "It's broken!") return 1 - else if(dirty==100) // The machine is all dirty so can't be used! + else if(dirty == MAX_DIRT) // The machine is all dirty so can't be used! if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap)) // If they're trying to clean it then let them user.visible_message("[user] starts to clean [src].", "You start to clean [src].") if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src)) add_fingerprint(user) user.visible_message("[user] has cleaned [src].", "You have cleaned [src].") - dirty = 0 // It's clean! + dirty = NO_DIRT // It's clean! broken = 0 // just to be sure - icon_state = off_icon + update_icon(UPDATE_ICON_STATE) container_type = OPENCONTAINER else //Otherwise bad luck!! to_chat(user, "It's dirty!") @@ -367,19 +369,19 @@ /obj/machinery/kitchen_machine/proc/start() visible_message("\The [src] turns on.", "You hear \a [src].") - operating = 1 - icon_state = on_icon + operating = TRUE + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/kitchen_machine/proc/abort() - operating = 0 // Turn it off again aferwards - icon_state = off_icon + operating = FALSE // Turn it off again aferwards + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/kitchen_machine/proc/stop() playsound(loc, 'sound/machines/ding.ogg', 50, 1) - operating = 0 // Turn it off again aferwards - icon_state = off_icon + operating = FALSE // Turn it off again aferwards + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/kitchen_machine/proc/dispose() @@ -393,24 +395,23 @@ /obj/machinery/kitchen_machine/proc/muck_start() playsound(loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound - icon_state = dirty_icon // Make it look dirty!! /obj/machinery/kitchen_machine/proc/muck_finish() playsound(loc, 'sound/machines/ding.ogg', 50, 1) visible_message("\The [src] gets covered in muck!") - dirty = 100 // Make it dirty so it can't be used util cleaned + dirty = MAX_DIRT // Make it dirty so it can't be used util cleaned flags = null //So you can't add condiments - icon_state = dirty_icon // Make it look dirty too - operating = 0 // Turn it off again aferwards + operating = FALSE // Turn it off again aferwards + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/kitchen_machine/proc/broke() do_sparks(2, 1, src) - icon_state = broken_icon // Make it look all busted up and shit visible_message("The [src] breaks!") //Let them know they're stupid broken = 2 // Make it broken so it can't be used util fixed flags = null //So you can't add condiments - operating = 0 // Turn it off again aferwards + operating = FALSE // Turn it off again aferwards + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/kitchen_machine/proc/fail() @@ -452,3 +453,18 @@ if("dispose") dispose() return + + +/obj/machinery/kitchen_machine/update_icon_state() + if(broken) + icon_state = broken_icon + return + if(dirty == MAX_DIRT) + icon_state = dirty_icon + return + icon_state = operating ? on_icon : off_icon + + +#undef NO_DIRT +#undef MAX_DIRT + diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm index 80e7b8a65f6..0cc63cf9ef3 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm @@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) icon_state = "grinder" layer = 2.9 density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 50 @@ -18,14 +18,15 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) var/obj/item/reagent_containers/food/snacks/monkeycube/cube_type = /obj/item/reagent_containers/food/snacks/monkeycube var/list/connected = list() -/obj/machinery/monkey_recycler/New() - ..() +/obj/machinery/monkey_recycler/Initialize(mapload) + . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/monkey_recycler(null) component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/matter_bin(null) GLOB.monkey_recyclers += src RefreshParts() + locate_camera_console() /obj/machinery/monkey_recycler/Destroy() GLOB.monkey_recyclers -= src @@ -35,6 +36,15 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) connected.Cut() return ..() +/obj/machinery/monkey_recycler/proc/locate_camera_console() + if(length(connected)) + return // we're already connected! + for(var/obj/machinery/computer/camera_advanced/xenobio/xeno_camera in GLOB.machines) + if(get_area(xeno_camera) == get_area(loc)) + xeno_camera.connected_recycler = src + connected |= xeno_camera + break + /obj/machinery/monkey_recycler/RefreshParts() var/req_grind = 5 var/cubes_made = 1 @@ -61,7 +71,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) if(default_deconstruction_crowbar(user, O)) return - if(istype(O, /obj/item/multitool)) + if(O.tool_behaviour == TOOL_MULTITOOL) add_fingerprint(user) if(!panel_open) cycle_through++ @@ -97,6 +107,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) add_fingerprint(user) user.drop_from_active_hand() qdel(target) + target = null //we sleep in this proc, clear reference NOW to_chat(user, "You stuff the monkey in the machine.") playsound(loc, 'sound/machines/juicer.ogg', 50, 1) var/offset = prob(50) ? -2 : 2 diff --git a/code/modules/food_and_drinks/kitchen_machinery/oven.dm b/code/modules/food_and_drinks/kitchen_machinery/oven.dm index 8645c8f8ab9..8abb6e2cb0e 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/oven.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/oven.dm @@ -5,16 +5,23 @@ icon_state = "oven_off" layer = 2.9 density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE - var/candy = 0 + var/candy = FALSE idle_power_usage = 5 var/on = FALSE //Is it making food already? var/list/food_choices = list() -/obj/machinery/cooking/New() - ..() + + +/obj/machinery/cooking/Initialize(mapload) + . = ..() updatefood() + +/obj/machinery/cooking/update_icon_state() + icon_state = "[candy ? "mixer" : "oven"][on ? "_on" : "_off"]" + + /obj/machinery/cooking/attackby(obj/item/I, mob/user, params) add_fingerprint(user) if(on) @@ -30,21 +37,15 @@ to_chat(user, "You put [F] into [src] for cooking.") user.drop_transfer_item_to_loc(F, src) on = TRUE - if(!candy) - icon_state = "oven_on" - else - icon_state = "mixer_on" - sleep(100) + update_icon(UPDATE_ICON_STATE) + sleep(10 SECONDS) on = FALSE - if(!candy) - icon_state = "oven_off" - else - icon_state = "mixer_off" + update_icon(UPDATE_ICON_STATE) C.loc = get_turf(src) C.attackby(F,user, params) playsound(loc, 'sound/machines/ding.ogg', 50, 1) updatefood() - return + /obj/machinery/cooking/proc/updatefood() return @@ -61,14 +62,14 @@ for(var/U in subtypesof(/obj/item/reagent_containers/food/snacks/customizable/cook)) var/obj/item/reagent_containers/food/snacks/customizable/cook/V = new U food_choices += V - return + /obj/machinery/cooking/candy name = "candy machine" desc = "Get yer box of deep fried deep fried deep fried deep fried cotton candy cereal sandwich cookies here!" icon = 'icons/obj/machines/cooking_machines.dmi' icon_state = "mixer_off" - candy = 1 + candy = TRUE /obj/machinery/cooking/candy/updatefood() for(var/U in food_choices) @@ -76,4 +77,4 @@ for(var/U in subtypesof(/obj/item/reagent_containers/food/snacks/customizable/candy)) var/obj/item/reagent_containers/food/snacks/customizable/candy/V = new U food_choices += V - return + diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index eccffcc2203..35bcf83228f 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -4,7 +4,7 @@ icon_state = "processor" layer = 2.9 density = 1 - anchored = 1 + anchored = TRUE var/broken = 0 var/processing = 0 diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index fa29ec2bc5e..fdbfe1e706a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -35,6 +35,23 @@ var/datum/wires/smartfridge/wires /// Typecache of accepted item types, init it in [/obj/machinery/smartfridge/Initialize]. var/list/accepted_items_typecache + /// Associative list (/obj/item => /number) representing the items the fridge should initially contain. + var/list/starting_items + /// Overlay used to visualize contents for default smartfringe. + var/contents_overlay = "smartfridge" + /// Overlay used to visualize broken status. + var/broken_overlay = "smartfridge-broken" + /// Additional overlay on top, like hazard symbol for smartfringe in virology. + var/icon_addon + /// Used to calculate smartfridge fullness while updating overlays. + var/fill_level + /// Lightmask used for emissive appearance if smartfringe has a light source. + var/icon_lightmask = "smartfridge" + /// Default light range, when on. + var/light_range_on = 1 + /// Default light power, when on. + var/light_power_on = 0.5 + /obj/machinery/smartfridge/Initialize(mapload) . = ..() @@ -54,6 +71,14 @@ wires = new/datum/wires/smartfridge/secure(src) else wires = new/datum/wires/smartfridge(src) + //Add starting items + if(mapload && starting_items) + for(var/typekey in starting_items) + var/amount = starting_items[typekey] || 1 + while(amount--) + var/obj/item/newitem = new typekey(src) + item_quants[newitem.name] += 1 + update_icon(UPDATE_OVERLAYS) // Accepted items accepted_items_typecache = typecacheof(list( /obj/item/reagent_containers/food/snacks/grown, @@ -81,38 +106,68 @@ if(shoot_inventory && prob(2)) throw_item() -/obj/machinery/smartfridge/power_change() - var/old_stat = stat + +/obj/machinery/smartfridge/extinguish_light(force = FALSE) + set_light(0) + underlays.Cut() + + +/obj/machinery/smartfridge/obj_break(damage_flag) ..() - if(old_stat != stat) - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/machinery/smartfridge/update_icon() - var/prefix = initial(icon_state) - if(stat & (BROKEN|NOPOWER)) - icon_state = "[prefix]-off" - else if(visible_contents) - switch(length(contents)) - if(0) - icon_state = "[prefix]" - if(1 to 25) - icon_state = "[prefix]1" - if(26 to 75) - icon_state = "[prefix]2" - if(76 to INFINITY) - icon_state = "[prefix]3" + +/obj/machinery/smartfridge/power_change() + . = ..() + if(stat & NOPOWER) + set_light(0) else - icon_state = "[prefix]" + set_light(light_range_on, light_power_on) + if(.) + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/smartfridge/update_overlays() + . = ..() + underlays.Cut() + if(panel_open) + . += "[icon_state]_panel" + if(stat & (BROKEN|NOPOWER)) + . += "[icon_state]_off" + if(icon_addon) + . += "[icon_addon]" + if(stat & BROKEN) + . += "[broken_overlay]" + return + if(visible_contents) + update_fridge_contents() + if(fill_level) + . += "[contents_overlay][fill_level]" + if(icon_addon) + . += "[icon_addon]" + if(icon_lightmask && light) + underlays += emissive_appearance(icon, "[icon_lightmask]_lightmask") + + +/obj/machinery/smartfridge/proc/update_fridge_contents() + switch(length(contents)) + if(0) + fill_level = null + if(1 to 25) + fill_level = 1 + if(26 to 75) + fill_level = 2 + if(76 to INFINITY) + fill_level = 3 + // Interactions /obj/machinery/smartfridge/screwdriver_act(mob/living/user, obj/item/I) . = default_deconstruction_screwdriver(user, icon_state, icon_state, I) if(!.) return + update_icon(UPDATE_OVERLAYS) - overlays.Cut() - if(panel_open) - overlays += image(icon, "[initial(icon_state)]-panel") /obj/machinery/smartfridge/wrench_act(mob/living/user, obj/item/I) . = default_unfasten_wrench(user, I) @@ -146,7 +201,7 @@ if(load(O, user)) user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_OVERLAYS) else if(istype(O, /obj/item/storage/bag) || istype(O, /obj/item/storage/box)) var/obj/item/storage/bag/P = O var/items_loaded = 0 @@ -157,7 +212,7 @@ if(items_loaded) user.visible_message("[user] loads \the [src] with \the [P].", "You load \the [src] with \the [P].") SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_OVERLAYS) var/failed = length(P.contents) if(failed) to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.") @@ -176,17 +231,17 @@ return ..() //Drag pill bottle to fridge to empty it into the fridge -/obj/machinery/smartfridge/MouseDrop_T(obj/over_object, mob/user) +/obj/machinery/smartfridge/MouseDrop_T(obj/over_object, mob/user, params) if(!istype(over_object, /obj/item/storage/pill_bottle)) //Only pill bottles, please return if(stat & (BROKEN|NOPOWER)) to_chat(user, "\The [src] is unpowered and useless.") - return + return TRUE var/obj/item/storage/box/pillbottles/P = over_object if(!length(P.contents)) to_chat(user, "\The [P] is empty.") - return + return TRUE add_fingerprint(user) var/items_loaded = 0 @@ -196,10 +251,11 @@ items_loaded++ if(items_loaded) user.visible_message("[user] empties \the [P] into \the [src].", "You empty \the [P] into \the [src].") - update_icon() + update_icon(UPDATE_OVERLAYS) var/failed = length(P.contents) if(failed) to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.") + return TRUE /obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) user.set_machine(src) @@ -265,14 +321,14 @@ O.forceMove(get_turf(src)) adjust_item_drop_location(O) user.put_in_hands(O, ignore_anim = FALSE) - update_icon() + update_icon(UPDATE_OVERLAYS) break else for(var/obj/O in contents) if(O.name == K) O.forceMove(loc) adjust_item_drop_location(O) - update_icon() + update_icon(UPDATE_OVERLAYS) i-- if(i <= 0) return TRUE @@ -340,7 +396,7 @@ if(I.name == O) I.forceMove(loc) throw_item = I - update_icon() + update_icon(UPDATE_OVERLAYS) break if(!throw_item) return FALSE @@ -367,7 +423,10 @@ */ /obj/machinery/smartfridge/syndie name = "\improper Suspicious SmartFridge" - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" + + /** * # Secure Fridge * @@ -396,7 +455,10 @@ /obj/machinery/smartfridge/seeds name = "\improper Seed Storage" desc = "When you need seeds fast!" - icon_state = "smartfridge" + icon = 'icons/obj/machines/vending.dmi' + icon_state = "seeds_off" + base_icon_state = "seeds" + /obj/machinery/smartfridge/seeds/Initialize(mapload) . = ..() @@ -404,6 +466,28 @@ /obj/item/seeds )) + +/obj/machinery/smartfridge/seeds/update_overlays() + . = list() + + underlays.Cut() + + if(panel_open) + . += "[base_icon_state]_panel" + + if((stat & NOPOWER)) + if(stat & BROKEN) + . += "[base_icon_state]_broken" + return + + if(stat & BROKEN) + . += "[base_icon_state]_broken" + underlays += emissive_appearance(icon, "[base_icon_state]_broken_lightmask") + else + . += base_icon_state + underlays += emissive_appearance(icon, "[base_icon_state]_lightmask") + + /** * # Refrigerated Medicine Storage * @@ -425,7 +509,10 @@ )) /obj/machinery/smartfridge/medbay/syndie - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" + + /** * # Slime Extract Storage * @@ -439,7 +526,8 @@ /obj/machinery/smartfridge/secure/extract/syndie name = "\improper Suspicious Slime Extract Storage" desc = "A refrigerated storage unit for slime extracts" - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" /obj/machinery/smartfridge/secure/extract/Initialize(mapload) . = ..() @@ -471,7 +559,8 @@ )) /obj/machinery/smartfridge/secure/medbay/syndie - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" req_access = list(ACCESS_SYNDICATE) /** @@ -485,20 +574,9 @@ icon_state = "smartfridge" //To fix the icon in the map editor. req_access = list(ACCESS_CHEMISTRY) - /// Associative list (/obj/item => /number) representing the items the fridge should initially contain. - var/list/spawn_meds /obj/machinery/smartfridge/secure/chemistry/Initialize(mapload) . = ..() - // Spawn initial chemicals - if(mapload) - LAZYINITLIST(spawn_meds) - for(var/typekey in spawn_meds) - var/amount = spawn_meds[typekey] || 1 - while(amount--) - var/obj/item/I = new typekey(src) - item_quants[I.name] += 1 - update_icon() // Accepted items accepted_items_typecache = typecacheof(list( /obj/item/storage/pill_bottle, @@ -514,7 +592,7 @@ // I exist! /obj/machinery/smartfridge/secure/chemistry/preloaded/Initialize(mapload) - spawn_meds = list( + starting_items = list( /obj/item/reagent_containers/food/pill/epinephrine = 12, /obj/item/reagent_containers/food/pill/charcoal = 5, /obj/item/reagent_containers/glass/bottle/epinephrine = 1, @@ -529,16 +607,17 @@ */ /obj/machinery/smartfridge/secure/chemistry/preloaded/syndicate req_access = list(ACCESS_SYNDICATE) - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" -/obj/machinery/smartfridge/secure/chemistry/preloaded/syndicate/Initialize(mapload) - . = ..() /obj/machinery/smartfridge/secure/medbay/organ req_access = list(ACCESS_SURGERY) name = "\improper Secure Refrigerated Organ Storage" desc = "A refrigerated storage unit for storing organs, limbs, implants and IV bags." - opacity = 1 + opacity = TRUE + contents_overlay = "smartfridge-organ" + /obj/machinery/smartfridge/secure/medbay/organ/Initialize(mapload) . = ..() @@ -551,23 +630,6 @@ /obj/item/robot_parts/r_leg, )) -/// Copy pasting to reuse existing sprites -/obj/machinery/smartfridge/secure/medbay/organ/update_icon() - var/prefix = initial(icon_state) - if(stat & (BROKEN|NOPOWER)) - icon_state = "[prefix]-off" - else if(visible_contents) - switch(length(contents)) - if(0) - icon_state = "[prefix]" - if(1 to 25) - icon_state = "[prefix]-organ1" - if(26 to 75) - icon_state = "[prefix]-organ2" - if(76 to INFINITY) - icon_state = "[prefix]-organ3" - else - icon_state = "[prefix]" /** * # Disk Compartmentalizer @@ -577,9 +639,12 @@ /obj/machinery/smartfridge/disks 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" + icon_state = "disktoaster_off" + base_icon_state = "disktoaster" pass_flags = PASSTABLE visible_contents = FALSE + icon_lightmask = "disktoaster" + /obj/machinery/smartfridge/disks/Initialize(mapload) . = ..() @@ -587,6 +652,21 @@ /obj/item/disk, )) + +/obj/machinery/smartfridge/disks/update_overlays() + . = list() + underlays.Cut() + if(panel_open) + . += "[base_icon_state]_panel" + if(stat & (BROKEN|NOPOWER)) + if(stat & BROKEN) + . += "[icon_state]_broken" + return + . += "[base_icon_state]" + if(icon_lightmask && light) + underlays += emissive_appearance(icon, "[icon_lightmask]_lightmask") + + /** * # Smart Virus Storage * @@ -596,20 +676,11 @@ /obj/machinery/smartfridge/secure/chemistry/virology name = "\improper Smart Virus Storage" desc = "A refrigerated storage unit for volatile sample storage." - icon_state = "smartfridge_virology" + icon_state = "smartfridge" req_access = list(ACCESS_VIROLOGY) + icon_addon = "smartfridge-viro-overlay" /obj/machinery/smartfridge/secure/chemistry/virology/Initialize(mapload) - spawn_meds = list( - /obj/item/reagent_containers/syringe/antiviral = 4, - /obj/item/reagent_containers/glass/bottle/cold = 1, - /obj/item/reagent_containers/glass/bottle/flu = 1, - /obj/item/reagent_containers/glass/bottle/sneezing = 1, - /obj/item/reagent_containers/glass/bottle/cough = 1, - /obj/item/reagent_containers/glass/bottle/mutagen = 1, - /obj/item/reagent_containers/glass/bottle/plasma = 1, - /obj/item/reagent_containers/glass/bottle/diphenhydramine = 1 - ) . = ..() accepted_items_typecache = typecacheof(list( /obj/item/reagent_containers/syringe, @@ -617,22 +688,6 @@ /obj/item/reagent_containers/glass/beaker, )) -/obj/machinery/smartfridge/secure/chemistry/virology/update_icon() - var/prefix = initial(icon_state) - if(stat & (BROKEN|NOPOWER)) - icon_state = "[prefix]-off" - else if(visible_contents) - switch(length(contents)) - if(0) - icon_state = "[prefix]" - if(1 to 25) - icon_state = "[prefix]1" - if(26 to 75) - icon_state = "[prefix]2" - if(76 to INFINITY) - icon_state = "[prefix]3" - else - icon_state = "[prefix]" /** * # Smart Virus Storage (Preloaded) @@ -643,7 +698,7 @@ // I exist! /obj/machinery/smartfridge/secure/chemistry/virology/preloaded/Initialize(mapload) - spawn_meds = list( + starting_items = list( /obj/item/reagent_containers/syringe/antiviral = 4, /obj/item/reagent_containers/glass/bottle/cold = 1, /obj/item/reagent_containers/glass/bottle/flu = 1, @@ -662,11 +717,10 @@ * A [Smart Virus Storage (Preloaded)][/obj/machinery/smartfridge/secure/chemistry/virology/preloaded] but with exclusive access to Syndicate. */ /obj/machinery/smartfridge/secure/chemistry/virology/preloaded/syndicate - icon_state = "syndi_smartfridge" + icon_state = "smartfridge-syndie" + contents_overlay = "smartfridge-syndie" req_access = list(ACCESS_SYNDICATE) -/obj/machinery/smartfridge/secure/chemistry/virology/preloaded/syndicate/Initialize(mapload) - . = ..() /** * # Drink Showcase @@ -713,12 +767,13 @@ name = "drying rack" desc = "A wooden contraption, used to dry plant products, food and leather." icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "drying_rack" + icon_state = "drying-rack_off" use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 200 can_dry = TRUE visible_contents = FALSE + icon_lightmask = null /obj/machinery/smartfridge/drying_rack/Initialize(mapload) . = ..() @@ -738,13 +793,13 @@ /obj/machinery/smartfridge/drying_rack/RefreshParts() return -/obj/machinery/smartfridge/drying_rack/power_change() +/obj/machinery/smartfridge/drying_rack/power_change(forced = FALSE) if(powered() && anchored) stat &= ~NOPOWER else stat |= NOPOWER - toggle_drying(TRUE) - update_icon() + toggle_drying(forceoff =TRUE) + update_icon(UPDATE_OVERLAYS) /obj/machinery/smartfridge/drying_rack/screwdriver_act(mob/living/user, obj/item/I) return @@ -769,20 +824,21 @@ if("drying") drying = !drying use_power = drying ? ACTIVE_POWER_USE : IDLE_POWER_USE - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/machinery/smartfridge/drying_rack/update_icon() - ..() - overlays.Cut() + +/obj/machinery/smartfridge/drying_rack/update_overlays() + . = list() if(drying) - overlays += "drying_rack_drying" + . += "drying-rack_drying" if(length(contents)) - overlays += "drying_rack_filled" + . += "drying-rack_filled" + /obj/machinery/smartfridge/drying_rack/process() - ..() if(drying && rack_dry())//no need to update unless something got dried - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/machinery/smartfridge/drying_rack/accept_check(obj/item/O) . = ..() @@ -798,14 +854,14 @@ * Arguments: * * forceoff - Whether to force turn off the drying rack. */ -/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff) +/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff = FALSE) if(drying || forceoff) drying = FALSE use_power = IDLE_POWER_USE else drying = TRUE use_power = ACTIVE_POWER_USE - update_icon() + update_icon(UPDATE_OVERLAYS) /** * Called in [/obj/machinery/smartfridge/drying_rack/process] to dry the contents. diff --git a/code/modules/food_and_drinks/recipes/recipes_grill.dm b/code/modules/food_and_drinks/recipes/recipes_grill.dm index 88e174abd5c..cbfb182717d 100644 --- a/code/modules/food_and_drinks/recipes/recipes_grill.dm +++ b/code/modules/food_and_drinks/recipes/recipes_grill.dm @@ -57,6 +57,169 @@ ) result = /obj/item/reagent_containers/food/snacks/meatsteak +/datum/recipe/grill/meatsteak_human + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, + /obj/item/reagent_containers/food/snacks/grown/eggplant + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/human + +/datum/recipe/grill/meatsteak_vulpkanin + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "lemonjuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin, + /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle, + /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin + +/datum/recipe/grill/meatsteak_tajaran + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "sodawater" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran, + /obj/item/grown/nettle/basic + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/tajaran + +/datum/recipe/grill/meatsteak_unathi + reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "tomatojuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi, + /obj/item/reagent_containers/food/snacks/grown/harebell + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/unathi + +/datum/recipe/grill/meatsteak_drask + reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "capsaicin" = 10, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/drask, + /obj/item/reagent_containers/food/snacks/grown/garlic, + /obj/item/reagent_containers/food/snacks/grown/chili, + /obj/item/reagent_containers/food/snacks/grown/berries, + /obj/item/reagent_containers/food/snacks/grown/berries, + /obj/item/reagent_containers/food/snacks/grown/berries + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/drask + +/datum/recipe/grill/meatsteak_grey + reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "tomatojuice" = 10, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/grey, + /obj/item/reagent_containers/food/snacks/grown/garlic, + /obj/item/reagent_containers/food/snacks/grown/cabbage + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/grey + +/datum/recipe/grill/meatsteak_skrell + reagents = list("sodiumchloride" = 1, "blackpepper" = 5, "tomatojuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell, + /obj/item/reagent_containers/food/snacks/grown/banana + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/skrell + +/datum/recipe/grill/meatsteak_vox + reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/vox, + /obj/item/reagent_containers/food/snacks/grown/garlic, + /obj/item/reagent_containers/food/snacks/grown/potato/sweet, + /obj/item/reagent_containers/food/snacks/grown/potato/sweet + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/vox + +/datum/recipe/grill/meatsteak_slime + reagents = list("sodiumchloride" = 10, "sugar" = 5, "herbsmix" = 5, "lemonjuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/slime, + /obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/slime + +/datum/recipe/grill/meatsteak_wryn + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "orangejuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn, + /obj/item/reagent_containers/food/snacks/grown/potato, + /obj/item/reagent_containers/food/snacks/grown/potato + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/wryn + +/datum/recipe/grill/meatsteak_kidan + reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan, + /obj/item/reagent_containers/food/snacks/grown/garlic, + /obj/item/reagent_containers/food/snacks/grown/olive, + /obj/item/reagent_containers/food/snacks/grown/olive, + /obj/item/reagent_containers/food/snacks/grown/olive + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/kidan + +/datum/recipe/grill/meatsteak_nian + reagents = list("sodiumchloride" = 5, "sugar" = 5, "herbsmix" = 5, "lemonjuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/nian, + /obj/item/reagent_containers/food/snacks/grown/citrus/orange + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/nian + +/datum/recipe/grill/meatsteak_diona + reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/diona, + /obj/item/reagent_containers/food/snacks/grown/garlic, + /obj/item/reagent_containers/food/snacks/grown/citrus/lemon + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/diona + +/datum/recipe/grill/meatsteak_monkey + reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, + /obj/item/reagent_containers/food/snacks/grown/chili, + /obj/item/reagent_containers/food/snacks/grown/chili, + /obj/item/reagent_containers/food/snacks/grown/citrus/lemon + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/monkey + +/datum/recipe/grill/meatsteak_farwa + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "grapejuice" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa, + /obj/item/reagent_containers/food/snacks/grown/poppy, + /obj/item/reagent_containers/food/snacks/grown/poppy + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/farwa + +/datum/recipe/grill/meatsteak_wolpin + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "potato" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin, + /obj/item/reagent_containers/food/snacks/onion_slice/red, + /obj/item/reagent_containers/food/snacks/onion_slice/red + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/wolpin + +/datum/recipe/grill/meatsteak_neara + reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "lemonjuice" = 5, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/neara, + /obj/item/reagent_containers/food/snacks/grown/soybeans, + /obj/item/reagent_containers/food/snacks/grown/soybeans + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/neara + +/datum/recipe/grill/meatsteak_stok + reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "orangejuice" = 5, "herbsmix" = 5, "oliveoil" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/meat/humanoid/stok, + /obj/item/reagent_containers/food/snacks/cucumberslice, + /obj/item/reagent_containers/food/snacks/cucumberslice + ) + result = /obj/item/reagent_containers/food/snacks/meatsteak/stok + /datum/recipe/grill/waffles reagents = list("sugar" = 10) items = list( @@ -126,16 +289,16 @@ /datum/recipe/grill/human/kabob items = list( /obj/item/stack/rods, - /obj/item/reagent_containers/food/snacks/meat/human, - /obj/item/reagent_containers/food/snacks/meat/human, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, ) result = /obj/item/reagent_containers/food/snacks/kabob /datum/recipe/grill/monkeykabob items = list( /obj/item/stack/rods, - /obj/item/reagent_containers/food/snacks/meat/monkey, - /obj/item/reagent_containers/food/snacks/meat/monkey, + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, ) result = /obj/item/reagent_containers/food/snacks/monkeykabob diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index 9fb68cf7f84..7d5181fd3f1 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -51,7 +51,7 @@ /datum/recipe/microwave/human/burger items = list( - /obj/item/reagent_containers/food/snacks/meat/human, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, /obj/item/reagent_containers/food/snacks/bun ) result = /obj/item/reagent_containers/food/snacks/human_burger @@ -176,8 +176,8 @@ /datum/recipe/microwave/soylentgreen reagents = list("flour" = 10) items = list( - /obj/item/reagent_containers/food/snacks/meat/human, - /obj/item/reagent_containers/food/snacks/meat/human, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, ) result = /obj/item/reagent_containers/food/snacks/soylentgreen diff --git a/code/modules/food_and_drinks/recipes/recipes_oven.dm b/code/modules/food_and_drinks/recipes/recipes_oven.dm index 62d4e29dd14..44378766fd4 100644 --- a/code/modules/food_and_drinks/recipes/recipes_oven.dm +++ b/code/modules/food_and_drinks/recipes/recipes_oven.dm @@ -105,6 +105,151 @@ ) result = /obj/item/reagent_containers/food/snacks/meatpie +/datum/recipe/oven/meatpie_human + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/human, + /obj/item/organ/internal/liver, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/human + +/datum/recipe/oven/meatpie_vulpkanin + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin, + /obj/item/organ/internal/liver/vulpkanin, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/vulpkanin + +/datum/recipe/oven/meatpie_tajaran + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran, + /obj/item/organ/internal/liver/tajaran, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/tajaran + +/datum/recipe/oven/meatpie_unathi + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi, + /obj/item/organ/internal/liver/unathi, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/unathi + +/datum/recipe/oven/meatpie_drask + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/drask, + /obj/item/organ/internal/liver/drask, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/drask + +/datum/recipe/oven/meatpie_grey + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/grey, + /obj/item/organ/internal/liver/grey, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/grey + +/datum/recipe/oven/meatpie_skrell + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell, + /obj/item/organ/internal/liver/skrell, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/skrell + +/datum/recipe/oven/meatpie_vox + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/vox, + /obj/item/organ/internal/liver/vox, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/vox + +/datum/recipe/oven/meatpie_slime + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/slime, + /obj/item/organ/internal/heart/slime, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/slime + +/datum/recipe/oven/meatpie_wryn + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn, + /obj/item/organ/internal/wryn/glands, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/wryn + +/datum/recipe/oven/meatpie_kidan + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan, + /obj/item/organ/internal/liver/kidan, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/kidan + +/datum/recipe/oven/meatpie_nian + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/nian, + /obj/item/organ/internal/liver/nian, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/nian + +/datum/recipe/oven/meatpie_diona + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/diona, + /obj/item/reagent_containers/food/snacks/meat/humanoid/diona, + /obj/item/organ/internal/liver/diona, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/diona + +/datum/recipe/oven/meatpie_monkey + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey, + /obj/item/organ/internal/heart, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/monkey + +/datum/recipe/oven/meatpie_farwa + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa, + /obj/item/organ/internal/heart/tajaran, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/farwa + +/datum/recipe/oven/meatpie_wolpin + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin, + /obj/item/organ/internal/heart/vulpkanin, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/wolpin + +/datum/recipe/oven/meatpie_neara + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/neara, + /obj/item/organ/internal/heart/skrell, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/neara + +/datum/recipe/oven/meatpie_stok + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/meat/humanoid/stok, + /obj/item/organ/internal/heart/unathi, + ) + result = /obj/item/reagent_containers/food/snacks/meatpie/stok + /datum/recipe/oven/tofupie items = list( /obj/item/reagent_containers/food/snacks/sliceable/flatdough, diff --git a/code/modules/holiday/new_year.dm b/code/modules/holiday/new_year.dm index 0e78e181618..c747cbe348f 100644 --- a/code/modules/holiday/new_year.dm +++ b/code/modules/holiday/new_year.dm @@ -25,7 +25,7 @@ to_chat(user, span_notice("You [anchored ? "un" : ""]wrenched [src]")) /obj/structure/garland/attackby(obj/item/P, mob/user, params) - if(istype(P, /obj/item/wirecutters) || istype(P, /obj/item/wrench)) + if(P.tool_behaviour == TOOL_WIRECUTTER || P.tool_behaviour == TOOL_WRENCH) return return ..() diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 0afdf0822a4..2bbd51e0600 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -16,6 +16,7 @@ ..() pixel_x = rand(8,-8) pixel_y = rand(8,-8) + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/honeycomb/set_APTFT() set hidden = TRUE @@ -23,15 +24,16 @@ /obj/item/reagent_containers/honeycomb/empty() set hidden = TRUE -/obj/item/reagent_containers/honeycomb/update_icon() - overlays.Cut() + +/obj/item/reagent_containers/honeycomb/update_overlays() + . = ..() var/image/honey if(honey_color) honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "greyscale_honey") honey.color = honey_color else honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "honey") - overlays += honey + . += honey /obj/item/reagent_containers/honeycomb/proc/set_reagent(reagent) @@ -42,4 +44,5 @@ reagents.add_reagent(R.id,5) else honey_color = "" - update_icon() + update_icon(UPDATE_OVERLAYS) + diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index d6da06ceecf..b5c70900d02 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -57,7 +57,7 @@ if(A != container) return container = null - update_icon() + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) /obj/machinery/biogenerator/RefreshParts() @@ -75,7 +75,7 @@ if(effeciency_prev != efficiency) update_ui_product_list() // We have have a higher `efficiency` now, and need to re-calc the product costs. -/obj/machinery/biogenerator/update_icon() +/obj/machinery/biogenerator/update_icon_state() if(panel_open) icon_state = "biogen-empty-o" else if(!container) @@ -118,7 +118,7 @@ add_fingerprint(user) container = O to_chat(user, "You add the [container] to [src].") - update_icon() + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) return TRUE @@ -265,7 +265,7 @@ processing = TRUE SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_ICON_STATE) var/plants_processed = length(stored_plants) for(var/obj/plant as anything in stored_plants) @@ -281,7 +281,7 @@ /obj/machinery/biogenerator/proc/end_processing() processing = FALSE SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /** * Ejects the biogenerator's stored plants @@ -351,7 +351,7 @@ biomass -= (D.materials[MAT_BIOMASS] / efficiency) * amount SStgui.update_uis(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /** * Detach the `container` from the biogenerator. @@ -361,6 +361,6 @@ return container.forceMove(get_turf(src)) container = null - update_icon() + update_icon(UPDATE_ICON_STATE) #undef BASE_MAX_STORABLE_PLANTS diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 019557365b6..32c7329c4e2 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -63,7 +63,7 @@ else container_type = DRAINABLE | AMOUNT_VISIBLE to_chat(user, "You close [src], letting you draw from its tap.") - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/fermenting_barrel/crowbar_act(mob/living/user, obj/item/I) . = TRUE @@ -85,11 +85,10 @@ new /obj/item/stack/sheet/wood(drop_location(), mat_drop) ..() -/obj/structure/fermenting_barrel/update_icon() - if(open) - icon_state = "barrel_open" - else - icon_state = "barrel" + +/obj/structure/fermenting_barrel/update_icon_state() + icon_state = "barrel[open ? "_open" : ""]" + /datum/crafting_recipe/fermenting_barrel name = "Wooden Barrel" diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index e30b335fb64..6cc22b60605 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -5,7 +5,7 @@ pass_flags = PASSTABLE icon_state = "dnamod" density = 1 - anchored = 1 + anchored = TRUE var/obj/item/seeds/seed var/obj/item/disk/plantgene/disk @@ -82,22 +82,26 @@ min_wchance = 0 min_wrate = 0 -/obj/machinery/plantgenes/update_icon() - ..() - overlays.Cut() + +/obj/machinery/plantgenes/update_icon_state() if((stat & (BROKEN|NOPOWER))) icon_state = "dnamod-off" else icon_state = "dnamod" + + +/obj/machinery/plantgenes/update_overlays() + . = ..() if(seed) - overlays += "dnamod-dna" + . += "dnamod-dna" if(panel_open) - overlays += "dnamod-open" + . += "dnamod-open" + /obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I)) add_fingerprint(user) - update_icon() + update_icon(UPDATE_OVERLAYS) return if(exchange_parts(user, I)) return @@ -303,7 +307,7 @@ seed.verb_pickup() seed = null update_genes() - update_icon() + update_icon(UPDATE_OVERLAYS) else var/obj/item/I = usr.get_active_hand() if(istype(I, /obj/item/seeds)) @@ -311,7 +315,6 @@ return insert_seed(I) to_chat(usr, "You add [I] to the machine.") - update_icon() else if(href_list["eject_disk"] && !operation) if(disk) disk.forceMove(loc) @@ -378,7 +381,7 @@ if(!HAS_TRAIT(disk, TRAIT_CMAGGED)) disk.update_name() QDEL_NULL(seed) - update_icon() + update_icon(UPDATE_OVERLAYS) if("replace") if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core)) seed.genes -= G @@ -420,7 +423,7 @@ S.forceMove(src) seed = S update_genes() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/plantgenes/proc/update_genes() core_genes = list() @@ -467,7 +470,7 @@ /obj/item/disk/plantgene/New() ..() - overlays += "datadisk_gene" + update_icon(UPDATE_OVERLAYS) pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) @@ -493,44 +496,50 @@ if(do_after(user, 50, target = src)) user.visible_message("[user] cleans the ooze off [src].", "You clean the ooze off [src].") REMOVE_TRAIT(src, TRAIT_CMAGGED, CMAGGED) - update_name() - update_desc() - update_icon_state() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON) ..() if(istype(W, /obj/item/pen) && !HAS_TRAIT(src, TRAIT_CMAGGED)) rename_interactive(user, W) -/obj/item/disk/plantgene/update_desc() + +/obj/item/disk/plantgene/update_name(updates = ALL) . = ..() if(HAS_TRAIT(src, TRAIT_CMAGGED)) - desc = "Better keep this safe." + name = "nuclear authentication disk" + return + if(gene) + name = "[gene.get_name()] (Plant Data Disk)" else - desc = initial(desc) + name = initial(name) -/obj/item/disk/plantgene/update_name() + +/obj/item/disk/plantgene/update_desc(updates = ALL) . = ..() if(HAS_TRAIT(src, TRAIT_CMAGGED)) - name = "nuclear authentication disk" - else - if(gene) - name = "[gene.get_name()] (Plant Data Disk)" - else - name = initial(name) + desc = "Better keep this safe." + return + desc = initial(desc) + /obj/item/disk/plantgene/update_icon_state() if(HAS_TRAIT(src, TRAIT_CMAGGED)) icon_state = "nucleardisk" - overlays -= "datadisk_gene" - else - icon_state = initial(icon_state) - overlays += "datadisk_gene" + return + icon_state = initial(icon_state) + + +/obj/item/disk/plantgene/update_overlays() + . = ..() + if(HAS_TRAIT(src, TRAIT_CMAGGED)) + return + . += "datadisk_gene" + /obj/item/disk/plantgene/cmag_act() . = ..() ADD_TRAIT(src, TRAIT_CMAGGED, CMAGGED) - update_name() - update_desc() - update_icon_state() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON) + /obj/item/disk/plantgene/attack_self(mob/user) if(HAS_TRAIT(src, TRAIT_CMAGGED)) diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index e2cb65c56cc..bcd4eb7232f 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -10,7 +10,7 @@ yield = 4 potency = 15 icon_dead = "wheat-dead" - mutatelist = list(/obj/item/seeds/wheat/oat, /obj/item/seeds/wheat/meat) + mutatelist = list(/obj/item/seeds/wheat/oat) reagents_add = list("plantmatter" = 0.04) /obj/item/reagent_containers/food/snacks/grown/wheat diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index fb3fdec085e..afb48e9720b 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -156,13 +156,18 @@ density = FALSE anchored = TRUE buckle_lying = FALSE - var/burning = 0 + var/burning = FALSE var/lighter // Who lit the fucking thing var/fire_stack_strength = 5 /obj/structure/bonfire/dense density = TRUE + +/obj/structure/bonfire/update_icon_state() + icon_state = "bonfire[burning ? "_on_fire" : ""]" + + /obj/structure/bonfire/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stack/rods) && !can_buckle) add_fingerprint(user) @@ -202,8 +207,8 @@ /obj/structure/bonfire/proc/StartBurning() if(!burning && CheckOxygen()) - icon_state = "bonfire_on_fire" - burning = 1 + burning = TRUE + update_icon(UPDATE_ICON_STATE) set_light(6, l_color = "#ED9200") Burn() START_PROCESSING(SSobj, src) @@ -241,8 +246,8 @@ /obj/structure/bonfire/extinguish() if(burning) - icon_state = "bonfire" - burning = 0 + burning = FALSE + update_icon(UPDATE_ICON_STATE) set_light(0) STOP_PROCESSING(SSobj, src) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index e5d064edf91..fdf2940df3d 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -184,8 +184,6 @@ extend = !extend if(extend) to_chat(user, "With a flick of your wrist, you extend the scythe. It's reaping time!") - icon_state = "tscythe1" - item_state = "scythe0" //use the normal scythe in-hands slot_flags = SLOT_BACK //won't fit on belt, but can be worn on belt when extended w_class = WEIGHT_CLASS_BULKY //won't fit in backpacks while extended force = 15 //slightly better than normal scythe damage @@ -195,8 +193,6 @@ playsound(src.loc, 'sound/weapons/blade_unsheath.ogg', 50, 1) //Sound credit to Qat of Freesound.org else to_chat(user, "You collapse the scythe, folding it away for easy storage.") - icon_state = "tscythe0" - item_state = null //no sprite for folded version, like a tele-baton slot_flags = SLOT_BELT //can be worn on belt again, but no longer makes sense to wear on the back w_class = WEIGHT_CLASS_SMALL force = 3 @@ -205,13 +201,19 @@ //Collapse sound (blade sheath) playsound(src.loc, 'sound/weapons/blade_sheath.ogg', 50, 1) //Sound credit to Q.K. of Freesound.org sharp = extend - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() + update_icon(UPDATE_ICON_STATE) + update_equipped_item() add_fingerprint(user) +/obj/item/scythe/tele/update_icon_state() + if(extend) + icon_state = "tscythe1" + item_state = "scythe0" //use the normal scythe in-hands + else + icon_state = "tscythe0" + item_state = null //no sprite for folded version, like a tele-baton + // ************************************* // Nutrient defines for hydroponics @@ -242,7 +244,7 @@ /obj/item/reagent_containers/glass/bottle/nutrient/on_reagent_change() . = ..() - update_icon() + update_icon(UPDATE_OVERLAYS) if(reagents.total_volume) hitsound = 'sound/weapons/jug_filled_impact.ogg' mob_throw_hit_sound = 'sound/weapons/jug_filled_impact.ogg' @@ -250,9 +252,9 @@ hitsound = 'sound/weapons/jug_empty_impact.ogg' mob_throw_hit_sound = 'sound/weapons/jug_empty_impact.ogg' -/obj/item/reagent_containers/glass/bottle/nutrient/update_icon() - cut_overlays() +/obj/item/reagent_containers/glass/bottle/nutrient/update_overlays() + . = ..() if(reagents.total_volume) var/image/filling = image('icons/obj/reagentfillings.dmi', src, "plastic_jug10") @@ -274,10 +276,10 @@ filling.icon_state = "plastic_jug100" filling.icon += mix_color_from_reagents(reagents.reagent_list) - add_overlay(filling) + . += filling if(!is_open_container()) - add_overlay("lid_jug") + . += "lid_jug" /obj/item/reagent_containers/glass/bottle/nutrient/ez diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index be88cebe3ce..629fbd9d678 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "hydrotray" density = 1 - anchored = 1 + anchored = TRUE pixel_y = 8 var/waterlevel = 100 //The amount of water in the tray (max 100) var/maxwater = 100 //The maximum amount of water in the tray @@ -27,7 +27,7 @@ var/obj/item/seeds/myseed = null //The currently planted seed var/rating = 1 var/wrenchable = 1 - var/lid_state = 0 + var/lid_closed = FALSE var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpollinate one plant var/using_irrigation = FALSE //If the tray is connected to other trays via irrigation hoses var/self_sufficiency_req = 20 //Required total dose to make a self-sufficient hydro tray. 1:1 with earthsblood. @@ -128,9 +128,9 @@ if(!user || user.stat || user.restrained()) return - lid_state = !lid_state - to_chat(user, "You [lid_state ? "close" : "open"] the tray's lid.") - update_icon() + lid_closed = !lid_closed + to_chat(user, "You [lid_closed ? "close" : "open"] the tray's lid.") + update_state() /obj/machinery/hydroponics/bullet_act(obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables. @@ -257,9 +257,9 @@ else weedinvasion() // Weed invasion into empty tray needs_update = 1 - if (needs_update) - update_icon() - return + if(needs_update) + update_state() + /obj/machinery/hydroponics/proc/nutrimentMutation() if (mutmod == 0) @@ -277,39 +277,38 @@ hardmutate() else if(prob(50)) //12.5% mutatespecie() - return - return -/obj/machinery/hydroponics/update_icon() - //Refreshes the icon and sets the luminosity - overlays.Cut() +/obj/machinery/hydroponics/proc/update_state() + //Refreshes the icon and sets the luminosity if(self_sustaining) if(istype(src, /obj/machinery/hydroponics/soil)) color = rgb(255, 175, 0) - else - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing") set_light(3) - - update_icon_hoses() - - if(myseed) - update_icon_plant() - update_icon_lights() - - if(!self_sustaining) + else if(myseed && myseed.get_gene(/datum/plant_gene/trait/glow)) var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow) set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color) else set_light(0) - if(lid_state) - overlays += image(icon='icons/obj/hydroponics/equipment.dmi', icon_state = "hydrocover", layer = LID_LAYER) + update_icon() - return -/obj/machinery/hydroponics/proc/update_icon_hoses() +/obj/machinery/hydroponics/update_overlays() + . = ..() + if(self_sustaining && !istype(src, /obj/machinery/hydroponics/soil)) + . += "gaia_blessing" + + if(myseed) + . += update_icon_plant() + . += update_icon_lights() + + if(lid_closed) + . += image(icon='icons/obj/hydroponics/equipment.dmi', icon_state = "hydrocover", layer = LID_LAYER) + + +/obj/machinery/hydroponics/update_icon_state() var/n = 0 for(var/Dir in GLOB.cardinal) var/obj/machinery/hydroponics/t = locate() in get_step(src,Dir) @@ -318,6 +317,7 @@ icon_state = "hoses-[n]" + /obj/machinery/hydroponics/proc/update_icon_plant() var/image/I if(dead) @@ -331,19 +331,21 @@ var/t_growthstate = clamp(round((age / myseed.maturation) * myseed.growthstages), 1, myseed.growthstages) I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][t_growthstate]") I.layer = PLANT_LAYER - overlays += I + return I + /obj/machinery/hydroponics/proc/update_icon_lights() + . = list() if(waterlevel <= 10) - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowwater3") + . += "over_lowwater3" if(nutrilevel <= 2) - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lownutri3") + . += "over_lownutri3" if(plant_health <= (myseed.endurance / 2)) - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowhealth3") + . += "over_lowhealth3" if(weedlevel >= 5 || pestlevel >= 5 || toxic >= 40) - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_alert3") + . += "over_alert3" if(harvest) - overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_harvest3") + . += "over_harvest3" /obj/machinery/hydroponics/examine(mob/user) @@ -353,7 +355,7 @@ . += "It has the [myseed.variant] variant of [myseed.plantname] planted." else . += "It has [myseed.plantname] planted." - if (hasHUD(user, DATA_HUD_HYDROPONIC) || isobserver(user)) + if (hasHUD(user, EXAMINE_HUD_BOTANY) || isobserver(user)) . += myseed.get_analyzer_text() . += "Weed: [weedlevel] / 10" . += "Pest: [pestlevel] / 10" @@ -414,7 +416,7 @@ harvest = 0 adjustWeeds(-10) // Reset adjustPests(-10) // Reset - update_icon() + update_state() plant_hud_set_health() plant_hud_set_status() visible_message("The [oldPlantName] is overtaken by some [myseed.plantname]!") @@ -452,7 +454,7 @@ adjustWeeds(-10) // Reset sleep(5) // Wait a while - update_icon() + update_state() visible_message("[oldPlantName] suddenly mutates into [myseed.plantname]!") @@ -472,7 +474,7 @@ adjustWeeds(-10) // Reset sleep(5) // Wait a while - update_icon() + update_state() visible_message("The mutated weeds in [src] spawn some [myseed.plantname]!") else to_chat(usr, "The few weeds in [src] seem to react, but only for a moment...") @@ -483,8 +485,8 @@ harvest = 0 adjustPests(-10) // Pests die if(!dead) - update_icon() - dead = 1 + dead = TRUE + update_state() plant_hud_set_health() plant_hud_set_status() @@ -816,7 +818,7 @@ S.clear_reagents() qdel(S) - H.update_icon() + H.update_state() if(reagent_source) // If the source wasn't composted and destroyed reagent_source.update_icon() return 1 @@ -835,7 +837,7 @@ plant_hud_set_health() plant_hud_set_status() lastcycle = world.time - update_icon() + update_state() else to_chat(user, "[src] already has seeds in it!") @@ -861,7 +863,7 @@ add_fingerprint(user) user.visible_message("[user] uproots the weeds.", "You remove the weeds from [src].") adjustWeeds(-10) - update_icon() + update_state() else to_chat(user, "This plot is completely devoid of weeds! It doesn't need uprooting.") @@ -894,7 +896,7 @@ plant_hud_set_health() plant_hud_set_status() adjustWeeds(-10) //Has a side effect of cleaning up those nasty weeds - update_icon() + update_state() else if(is_pen(O) && myseed) add_fingerprint(user) myseed.variant_prompt(user, src) @@ -910,7 +912,7 @@ user.visible_message("[user] [using_irrigation ? "" : "dis"]connects [src]'s irrigation hoses.", \ "You [using_irrigation ? "" : "dis"]connect [src]'s irrigation hoses.") for(var/obj/machinery/hydroponics/h in range(1,src)) - h.update_icon() + h.update_state() /obj/machinery/hydroponics/wrench_act(mob/user, obj/item/I) . = TRUE @@ -942,7 +944,7 @@ /obj/machinery/hydroponics/attack_hand(mob/user) if(issilicon(user)) //How does AI know what plant is? return - if(lid_state) + if(lid_closed) to_chat(user, "You can't reach the plant through the cover.") return if(harvest) @@ -953,7 +955,7 @@ dead = 0 to_chat(user, "You remove the dead plant from [src].") QDEL_NULL(myseed) - update_icon() + update_state() plant_hud_set_status() plant_hud_set_health() else @@ -973,7 +975,7 @@ dead = 0 plant_hud_set_status() plant_hud_set_health() - update_icon() + update_state() /// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// /obj/machinery/hydroponics/proc/adjustNutri(adjustamt) @@ -1012,7 +1014,7 @@ /obj/machinery/hydroponics/proc/become_self_sufficient() // Ambrosia Gaia effect visible_message("[src] begins to glow with a beautiful light!") self_sustaining = TRUE - update_icon() + update_state() ///Diona Nymph Related Procs/// /obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0) //So nymphs can climb over top of trays. @@ -1029,12 +1031,12 @@ if(weedlevel > 0) user.adjust_nutrition(weedlevel * 15) adjustWeeds(-10) - update_icon() + update_state() visible_message("[user] begins rooting through [src], ripping out weeds and eating them noisily.","You begin rooting through [src], ripping out weeds and eating them noisily.") else if(nutrilevel < 10) user.adjust_nutrition(-((10 - nutrilevel) * 5)) adjustNutri(10) - update_icon() + update_state() visible_message("[user] secretes a trickle of green liquid from its tail, refilling [src]'s nutrient tray.","You secrete a trickle of green liquid from your tail, refilling [src]'s nutrient tray.") else return ..() @@ -1048,7 +1050,7 @@ use_power = NO_POWER_USE wrenchable = 0 -/obj/machinery/hydroponics/soil/update_icon_hoses() +/obj/machinery/hydroponics/soil/update_icon_state() return // Has no hoses /obj/machinery/hydroponics/soil/update_icon_lights() diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 9f0c5a9cb35..08b3a8bae96 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -43,7 +43,7 @@ icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "sextractor" density = 1 - anchored = 1 + anchored = TRUE var/list/piles = list() var/max_seeds = 1000 var/seed_multiplier = 1 diff --git a/code/modules/input/input.dm b/code/modules/input/input.dm index 23b5c0e2e5b..17877e5eb51 100644 --- a/code/modules/input/input.dm +++ b/code/modules/input/input.dm @@ -24,11 +24,11 @@ "default" = list( "Any" = "\"KeyDown \[\[*\]\]\"", // Passes any key down to the rebindable input system "Any+UP" = "\"KeyUp \[\[*\]\]\"", // Passes any key up to the rebindable input system - "Tab" = "\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", // Swaps us to legacy mode, forces input to the input bar, sets the input bar colour to salmon pink + "Tab" = "\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_ENABLED : COLOR_INPUT_ENABLED]\\\"\"", // Swaps us to legacy mode, forces input to the input bar, sets the input bar colour to salmon pink "Back" = "\".winset \\\"input.focus=true ? input.text=\\\"\"" // This makes it so backspace can remove default inputs ), "legacy" = list( - "Tab" = "\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"", // Swaps us to rebind mode, moves input away from input bar, sets input bar to white + "Tab" = "\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_DISABLED : COLOR_INPUT_DISABLED]\\\"\"", // Swaps us to rebind mode, moves input away from input bar, sets input bar to white "Back" = "\".winset \\\"input.focus=true ? input.text=\\\"\"" // This makes it so backspace can remove default inputs ), ) @@ -62,8 +62,7 @@ var/key = macro_set[k] var/command = macro_set[key] winset(src, "[setname]-[key]", "parent=[setname];name=[key];command=[command]") - - winset(src, null, "input.background-color=[COLOR_INPUT_DISABLED]") //screw you, we start in hotkey mode now + winset(src, null, "input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_DISABLED : COLOR_INPUT_DISABLED]") //screw you, we start in hotkey mode now macro_sets = null //not needed anymore, bye have a great time /client/verb/KeyDown(_key as text) diff --git a/code/modules/input/keybindings.dm b/code/modules/input/keybindings.dm index 1d231127996..7f064cf64ad 100644 --- a/code/modules/input/keybindings.dm +++ b/code/modules/input/keybindings.dm @@ -13,4 +13,11 @@ else active_keybindings[key] += list(KB) + if(!mob) // Clients can join before world/new is setup, so we gotta mob check em + return active_keybindings + for(var/datum/action/action as anything in mob.actions) + if(action.button?.linked_keybind?.binded_to) + var/datum/keybinding/mob/trigger_action_button/linked_bind = action.button.linked_keybind + active_keybindings[linked_bind.binded_to] += list(linked_bind) + return active_keybindings diff --git a/code/modules/instruments/objs/items/headphones.dm b/code/modules/instruments/objs/items/headphones.dm index 741032ef3e2..5366a777640 100644 --- a/code/modules/instruments/objs/items/headphones.dm +++ b/code/modules/instruments/objs/items/headphones.dm @@ -5,6 +5,8 @@ item_state = "headphones0" actions_types = list(/datum/action/item_action/change_headphones_song) var/datum/song/headphones/song + var/on = FALSE + /obj/item/clothing/ears/headphones/Initialize(mapload) . = ..() @@ -15,50 +17,60 @@ RegisterSignal(src, COMSIG_SONG_START, PROC_REF(start_playing)) RegisterSignal(src, COMSIG_SONG_END, PROC_REF(stop_playing)) + /obj/item/clothing/ears/headphones/Destroy() QDEL_NULL(song) return ..() + /obj/item/clothing/ears/headphones/attack_self(mob/user) ui_interact(user) + /obj/item/clothing/ears/headphones/ui_data(mob/user) return song.ui_data(user) + /obj/item/clothing/ears/headphones/ui_interact(mob/user) if(should_stop_playing(user) || user.incapacitated()) return song.ui_interact(user) + /obj/item/clothing/ears/headphones/ui_act(action, params) if(..()) return return song.ui_act(action, params) -/obj/item/clothing/ears/headphones/update_icon() - var/mob/living/carbon/human/user = loc - if(istype(user)) - user.update_action_buttons_icon() - user.update_inv_ears() - ..() + +/obj/item/clothing/ears/headphones/update_icon_state() + icon_state = "headphones[on]" + item_state = "headphones[on]" + update_equipped_item() + /obj/item/clothing/ears/headphones/item_action_slot_check(slot) if(slot == slot_l_ear || slot == slot_r_ear) return TRUE + /** * Called by a component signal when our song starts playing. */ /obj/item/clothing/ears/headphones/proc/start_playing() - icon_state = item_state = "headphones1" - update_icon() + SIGNAL_HANDLER + on = TRUE + update_icon(UPDATE_ICON_STATE) + /** * Called by a component signal when our song stops playing. */ /obj/item/clothing/ears/headphones/proc/stop_playing() - icon_state = item_state = "headphones0" - update_icon() + SIGNAL_HANDLER + on = FALSE + update_icon(UPDATE_ICON_STATE) + /** * Whether the headphone's song should stop playing @@ -69,12 +81,15 @@ /obj/item/clothing/ears/headphones/proc/should_stop_playing(mob/living/carbon/human/user) return !(src in user) || !istype(user) || !((src == user.l_ear) || (src == user.r_ear)) + // special subtype so it uses the correct item type /datum/song/headphones + /datum/song/headphones/should_stop_playing(mob/user) . = ..() if(.) return TRUE var/obj/item/clothing/ears/headphones/I = parent return I.should_stop_playing(user) + diff --git a/code/modules/library/admin.dm b/code/modules/library/admin.dm index 8ec728d0267..5cc288bcfe1 100644 --- a/code/modules/library/admin.dm +++ b/code/modules/library/admin.dm @@ -37,14 +37,15 @@ if(!usr.client.holder) return - var/dat = {"
    " var/rank if(job.alt_titles) rank = "[GetPlayerAltTitle(job)]" else rank = job.title + if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian")) + rank = "[GetPlayerAltTitle(job)]" lastJob = job if(!is_job_whitelisted(user, job.title)) - html += "[rank] \[КАРМА]
    \[КАРМА]
    \[ЗАБАНЕНО]
    \[ЗАБАНЕНО]
    \[" + get_exp_format(available_in_playtime) + " за " + job.get_exp_req_type() + "\]
    \[" + get_exp_format(available_in_playtime) + " за " + job.get_exp_req_type() + "\]
    \[ИНВАЛИДНОСТЬ\]
    \[ИНВАЛИДНОСТЬ\]
    \[ЧЕРЕЗ [(available_in_days)] ДНЕЙ]
    \[ЧЕРЕЗ [(available_in_days)] ДНЕЙ]
    \[ВОЗРАСТ ОТ [(job.min_age_allowed)]]
    \[ВОЗРАСТ ОТ [(job.min_age_allowed)]]
    " - var/prefLevelLabel = "ERROR" - var/prefLevelColor = "pink" + var/prefLevelLabel = "ОШИБКА" + var/prefLevelColor = "bg-danger" var/prefUpperLevel = -1 // level to assign on left click var/prefLowerLevel = -1 // level to assign on right click if(GetJobDepartment(job, 1) & job.flag) - prefLevelLabel = "High" - prefLevelColor = "slateblue" + prefLevelLabel = "Высокий" + prefLevelColor = "btn-primary text-light" prefUpperLevel = 4 prefLowerLevel = 2 else if(GetJobDepartment(job, 2) & job.flag) - prefLevelLabel = "Medium" - prefLevelColor = "green" + prefLevelLabel = "Средний" + prefLevelColor = "btn-success text-light" prefUpperLevel = 1 prefLowerLevel = 3 else if(GetJobDepartment(job, 3) & job.flag) - prefLevelLabel = "Low" - prefLevelColor = "orange" + prefLevelLabel = "Низкий" + prefLevelColor = "btn-warning text-dark" prefUpperLevel = 2 prefLowerLevel = 4 else - prefLevelLabel = "NEVER" - prefLevelColor = "red" + prefLevelLabel = "НИКОГДА" + prefLevelColor = "btn-outline-secondary" prefUpperLevel = 3 prefLowerLevel = 1 - html += "" - - // HTML += "" + html += "" if(job.title == "Civilian")//Civilian is special if(job_support_low & JOB_CIVILIAN) - html += " Yes" + html += " Да" else - html += " No" + html += " Нет" html += "
      
      
    "} + var/dat = {"
    ISBNTitleTotal FlagsOptions
    "} - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged FROM [format_table_name("library")] WHERE \ + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged, flaggedby FROM [format_table_name("library")] WHERE \ flagged > 0 ORDER BY flagged DESC LIMIT :lowerlimit, :upperlimit", list( "lowerlimit" = text2num((page_num - 1) * FLAGGED_BOOKS_PER_PAGE), "upperlimit" = FLAGGED_BOOKS_PER_PAGE )) + if(!query.warn_execute()) qdel(query) return @@ -53,7 +54,7 @@ while(query.NextRow()) books++ var/isbn = query.item[1] - dat += "
    ISBNTitleTotal FlagsFlagged by (Last ckey)Options
    [add_zero(isbn, 4)][query.item[2]][query.item[3]]" + dat += "
    [add_zero(isbn, 4)][query.item[2]][query.item[3]][query.item[4]]" dat += "View Content" dat += "Unflag" dat += "Delete" diff --git a/code/modules/library/computers/base.dm b/code/modules/library/computers/base.dm index 334d14ed987..ecd2a166fd0 100644 --- a/code/modules/library/computers/base.dm +++ b/code/modules/library/computers/base.dm @@ -2,7 +2,7 @@ /obj/machinery/computer/library name = "visitor computer" - anchored = 1 + anchored = TRUE density = 1 icon_keyboard = "" icon_screen = "computer_on" diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm index 4f1576655fc..ef45abfb76c 100644 --- a/code/modules/library/computers/checkout.dm +++ b/code/modules/library/computers/checkout.dm @@ -4,9 +4,10 @@ /obj/machinery/computer/library/checkout name = "Check-In/Out Computer" icon = 'icons/obj/library.dmi' - icon_state = "computer" - anchored = 1 - density = 1 + icon_state = "oldcomp" + anchored = TRUE + density = TRUE + icon_screen = "library" var/arcanecheckout = 0 //var/screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book var/buffer_book diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index fc5b09873bd..8d286faff0d 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -15,103 +15,110 @@ name = "bookcase" icon = 'icons/obj/library.dmi' icon_state = "book-0" - anchored = 1 + anchored = TRUE density = 1 opacity = 1 resistance_flags = FLAMMABLE max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) - var/tmp/busy = 0 - var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/bible, /obj/item/tome) //Things allowed in the bookcase + /// Things allowed in the bookcase + var/list/allowed_books = list( + /obj/item/book, + /obj/item/spellbook, + /obj/item/storage/bible, + /obj/item/tome, + ) + /obj/structure/bookcase/Initialize() ..() for(var/obj/item/I in loc) if(is_type_in_list(I, allowed_books)) I.forceMove(src) - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/structure/bookcase/attackby(obj/item/O as obj, mob/user as mob, params) - if(busy) //So that you can't mess with it while deconstructing - return TRUE + +/obj/structure/bookcase/attackby(obj/item/O, mob/user, params) if(is_type_in_list(O, allowed_books)) if(!user.drop_transfer_item_to_loc(O, src)) return add_fingerprint(user) - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE - else if(istype(O, /obj/item/storage/bag/books)) + if(istype(O, /obj/item/storage/bag/books)) var/obj/item/storage/bag/books/B = O for(var/obj/item/T in B.contents) - if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook) || istype(T, /obj/item/tome) || istype(T, /obj/item/storage/bible)) + if(is_type_in_list(T, allowed_books)) T.add_fingerprint(user) B.remove_from_storage(T, src) add_fingerprint(user) - to_chat(user, "You empty [O] into [src].") - update_icon() + to_chat(user, span_notice("You empty [O] into [src].")) + update_icon(UPDATE_ICON_STATE) return TRUE - else if(istype(O, /obj/item/wrench)) - user.visible_message("[user] starts disassembling \the [src].", \ - "You start disassembling \the [src].") - playsound(get_turf(src), O.usesound, 50, 1) - busy = TRUE - - if(do_after(user, 50 * O.toolspeed * gettoolspeedmod(user), target = src)) - playsound(get_turf(src), O.usesound, 75, 1) - user.visible_message("[user] disassembles \the [src].", \ - "You disassemble \the [src].") - busy = FALSE - density = 0 - deconstruct(TRUE) - else - busy = FALSE - return TRUE - else if(istype(O, /obj/item/pen)) + if(is_pen(O)) add_fingerprint(user) rename_interactive(user, O) return TRUE - else - return ..() + return ..() + + +/obj/structure/bookcase/screwdriver_act(mob/user, obj/item/I) + if(flags & NODECONSTRUCT) + return + . = TRUE + if(!I.tool_use_check(user, 0)) + return + TOOL_ATTEMPT_DISMANTLE_MESSAGE + if(!I.use_tool(src, user, 2 SECONDS, volume = I.tool_volume)) + return + TOOL_DISMANTLE_SUCCESS_MESSAGE + deconstruct(TRUE) + + +/obj/structure/bookcase/wrench_act(mob/user, obj/item/I) + . = TRUE + default_unfasten_wrench(user, I, 0) + + +/obj/structure/bookcase/attack_hand(mob/user) + if(!length(contents)) + return + + var/obj/item/book/choice = tgui_input_list(user, "Which book would you like to remove from [src]?", "Bookcase", contents) + if(!choice || user.incapacitated() || !Adjacent(user)) + return + add_fingerprint(user) + choice.forceMove_turf() + user.put_in_hands(choice, ignore_anim = FALSE) + update_icon(UPDATE_ICON_STATE) -/obj/structure/bookcase/attack_hand(var/mob/user as mob) - if(contents.len) - var/obj/item/book/choice = tgui_input_list(user, "Which book would you like to remove from [src]?", "Bookcase", contents) - if(choice) - if(user.incapacitated() || user.lying || !Adjacent(user)) - return - add_fingerprint(user) - if(!user.get_active_hand()) - choice.forceMove_turf() - user.put_in_hands(choice, ignore_anim = FALSE) - else - choice.forceMove(get_turf(src)) - update_icon() /obj/structure/bookcase/deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/wood(loc, 5) for(var/obj/item/I in contents) if(is_type_in_list(I, allowed_books)) I.forceMove(get_turf(src)) - qdel(src) + ..() + + +/obj/structure/bookcase/update_icon_state() + icon_state = "book-[min(length(contents), 5)]" -/obj/structure/bookcase/update_icon() - if(contents.len < 5) - icon_state = "book-[contents.len]" - else - icon_state = "book-5" /obj/structure/bookcase/manuals/medical name = "Medical Manuals bookcase" + /obj/structure/bookcase/manuals/medical/Initialize() . = ..() new /obj/item/book/manual/medical_cloning(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/bookcase/manuals/engineering name = "Engineering Manuals bookcase" + /obj/structure/bookcase/manuals/engineering/Initialize() . = ..() new /obj/item/book/manual/engineering_construction(src) @@ -120,15 +127,17 @@ new /obj/item/book/manual/engineering_guide(src) new /obj/item/book/manual/engineering_singularity_safety(src) new /obj/item/book/manual/robotics_cyborgs(src) - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/structure/bookcase/manuals/research_and_development name = "R&D Manuals bookcase" + /obj/structure/bookcase/manuals/research_and_development/Initialize() . = ..() new /obj/item/book/manual/research_and_development(src) - update_icon() + update_icon(UPDATE_ICON_STATE) /* diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 316fc48657e..e393067a59b 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A var/forbidden=0 var/path = /obj/item/book // Type path of the book to generate var/flagged = 0 + var/flaggedby /datum/cachedbook/proc/LoadFromRow(var/list/row) id = row["id"] @@ -34,6 +35,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A category = row["category"] ckey = row["ckey"] flagged = row["flagged"] + flaggedby = row["flaggedby"] if("content" in row) content = row["content"] programmatic=0 @@ -80,8 +82,9 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A log_game("[user] (ckey: [user.key]) has flagged book #[id] as inappropriate.") - var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1 WHERE id=:id", list( - "id" = text2num(id) + var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1, flaggedby=:flaggedby WHERE id=:id", list( + "id" = text2num(id), + "flaggedby" = user.key )) if(!query.warn_execute()) qdel(query) @@ -107,7 +110,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A if("[id]" in cached_books) return cached_books["[id]"] - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM [format_table_name("library")] WHERE id=:id", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged, flaggedby FROM [format_table_name("library")] WHERE id=:id", list( "id" = text2num(id) )) if(!query.warn_execute()) @@ -124,7 +127,8 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A "category"=query.item[4], "content" =query.item[5], "ckey" =query.item[6], - "flagged" =query.item[7] + "flagged" =query.item[7], + "flaggedby"=query.item[8] )) results += CB cached_books["[id]"]=CB @@ -138,7 +142,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A name = "scanner" icon = 'icons/obj/library.dmi' icon_state = "bigscanner" - anchored = 1 + anchored = TRUE density = 1 var/obj/item/book/cache // Last scanned book @@ -205,7 +209,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A name = "Book Binder" icon = 'icons/obj/library.dmi' icon_state = "binder" - anchored = 1 + anchored = TRUE density = 1 /obj/machinery/bookbinder/attackby(obj/item/I, mob/user) diff --git a/code/modules/martial_arts/adminfu.dm b/code/modules/martial_arts/adminfu.dm index f174bc0b44f..020f44f1156 100644 --- a/code/modules/martial_arts/adminfu.dm +++ b/code/modules/martial_arts/adminfu.dm @@ -38,9 +38,24 @@ desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" - var/used = 0 + var/used = FALSE -/obj/item/adminfu_scroll/attack_self(mob/user as mob) + +/obj/item/adminfu_scroll/update_icon_state() + icon_state = used ? "blankscroll" : initial(icon_state) + + +/obj/item/adminfu_scroll/update_name(updates = ALL) + . = ..() + name = used ? "empty scroll" : initial(name) + + +/obj/item/adminfu_scroll/update_desc(updates = ALL) + . = ..() + desc = used ? "It's completely blank." : initial(desc) + + +/obj/item/adminfu_scroll/attack_self(mob/user) if(!ishuman(user)) return if(!used) @@ -48,7 +63,6 @@ var/datum/martial_art/adminfu/F = new/datum/martial_art/adminfu(null) F.teach(H) to_chat(H, "You have learned the ancient martial art of the Admins.") - used = 1 - desc = "It's completely blank." - name = "empty scroll" - icon_state = "blankscroll" + used = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm index 1d4d0cedbc9..a8e4412db95 100644 --- a/code/modules/martial_arts/cqc.dm +++ b/code/modules/martial_arts/cqc.dm @@ -17,15 +17,15 @@ weight = 5 /datum/martial_art/cqc/under_siege/teach(mob/living/carbon/human/H, make_temporary) - RegisterSignal(H, COMSIG_AREA_ENTERED, PROC_REF(kitchen_check)) + RegisterSignal(H, COMSIG_ATOM_ENTERED_AREA, PROC_REF(kitchen_check)) return ..() /datum/martial_art/cqc/under_siege/remove(mob/living/carbon/human/H) - UnregisterSignal(H, COMSIG_AREA_ENTERED) + UnregisterSignal(H, COMSIG_ATOM_ENTERED_AREA) return ..() /datum/martial_art/cqc/under_siege/proc/kitchen_check(mob/living/carbon/human/H, area/entered_area) - SIGNAL_HANDLER //COMSIG_AREA_ENTERED + SIGNAL_HANDLER //COMSIG_ATOM_ENTERED_AREA if(!is_type_in_typecache(entered_area, areas_under_siege)) weight = 0 else diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 463f090552c..59c27c21b1c 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -330,7 +330,22 @@ desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" - var/used = 0 + var/used = FALSE + + +/obj/item/plasma_fist_scroll/update_icon_state() + icon_state = used ? "blankscroll" : initial(icon_state) + + +/obj/item/plasma_fist_scroll/update_name(updates = ALL) + . = ..() + name = used ? "empty scroll" : initial(name) + + +/obj/item/plasma_fist_scroll/update_desc(updates = ALL) + . = ..() + desc = used ? "It's completely blank." : initial(desc) + /obj/item/plasma_fist_scroll/attack_self(mob/user as mob) if(!ishuman(user)) @@ -341,10 +356,9 @@ var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) F.teach(H) to_chat(H, "You have learned the ancient martial art of Plasma Fist.") - used = 1 - desc = "It's completely blank." - name = "empty scroll" - icon_state = "blankscroll" + used = TRUE + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + /obj/item/sleeping_carp_scroll name = "mysterious scroll" @@ -484,9 +498,10 @@ icon_state = "bostaff0" block_chance = 50 -/obj/item/twohanded/bostaff/update_icon() - icon_state = "bostaff[wielded]" - return + +/obj/item/twohanded/bostaff/update_icon_state() + icon_state = "bostaff[HAS_TRAIT(src, TRAIT_WIELDED)]" + /obj/item/twohanded/bostaff/attack(mob/target, mob/living/user) add_fingerprint(user) @@ -512,7 +527,7 @@ return switch(user.a_intent) if(INTENT_DISARM) - if(!wielded) + if(!HAS_TRAIT(src, TRAIT_WIELDED)) return ..() if(!ishuman(target)) return ..() @@ -543,9 +558,9 @@ return ..() /obj/item/twohanded/bostaff/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(wielded) + if(HAS_TRAIT(src, TRAIT_WIELDED)) return ..() - return 0 + return FALSE /obj/screen/combo icon_state = "" @@ -554,24 +569,33 @@ layer = ABOVE_HUD_LAYER var/streak + /obj/screen/combo/proc/clear_streak() cut_overlays() streak = "" icon_state = "" + /obj/screen/combo/update_icon(updates, _streak) streak = _streak - icon_state = "" - if(!streak) - clear_streak() - return - icon_state = "combo" + return ..() + + +/obj/screen/combo/update_overlays() + . = list() for(var/i in 1 to length(streak)) var/intent_text = copytext(streak, i, i + 1) var/image/intent_icon = image(icon, src, "combo_[intent_text]") intent_icon.pixel_x = 16 * (i - 1) - 8 * length(streak) - overlays += intent_icon - return ..() + . += intent_icon + + +/obj/screen/combo/update_icon_state() + icon_state = "" + if(!streak) + return + icon_state = "combo" + #undef HAS_COMBOS #undef COMBO_ALIVE_TIME diff --git a/code/modules/martial_arts/synthojitsu.dm b/code/modules/martial_arts/synthojitsu.dm index 5af35c44d8a..ca81d5a326f 100644 --- a/code/modules/martial_arts/synthojitsu.dm +++ b/code/modules/martial_arts/synthojitsu.dm @@ -43,7 +43,20 @@ icon_state ="viable" var/is_used = FALSE -/obj/item/ipc_combat_upgrade/attack_self(mob/user as mob) + +/obj/item/ipc_combat_upgrade/update_icon_state() + icon_state = "[is_used ? "un" : ""]viable" + + +/obj/item/ipc_combat_upgrade/update_desc(updates = ALL) + . = ..() + if(!is_used) + desc = initial(desc) + return + desc = "Advanced data storage designed to be compatible with positronic systems.This one include melee algorithms along with overwritten microbattery safety protocols.It's hardlocked" + + +/obj/item/ipc_combat_upgrade/attack_self(mob/user) if(!ismachineperson(user) || is_used == TRUE) return to_chat(user, "Installation sequence initialized. It will take some time...") @@ -55,9 +68,8 @@ H.Weaken(10 SECONDS) to_chat(H, "Melee algorithms installed. Safety disabled.") is_used = TRUE - desc = "Advanced data storage designed to be compatible with positronic systems.This one include melee algorithms along with overwritten microbattery safety protocols.It's hardlocked" - name = "IPC combat upgrade" - icon_state = "unviable" + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + /datum/martial_art/synthojitsu/explaination_header(user) to_chat(user, "You reapload some of the basics of synthojitsu.") diff --git a/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm b/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm index 31b00f6d9f6..c0469590cd4 100644 --- a/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm +++ b/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm @@ -70,7 +70,7 @@ /obj/item/gun/projectile/shotgun/boltaction = 1, /obj/item/gun/projectile/shotgun/automatic/combat = 2, /obj/item/gun/projectile/automatic/pistol/APS = 1, - /obj/item/gun/projectile/automatic/pistol/sp8ar = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8ar = 1, /obj/item/gun/projectile/automatic/pistol/m1911 = 1, /obj/item/gun/projectile/revolver/golden = 1, /obj/item/gun/projectile/revolver/nagant = 1, @@ -130,7 +130,7 @@ /obj/item/gun/projectile/shotgun/boltaction = 1, /obj/item/gun/projectile/shotgun/automatic/combat = 2, /obj/item/gun/projectile/automatic/pistol/APS = 1, - /obj/item/gun/projectile/automatic/pistol/sp8ar = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8ar = 1, /obj/item/gun/projectile/automatic/pistol/m1911 = 1, /obj/item/gun/projectile/revolver/golden = 1, /obj/item/gun/projectile/revolver/nagant = 1, @@ -140,4 +140,25 @@ /obj/item/storage/box/thunderdome/crossbow/energy = 1, /obj/item/storage/box/thunderdome/laser_eyes = 1, /obj/item/implanter/adrenalin = 1, + /obj/item/melee/rapier = 1, + /obj/item/melee/energy/axe = 1, + /obj/item/melee/energy/sword/saber/red = 1, + /obj/item/melee/energy/cleaving_saw = 1, + /obj/item/twohanded/mjollnir = 1, + /obj/item/twohanded/chainsaw = 1, + /obj/item/twohanded/dualsaber = 1, + /obj/item/twohanded/fireaxe = 1, + /obj/item/melee/icepick = 1, + /obj/item/melee/candy_sword = 1, + /obj/item/melee/energy/sword/pirate = 1, + /obj/item/storage/toolbox/surgery = 1, + /obj/item/storage/toolbox/mechanical = 1, + /obj/item/storage/toolbox/syndicate = 1, + /obj/item/storage/box/syndie_kit/mantisblade = 1, + /obj/item/CQC_manual = 1, + /obj/item/sleeping_carp_scroll = 1, + /obj/item/clothing/gloves/fingerless/rapid = 1, + /obj/item/storage/box/thunderdome/spears = 1, + /obj/item/storage/box/thunderdome/maga = 1, + /obj/item/storage/box/thunderdome/singulatiry = 1, ) diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 5e6561bd36d..d0c4aed9906 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -180,7 +180,7 @@ if(istype(W, /obj/item/card/emag)) boom(user) return 1 - if(istype(W, /obj/item/multitool)) + if(W.tool_behaviour == TOOL_MULTITOOL) add_fingerprint(user) to_chat(user, "DECA-CODE LOCK REPORT:") if(attempts == 1) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 59738cd2fa3..2d35238543f 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -75,15 +75,18 @@ allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/kinetic_crusher, /obj/item/hierophant_club, /obj/item/twohanded/fireaxe/boneaxe) jetpack = /obj/item/tank/jetpack/suit -/obj/item/clothing/suit/space/hostile_environment/New() + +/obj/item/clothing/suit/space/hostile_environment/Initialize(mapload) + . = ..() AddComponent(/datum/component/spraycan_paintable) START_PROCESSING(SSobj, src) - ..() + /obj/item/clothing/suit/space/hostile_environment/Destroy() STOP_PROCESSING(SSobj, src) return ..() + /obj/item/clothing/suit/space/hostile_environment/process() var/mob/living/carbon/C = loc if(istype(C) && prob(2)) //cursed by bubblegum @@ -103,17 +106,17 @@ armor = list("melee" = 70, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF -/obj/item/clothing/head/helmet/space/hostile_environment/New() - ..() + +/obj/item/clothing/head/helmet/space/hostile_environment/Initialize(mapload) + . = ..() AddComponent(/datum/component/spraycan_paintable) - update_icon() - -/obj/item/clothing/head/helmet/space/hostile_environment/update_icon() - ..() - cut_overlays() - var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass") - glass_overlay.appearance_flags = RESET_COLOR - add_overlay(glass_overlay) + update_icon(UPDATE_OVERLAYS) + + +/obj/item/clothing/head/helmet/space/hostile_environment/update_overlays() + . = ..() + . += mutable_appearance(icon, "hostile_env_glass", appearance_flags = RESET_COLOR) + /obj/item/clothing/head/helmet/space/hardsuit/champion name = "champion's helmet" diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index ca7de1c5a13..3677a45ea47 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -62,7 +62,7 @@ to_chat(user, "There are no trophies on [src].") /obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) - if(!wielded) + if(!HAS_TRAIT(src, TRAIT_WIELDED)) to_chat(user, "[src] is too heavy to use with one hand. You fumble and drop everything.") user.drop_r_hand() user.drop_l_hand() @@ -90,7 +90,7 @@ /obj/item/twohanded/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) . = ..() - if(!wielded) + if(!HAS_TRAIT(src, TRAIT_WIELDED)) return if(user.has_status_effect(STATUS_EFFECT_DASH) && user.a_intent == INTENT_HELP) if(user.throw_at(target, range = 3, speed = 3, spin = FALSE, diagonals_first = TRUE)) @@ -164,21 +164,27 @@ else set_light(0) -/obj/item/twohanded/kinetic_crusher/update_icon() - ..() - cut_overlays() + +/obj/item/twohanded/kinetic_crusher/update_icon_state() + if(upgraded) + item_state = "magmite_crusher[HAS_TRAIT(src, TRAIT_WIELDED)]" + else + item_state = "crusher[HAS_TRAIT(src, TRAIT_WIELDED)]" + + +/obj/item/twohanded/kinetic_crusher/update_overlays() + . = ..() if(!charged) - add_overlay("[icon_state]_uncharged") + . += "[icon_state]_uncharged" if(light_on) - add_overlay("[icon_state]_lit") - spawn(1) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - if(!upgraded) - item_state = "crusher[wielded]" - else - item_state = "magmite_crusher[wielded]" + . += "[icon_state]_lit" + addtimer(CALLBACK(src, PROC_REF(buttons_update)), 0.1 SECONDS) + + +/obj/item/twohanded/kinetic_crusher/proc/buttons_update() + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + //destablizing force /obj/item/projectile/destabilizer @@ -402,7 +408,8 @@ if(.) H.force += bonus_value * 0.2 H.force_unwielded += bonus_value * 0.2 - H.force_wielded += bonus_value * 0.2 + // don't update force since KCs have 0 force by default + H.AddComponent(/datum/component/two_handed, force_wielded = H.force_wielded, force_unwielded = H.force) H.detonation_damage += bonus_value * 0.8 /obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user) @@ -410,7 +417,7 @@ if(.) H.force -= bonus_value * 0.2 H.force_unwielded -= bonus_value * 0.2 - H.force_wielded -= bonus_value * 0.2 + H.AddComponent(/datum/component/two_handed, force_wielded = H.force_wielded, force_unwielded = H.force) H.detonation_damage -= bonus_value * 0.8 /obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user) diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm index cd9aeb3677f..66cea2273d0 100644 --- a/code/modules/mining/equipment/lazarus_injector.dm +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -10,10 +10,15 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 5 - var/loaded = 1 + var/loaded = TRUE var/malfunctioning = 0 var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it + +/obj/item/lazarus_injector/update_icon_state() + icon_state = "lazarus_[loaded ? "hypo" : "empty"]" + + /obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) if(!loaded) return @@ -37,10 +42,10 @@ add_game_logs("[user] has revived hostile mob [target] with a malfunctioning lazarus injector", user) else H.attack_same = 0 - loaded = 0 + loaded = FALSE user.visible_message("[user] injects [M] with [src], reviving it.") playsound(src,'sound/effects/refill.ogg',50,1) - icon_state = "lazarus_empty" + update_icon(UPDATE_ICON_STATE) return else to_chat(user, "[src] is only effective on the dead.") @@ -116,9 +121,14 @@ captured.forceMove(get_turf(src)) captured = null + +/obj/item/mobcapsule/update_icon_state() + icon_state = "mobcap[colorindex]" + + /obj/item/mobcapsule/attack_self(mob/user) colorindex += 1 if(colorindex >= 6) colorindex = 0 - icon_state = "mobcap[colorindex]" - update_icon() + update_icon(UPDATE_ICON_STATE) + diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 761d8560314..43619296302 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -34,14 +34,14 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( /obj/item/stack/marker_beacon/Initialize(mapload) . = ..() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/item/stack/marker_beacon/examine(mob/user) . = ..() . += "Use in-hand to place a [singular_name]." . += "Alt-click to select a color. Current color is [picked_color]." -/obj/item/stack/marker_beacon/update_icon() +/obj/item/stack/marker_beacon/update_icon_state() icon_state = "[initial(icon_state)][lowertext(picked_color)]" /obj/item/stack/marker_beacon/attack_self(mob/user) @@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( return if(input_color) picked_color = input_color - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/marker_beacon name = "marker beacon" @@ -84,25 +84,31 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( /obj/structure/marker_beacon/Initialize(mapload, set_color) . = ..() picked_color = set_color - update_icon() + update_state() /obj/structure/marker_beacon/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) var/obj/item/stack/marker_beacon/M = new(loc) M.picked_color = picked_color - M.update_icon() + M.update_icon(UPDATE_ICON_STATE) qdel(src) /obj/structure/marker_beacon/examine(mob/user) . = ..() . += "Alt-click to select a color. Current color is [picked_color]." -/obj/structure/marker_beacon/update_icon() + +/obj/structure/marker_beacon/update_icon_state() while(!picked_color || !GLOB.marker_beacon_colors[picked_color]) picked_color = pick(GLOB.marker_beacon_colors) icon_state = "[initial(icon_state)][lowertext(picked_color)]-on" + + +/obj/structure/marker_beacon/proc/update_state() + update_icon(UPDATE_ICON_STATE) set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color]) + /obj/structure/marker_beacon/attack_hand(mob/living/user) . = ..() if(.) @@ -114,7 +120,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( if(do_after(user, remove_speed, target = src)) var/obj/item/stack/marker_beacon/M = new(drop_location()) M.picked_color = picked_color - M.update_icon() + M.update_icon(UPDATE_ICON_STATE) transfer_fingerprints_to(M) user.put_in_hands(M, ignore_anim = FALSE) playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) @@ -140,4 +146,4 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( return if(input_color) picked_color = input_color - update_icon() + update_state() diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index fc49ee0993f..cf3f2508f58 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -43,6 +43,7 @@ desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range. \nIt has a speaker that can be toggled with alt+click" name = "advanced automatic mining scanner" icon_state = "adv_mining0" + base_icon_state = "adv_mining" item_state = "analyzer" w_class = WEIGHT_CLASS_SMALL flags = CONDUCT @@ -67,6 +68,7 @@ /obj/item/t_scanner/adv_mining_scanner/lesser name = "automatic mining scanner" icon_state = "mining0" + base_icon_state = "mining" desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. \nIt has a speaker that can be toggled with alt+click" range = 4 cooldown = 50 diff --git a/code/modules/mining/equipment/mining_charges.dm b/code/modules/mining/equipment/mining_charges.dm index 6a3bddc3667..4895441d3db 100644 --- a/code/modules/mining/equipment/mining_charges.dm +++ b/code/modules/mining/equipment/mining_charges.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "mining-charge-2" item_state = "charge_indust" - det_time = 5 + det_time = 5 SECONDS notify_admins = FALSE // no need to make adminlogs on lavaland, while they are "safe" to use var/timer_off = FALSE var/installed = FALSE @@ -192,13 +192,13 @@ . += "[bicon(charge)] [charge]. Current status: [charge.installed ? "ready to detonate" : "ready to deploy"]." -/obj/item/detonator/update_icon() - . = ..() - if(bombs.len) +/obj/item/detonator/update_icon_state() + if(length(bombs)) icon_state = "Detonator-1" else icon_state = initial(icon_state) + /obj/item/detonator/attack_self(mob/user) playsound(src, 'sound/items/detonator.ogg', 40) if(bombs.len) @@ -213,5 +213,5 @@ charge.detonate() else to_chat(user, span_warning("There is no charges linked to a detonator!")) - update_icon() + update_icon(UPDATE_ICON_STATE) . = ..() diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index a2f37176169..48b30d10617 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -120,14 +120,22 @@ . = ..() update_icon() -/obj/item/organ/internal/regenerative_core/legion/update_icon() + +/obj/item/organ/internal/regenerative_core/legion/update_icon_state() icon_state = inert ? "legion_soul_inert" : "legion_soul" - cut_overlays() + + +/obj/item/organ/internal/regenerative_core/legion/update_overlays() + . = ..() if(!inert && !preserved) - add_overlay("legion_soul_crackle") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + . += "legion_soul_crackle" + addtimer(CALLBACK(src, PROC_REF(buttons_update)), 0.1 SECONDS) + + +/obj/item/organ/internal/regenerative_core/legion/proc/buttons_update() + for(var/datum/action/action as anything in actions) + action.UpdateButtonIcon() + /obj/item/organ/internal/regenerative_core/legion/go_inert() ..() diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index c293d2f35a1..c9d4cf55234 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -197,12 +197,12 @@ name = "pod computer" icon_state = "pod_computer" icon = 'icons/obj/lavaland/pod_computer.dmi' - anchored = 1 + anchored = TRUE density = 1 pixel_y = -32 /obj/item/gps/computer/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) playsound(loc, W.usesound, 50, 1) user.visible_message("[user] disassembles the gps.", \ "You start to disassemble the gps...", "You hear clanking and banging noises.") @@ -250,7 +250,7 @@ var/obj/item/instrument/guitar/G = new(src) load(G) -/obj/machinery/smartfridge/survival_pod/update_icon() +/obj/machinery/smartfridge/survival_pod/update_overlays() return /obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O) @@ -270,7 +270,7 @@ icon_state = "fans" name = "environmental regulation system" desc = "A large machine releasing a constant gust of air." - anchored = 1 + anchored = TRUE density = 1 var/arbitraryatmosblockingvar = 1 var/buildstacktype = /obj/item/stack/sheet/metal @@ -295,7 +295,7 @@ qdel(src) /obj/structure/fans/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) playsound(loc, W.usesound, 50, 1) user.visible_message("[user] disassembles the fan.", \ "You start to disassemble the fan...", "You hear clanking and banging noises.") @@ -333,12 +333,12 @@ icon_state = "tubes" icon = 'icons/obj/lavaland/survival_pod.dmi' name = "tubes" - anchored = 1 + anchored = TRUE layer = MOB_LAYER - 0.2 density = 0 /obj/structure/tubes/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) playsound(loc, W.usesound, 50, 1) user.visible_message("[user] disassembles [src].", \ "You start to disassemble [src]...", "You hear clanking and banging noises.") diff --git a/code/modules/mining/equipment/upgrades.dm b/code/modules/mining/equipment/upgrades.dm index 715b95301bb..e45ecaf8b21 100644 --- a/code/modules/mining/equipment/upgrades.dm +++ b/code/modules/mining/equipment/upgrades.dm @@ -18,24 +18,39 @@ . = ..() addtimer(CALLBACK(src, PROC_REF(go_inert)), 50 SECONDS) //you know... + +/obj/item/magmite_parts/update_icon_state() + icon_state = "upgrade_parts[inert ? "_inert" : ""]" + + +/obj/item/magmite_parts/update_name(updates = ALL) + . = ..() + name = initial(name) + if(inert) + name = "inert [name]" + + +/obj/item/magmite_parts/update_desc(updates = ALL) + . = ..() + desc = inert ? "It appears to have lost its magma-like glow." : initial(desc) + + /obj/item/magmite_parts/proc/go_inert() if(inert) return visible_message(span_warning("The [src] loses it's glow!")) inert = TRUE - name = "inert plasma magmite upgrade parts" - icon_state = "upgrade_parts_inert" - desc += "It appears to have lost its magma-like glow." + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) + /obj/item/magmite_parts/proc/restore() if(!inert) return inert = FALSE - name = initial(name) - icon_state = initial(icon_state) - desc = initial(desc) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC) addtimer(CALLBACK(src, PROC_REF(go_inert)), 50 SECONDS) + /obj/item/magmite_parts/afterattack(atom/target, mob/user, proximity_flag, click_parameters) if(!proximity_flag) return diff --git a/code/modules/mining/equipment/weather_radio.dm b/code/modules/mining/equipment/weather_radio.dm index 1c7937541f8..389f9954ebb 100644 --- a/code/modules/mining/equipment/weather_radio.dm +++ b/code/modules/mining/equipment/weather_radio.dm @@ -28,7 +28,7 @@ START_PROCESSING(SSprocessing, src) set_frequency(SUP_FREQ) update_light_color() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/radio/weather_monitor/Destroy() . = ..() @@ -41,18 +41,18 @@ if(previous_level == warning_level && previous_danger == is_weather_dangerous) return // No change atom_say(get_warning_message()) - update_icon() + update_icon(UPDATE_OVERLAYS) update_light_color() -/obj/item/radio/weather_monitor/update_icon() - overlays.Cut() +/obj/item/radio/weather_monitor/update_overlays() + . = ..() switch(warning_level) if(WEATHER_ALERT_CLEAR) - overlays += state_normal + . += state_normal if(WEATHER_ALERT_INCOMING) - overlays += state_warning + . += state_warning if(WEATHER_ALERT_IMMINENT_OR_ACTIVE) - overlays += (is_weather_dangerous) ? state_danger : state_warning + . += is_weather_dangerous ? state_danger : state_warning /obj/item/radio/weather_monitor/proc/update_light_color() switch(warning_level) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index f880c90c394..3f2e15fa28b 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -38,15 +38,15 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) beacon = A to_chat(user, "You link the extraction pack to the beacon system.") -/obj/item/extraction_pack/MouseDrop(atom/over) +/obj/item/extraction_pack/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) if(!..()) return FALSE - if(!(loc == usr && loc.Adjacent(over))) + if(!(loc == usr && loc.Adjacent(over_object))) return FALSE - if(usr.stat || !ishuman(usr) || usr.incapacitated()) + if(!ishuman(usr) || usr.incapacitated()) return FALSE - over.add_fingerprint(usr) - afterattack(over, usr, TRUE) + over_object.add_fingerprint(usr) + afterattack(over_object, usr, TRUE, params) return TRUE /obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 8c805bfba7a..4738e26de91 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/machines/mining_machines.dmi' icon_state = "console" density = FALSE - anchored = 1 + anchored = TRUE var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null var/machinedir = SOUTH var/obj/item/card/id/prisoner/inserted_id @@ -165,7 +165,7 @@ icon = 'icons/obj/machines/mining_machines.dmi' icon_state = "console" density = FALSE - anchored = 1 + anchored = TRUE /obj/machinery/mineral/labor_points_checker/attack_hand(mob/user) . = ..() diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 9840225bb54..e5024d455dd 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -352,7 +352,7 @@ desc = "You can hardly comprehend this thing... which is why you can't see it." icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice density = 1 - anchored = 1 + anchored = TRUE resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE var/mob/living/simple_animal/holder_animal diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm index 1cd2ac26826..29958f11501 100644 --- a/code/modules/mining/lavaland/loot/hierophant_loot.dm +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -109,19 +109,18 @@ chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health -/obj/item/hierophant_club/update_icon() + +/obj/item/hierophant_club/update_icon_state() icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]" item_state = icon_state - if(ismob(loc)) - var/mob/M = loc - M.update_inv_l_hand() - M.update_inv_r_hand() - M.update_inv_back() + update_equipped_item() + /obj/item/hierophant_club/proc/prepare_icon_update() - update_icon() + update_icon(UPDATE_ICON_STATE) sleep(timer - world.time) - update_icon() + update_icon(UPDATE_ICON_STATE) + /obj/item/hierophant_club/ui_action_click(mob/user, actiontype) if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire... @@ -174,7 +173,8 @@ user.visible_message("[user] starts to glow faintly...") timer = world.time + 50 INVOKE_ASYNC(src, PROC_REF(prepare_icon_update)) - beacon.icon_state = "hierophant_tele_on" + beacon.teleporting = TRUE + beacon.update_icon(UPDATE_ICON_STATE) var/obj/effect/temp_visual/hierophant/telegraph/edge/TE1 = new /obj/effect/temp_visual/hierophant/telegraph/edge(user.loc) var/obj/effect/temp_visual/hierophant/telegraph/edge/TE2 = new /obj/effect/temp_visual/hierophant/telegraph/edge(beacon.loc) if(do_after(user, 40, target = user) && user && beacon) @@ -186,7 +186,8 @@ user.update_action_buttons_icon() timer = world.time INVOKE_ASYNC(src, PROC_REF(prepare_icon_update)) - beacon.icon_state = "hierophant_tele_off" + beacon.teleporting = FALSE + beacon.update_icon(UPDATE_ICON_STATE) return new /obj/effect/temp_visual/hierophant/telegraph(T, user) new /obj/effect/temp_visual/hierophant/telegraph(source, user) @@ -199,7 +200,8 @@ timer = world.time INVOKE_ASYNC(src, PROC_REF(prepare_icon_update)) if(beacon) - beacon.icon_state = "hierophant_tele_off" + beacon.teleporting = FALSE + beacon.update_icon(UPDATE_ICON_STATE) return if(is_blocked_turf(T, TRUE)) teleporting = FALSE @@ -207,7 +209,8 @@ user.update_action_buttons_icon() timer = world.time INVOKE_ASYNC(src, PROC_REF(prepare_icon_update)) - beacon.icon_state = "hierophant_tele_off" + beacon.teleporting = FALSE + beacon.update_icon(UPDATE_ICON_STATE) return add_attack_logs(user, beacon, "Teleported self from ([AREACOORD(source)]) to ([AREACOORD(beacon)])") new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user) @@ -222,14 +225,16 @@ INVOKE_ASYNC(src, PROC_REF(teleport_mob), source, L, T, user) //regardless, take all mobs near us along sleep(6) //at this point the blasts detonate if(beacon) - beacon.icon_state = "hierophant_tele_off" + beacon.teleporting = FALSE + beacon.update_icon(UPDATE_ICON_STATE) else qdel(TE1) qdel(TE2) timer = world.time INVOKE_ASYNC(src, PROC_REF(prepare_icon_update)) if(beacon) - beacon.icon_state = "hierophant_tele_off" + beacon.teleporting = FALSE + beacon.update_icon(UPDATE_ICON_STATE) teleporting = FALSE if(user) user.update_action_buttons_icon() @@ -295,4 +300,260 @@ var/obj/effect/temp_visual/hierophant/blast/B = new(t, user, friendly_fire_check) B.damage = 15 //keeps monster damage boost due to lower damage +/obj/item/clothing/accessory/necklace/hierophant_talisman + name = "Dormnant talisman of warding" + desc = "Hierophant's talisman of warding. It will save you." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "hierophant_talisman_nonactive" + item_state = "hierophant_talisman_nonactive" + item_color = "hierophant_talisman_nonactive" + armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 100, "acid" = 100) + slot_flags = SLOT_TIE + allow_duplicates = FALSE + var/possessed = FALSE + var/mob/living/simple_animal/shade/talisman/slave // Talisman + var/obj/effect/proc_holder/spell/hierophant_talisman_heal/spell_heal + var/obj/effect/proc_holder/spell/hierophant_talisman_teleport/spell_teleport + var/obj/effect/proc_holder/spell/hierophant_talisman_message/spell_message + +/obj/item/clothing/accessory/necklace/hierophant_talisman/attack_self(mob/living/user) + if(possessed) + if(!slave) + to_chat(user, span_hierophant("Still searching unique soul for you..")) + return + if(slave.master != user.ckey) + to_chat(slave, span_hierophant("Now you are serving to [user.real_name]. You must ward him.")) + to_chat(user, span_hierophant("Now this talisman is yours... It will ward you...")) + log_game("[user.real_name] has become master of [slave.ckey] hierophant's talisman.") + slave.master = user.ckey + else + to_chat(user, span_hierophant("This talisman is already yours... WHAT ELSE YOU NEED!?")) + return + + + to_chat(user, span_hierophant("You attempt to awake my appertience...")) + + possessed = TRUE + + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the spirit of [user.real_name]'s talisman of warding?", ROLE_PAI, FALSE, 15 SECONDS, source = src) + var/mob/dead/observer/theghost = null + + if(length(candidates)) + theghost = pick(candidates) + slave = new(src) + slave.ckey = theghost.ckey + slave.master = user.ckey + name = "Talisman of warding" + slave.real_name = name + slave.name = name + var/input = stripped_input(slave, "What are you named?", null, "", MAX_NAME_LEN) + if(QDELETED(src)) + return + if(input) + name = input + slave.real_name = input + slave.name = input + log_game("[slave.ckey] has become spirit of [user.real_name]'s talisman.") + to_chat(slave, span_hierophant("Now you are serving to [user.real_name]. You must ward him.")) + update_icon(UPDATE_ICON_STATE) + else + log_game("No one has decided to be [user.real_name]'s talisman.") + to_chat(user, span_hierophant("This talisman is dormnant... Try again or later...")) + possessed = FALSE + +/obj/item/clothing/accessory/necklace/hierophant_talisman/update_icon_state() + icon_state = "hierpohant_talisman_active" + item_state = "hierpohant_talisman_active" + item_color = "hierophant_talisman_active" + +/obj/item/clothing/accessory/necklace/hierophant_talisman/Initialize(mapload) + .=..() + spell_heal = new + spell_teleport = new + spell_message = new + +/obj/item/clothing/accessory/necklace/hierophant_talisman/Destroy() + for(var/mob/living/simple_animal/shade/talisman/S in contents) + to_chat(S, span_hierophant("You were destroyed! So... I will create another one in future.")) + playsound(get_turf(src),'sound/magic/repulse.ogg', 200, 1) + S.ghostize() + qdel(S) + QDEL_NULL(spell_heal) + QDEL_NULL(spell_teleport) + QDEL_NULL(spell_message) + return ..() + +/obj/effect/proc_holder/spell/hierophant_talisman_heal + name = "Beacon of help" + desc = "Healing your master." + base_cooldown = 20 SECONDS + clothes_req = FALSE + human_req = FALSE + phase_allowed = TRUE + should_recharge_after_cast = FALSE + stat_allowed = UNCONSCIOUS + action_icon_state = "hierophant_talisman_heal" + action_background_icon_state = "bg_hierophant_talisman" + panel = "Hierophant Talisman" + +/obj/effect/proc_holder/spell/hierophant_talisman_heal/create_new_targeting() + var/datum/spell_targeting/targeted/T = new() + T.target_priority = SPELL_TARGET_CLOSEST + T.max_targets = 1 + T.range = 1 + T.use_turf_of_user = TRUE + return T + +/obj/effect/proc_holder/spell/hierophant_talisman_heal/valid_target(mob/living/carbon/human/target, mob/living/simple_animal/shade/talisman/user) + if (target.ckey == user.master) + return TRUE + return FALSE + +/obj/effect/proc_holder/spell/hierophant_talisman_heal/cast(list/targets, mob/living/simple_animal/shade/talisman/user = usr) + var/mob/living/carbon/human/target = targets[1] + target.adjustBruteLoss(-15) + target.adjustFireLoss(-15) + target.adjustToxLoss(-15) + if(target.health / target.maxHealth <= 0.25) + cooldown_handler.start_recharge(10 SECONDS) + to_chat(user, span_hierophant("This creature is dying... Pathetic but... You must protect this creature...")) + else + cooldown_handler.start_recharge(20 SECONDS) + to_chat(user, span_hierophant("You are warding... This creature... Very well my apprentice.")) + to_chat(target, span_hierophant("My talisman is warding you... Pathetic...")) + +/obj/effect/proc_holder/spell/hierophant_talisman_teleport + name = "Hierophant's lesser teleportation" + desc = "Blink your master to location." + base_cooldown = 30 SECONDS + clothes_req = FALSE + human_req = FALSE + phase_allowed = TRUE + should_recharge_after_cast = FALSE + stat_allowed = UNCONSCIOUS + centcom_cancast = FALSE + action_icon_state = "hierophant_talisman_teleport" + action_background_icon_state = "bg_hierophant_talisman" + panel = "Hierophant Talisman" + +/obj/effect/proc_holder/spell/hierophant_talisman_teleport/create_new_targeting() + var/datum/spell_targeting/click/T = new() + T.allowed_type = /turf/simulated + T.range = 3 + T.use_turf_of_user = TRUE + return T + +/obj/effect/proc_holder/spell/hierophant_talisman_teleport/cast(list/targets, mob/living/simple_animal/shade/talisman/user) + var/turf/target_turf = get_turf(targets[1]) + for(var/mob/living/carbon/human/H in GLOB.human_list) + if(H.ckey == user.master) + var/turf/start_turf = get_turf(H) + H.forceMove(target_turf) + new /obj/effect/temp_visual/hierophant/telegraph(target_turf, src) + new /obj/effect/temp_visual/hierophant/telegraph(start_turf, src) + playsound(start_turf,'sound/machines/airlock_open.ogg', 200, 1) + if(H.health / H.maxHealth <= 0.25) + cooldown_handler.start_recharge(15 SECONDS) + to_chat(user, span_hierophant("Blink! Blink! Blink! You shall never surrender.")) + user.say("Instant teleportation, my fellow friend!") + else + cooldown_handler.start_recharge(30 SECONDS) + to_chat(user, span_hierophant("Dance, my pretties!")) + user.say("Blink, my fellow friend!") + addtimer(CALLBACK(src, PROC_REF(talisman_teleport_2), target_turf, start_turf), 2) + break + +/obj/effect/proc_holder/spell/hierophant_talisman_teleport/proc/talisman_teleport_2(turf/T, turf/S) + new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src) + new /obj/effect/temp_visual/hierophant/telegraph/teleport(S, src) + animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out + visible_message(span_hierophant("[src] fades out!")) + set_density(FALSE) + addtimer(CALLBACK(src, PROC_REF(talisman_teleport_3), T), 2) + +/obj/effect/proc_holder/spell/hierophant_talisman_teleport/proc/talisman_teleport_3(turf/T) + animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN + set_density(TRUE) + visible_message(span_hierophant("[src] fades in!")) + +/obj/effect/proc_holder/spell/hierophant_talisman_message + name = "Telepathtic Message" + desc = "Send a telepathic message to those humans." + base_cooldown = 5 SECONDS + clothes_req = FALSE + human_req = FALSE + phase_allowed = TRUE + should_recharge_after_cast = TRUE + stat_allowed = UNCONSCIOUS + action_icon_state = "hierophant_talisman_message" + action_background_icon_state = "bg_hierophant_talisman" + panel = "Hierophant Talisman" + +/obj/effect/proc_holder/spell/hierophant_talisman_message/create_new_targeting() + var/datum/spell_targeting/click/T = new() + T.selection_type = SPELL_SELECTION_RANGE + T.use_turf_of_user = TRUE + return T + +/obj/effect/proc_holder/spell/hierophant_talisman_message/cast(list/targets, mob/living/simple_animal/shade/talisman/user) + var/mob/living/carbon/human/choice = targets[1] + var/msg = stripped_input(usr, "What do you wish to tell [choice]?", null, "") + if(!(msg)) + return + add_say_logs(usr, msg, choice, "SLAUGHTER") + to_chat(usr, span_hierophant("You translating directly to mind [choice]: [msg]")) + to_chat(choice, "[span_deadsay(span_hierophant("A strange, magical and at the same time alien broadcast conveys to you... "))][span_hierophant("[msg]")]") + for(var/mob/dead/observer/G in GLOB.player_list) + G.show_message(span_hierophant("Hierophant's message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [choice] ([ghost_follow_link(choice, ghost=G)]): [msg]")) + +/obj/item/clothing/accessory/necklace/hierophant_talisman/on_attached(obj/item/clothing/under/S, mob/user) + . = ..() + if(!ishuman(user) || !slave) + return + if(slave.master == user.ckey) + slave.mob_spell_list += spell_heal + slave.mob_spell_list += spell_teleport + slave.mob_spell_list += spell_message + spell_heal.action.Grant(slave) + spell_teleport.action.Grant(slave) + spell_message.action.Grant(slave) + +/obj/item/clothing/accessory/necklace/hierophant_talisman/on_removed(mob/user) + . = ..() + if(!ishuman(user) || !slave) + return + slave.mob_spell_list -= spell_heal + slave.mob_spell_list -= spell_teleport + slave.mob_spell_list -= spell_message + spell_heal.action.Remove(slave) + spell_teleport.action.Remove(slave) + spell_message.action.Remove(slave) + +/obj/item/clothing/accessory/necklace/hierophant_talisman/attached_unequip() + if(!ishuman(usr)) + return + if(!slave) + return ..() + slave.mob_spell_list -= spell_heal + slave.mob_spell_list -= spell_teleport + slave.mob_spell_list -= spell_message + spell_heal.action.Remove(slave) + spell_teleport.action.Remove(slave) + spell_message.action.Remove(slave) + return ..() + +/obj/item/clothing/accessory/necklace/hierophant_talisman/attached_equip() + if(!ishuman(usr)) + return + if(!slave) + return ..() + if(slave.master == usr.ckey) + slave.mob_spell_list += spell_heal + slave.mob_spell_list += spell_teleport + slave.mob_spell_list += spell_message + spell_heal.action.Grant(slave) + spell_teleport.action.Grant(slave) + spell_message.action.Grant(slave) + return ..() + #undef HIEROPHANT_CLUB_CARDINAL_DAMAGE diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index b8cf1d16289..1d1413d8bc7 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -21,62 +21,50 @@ name = "paradox bag" desc = "Somehow, it's in two places at once." -/obj/item/shared_storage/red/New() - ..() +/obj/item/shared_storage/red/Initialize(mapload) + . = ..() if(!bag) - var/obj/item/storage/backpack/shared/S = new(src) + var/obj/item/storage/backpack/shared/shared_storage = new(src) var/obj/item/shared_storage/blue = new(loc) + bag = shared_storage + blue.bag = shared_storage - bag = S - blue.bag = S /obj/item/shared_storage/attackby(obj/item/W, mob/user, params) if(bag) bag.loc = user bag.attackby(W, user, params) + add_fingerprint(user) + + +/obj/item/shared_storage/proc/open_bag(mob/user) + if(bag) + bag.loc = user + bag.attack_hand(user) + add_fingerprint(user) + /obj/item/shared_storage/attack_self(mob/living/carbon/user) - if(!iscarbon(user)) - return - if(src == user.l_hand || src == user.r_hand) - if(bag) - bag.loc = user - bag.attack_hand(user) - else - ..() + if(!bag || !iscarbon(user) || !user.is_in_hands(src)) + return ..() -/obj/item/shared_storage/attack_hand(mob/living/carbon/user) - if(!iscarbon(user)) - return - if(loc == user && user.back && user.back == src) - if(bag) - bag.loc = user - bag.attack_hand(user) - else - ..() + open_bag(user) + + +/obj/item/shared_storage/AltClick(mob/user) + if(!bag || !iscarbon(user) || !Adjacent(user)) + return ..() -/obj/item/shared_storage/MouseDrop(atom/over_object) - if(iscarbon(usr)) - var/mob/M = usr + open_bag(user) - if(!over_object) - return - if(istype(M.loc, /obj/mecha)) - return - if(!M.restrained() && !M.stat) - playsound(loc, "rustle", 50, 1, -5) +/obj/item/shared_storage/attack_hand(mob/living/carbon/user) + if(!iscarbon(user) || !bag || loc != user || !user.back || user.back != src) + return ..() - if(istype(over_object, /obj/screen/inventory/hand)) - if(!M.drop_item_ground(src)) - return - M.put_in_active_hand(src) - else if(bag) - bag.loc = usr - bag.attack_hand(usr) + open_bag(user) - add_fingerprint(M) //Book of Babel @@ -104,7 +92,7 @@ desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'." list_reagents = list("flightpotion" = 5) -/obj/item/reagent_containers/glass/bottle/potion/update_icon() +/obj/item/reagent_containers/glass/bottle/potion/update_icon_state() if(reagents.total_volume) icon_state = "potionflask" else @@ -243,18 +231,26 @@ var/sight_flags = SEE_MOBS var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + +/obj/item/wisp_lantern/update_icon_state() + if(!wisp) + icon_state = "lantern" + return + icon_state = "lantern[wisp.loc == src ? "" : "-blue"]" + + /obj/item/wisp_lantern/attack_self(mob/user) if(!wisp) to_chat(user, "The wisp has gone missing!") - icon_state = "lantern" + update_icon(UPDATE_ICON_STATE) return if(wisp.loc == src) RegisterSignal(user, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(update_user_sight)) to_chat(user, "You release the wisp. It begins to bob around your head.") - icon_state = "lantern" - spawn() wisp.orbit(user, 20) // spawn prevents endless loop in .orbit from blocking code execution here + update_icon(UPDATE_ICON_STATE) + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, orbit), user, 20) set_light(0) user.update_sight() @@ -272,7 +268,7 @@ user.update_sight() to_chat(user, "Your vision returns to normal.") - icon_state = "lantern-blue" + update_icon(UPDATE_ICON_STATE) SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") // returned /obj/item/wisp_lantern/Initialize(mapload) diff --git a/code/modules/mining/lavaland/world_anvil.dm b/code/modules/mining/lavaland/world_anvil.dm index 0912589648f..f4359696e61 100644 --- a/code/modules/mining/lavaland/world_anvil.dm +++ b/code/modules/mining/lavaland/world_anvil.dm @@ -29,13 +29,18 @@ GLOB.anvils -= src . = ..() -/obj/structure/world_anvil/update_icon() +/obj/structure/world_anvil/update_icon_state() icon_state = forge_charges > 0 ? "anvil_a" : "anvil" + + +/obj/structure/world_anvil/proc/update_state() + update_icon(UPDATE_ICON_STATE) if(forge_charges > 0) set_light(4,1,LIGHT_COLOR_ORANGE) else set_light(0) + /obj/structure/world_anvil/examine(mob/user) . = ..() . += "It currently has [forge_charges] forge[forge_charges != 1 ? "s" : ""] remaining." @@ -46,14 +51,14 @@ forge_charges = forge_charges + placed_ore.quality to_chat(user,"You place down the gibtonite on the World Anvil, and watch as the gibtonite melts into it. The World Anvil is now heated enough for [forge_charges] forge[forge_charges > 1 ? "s" : ""].") qdel(placed_ore) - update_icon() + update_state() return if(istype(I, /obj/item/gem/amber)) var/obj/item/gem/amber/gem = I forge_charges += 3 to_chat(user,"You place down the draconic amber on the World Anvil, and watch as amber melts into it. The World Anvil is now heated enough for [forge_charges] forge[forge_charges > 1 ? "s" : ""].") qdel(gem) - update_icon() + update_state() return if(forge_charges <= 0) to_chat(user,"The World Anvil is not hot enough to be usable!") @@ -83,5 +88,5 @@ forge_charges-- if(forge_charges <= 0) visible_message("The World Anvil cools down.") - update_icon() + update_state() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 083945f9ce3..ad454a44f90 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -153,15 +153,16 @@ sheet_per_ore = S SStgui.update_uis(src) -/obj/machinery/mineral/ore_redemption/power_change() - ..() - update_icon() +/obj/machinery/mineral/ore_redemption/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) if(inserted_id && !powered()) visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.") inserted_id.forceMove(get_turf(src)) inserted_id = null -/obj/machinery/mineral/ore_redemption/update_icon() +/obj/machinery/mineral/ore_redemption/update_icon_state() if(powered()) icon_state = initial(icon_state) else diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm index 39feeb38a61..550c3865f0a 100644 --- a/code/modules/mining/machine_unloading.dm +++ b/code/modules/mining/machine_unloading.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/machines/mining_machines.dmi' icon_state = "unloader" density = 1 - anchored = 1.0 + anchored = TRUE input_dir = WEST output_dir = EAST speed_process = 1 diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 74acb4926e6..83cf8214b7c 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -119,14 +119,15 @@ inserted_id.forceMove(get_turf(src)) inserted_id = null -/obj/machinery/mineral/equipment_vendor/power_change() - ..() - update_icon() +/obj/machinery/mineral/equipment_vendor/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) if(inserted_id && !powered()) visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.") remove_id() -/obj/machinery/mineral/equipment_vendor/update_icon() +/obj/machinery/mineral/equipment_vendor/update_icon_state() if(powered()) icon_state = initial(icon_state) else @@ -229,7 +230,7 @@ add_fingerprint(user) return if(panel_open) - if(istype(I, /obj/item/crowbar)) + if(I.tool_behaviour == TOOL_CROWBAR) remove_id() //Prevents deconstructing the ORM from deleting whatever ID was inside it. default_deconstruction_crowbar(user, I) return TRUE @@ -369,7 +370,7 @@ EQUIPMENT("Plushie", /obj/random/plushie, 750), EQUIPMENT("Dnd set", /obj/item/storage/box/characters, 500), EQUIPMENT("Dice set", /obj/item/storage/box/dice, 250), - EQUIPMENT("Cards", /obj/item/deck/cards, 150), + EQUIPMENT("Cards", /obj/item/deck/cards, 150), EQUIPMENT("Guitar", /obj/item/instrument/guitar, 750), EQUIPMENT("Synthesizer", /obj/item/instrument/piano_synth, 1500), EQUIPMENT("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index ca8016d5e59..266e00e97c4 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -16,25 +16,31 @@ var/refined_type = null //What this ore defaults to being refined into var/list/stack_overlays -/obj/item/stack/ore/update_icon() + +/obj/item/stack/ore/update_overlays() + . = ..() + var/difference = min(ORESTACK_OVERLAYS_MAX, amount) - (LAZYLEN(stack_overlays)+1) if(difference == 0) + . += stack_overlays return - else if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess. - cut_overlays() - if (LAZYLEN(stack_overlays)-difference <= 0) - stack_overlays = null; + + if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess. + if(LAZYLEN(stack_overlays)-difference <= 0) + stack_overlays = null else stack_overlays.len += difference + else if(difference > 0) //amount > stack_overlays, add some. - cut_overlays() for(var/i in 1 to difference) var/mutable_appearance/newore = mutable_appearance(icon, icon_state) newore.pixel_x = rand(-8,8) newore.pixel_y = rand(-8,8) LAZYADD(stack_overlays, newore) + if(stack_overlays) - add_overlay(stack_overlays) + . += stack_overlays + /obj/item/stack/ore/Initialize(mapload, new_amount , merge = TRUE) . = ..() @@ -269,7 +275,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ return if(wires && !primed) - if(istype(I, /obj/item/wirecutters) || istype(I, /obj/item/multitool) || istype(I, /obj/item/assembly/signaler)) + if(I.tool_behaviour == TOOL_WIRECUTTER || I.tool_behaviour == TOOL_MULTITOOL || istype(I, /obj/item/assembly/signaler)) wires.Interact(user) return @@ -277,7 +283,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ GibtoniteReaction(user) return if(primed) - if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) || istype(I, /obj/item/multitool) || istype(I, /obj/item/mecha_parts/mecha_equipment/mining_scanner)) + if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) || I.tool_behaviour == TOOL_MULTITOOL || istype(I, /obj/item/mecha_parts/mecha_equipment/mining_scanner)) primed = 0 user.visible_message("The chain reaction was stopped! ...The ore's quality looks diminished.", "You stopped the chain reaction. ...The ore's quality looks diminished.") icon_state = "Gibtonite ore" diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 056d86386c0..f33fc6814e0 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -22,7 +22,7 @@ S.remove_from_storage(O, src) //This will move the item to this item's contents CHECK_TICK to_chat(user, "You empty the satchel into the box.") - else if(istype(W, /obj/item/crowbar)) + else if(W.tool_behaviour == TOOL_CROWBAR) playsound(src, W.usesound, 50, 1) var/obj/item/crowbar/C = W if(do_after(user, 50 * C.toolspeed * gettoolspeedmod(user), target = src)) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index aa3a71e62d3..3e71a7c912a 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -95,11 +95,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) //starts ghosts off with all HUDs. show_me_the_hud(THOUGHTS_HUD) toggle_all_huds_on(body) + RegisterSignal(src, COMSIG_MOB_HUD_CREATED, PROC_REF(set_ghost_darkness_level)) //something something don't call this until we have a HUD ..() /mob/dead/observer/Destroy() toggle_all_huds_off() + UnregisterSignal(src, COMSIG_MOB_HUD_CREATED) if(ghostimage) GLOB.ghost_images -= ghostimage QDEL_NULL(ghostimage) @@ -114,6 +116,14 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) if(!invisibility) . += "It seems extremely obvious." +/mob/dead/observer/proc/set_ghost_darkness_level() + if(!client) + return + UnregisterSignal(src, COMSIG_MOB_HUD_CREATED) + lighting_alpha = client.prefs.ghost_darkness_level //Remembers ghost lighting pref + update_sight() + + // This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening // Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density // You might recognize these things as "fucking ridiculous to put in an appearance" @@ -605,19 +615,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp update_sight() to_chat(usr, "You [(ghostvision?"now":"no longer")] have ghost vision.") -/mob/dead/observer/verb/toggle_darkness() - set name = "Toggle Darkness" +/mob/dead/observer/verb/pick_darkness() + set name = "Pick Darkness" + set desc = "Choose how much darkness you want to see." set category = "Ghost" - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - + var/list/ghost_darkness_levels = list("Strong Darkness" = LIGHTING_PLANE_ALPHA_VISIBLE, + "Darkness" = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE, + "Light Darkness" = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE, + "No Darkness" = LIGHTING_PLANE_ALPHA_INVISIBLE) + var/desired_dark = tgui_input_list(usr, "Choose how much darkness you want to see", "Pick darkness", ghost_darkness_levels) + if(isnull(desired_dark)) + return + if(!client) + return + client.prefs.ghost_darkness_level = ghost_darkness_levels[desired_dark] + client.prefs.save_preferences(src) + lighting_alpha = client.prefs.ghost_darkness_level update_sight() /mob/dead/observer/update_sight() diff --git a/code/modules/mob/holder_pet_carrier.dm b/code/modules/mob/holder_pet_carrier.dm index 2a3be99a13e..25a2bc9199d 100644 --- a/code/modules/mob/holder_pet_carrier.dm +++ b/code/modules/mob/holder_pet_carrier.dm @@ -30,7 +30,7 @@ . = ..() if(!color_skin) color_skin = pick(possible_skins) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/pet_carrier/Destroy() @@ -83,19 +83,16 @@ return FALSE target.forceMove(src) - name += " ([target.name])" - if(target.desc) - desc += "\n\nВнутри [target.name]\n" - desc += target.desc contains_pet = TRUE + update_appearance(UPDATE_OVERLAYS|UPDATE_NAME|UPDATE_DESC) to_chat(user, span_notice("Вы поместили [target.name] в [name].")) to_chat(target, span_notice("[user.name] поместил[genderize_ru(user.gender,"","а","о","и")] вас в [name].")) - update_icon() return TRUE /obj/item/pet_carrier/proc/try_free_content(atom/new_location, mob/user) + add_fingerprint(user) if(!opened) if(user) to_chat(user, span_warning("Ваша переноска закрыта! Содержимое невозможно выгрузить!")) @@ -104,27 +101,41 @@ /obj/item/pet_carrier/proc/free_content(atom/new_location) - if(istype(loc,/turf) || length(contents)) - for(var/mob/living/L in contents) - var/atom/movable/mob_container - mob_container = L - mob_container.forceMove(new_location ? new_location : get_turf(src)) + if(isturf(loc) || length(contents)) + var/atom/drop_loc = new_location ? new_location : get_turf(src) + for(var/mob/living/animal in contents) + animal.forceMove(drop_loc) contains_pet = FALSE - name = initial(name) - desc = initial(desc) - update_icon() - L.resting = FALSE + update_appearance(UPDATE_OVERLAYS|UPDATE_NAME|UPDATE_DESC) + animal.resting = FALSE return TRUE return FALSE /obj/item/pet_carrier/proc/change_state() opened = !opened - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/pet_carrier/update_icon() - overlays.Cut() +/obj/item/pet_carrier/update_name(updates = ALL) + . = ..() + name = initial(name) + var/mob/living/animal = locate() in src + if(animal) + name += " ([animal.name])" + + +/obj/item/pet_carrier/update_desc(updates = ALL) + . = ..() + desc = initial(desc) + var/mob/living/animal = locate() in src + if(animal) + desc += "\n\nВнутри [animal.name]\n" + desc += animal.desc + + +/obj/item/pet_carrier/update_overlays() + . = ..() if(contains_pet) var/mob/living/M for(var/mob/living/temp_M in contents) @@ -133,15 +144,13 @@ var/image/I = image(M.icon, icon_state = M.icon_state) I.color = opened ? contains_pet_color_open : contains_pet_color_close I.pixel_y = M.mob_size <= MOB_SIZE_TINY ? 6 : 3 - overlays += I + . += I if(!opened) - var/image/I = image(icon, icon_state = "[icon_state]_door") - overlays += I + . += image(icon, icon_state = "[icon_state]_door") if(color_skin) - var/image/I = image(icon, icon_state = "[icon_state]_[color_skin]") - overlays += I + . += image(icon, icon_state = "[icon_state]_[color_skin]") /obj/item/pet_carrier/emp_act(intensity) @@ -158,7 +167,7 @@ var/breakout_time = 60 SECONDS var/breakout_time_open = 5 SECONDS - to_chat(L, span_warning("Вы начали вылезать из переноски (это займет [breakout_time_open] секунд, не двигайтесь).")) + to_chat(L, span_warning("Вы начали вылезать из переноски (это займет [breakout_time_open/10] секунд, не двигайтесь).")) var/atom/target_atom = src if(ishuman(loc)) @@ -175,7 +184,7 @@ visible_message(span_warning("[L.name] вылез из переноски.")) return - to_chat(L, span_warning("Вы начали ломиться в закрытую дверцу переноски и пытаетесь её выбить или открыть (это займет [breakout_time] секунд, не двигайтесь).")) + to_chat(L, span_warning("Вы начали ломиться в закрытую дверцу переноски и пытаетесь её выбить или открыть (это займет [breakout_time/10] секунд, не двигайтесь).")) for(var/mob/O in viewers(usr.loc)) O.show_message(span_danger("[name] начинает трястись!"), 1) @@ -220,49 +229,37 @@ try_free_content(null, usr) -/obj/item/pet_carrier/MouseDrop(obj/over_object) - if(ishuman(usr)) - var/mob/M = usr - if(istype(M.loc, /obj/mecha) || M.incapacitated(FALSE, TRUE, TRUE)) // Stops inventory actions in a mech as well as while being incapacitated - return +/obj/item/pet_carrier/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + if(!ishuman(usr)) + return FALSE - if(over_object == M && Adjacent(M)) // this must come before the screen objects only block - try_free_content(null, M) - return + var/mob/living/carbon/human/user = usr + + // Stops inventory actions in a mech, while ventcrawling and while being incapacitated + if(ismecha(user.loc) || is_ventcrawling(user) || user.incapacitated(FALSE, TRUE, TRUE)) + return FALSE + + if(over_object == user && user.Adjacent(src)) // this must come before the screen objects only block + try_free_content(user = user) + return FALSE + + if(opened && (istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor) \ + && length(contents) && loc == user && !user.incapacitated() && user.Adjacent(over_object))) + + if(alert(user, "Вытащить питомца из [name] на [over_object.name]?", "Подтверждение", "Да", "Нет") != "Да") + return FALSE + + if(!opened || !user || !over_object || user.incapacitated() || loc != user || !user.Adjacent(over_object)) + return FALSE + + user.face_atom(over_object) + user.visible_message( + span_notice("[user] вытащил питомца из [name] на [over_object.name]."), + span_notice("Вы вытащили питомца из [name] на [over_object.name]."), + ) + try_free_content(get_turf(over_object), user) + return FALSE + + return ..() - if((istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor)) \ - && length(contents) && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && over_object.Adjacent(usr)) - var/turf/T = get_turf(over_object) - if(istype(over_object, /turf/simulated/floor)) - if(get_turf(usr) != T) - return // Can only empty containers onto the floor under you - if("Да" != alert(usr,"Вытащить питомца из [name] на [T.name]?","Подтверждение","Да","Нет")) - return - if(!(usr && over_object && contents.len && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && get_turf(usr) == T)) - return // Something happened while the player was thinking - - usr.face_atom(over_object) - usr.visible_message(span_notice("[usr] вытащил питомца из [name] на [over_object.name]."), - span_notice("Вы вытащили питомца из [name] на [over_object.name].")) - - try_free_content(T, usr) - return TRUE - - if(!(istype(over_object, /obj/screen))) - return ..() - if(!(loc == usr) || (loc && loc.loc == usr)) - return - playsound(loc, "rustle", 50, TRUE, -5) - if(!(M.restrained()) && !(M.stat)) - switch(over_object.name) - if("r_hand") - if(!M.drop_item_ground(src)) - return - M.put_in_r_hand(src, ignore_anim = FALSE) - if("l_hand") - if(!M.drop_item_ground(src)) - return - M.put_in_l_hand(src, ignore_anim = FALSE) - add_fingerprint(usr) - return diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index a930408f626..7ee5a2169cc 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -1,35 +1,64 @@ #define SCRAMBLE_CACHE_LEN 20 - /* + When creating new 2 letter language keys, use the following naming scheme: + For languages with a compound name, use the first letter of each word whenever possible, for example: Sol Common = "sc". + For racial languages, whenever possible, use the first two letters of the race name or use euphony for associative rows, for example: Vulpkanin = "vu" or Canilunzt = "ca". + Also don't forget about code/__DEFINES/language.dm + + Datum based languages. Easily editable and modular. Busy letters for language: - a b d f g j k o q v x y - aa as bo db fa fm fn fs vu + un ta vu sk vo di tr ki sl gr dr ni + xm db wr xh ts ch hs sh ab gl bo bi dt + sw gc sc tb gt cl nr mo ne st fa wo + + + Busy letters by radio(eng): + c e h i l m n p r s t u w x + - Busy symbols for language: - 0 1 2 3 4 5 6 7 8 9 - % ? ^ + Busy letters by radio(rus): + б г д е ё з к р с т у ц ч ш ы ь я э - CAUTION! The key must not repeat the key of the radio channel - and must not contain prohibited characters + + Busy symbols by radio: + ~ , $ _ - + * 1 2 3 + + CAUTION! The key must not repeat the key of the radio channel + and must not contain prohibited characters! */ /datum/language - var/name = "an unknown language" // Fluff name of language if any. - var/desc = "A language." // Short description for 'Check Languages'. - var/speech_verb = "says" // 'says', 'hisses', 'farts'. - var/ask_verb = "asks" // Used when sentence ends in a ? - var/list/exclaim_verbs = list("exclaims") // Used when sentence ends in a ! - var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. - var/colour = "body" // CSS style to use for strings in this language. - var/key = "x" // Character used to speak in language eg. :o for Unathi. - var/flags = 0 // Various language flags. - var/native // If set, non-native speakers will have trouble speaking. - var/list/syllables // Used when scrambling text for a non-speaker. - var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. - var/follow = 0 // Applies to HIVEMIND languages - should a follow link be included for dead mobs? - var/english_names = 0 // Do we want English names by default, no matter what? + /// Fluff name of language if any. + var/name = "an unknown language" + /// Short description for 'Check Languages'. + var/desc = "A language." + /// 'says', 'hisses', 'farts'. + var/speech_verb = "says" + /// Used when sentence ends in a '?'. + var/ask_verb = "asks" + /// Used when sentence ends in a '!'. + var/list/exclaim_verbs = list("exclaims") + /// Optional. When not specified speech_verb + quietly/softly is used instead. + var/whisper_verb + /// CSS style to use for strings in this language. + var/colour = "body" + /// Character used to speak in language eg. '"un"' for Unathi. + var/key = "key" + /// Various language flags. + var/flags = 0 + /// If set, non-native speakers will have trouble speaking. + var/native + /// Used when scrambling text for a non-speaker. + var/list/syllables + /// Likelihood of getting a space in the random scramble string. + var/list/space_chance = 55 + /// Applies to HIVEMIND languages - should a follow link be included for dead mobs? + var/follow = FALSE + /// Do we want English names by default, no matter what? + var/english_names = FALSE + /// List that saves sentences spoken in this language, so as not to generate different scrambles of syllables for the same sentences. var/list/scramble_cache = list() /// Do we want to override the word-join character for scrambled text? If null, defaults to " " or ". " var/join_override @@ -65,20 +94,20 @@ var/input_size = length(input) var/scrambled_text = "" - var/capitalize = 1 + var/capitalize = TRUE while(length(scrambled_text) < input_size) var/next = pick(syllables) if(capitalize) next = capitalize(next) - capitalize = 0 + capitalize = FALSE scrambled_text += next var/chance = rand(100) if(join_override) scrambled_text += join_override else if(chance <= 5) scrambled_text += ". " - capitalize = 1 + capitalize = TRUE else if(chance > 5 && chance <= space_chance) scrambled_text += " " @@ -116,7 +145,7 @@ if(!speaker_mask) speaker_mask = speaker.name - var/msg = "[name], [speaker_mask] [get_spoken_verb(message)], [format_message(message)]" + var/msg = "[name], [speaker_mask] [genderize_decode(speaker, get_spoken_verb(message))], [format_message(message)]" for(var/mob/player in GLOB.player_list) if(istype(player,/mob/dead) && follow) @@ -145,8 +174,7 @@ /datum/language/noise name = "Noise" desc = "Noises" - key = "" - flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER + flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER|NOBABEL /datum/language/noise/format_message(message) return "[message]" @@ -165,7 +193,7 @@ ask_verb = "hisses" exclaim_verbs = list("roars") colour = "soghun" - key = "o" + key = "un" flags = RESTRICTED syllables = list("za","az","ze","ez","zi","iz","zo","oz","zu","uz","zs","sz","ha","ah","he","eh","hi","ih", \ "ho","oh","hu","uh","hs","sh","la","al","le","el","li","il","lo","ol","lu","ul","ls","sl","ka","ak","ke","ek", \ @@ -186,7 +214,7 @@ ask_verb = "mrowls" exclaim_verbs = list("yowls") colour = "tajaran" - key = "j" + key = "ta" flags = RESTRICTED syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ @@ -198,7 +226,7 @@ var/list/ru_name_syllables = list("кан","тай","кир","раи","кии","мир","кра","тэк","нал","вар","хар","марр","ран","дарр", \ "мирк","ири","дин","манг","рик","зар","раз","кель","шера","тар","кей","ар","но","маи","зир","кер","нир","ра",\ "ми","рир","сей","эка","гир","ари","нэй","нре","ак","таир","эрай","жин","мра","зур","рин","сар","кин","рид","эра","ри","эна") - var/apostrophe = "’" + var/apostrophe = "'" var/new_name = "" var/full_name = "" @@ -226,7 +254,7 @@ ask_verb = "rurs" exclaim_verbs = list("barks") colour = "vulpkanin" - key = "7" + key = "vu" flags = RESTRICTED syllables = list("rur","ya","cen","rawr","bar","kuk","tek","qat","uk","wu","vuh","tah","tch","schz","auch", \ "ist","ein","entch","zwichs","tut","mir","wo","bis","es","vor","nic","gro","lll","enem","zandt","tzch","noch", \ @@ -240,7 +268,7 @@ ask_verb = "warbles" exclaim_verbs = list("warbles") colour = "skrell" - key = "k" + key = "sk" flags = RESTRICTED syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") @@ -251,7 +279,7 @@ ask_verb = "creels" exclaim_verbs = list("loudly skrees") colour = "vox" - key = "v" + key = "vo" flags = RESTRICTED | WHITELISTED syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","yi","chi","cha","kah", \ "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") @@ -273,7 +301,7 @@ ask_verb = "creaks" exclaim_verbs = list("rustles") colour = "diona" - key = "q" + key = "di" flags = RESTRICTED syllables = list("hs","zt","kr","st","sh") @@ -289,7 +317,7 @@ ask_verb = "queries" exclaim_verbs = list("exclaims") colour = "trinary" - key = "5" + key = "tr" flags = RESTRICTED | WHITELISTED syllables = list("0+2+0+1+1","0+1+2+2+2","1+0+1+0+0","1+0+2+1+0","2+1+0+1+2","0+2+0+1+1","2+1+2+0+0","1+0+0+2","2+0+0+1","0+0+0+2","0+0+1+2","0+0+1+2","0+0+0","1+2+0","1+2+1","2+0+1","2+2+0","1+0","1+1","0") @@ -308,7 +336,7 @@ ask_verb = "rubs their antennae together" exclaim_verbs = list("rubs their antennae together") colour = "kidan" - key = "4" + key = "ki" flags = RESTRICTED | WHITELISTED syllables = list("click","clack") @@ -328,7 +356,7 @@ ask_verb = "bubbles and pops" exclaim_verbs = list("bubbles and pops") colour = "slime" - key = "f" + key = "sl" flags = RESTRICTED | WHITELISTED syllables = list("blob","plop","pop","bop","boop") @@ -339,7 +367,7 @@ ask_verb = "inquires" exclaim_verbs = list("imparts") colour = "abductor" - key = "^" + key = "gr" flags = RESTRICTED | HIVEMIND follow = TRUE @@ -374,7 +402,7 @@ ask_verb = "hums" exclaim_verbs = list("rumbles") colour = "drask" - key = "%" + key = "dr" flags = RESTRICTED | WHITELISTED syllables = list("hoorb","vrrm","ooorm","urrrum","ooum","ee","ffm","hhh","mn","ongg") @@ -391,7 +419,7 @@ ask_verb = "flaps" exclaim_verbs = list("chatters") colour = "moth" - key = "#" + key = "ni" flags = RESTRICTED | WHITELISTED join_override = "-" syllables = list("år", "i", "går", "sek", "mo", "ff", "ok", "gj", "ø", "gå", "la", "le", @@ -412,10 +440,10 @@ speech_verb = "says" exclaim_verbs = list("exclaims", "shouts", "yells") whisper_verb = "whispers" - key = "9" + key = "gc" flags = RESTRICTED syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") - english_names = 1 + english_names = TRUE /datum/language/human name = "Sol Common" @@ -424,10 +452,10 @@ exclaim_verbs = list("exclaims", "shouts", "yells") whisper_verb = "whispers" colour = "solcom" - key = "1" + key = "sc" flags = RESTRICTED syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") - english_names = 1 + english_names = TRUE // Galactic common languages (systemwide accepted standards). /datum/language/trader @@ -435,7 +463,7 @@ desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." speech_verb = "enunciates" colour = "say_quote" - key = "2" + key = "tb" space_chance = 100 syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", @@ -453,7 +481,7 @@ ask_verb = "gnarls" exclaim_verbs = list("snarls") colour = "gutter" - key = "3" + key = "gt" syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh","gra") /datum/language/clown @@ -463,7 +491,7 @@ ask_verb = "honks" exclaim_verbs = list("toots", "wubs", "honks") colour = "clown" - key = "0" + key = "cl" syllables = list ("honk","squeak","bonk","toot","narf","zub","wee","wub","norf") /datum/language/com_srus @@ -473,9 +501,9 @@ whisper_verb = "mutters" exclaim_verbs = list("exaggerates") colour = "com_srus" - key = "?" + key = "nr" space_chance = 65 - english_names = 1 + english_names = TRUE syllables = list("dyen","bar","bota","vyek","tvo","slov","slav","syen","doup","vah","laz","gloz","yet", "nyet","da","sky","glav","glaz","netz","doomat","zat","moch","boz", "comy","vrad","vrade","tay","bli","ay","nov","livn","tolv","glaz","gliz", @@ -493,7 +521,7 @@ ask_verb = "chitters" exclaim_verbs = list("buzzes") colour = "alien" - key = "y" + key = "wr" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -513,18 +541,18 @@ speech_verb = "hisses" ask_verb = "hisses" exclaim_verbs = list("hisses") - key = "6" + key = "xm" flags = RESTRICTED syllables = list("sss","sSs","SSS") /datum/language/xenos - name = "Hivemind" + name = "Xenomorph Hivemind" desc = "Xenomorphs have the strange ability to commune over a psychic hivemind." speech_verb = "hisses" ask_verb = "hisses" exclaim_verbs = list("hisses") colour = "alien" - key = "a" + key = "xh" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -535,17 +563,17 @@ ask_verb = "chitters" exclaim_verbs = list("chitters") colour = "terrorspider" - key = "as" + key = "ts" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE /datum/language/ling - name = "Changeling" + name = "Changeling Hivemind" desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." speech_verb = "says" colour = "changeling" - key = "g" + key = "ch" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -558,11 +586,11 @@ ..(speaker,message) /datum/language/eventling - name = "Infiltrated changeling" + name = "Infiltrated Changeling Hivemind" desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." speech_verb = "says" colour = "changeling" - key = "gi" + key = "hs" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -579,7 +607,7 @@ desc = "Shadowlings and their thralls are capable of communicating over a psychic hivemind." speech_verb = "says" colour = "shadowling" - key = "8" + key = "sh" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -598,7 +626,7 @@ ask_verb = "gibbers" exclaim_verbs = list("gibbers") colour = "abductor" - key = "aa" //doesn't matter, this is their default and only language + key = "ab" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE @@ -613,15 +641,21 @@ return TRUE return FALSE -/datum/language/abductor/golem +/datum/language/golem name = "Golem Mindlink" desc = "Communicate with other alien alloy golems through a psychic link." + speech_verb = "gibbers" + ask_verb = "gibbers" + exclaim_verbs = list("gibbers") + colour = "abductor" + key = "gl" + flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE -/datum/language/abductor/golem/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker) - return TRUE +/datum/language/golem/broadcast(mob/living/speaker, message, speaker_mask) + ..(speaker,message,speaker.real_name) -/datum/language/corticalborer +/datum/language/borer name = "Cortical Link" desc = "Cortical borers possess a strange link between their tiny minds." speech_verb = "sings" @@ -632,7 +666,7 @@ flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE -/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask) +/datum/language/borer/broadcast(mob/living/speaker, message, speaker_mask) var/mob/living/simple_animal/borer/B if(iscarbon(speaker)) @@ -652,7 +686,7 @@ speech_verb = "states" ask_verb = "queries" exclaim_verbs = list("declares") - key = "b" + key = "bi" flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE var/drone_only @@ -699,7 +733,7 @@ ask_verb = "transmits" exclaim_verbs = list("transmits") colour = "say_quote" - key = "d" + key = "dt" flags = RESTRICTED | HIVEMIND | NOBABEL drone_only = TRUE follow = TRUE @@ -722,35 +756,44 @@ ask_verb = "tones" exclaim_verbs = list("tones") colour = "say_quote" - key = "as"//Zwarmer...Or Zerg! + key = "sw"//Zwarmer...Or Zerg! flags = RESTRICTED | HIVEMIND | NOBABEL follow = TRUE -// Language handling. -/mob/proc/add_language(language) - var/datum/language/new_language = GLOB.all_languages[language] +/datum/language/human/monkey + name = "Chimpanzee" + desc = "Ook ook ook." + speech_verb = "chimpers" + ask_verb = "chimpers" + exclaim_verbs = list("screeches") + key = "mo" - if(!istype(new_language) || (new_language in languages)) - return FALSE +/datum/language/skrell/monkey + name = "Neara" + desc = "Squik squik squik." + key = "ne" - languages |= new_language - return TRUE +/datum/language/unathi/monkey + name = "Stok" + desc = "Hiss hiss hiss." + key = "st" -/mob/proc/remove_language(rem_language) - var/datum/language/L = GLOB.all_languages[rem_language] - . = (L in languages) - languages.Remove(L) +/datum/language/tajaran/monkey + name = "Farwa" + desc = "Meow meow meow." + key = "fa" + +/datum/language/vulpkanin/monkey + name = "Wolpin" + desc = "Bark bark bark." + key = "wo" -/mob/living/remove_language(rem_language) - var/datum/language/L = GLOB.all_languages[rem_language] - if(default_language == L) - default_language = null - return ..() // Can we speak this language, as opposed to just understanding it? /mob/proc/can_speak_language(datum/language/speaking) return universal_speak || (speaking && speaking.flags & INNATE) || (speaking in languages) + //TBD /mob/proc/check_lang_data() . = "" @@ -759,6 +802,7 @@ if(!(L.flags & NONGLOBAL)) . += "[L.name] (:[L.key])
    [L.desc]

    " + /mob/living/check_lang_data() . = "" @@ -770,7 +814,8 @@ if(L == default_language) . += "[L.name] (:[L.key]) - default - reset
    [L.desc]

    " else - . += "[L.name] (:[L.key]) - set default
    [L.desc]

    " + . += "[L.name] (:[L.key]) - set default
    [L.desc]

    " + /mob/verb/check_languages() set name = "Check Known Languages" @@ -781,6 +826,7 @@ popup.set_content(check_lang_data()) popup.open() + /mob/living/Topic(href, href_list) . = ..() if(.) @@ -795,33 +841,43 @@ check_languages() return TRUE -/datum/language/human/monkey - name = "Chimpanzee" - desc = "Ook ook ook." - speech_verb = "chimpers" - ask_verb = "chimpers" - exclaim_verbs = list("screeches") - key = "fm" -/datum/language/skrell/monkey - name = "Neara" - desc = "Squik squik squik." - key = "fn" +// Language handling. +/mob/proc/add_language(language_name) + var/datum/language/new_language = GLOB.all_languages[language_name] + if(new_language in languages) + return FALSE + if(!istype(new_language)) + new_language = GLOB.all_languages[convert_lang_key_to_name(language_name)] + if(!istype(new_language)) + return FALSE -/datum/language/unathi/monkey - name = "Stok" - desc = "Hiss hiss hiss." - key = "fs" + languages |= new_language + return TRUE -/datum/language/tajaran/monkey - name = "Farwa" - desc = "Meow meow meow." - key = "fa" -/datum/language/vulpkanin/monkey - name = "Wolpin" - desc = "Bark bark bark." - key = "vu" +/mob/proc/remove_language(language_name) + var/datum/language/rem_language = GLOB.all_languages[language_name] + if(!istype(rem_language)) + rem_language = GLOB.all_languages[convert_lang_key_to_name(language_name)] + if(!istype(rem_language)) + return FALSE + + . = (rem_language in languages) + languages.Remove(rem_language) + + +/mob/living/remove_language(language_name) + var/datum/language/rem_language = GLOB.all_languages[language_name] + if(!istype(rem_language)) + rem_language = GLOB.all_languages[convert_lang_key_to_name(language_name)] + if(!istype(rem_language)) + return FALSE + + if(default_language == rem_language) + default_language = null + return ..() + /mob/proc/grant_all_babel_languages() for(var/la in GLOB.all_languages) @@ -830,8 +886,19 @@ continue languages |= new_language + /mob/proc/grant_all_languages() for(var/la in GLOB.all_languages) add_language(la) + +/proc/convert_lang_key_to_name(language_key) + var/static/list/language_keys_and_names = list() + if(!language_keys_and_names.len) + for(var/language_name in GLOB.all_languages) + var/datum/language/language = GLOB.all_languages[language_name] + language_keys_and_names[language.key] = language_name + return language_keys_and_names[language_key] + + #undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 102026c0f0b..ee98ba30d46 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -89,7 +89,7 @@ /mob/living/carbon/alien/get_default_language() if(default_language) return default_language - return GLOB.all_languages["Xenomorph"] + return GLOB.all_languages[LANGUAGE_XENOS] /mob/living/carbon/alien/say_quote(var/message, var/datum/language/speaking = null) var/verb = "hisses" diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm index e809f5e7fdb..e5610a983a1 100644 --- a/code/modules/mob/living/carbon/alien/death.dm +++ b/code/modules/mob/living/carbon/alien/death.dm @@ -4,7 +4,7 @@ death(1) var/atom/movable/overlay/animation = null notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT @@ -27,7 +27,7 @@ if(!death(TRUE) && stat != DEAD) return FALSE notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT dust_animation() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 6517c1543da..209dec3988c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -20,8 +20,8 @@ if(name == "alien") name = text("alien ([rand(1, 1000)])") real_name = name - add_language("Xenomorph") - add_language("Hivemind") + add_language(LANGUAGE_XENOS) + add_language(LANGUAGE_HIVE_XENOS) ..() AddSpell(new /obj/effect/proc_holder/spell/alien_spell/regurgitate) AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 715d8f9efe3..a7b92f1a0ab 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -25,8 +25,8 @@ name = "alien larva ([rand(1, 1000)])" real_name = name regenerate_icons() - add_language("Xenomorph") - add_language("Hivemind") + add_language(LANGUAGE_XENOS) + add_language(LANGUAGE_HIVE_XENOS) hide_action = new hide_action.Grant(src) ..() diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 5e6a36acf48..e468fff446e 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -6,9 +6,8 @@ w_class = WEIGHT_CLASS_NORMAL origin_tech = "biotech=3" origin_tech = "biotech=2;programming=3;engineering=2" - //Revised. Brainmob is now contained directly within object of transfer. MMI in this case. - var/alien = 0 + var/alien = FALSE var/clock = 0 var/syndiemmi = 0 //Whether or not this is a Syndicate MMI var/syndicate = 0 //Used to replace standart modules with the syndicate modules in module pick proc @@ -29,7 +28,28 @@ /// Time at which the ghost belonging to the mind in the mmi can be pinged again to be borged var/next_possible_ghost_ping -/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + +/obj/item/mmi/update_icon_state() + if(held_brain) + icon = held_brain.mmi_icon + icon_state = held_brain.mmi_icon_state + else + icon = initial(icon) + icon_state = initial(icon_state) + + +/obj/item/mmi/update_name(updates = ALL) + . = ..() + if(brainmob) + if(alien) + name = "Man-Machine Interface: Alien - [brainmob.real_name]" + else + name = "Man-Machine Interface: [brainmob.real_name]" + else + name = initial(name) + + +/obj/item/mmi/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/organ/internal/brain/crystal)) to_chat(user, " This brain is too malformed to be able to use with the [src].") return @@ -57,19 +77,9 @@ GLOB.dead_mob_list -= brainmob//Update dem lists GLOB.alive_mob_list += brainmob brainmob.update_sight() - held_brain = B - if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff - name = "Man-Machine Interface: Alien - [brainmob.real_name]" - icon = 'icons/mob/alien.dmi' - become_occupied("AlienMMI") - alien = 1 - else - name = "Man-Machine Interface: [brainmob.real_name]" - icon = B.mmi_icon - become_occupied("[B.mmi_icon_state]") - alien = 0 - + alien = istype(O, /obj/item/organ/internal/brain/xeno) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) if(radio_action) radio_action.UpdateButtonIcon() SSblackbox.record_feedback("amount", "mmis_filled", 1) @@ -121,17 +131,15 @@ "You uninstall the radio from [src].") -/obj/item/mmi/attack_self(mob/user as mob) +/obj/item/mmi/attack_self(mob/user) if(!brainmob) to_chat(user, "You upend the MMI, but there's nothing in it.") else to_chat(user, "You unlock and upend the MMI, spilling the brain onto the floor.") dropbrain(get_turf(user)) - icon = 'icons/obj/assemblies.dmi' - icon_state = "mmi_empty" - name = "Man-Machine Interface" -/obj/item/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people. + +/obj/item/mmi/proc/transfer_identity(mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people. brainmob = new(src) brainmob.name = H.real_name brainmob.real_name = H.real_name @@ -147,10 +155,9 @@ held_brain = new brain_path(src) // Slime people will keep their slimy brains this way held_brain.dna = brainmob.dna.Clone() held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]" - - name = "Man-Machine Interface: [brainmob.real_name]" - become_occupied("mmi_full") brainmob.update_sight() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + //I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the //problem i was having with alien/nonalien brain drops. @@ -171,11 +178,8 @@ brainmob = null//Set mmi brainmob var to null held_brain.forceMove(dropspot) held_brain = null + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) -/obj/item/mmi/proc/become_occupied(var/new_icon) - icon_state = new_icon - if(radio) - radio_action.ApplyIcon() /obj/item/mmi/examine(mob/user) . = ..() @@ -200,7 +204,7 @@ procname = "ui_interact" var/obj/item/mmi = null -/datum/action/generic/configure_mmi_radio/New(var/Target, var/obj/item/mmi/M) +/datum/action/generic/configure_mmi_radio/New(Target, obj/item/mmi/M) . = ..() mmi = M diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 6a1f291fa3c..bbfc5d718fc 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -9,7 +9,7 @@ /mob/living/carbon/brain/New() ..() - add_language("Galactic Common") + add_language(LANGUAGE_GALACTIC_COMMON) /mob/living/carbon/brain/Destroy() diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index a730a47da8a..dbef53fce91 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -13,7 +13,7 @@ if(!death(TRUE) && stat != DEAD) return FALSE notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm index 2513a6882e5..53a21f1886d 100644 --- a/code/modules/mob/living/carbon/brain/robotic_brain.dm +++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm @@ -48,6 +48,22 @@ imprinted_master = null return ..() + +/obj/item/mmi/robotic_brain/update_icon_state() + if(brainmob?.key) + icon_state = occupied_icon + return + icon_state = searching ? searching_icon : blank_icon + + +/obj/item/mmi/robotic_brain/update_name(updates = ALL) + . = ..() + if(brainmob) + name = "[src] ([brainmob.name])" + else + name = initial(name) + + /obj/item/mmi/robotic_brain/attack_self(mob/user) if(isgolem(user)) to_chat(user, "Your golem fingers are too large to press the switch on [src].") @@ -59,24 +75,28 @@ if(brainmob && !brainmob.key && !searching) //Start the process of searching for a new user. to_chat(user, "You carefully locate the manual activation switch and start [src]'s boot process.") - icon_state = searching_icon - ghost_volunteers.Cut() searching = TRUE + update_icon(UPDATE_ICON_STATE) + ghost_volunteers.Cut() request_player() - spawn(600) - if(ghost_volunteers.len) - var/mob/dead/observer/O - while(!istype(O) && ghost_volunteers.len) - O = pick_n_take(ghost_volunteers) - if(istype(O) && check_observer(O)) - transfer_personality(O) - reset_search() + addtimer(CALLBACK(src, PROC_REF(check_volunteers)), 60 SECONDS) else silenced = !silenced to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].") if(brainmob && brainmob.key) to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].") + +/obj/item/mmi/robotic_brain/proc/check_volunteers() + if(length(ghost_volunteers)) + var/mob/dead/observer/observer + while(!istype(observer) && length(ghost_volunteers)) + observer = pick_n_take(ghost_volunteers) + if(istype(observer) && check_observer(observer)) + transfer_personality(observer) + reset_search() + + /obj/item/mmi/robotic_brain/proc/request_player() for(var/mob/dead/observer/O in GLOB.player_list) if(check_observer(O)) @@ -110,7 +130,6 @@ log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src) /obj/item/mmi/robotic_brain/transfer_identity(mob/living/carbon/H) - name = "[src] ([H])" if(isnull(brainmob.dna)) brainmob.dna = H.dna.Clone() brainmob.name = brainmob.dna.real_name @@ -122,9 +141,9 @@ if(H.mind) H.mind.transfer_to(brainmob) to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [ejected_flavor_text].") - become_occupied(occupied_icon) - if(radio) - radio_action.ApplyIcon() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + if(radio_action) + radio_action.UpdateButtonIcon() /obj/item/mmi/robotic_brain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/target) @@ -137,26 +156,24 @@ searching = FALSE brainmob.revive() /// in case of death brainmob.key = candidate.key - name = "[src] ([brainmob.name])" - to_chat(brainmob, "You are a [src], brought into existence on [station_name()].") to_chat(brainmob, "As a non-sentient synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure or mech.") to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.") brainmob.mind.assigned_role = "Positronic Brain" - visible_message("[src] chimes quietly.") - become_occupied(occupied_icon) + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) + if(radio_action) + radio_action.UpdateButtonIcon() /obj/item/mmi/robotic_brain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. if(brainmob && brainmob.key) return - searching = FALSE - icon_state = blank_icon - + update_icon(UPDATE_ICON_STATE) visible_message("[src] buzzes quietly as the light fades out. Perhaps you could try again?") + /obj/item/mmi/robotic_brain/Topic(href, href_list) if("signup" in href_list) var/mob/dead/observer/O = locate(href_list["signup"]) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 48432a075e1..3f602673348 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -399,11 +399,6 @@ mind.disrupt_spells(0) - -/mob/living/carbon/proc/tintcheck() - return 0 - - /mob/living/carbon/proc/create_dna() if(!dna) dna = new() @@ -688,7 +683,7 @@ to_chat(src, "Вы [slipVerb] на [description]!") playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3) // Something something don't run with scissors - moving_diagonally = 0 //If this was part of diagonal move slipping will stop it. + moving_diagonally = NONE //If this was part of diagonal move slipping will stop it. Weaken(weaken) return TRUE @@ -807,8 +802,13 @@ so that different stomachs can handle things in different ways VB*/ clear_fullscreen("tint", 0) -/mob/living/carbon/proc/get_total_tint() +/// Checks eye covering items for visually impairing tinting, such as welding masks. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = casual blindness. +/mob/living/proc/get_total_tint() . = 0 + + +/mob/living/carbon/get_total_tint() + . = ..() if(istype(head, /obj/item/clothing/head)) var/obj/item/clothing/head/HT = head . += HT.tint diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 01a93b1eeeb..fe87453ae78 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -3,7 +3,7 @@ return FALSE var/atom/movable/overlay/animation = null notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT if(!ismachineperson(src)) @@ -51,7 +51,7 @@ if(!death(TRUE) && stat != DEAD) return FALSE notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT dust_animation() @@ -76,7 +76,7 @@ return FALSE var/atom/movable/overlay/animation = null notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 1d8a1b58801..a8269370b7d 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -430,39 +430,39 @@ //Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records. -/proc/hasHUD(mob/M, hudtype) +/proc/hasHUD(mob/M, hud_exam) if(istype(M, /mob/living/carbon/human)) - var/have_hudtypes = list() + var/have_hud_exam = 0 var/mob/living/carbon/human/H = M if(istype(H.glasses, /obj/item/clothing/glasses/hud)) var/obj/item/clothing/glasses/hud/hudglasses = H.glasses if(hudglasses?.examine_extensions) - have_hudtypes += hudglasses.examine_extensions + have_hud_exam |= hudglasses.examine_extensions if(istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) var/obj/item/clothing/head/helmet/space/plasmaman/helmet = H.head if(helmet?.examine_extensions) - have_hudtypes += helmet.examine_extensions + have_hud_exam |= helmet.examine_extensions var/obj/item/organ/internal/cyberimp/eyes/hud/CIH = H.get_int_organ(/obj/item/organ/internal/cyberimp/eyes/hud) if(CIH?.examine_extensions) - have_hudtypes += CIH.examine_extensions + have_hud_exam |= CIH.examine_extensions - return (hudtype in have_hudtypes) + return (have_hud_exam & hud_exam) else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system - return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL)) + return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SECURITY_WRITE || hud_exam & EXAMINE_HUD_MEDICAL else if(ispAI(M)) var/mob/living/silicon/pai/P = M if(P.adv_secHUD) - return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)) + return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SECURITY_WRITE else if(isobserver(M)) var/mob/dead/observer/O = M if(DATA_HUD_SECURITY_ADVANCED in O.data_hud_seen) - return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SKILLS)) + return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SKILLS return FALSE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index cf7473f68f1..6ab6b2399a8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1,12 +1,3 @@ -/mob/living/carbon/human - name = "unknown" - real_name = "unknown" - voice_name = "unknown" - icon = 'icons/mob/human.dmi' - icon_state = "body_m_s" - deathgasp_on_death = TRUE - - /mob/living/carbon/human/New(loc) icon = null // This is now handled by overlays -- we just keep an icon for the sake of the map editor. . = ..() @@ -987,24 +978,6 @@ return HEARING_PROTECTION_MINOR -///tintcheck() -///Checks eye covering items for visually impairing tinting, such as welding masks -///Checked in life.dm. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = You can see jack, but you can't see shit. -/mob/living/carbon/human/tintcheck() - var/tinted = 0 - if(istype(src.head, /obj/item/clothing/head)) - var/obj/item/clothing/head/HT = src.head - tinted += HT.tint - if(istype(src.glasses, /obj/item/clothing/glasses)) - var/obj/item/clothing/glasses/GT = src.glasses - tinted += GT.tint - if(istype(src.wear_mask, /obj/item/clothing/mask)) - var/obj/item/clothing/mask/MT = src.wear_mask - tinted += MT.tint - - return tinted - - /mob/living/carbon/human/abiotic(var/full_body = 0) if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves))) return 1 @@ -1734,10 +1707,10 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(!H.check_has_mouth()) to_chat(src, "They don't have a mouth, you cannot perform CPR!") return - if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted)) + if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.up)) to_chat(src, "Remove your mask first!") return - if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.mask_adjusted)) + if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.up)) to_chat(src, "Remove [H.p_their()] mask first!") return if(H.receiving_cpr) // To prevent spam stacking @@ -2132,3 +2105,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X set category = "IC" update_flavor_text() + +/mob/living/carbon/human/harvest(mob/living/user) + if(QDELETED(src)) + return + + if(issmall(src)) + while(meatleft > 0) + new dna.species.meat_type(loc) + meatleft-- + visible_message(span_notice("[user] butchers [src].")) + gib() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 35d5c793b40..cd6c3f2fbfc 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -419,12 +419,7 @@ emp_act return FALSE if((istype(I, /obj/item/kitchen/knife/butcher/meatcleaver) || istype(I, /obj/item/twohanded/chainsaw)) && stat == DEAD && user.a_intent == INTENT_HARM) - var/obj/item/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/reagent_containers/food/snacks/meat/human(get_turf(loc)) - newmeat.name = real_name + newmeat.name - newmeat.subjectname = real_name - newmeat.subjectjob = job - newmeat.reagents.add_reagent("nutriment", (nutrition / 15) / 3) - reagents.trans_to(newmeat, round((reagents.total_volume) / 3, 1)) + new dna.species.meat_type(get_turf(loc), src) add_mob_blood(src) --meatleft to_chat(user, span_warning("You hack off a chunk of meat from [name].")) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 9d1f6e03cb2..32e1f33d956 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,14 @@ /mob/living/carbon/human - + name = "unknown" + real_name = "unknown" + voice_name = "unknown" + icon = 'icons/mob/human.dmi' + icon_state = "body_m_s" + appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE + deathgasp_on_death = TRUE hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD,THOUGHT_HUD) pressure_resistance = 25 + blocks_emissive = EMISSIVE_BLOCK_UNIQUE //Marking colour and style var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000. var/list/m_styles = DEFAULT_MARKING_STYLES //All markings set to None. diff --git a/code/modules/mob/living/carbon/human/interactions.dm b/code/modules/mob/living/carbon/human/interactions.dm index 6e71e0bcabe..2fcc2c3752c 100644 --- a/code/modules/mob/living/carbon/human/interactions.dm +++ b/code/modules/mob/living/carbon/human/interactions.dm @@ -2,10 +2,11 @@ *******Interactions code by HONKERTRON feat TestUnit******** ***********************************/ -/mob/living/carbon/human/MouseDrop(mob/M as mob) - ..() +/mob/living/carbon/human/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + . = ..() if(src == usr) - interact(M) + interact(over_object) + /mob/proc/make_interaction() return diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index d840e0560d4..23e3648a583 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -56,7 +56,7 @@ if(istype(mask) && mask.tint || initial(mask.tint)) update_tint() - if(mask.flags & BLOCKHAIR || mask.flags & BLOCKHEADHAIR) + if((mask.flags & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)) || (initial(mask.flags) & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR))) update_hair() //rebuild hair update_fhair() update_head_accessory() @@ -65,9 +65,9 @@ internal = null update_action_buttons_icon() - if(mask.flags_inv & HIDEGLASSES) + if((mask.flags_inv & HIDEGLASSES) || (initial(mask.flags_inv) & HIDEGLASSES)) update_inv_glasses() - if(mask.flags_inv & HIDEHEADSETS) + if((mask.flags_inv & HIDEHEADSETS) || (initial(mask.flags_inv) & HIDEHEADSETS)) update_inv_ears() sec_hud_set_ID() @@ -82,7 +82,7 @@ if(!check_item) return - if(forced || (check_item.flags & BLOCKHAIR) || (check_item.flags & BLOCKHEADHAIR)) + if(forced || (check_item.flags & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)) || (initial(check_item.flags) & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR))) update_hair() //rebuild hair update_fhair() update_head_accessory() @@ -96,11 +96,11 @@ if(forced || hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha)) update_sight() - if(forced || (check_item.flags_inv & HIDEHEADSETS)) + if(forced || (check_item.flags_inv & HIDEHEADSETS) || (initial(check_item.flags_inv) & HIDEHEADSETS)) update_inv_ears() - if(forced || (check_item.flags_inv & HIDEMASK)) + if(forced || (check_item.flags_inv & HIDEMASK) || (initial(check_item.flags_inv) & HIDEMASK)) update_inv_wear_mask() - if(forced || (check_item.flags_inv & HIDEGLASSES)) + if(forced || (check_item.flags_inv & HIDEGLASSES) || (initial(check_item.flags_inv) & HIDEGLASSES)) update_inv_glasses() sec_hud_set_ID() @@ -111,11 +111,11 @@ * Handles stuff to update when a mob equips/unequips a suit. */ /mob/living/carbon/human/wear_suit_update(obj/item/clothing/suit) - if(suit.flags_inv & HIDEJUMPSUIT) + if((suit.flags_inv & HIDEJUMPSUIT) || (initial(suit.flags_inv) & HIDEJUMPSUIT)) update_inv_w_uniform() - if(suit.flags_inv & HIDESHOES) + if((suit.flags_inv & HIDESHOES) || (initial(suit.flags_inv) & HIDESHOES)) update_inv_shoes() - if(suit.flags_inv & HIDEGLOVES) + if((suit.flags_inv & HIDEGLOVES) || (initial(suit.flags_inv) & HIDEGLOVES)) update_inv_gloves() update_inv_wear_suit() @@ -412,7 +412,7 @@ if(slot_wear_mask) return head && (head.flags_inv & HIDEMASK) if(slot_glasses) - return head && (head.flags_inv & HIDEGLASSES) + return head && (head.flags_inv & HIDEGLASSES) || wear_mask && (wear_mask.flags_inv & HIDEGLASSES) if(slot_l_ear, slot_r_ear) return head && (head.flags_inv & HIDEHEADSETS) else diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index ec3125614c7..b2f3ab81c4b 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -99,16 +99,12 @@ /mob/living/carbon/human/handle_disabilities() //Vision //god knows why this is here - var/obj/item/organ/vision - if(dna.species.vision_organ) - vision = get_int_organ(dna.species.vision_organ) - - if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. + var/obj/item/organ/vision = dna?.species?.get_vision_organ(src) + if(vision == NO_VISION_ORGAN) SetEyeBlind(0) SetEyeBlurry(0) - - else if(!vision || vision.is_traumatized()) // Vision organs cut out or broken? Permablind. - EyeBlind(4 SECONDS) + else if(!vision || vision.is_traumatized()) // Vision organs cut out or broken? Permablind. + SetEyeBlind(4 SECONDS) if(getBrainLoss() >= 60 && stat != DEAD) if(prob(3)) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index cdc69b1e6e7..b1c1e7f3d31 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -132,12 +132,12 @@ "задерживает дыхание!") // Language/culture vars. - var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers. - var/language = "Galactic Common" // Default racial language, if any. - var/secondary_langs = list() // The names of secondary languages that are available to this species. - var/list/speech_sounds // A list of sounds to potentially play when speaking. - var/list/speech_chance // The likelihood of a speech sound playing. - var/scream_verb = "крич%(ит,ат)%" // Special symbols used to apply correct gender. See [/proc/genderize_decode] for more info. + var/default_language = LANGUAGE_GALACTIC_COMMON // Default language is used when 'say' is used without modifiers. + var/language = LANGUAGE_GALACTIC_COMMON // Default racial language, if any. + var/secondary_langs = list() // The keys of secondary languages that are available to this species. + var/list/speech_sounds // A list of sounds to potentially play when speaking. + var/list/speech_chance // The likelihood of a speech sound playing. + var/scream_verb = "крич%(ит,ат)%" // Special symbols used to apply correct gender. See [/proc/genderize_decode] for more info. var/female_giggle_sound = list('sound/voice/giggle_female_1.ogg','sound/voice/giggle_female_2.ogg','sound/voice/giggle_female_3.ogg') var/male_giggle_sound = list('sound/voice/giggle_male_1.ogg','sound/voice/giggle_male_2.ogg') var/male_scream_sound = list('sound/goonstation/voice/male_scream.ogg') @@ -190,8 +190,7 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) - /// If set, this organ is required for vision. Defaults to "eyes" if the species has them. - var/vision_organ + var/meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid var/list/has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), @@ -223,10 +222,6 @@ var/list/autohiss_exempt = null /datum/species/New() - //If the species has eyes, they are the default vision organ - if(!vision_organ && has_organ[INTERNAL_ORGAN_EYES]) - vision_organ = /obj/item/organ/internal/eyes - unarmed = new unarmed_type() /datum/species/proc/get_random_name(gender) @@ -366,8 +361,7 @@ H.faction += i //Using +=/-= for this in case you also gain the faction from a different source. /datum/species/proc/on_species_loss(mob/living/carbon/human/H) - if(H.butcher_results) //clear it out so we don't butcher a actual human. - H.butcher_results = null + H.meatleft = initial(H.meatleft) H.ventcrawler = initial(H.ventcrawler) if(inherent_factions) @@ -1159,7 +1153,20 @@ It'll return null if the organ doesn't correspond, so include null checks when u /datum/species/proc/can_hear(mob/living/carbon/human/user) var/obj/item/organ/internal/ears/ears = user.get_organ_slot(INTERNAL_ORGAN_EARS) - return ears && !(DEAF in user.mutations) && !HAS_TRAIT(user, TRAIT_DEAF) + return ears && !HAS_TRAIT(user, TRAIT_DEAF) + + +/datum/species/proc/has_vision(mob/living/carbon/human/user, information_only = FALSE) + if(information_only && user.stat == DEAD) + return TRUE + if(user.AmountBlinded() || (BLINDNESS in user.mutations) || user.stat) + return FALSE + var/obj/item/organ/vision = get_vision_organ(user) + return vision && (vision == NO_VISION_ORGAN || !vision.is_traumatized()) + + +/datum/species/proc/get_vision_organ(mob/living/carbon/human/user) + return user.get_organ_slot(INTERNAL_ORGAN_EYES) /datum/species/proc/spec_Process_Spacemove(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index 5155d8f4f99..326c270790e 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -4,8 +4,8 @@ a = "an" icobase = 'icons/mob/human_races/r_abductor.dmi' deform = 'icons/mob/human_races/r_abductor.dmi' - language = "Abductor Mindlink" - default_language = "Abductor Mindlink" + language = LANGUAGE_HIVE_ABDUCTOR + default_language = LANGUAGE_HIVE_ABDUCTOR eyes = "blank_eyes" has_organ = list( INTERNAL_ORGAN_HEART = /obj/item/organ/internal/heart, @@ -16,6 +16,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/grey + species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_HUNGER, NO_EXAMINE) dies_at_threshold = TRUE @@ -40,8 +42,8 @@ ..() H.gender = NEUTER H.languages.Cut() //Under no condition should you be able to speak any language - H.add_language("Abductor Mindlink") //other than over the abductor's own mindlink - H.add_language("Psionic Communication") // still grey enouhg to speak in psi link + H.add_language(LANGUAGE_HIVE_ABDUCTOR) //other than over the abductor's own mindlink + H.add_language(LANGUAGE_GREY) // still grey enouhg to speak in psi link var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] abductor_hud.add_hud_to(H) diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm index 643b9724526..7778d5d34f5 100644 --- a/code/modules/mob/living/carbon/human/species/diona.dm +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -3,7 +3,7 @@ name_plural = "Dionaea" icobase = 'icons/mob/human_races/r_diona.dmi' deform = 'icons/mob/human_races/r_def_plant.dmi' - language = "Rootspeak" + language = LANGUAGE_DIONA speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] speech_chance = 20 unarmed_type = /datum/unarmed_attack/diona @@ -46,6 +46,8 @@ INTERNAL_ORGAN_HEART = /obj/item/organ/internal/heart/diona, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/diona + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/diona), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/diona), diff --git a/code/modules/mob/living/carbon/human/species/drask.dm b/code/modules/mob/living/carbon/human/species/drask.dm index f2dee15f777..9552da20cbd 100644 --- a/code/modules/mob/living/carbon/human/species/drask.dm +++ b/code/modules/mob/living/carbon/human/species/drask.dm @@ -3,7 +3,7 @@ name_plural = "Drask" icobase = 'icons/mob/human_races/r_drask.dmi' deform = 'icons/mob/human_races/r_drask.dmi' - language = "Orluum" + language = LANGUAGE_DRASK eyes = "drask_eyes_s" speech_sounds = list('sound/voice/drasktalk.ogg') @@ -69,6 +69,8 @@ INTERNAL_ORGAN_BRAIN = /obj/item/organ/internal/brain/drask, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/drask + disliked_food = SUGAR | GROSS liked_food = DAIRY diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 133308e84d1..0d5cb77a5ce 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -162,6 +162,11 @@ H.name = H.real_name to_chat(H, info_text) + +/datum/species/golem/get_vision_organ(mob/living/carbon/human/user) + return NO_VISION_ORGAN + + //Random Golem /datum/species/golem/random @@ -407,8 +412,8 @@ name = "Голем из инопланетных сплавов" golem_colour = rgb(51, 51, 51) skinned_type = /obj/item/stack/sheet/mineral/abductor - language = "Golem Mindlink" - default_language = "Golem Mindlink" + language = LANGUAGE_HIVE_GOLEM + default_language = LANGUAGE_HIVE_GOLEM speed_mod = 1 //faster info_text = "Будучи големом из инопланетных сплавов, вы быстрее двигаетесь и со временем регенерируете. Однако, вы можете разговаривать только с големами из того же материала, что и вы." prefix = "Инопланетн" //неполное окончание т.к. гендеризация идет через другую функцию (/datum/species/golem/get_random_name()) @@ -436,8 +441,8 @@ /datum/species/golem/alloy/on_species_gain(mob/living/carbon/human/H) ..() H.languages.Cut() - H.add_language("Golem Mindlink") - H.add_language("Psionic Communication") // still grey enouhg to speak in psi link + H.add_language(LANGUAGE_HIVE_GOLEM) + H.add_language(LANGUAGE_GREY) // still grey enouhg to speak in psi link //Regenerates like dionas, less resistant /datum/species/golem/wood diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm index 0dd88292f69..3c464c0a042 100644 --- a/code/modules/mob/living/carbon/human/species/grey.dm +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -3,7 +3,7 @@ name_plural = "Greys" icobase = 'icons/mob/human_races/r_grey.dmi' deform = 'icons/mob/human_races/r_def_grey.dmi' - language = "Psionic Communication" + language = LANGUAGE_GREY eyes = "grey_eyes_s" butt_sprite = "grey" @@ -18,6 +18,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/grey + total_health = 90 oxy_mod = 1.2 //greys are fragile stamina_mod = 1.2 diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm index eb93d1ec2e4..f1ff075a0b6 100644 --- a/code/modules/mob/living/carbon/human/species/human.dm +++ b/code/modules/mob/living/carbon/human/species/human.dm @@ -4,7 +4,7 @@ icobase = 'icons/mob/human_races/r_human.dmi' deform = 'icons/mob/human_races/r_def_human.dmi' primitive_form = /datum/species/monkey - language = "Sol Common" + language = LANGUAGE_SOL_COMMON species_traits = list(LIPS) skinned_type = /obj/item/stack/sheet/animalhide/human clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS @@ -17,5 +17,7 @@ interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ worlds tumultous at best." + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/human + reagent_tag = PROCESS_ORG //Has standard darksight of 2. diff --git a/code/modules/mob/living/carbon/human/species/kidan.dm b/code/modules/mob/living/carbon/human/species/kidan.dm index 0993ac24e42..33d2da40f10 100644 --- a/code/modules/mob/living/carbon/human/species/kidan.dm +++ b/code/modules/mob/living/carbon/human/species/kidan.dm @@ -6,7 +6,7 @@ name_plural = "Kidan" icobase = 'icons/mob/human_races/r_kidan.dmi' deform = 'icons/mob/human_races/r_def_kidan.dmi' - language = "Chittin" + language = LANGUAGE_KIDAN unarmed_type = /datum/unarmed_attack/claws brute_mod = 0.8 @@ -37,6 +37,8 @@ INTERNAL_ORGAN_LANTERN = /obj/item/organ/internal/lantern, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/kidan), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/kidan), diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 43a5f6df776..3df1176a6c1 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -10,7 +10,7 @@ icobase = 'icons/mob/human_races/r_machine.dmi' deform = 'icons/mob/human_races/r_machine.dmi' - language = "Trinary" + language = LANGUAGE_TRINARY remains_type = /obj/effect/decal/remains/robot skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources! @@ -54,7 +54,7 @@ INTERNAL_ORGAN_R_ARM_DEVICE = /obj/item/organ/internal/cyberimp/arm/power_cord, ) - vision_organ = /obj/item/organ/internal/eyes/optical_sensor + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/machine has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/ipc), diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index e9a2e4e2a40..1b1bc2be776 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -8,8 +8,8 @@ damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi' damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi' blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi' - language = "Galactic Common" - default_language = "Chimpanzee" + language = LANGUAGE_GALACTIC_COMMON + default_language = LANGUAGE_MONKEY_HUMAN species_traits = list(NO_EXAMINE) skinned_type = /obj/item/stack/sheet/animalhide/monkey greater_form = /datum/species/human @@ -40,6 +40,8 @@ brute_mod = 1.5 burn_mod = 1.5 + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), @@ -70,7 +72,7 @@ ..() H.real_name = "[lowertext(name)] ([rand(100,999)])" H.name = H.real_name - H.butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/monkey = 5) + H.meatleft = 5 /datum/species/monkey/handle_dna(mob/living/carbon/human/H, remove) ..() @@ -86,11 +88,12 @@ deform = 'icons/mob/human_races/monkeys/r_farwa.dmi' greater_form = /datum/species/tajaran - default_language = "Farwa" + default_language = LANGUAGE_MONKEY_TAJARAN blood_species = "Tajaran" flesh_color = "#AFA59E" base_color = "#000000" tail = "farwatail" + skinned_type = /obj/item/stack/sheet/animalhide/farwa reagent_tag = PROCESS_ORG has_organ = list( @@ -104,6 +107,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), @@ -128,11 +133,12 @@ deform = 'icons/mob/human_races/monkeys/r_wolpin.dmi' greater_form = /datum/species/vulpkanin - default_language = "Wolpin" + default_language = LANGUAGE_MONKEY_VULPKANIN blood_species = "Vulpkanin" flesh_color = "#966464" base_color = "#000000" tail = "wolpintail" + skinned_type = /obj/item/stack/sheet/animalhide/wolpin reagent_tag = PROCESS_ORG has_organ = list( @@ -146,6 +152,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), @@ -169,10 +177,11 @@ deform = 'icons/mob/human_races/monkeys/r_neara.dmi' greater_form = /datum/species/skrell - default_language = "Neara" + default_language = LANGUAGE_MONKEY_SKRELL blood_species = "Skrell" flesh_color = "#8CD7A3" blood_color = "#1D2CBF" + skinned_type = /obj/item/stack/sheet/animalhide/neara reagent_tag = PROCESS_ORG tail = null @@ -187,6 +196,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/neara + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), @@ -219,10 +230,11 @@ tail = "stoktail" greater_form = /datum/species/unathi - default_language = "Stok" + default_language = LANGUAGE_MONKEY_UNATHI blood_species = "Unathi" flesh_color = "#34AF10" base_color = "#000000" + skinned_type = /obj/item/stack/sheet/animalhide/stok reagent_tag = PROCESS_ORG bodyflags = HAS_TAIL @@ -238,6 +250,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/stok + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), diff --git a/code/modules/mob/living/carbon/human/species/moth.dm b/code/modules/mob/living/carbon/human/species/moth.dm index 02856a2679b..75a2ca4f18e 100644 --- a/code/modules/mob/living/carbon/human/species/moth.dm +++ b/code/modules/mob/living/carbon/human/species/moth.dm @@ -8,7 +8,7 @@ /datum/species/moth name = "Nian" name_plural = "Nianae" - language = "Tkachi" + language = LANGUAGE_MOTH icobase = 'icons/mob/human_races/r_moth.dmi' deform = 'icons/mob/human_races/r_moth.dmi' inherent_factions = list("moth") @@ -48,6 +48,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/nian + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm index 93a9c156876..2953c547869 100644 --- a/code/modules/mob/living/carbon/human/species/nucleation.dm +++ b/code/modules/mob/living/carbon/human/species/nucleation.dm @@ -10,7 +10,7 @@ obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ way as lepers were back on Earth." - language = "Sol Common" + language = LANGUAGE_SOL_COMMON burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores brute_mod = 2 // damn, double wham, double dam species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_PAIN_FEEL, NO_SCAN, RADIMMUNE, VIRUSIMMUNE, NO_GERMS) @@ -28,7 +28,9 @@ INTERNAL_ORGAN_STRANGE_CRYSTAL = /obj/item/organ/internal/nucleation/strange_crystal, INTERNAL_ORGAN_RESONANT_CRYSTAL = /obj/item/organ/internal/nucleation/resonant_crystal, ) - vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal + + + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/nucleation /datum/species/nucleation/on_species_gain(mob/living/carbon/human/H) ..() diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 86c45e7a33c..14049fbfba6 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -43,6 +43,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/plasmaman + speciesbox = /obj/item/storage/box/survival_plasmaman flesh_color = "#8b3fba" diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index 8c48b003f88..78afab06e39 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -72,3 +72,8 @@ return TRUE return ..() + + +/datum/species/skeleton/get_vision_organ(mob/living/carbon/human/user) + return NO_VISION_ORGAN + diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm index ed6f6562901..26615a8f232 100644 --- a/code/modules/mob/living/carbon/human/species/skrell.dm +++ b/code/modules/mob/living/carbon/human/species/skrell.dm @@ -3,7 +3,7 @@ name_plural = "Skrell" icobase = 'icons/mob/human_races/r_skrell.dmi' deform = 'icons/mob/human_races/r_def_skrell.dmi' - language = "Skrellian" + language = LANGUAGE_SKRELL primitive_form = /datum/species/monkey/skrell blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ @@ -51,6 +51,8 @@ INTERNAL_ORGAN_HEADPOCKET = /obj/item/organ/internal/headpocket, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell + suicide_messages = list( "пытается откусить себе язык!", "выдавливает большими пальцами свои глазницы!", diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index 39220045d7b..718a0877707 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -11,7 +11,7 @@ /datum/species/slime name = "Slime People" name_plural = "Slime People" - language = "Bubblish" + language = LANGUAGE_SLIME icobase = 'icons/mob/human_races/r_slime.dmi' deform = 'icons/mob/human_races/r_slime.dmi' remains_type = /obj/effect/decal/remains/slime @@ -45,6 +45,8 @@ INTERNAL_ORGAN_LUNGS = /obj/item/organ/internal/lungs/slime, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/unbreakable), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable), @@ -143,7 +145,11 @@ /datum/species/slime/can_hear(mob/living/carbon/human/user) - return !(DEAF in user.mutations) && !HAS_TRAIT(user, TRAIT_DEAF) + return !HAS_TRAIT(user, TRAIT_DEAF) + + +/datum/species/slime/get_vision_organ(mob/living/carbon/human/user) + return NO_VISION_ORGAN /datum/action/innate/slimecolor diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm index b8ad91b1dbb..6653346f4f9 100644 --- a/code/modules/mob/living/carbon/human/species/tajaran.dm +++ b/code/modules/mob/living/carbon/human/species/tajaran.dm @@ -3,7 +3,7 @@ name_plural = "Tajaran" icobase = 'icons/mob/human_races/r_tajaran.dmi' deform = 'icons/mob/human_races/r_def_tajaran.dmi' - language = "Siik'tajr" + language = LANGUAGE_TAJARAN tail = "tajtail" skinned_type = /obj/item/stack/sheet/fur unarmed_type = /datum/unarmed_attack/claws @@ -46,6 +46,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm index a83e48de6b2..53369bfb68b 100644 --- a/code/modules/mob/living/carbon/human/species/unathi.dm +++ b/code/modules/mob/living/carbon/human/species/unathi.dm @@ -3,7 +3,7 @@ name_plural = "Unathi" icobase = 'icons/mob/human_races/r_lizard.dmi' deform = 'icons/mob/human_races/r_def_lizard.dmi' - language = "Sinta'unathi" + language = LANGUAGE_UNATHI tail = "sogtail" speech_sounds = list('sound/voice/unathitalk.mp3', 'sound/voice/unathitalk2.mp3', 'sound/voice/unathitalk4.mp3') speech_chance = 33 @@ -60,6 +60,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), @@ -150,8 +152,8 @@ blurb = "Пеплоходцы — рептильные гуманоиды, по-видимому, родственные унати. Но кажутся значительно менее развитыми. \ Они бродят по пустошам Лаваленда, поклоняются мёртвому городу и ловят ничего не подозревающих шахтёров." - language = "Sinta'unathi" - default_language = "Sinta'unathi" + language = LANGUAGE_UNATHI + default_language = LANGUAGE_UNATHI speed_mod = -0.80 species_traits = list(NOGUNS, LIPS, PIERCEIMMUNE) @@ -228,7 +230,7 @@ if(fire) fire.Remove(C) -//basic touch ability that heals brute and burn, only accessed by the ashwalker shaman +//basic touch ability that heals basic damage types accessed by the ashwalker shaman /obj/effect/proc_holder/spell/touch/healtouch name = "healing touch" desc = "This spell charges your hand with the vile energy of the Necropolis, permitting you to undo some external injuries from a target." @@ -239,7 +241,7 @@ base_cooldown = 20 SECONDS clothes_req = FALSE - action_icon_state = "spell_default" + action_icon_state = "healtouch" /obj/item/melee/touch_attack/healtouch name = "\improper healing touch" @@ -248,14 +250,20 @@ on_use_sound = 'sound/magic/staff_healing.ogg' icon_state = "disintegrate" //ironic huh item_state = "disintegrate" - var/healamount = 20 //total of 40 assuming they're hurt by both brute and burn + //total of 40 assuming they're hurt by both brute and burn + var/brute = 20 + var/burn = 20 + var/tox = 10 + var/oxy = 50 /obj/item/melee/touch_attack/healtouch/afterattack(atom/target, mob/living/carbon/user, proximity) if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //no healing yourself return var/mob/living/M = target new /obj/effect/temp_visual/heal(get_turf(M), "#899d39") - M.heal_overall_damage(healamount, healamount, 0) //notice it doesn't heal toxins, still need to learn chems for that + M.heal_overall_damage(brute, burn, 0) + M.adjustToxLoss(-tox) + M.adjustOxyLoss(-oxy) return ..() /datum/species/unathi/on_species_gain(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm index 0584cb6395e..b37ef8d384d 100644 --- a/code/modules/mob/living/carbon/human/species/vox.dm +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -4,7 +4,7 @@ icobase = 'icons/mob/human_races/vox/r_vox.dmi' deform = 'icons/mob/human_races/vox/r_def_vox.dmi' dangerous_existence = TRUE - language = "Vox-pidgin" + language = LANGUAGE_VOX tail = "voxtail" speech_sounds = list('sound/voice/shriek1.ogg') speech_chance = 20 @@ -67,6 +67,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/vox + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm index 582825ef1a5..6df149c451e 100644 --- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm +++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -3,7 +3,7 @@ name_plural = "Vulpkanin" icobase = 'icons/mob/human_races/r_vulpkanin.dmi' deform = 'icons/mob/human_races/r_vulpkanin.dmi' - language = "Canilunzt" + language = LANGUAGE_VULPKANIN primitive_form = /datum/species/monkey/vulpkanin tail = "vulptail" skinned_type = /obj/item/stack/sheet/fur @@ -39,6 +39,8 @@ INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin), diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm index 6499c5192d3..3e56459e92e 100644 --- a/code/modules/mob/living/carbon/human/species/wryn.dm +++ b/code/modules/mob/living/carbon/human/species/wryn.dm @@ -4,7 +4,7 @@ icobase = 'icons/mob/human_races/r_wryn.dmi' deform = 'icons/mob/human_races/r_wryn.dmi' blacklisted = TRUE - language = "Wryn Hivemind" + language = LANGUAGE_WRYN tail = "wryntail" punchdamagelow = 0 punchdamagehigh = 1 @@ -37,6 +37,8 @@ INTERNAL_ORGAN_WAX_GLANDS = /obj/item/organ/internal/wryn/glands, ) + meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn + has_limbs = list( BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/wryn), BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/wryn), @@ -178,7 +180,7 @@ user.visible_message("[user] начина[pluralize_ru(user.gender,"ет","ют")] яростно отрывать усики [target].") to_chat(target, "[user] схватил[genderize_ru(user.gender,"","а","о","и")] ваши усики и яростно тян[pluralize_ru(user.gender,"ет","ут")] их!") if(do_mob(user, target, 250)) - target.remove_language("Wryn Hivemind") + target.remove_language(LANGUAGE_WRYN) node.remove(target) node.forceMove(get_turf(target)) to_chat(user, "Вы слышите громкий хруст, когда безжалостно отрываете усики [target].") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 527690de353..0eba1270d66 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -144,7 +144,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) // blend the individual damage states with our icons for(var/obj/item/organ/external/bodypart as anything in bodyparts) - bodypart.update_icon() + bodypart.update_state() if(bodypart.damage_state == "00") continue @@ -165,7 +165,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //BASE MOB SPRITE /mob/living/carbon/human/proc/update_body(rebuild_base = FALSE) - remove_overlay(BODY_LAYER) remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's remove_overlay(UNDERWEAR_LAYER) @@ -283,8 +282,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER) apply_overlay(UNDERWEAR_LAYER) - overlays_standing[BODY_LAYER] = standing - apply_overlay(BODY_LAYER) //wings update_wing_layer() //tail @@ -433,7 +430,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) return //masks and helmets can obscure our facial hair, unless we're a synthetic - if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR))) + if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKFACIALHAIR))) return //base icons @@ -704,6 +701,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) remove_overlay(GLASSES_LAYER) remove_overlay(GLASSES_OVER_LAYER) remove_overlay(OVER_MASK_LAYER) + remove_overlay(OVER_HEAD_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_glasses] @@ -727,7 +725,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style] var/obj/item/clothing/glasses/G = glasses - if(istype(G) && G.over_mask) //If the user's used the 'wear over mask' verb on the glasses. + if(head && !(head.flags_inv & MASKCOVERSEYES || head.flags_cover & HEADCOVERSEYES) && G.over_hat && istype(G)) + new_glasses.layer = -OVER_HEAD_LAYER + overlays_standing[OVER_HEAD_LAYER] = new_glasses + apply_overlay(OVER_HEAD_LAYER) + else if(istype(G) && G.over_mask) //If the user's used the 'wear over mask' verb on the glasses. new_glasses.layer = -OVER_MASK_LAYER overlays_standing[OVER_MASK_LAYER] = new_glasses apply_overlay(OVER_MASK_LAYER) diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm index 1a88a0fa867..afb708a6496 100644 --- a/code/modules/mob/living/carbon/human/update_stat.dm +++ b/code/modules/mob/living/carbon/human/update_stat.dm @@ -23,5 +23,11 @@ return ..() // Fallback if we don't have a species or DNA +/mob/living/carbon/human/has_vision(information_only = FALSE) + if(dna?.species) + return dna.species.has_vision(src, information_only) + return ..() + + /mob/living/carbon/human/check_death_method() return dna.species.dies_at_threshold diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a57a08e9e77..e39b81920b8 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -97,6 +97,8 @@ if(breath) loc.assume_air(breath) air_update_turf() + if(ishuman(src) && !internal && environment.temperature < 278 && environment.return_pressure() > 20) + new /obj/effect/frosty_breath(loc, src) //Third link in a breath chain, calls handle_breath_temperature() /mob/living/carbon/proc/check_breath(datum/gas_mixture/breath) diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index a59388ce6a7..efc4f388069 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -5,7 +5,7 @@ return FALSE // hide and freeze for the GC notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT @@ -23,7 +23,7 @@ new /obj/effect/decal/cleanable/ash(loc) // hide and freeze them while they get GC'd notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT QDEL_IN(src, 0) @@ -34,7 +34,7 @@ return FALSE // hide and freeze them while they get GC'd notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT QDEL_IN(src, 0) diff --git a/code/modules/mob/living/default_language.dm b/code/modules/mob/living/default_language.dm index f6c9c3abc0e..de181396eba 100644 --- a/code/modules/mob/living/default_language.dm +++ b/code/modules/mob/living/default_language.dm @@ -6,9 +6,9 @@ set category = "IC" if(language) - to_chat(src, "You will now speak [language] if you do not specify a language when speaking.") + to_chat(src, span_notice("You will now speak [language] if you do not specify a language when speaking.")) else - to_chat(src, "You will now speak whatever your standard default language is if you do not specify one when speaking.") + to_chat(src, span_notice("You will now speak whatever your standard default language is if you do not specify one when speaking.")) default_language = language // Silicons can't neccessarily speak everything in their languages list @@ -20,6 +20,6 @@ set category = "IC" if(default_language) - to_chat(src, "You are currently speaking [default_language] by default.") + to_chat(src, span_notice("You are currently speaking [default_language] by default.")) else - to_chat(src, "Your current default language is your species or mob type default.") + to_chat(src, span_notice("Your current default language is your species or mob type default.")) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3598a00aa93..823837544df 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -376,7 +376,7 @@ return 1 /mob/living/welder_act(mob/user, obj/item/I) - if(!I.tool_use_check(null, 0)) //Don't need the message, just if it succeeded + if(!I.tool_use_check(user, 0, silent = TRUE)) //Don't need the message, just if it succeeded return if(IgniteMob()) message_admins("[key_name_admin(user)] set [key_name_admin(src)] on fire with [I]") @@ -1120,7 +1120,7 @@ return 0 /mob/living/proc/attempt_harvest(obj/item/I, mob/user) - if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results) //can we butcher it? + if(user.a_intent == INTENT_HARM && stat == DEAD && (butcher_results || issmall(src))) //can we butcher it? var/sharpness = is_sharp(I) if(sharpness) to_chat(user, "You begin to butcher [src]...") @@ -1388,15 +1388,18 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven /mob/living/run_examinate(atom/target) var/datum/status_effect/staring/user_staring_effect = has_status_effect(STATUS_EFFECT_STARING) + if(user_staring_effect || hindered_inspection(target)) return var/examine_time = target.get_examine_time() - face_atom(target) if(examine_time && target != src) var/visible_gender = target.get_visible_gender() var/visible_species = "Unknown" + // If we did not see the target with our own eyes when starting the examine, then there is no need to check whether it is close. + var/near_target = examine_distance_check(target) + if(isliving(target)) var/mob/living/target_living = target visible_species = target_living.get_visible_species() @@ -1407,17 +1410,24 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven target_staring_effect.catch_look(src) user_staring_effect = apply_status_effect(STATUS_EFFECT_STARING, examine_time, target, visible_gender, visible_species) - if(do_mob(src, target, examine_time, FALSE, list(CALLBACK(src, PROC_REF(hindered_inspection), target)), TRUE)) + if(do_mob(src, src, examine_time, TRUE, only_use_extra_checks = TRUE)) + if(hindered_inspection(target) || (near_target && !examine_distance_check(target))) + return ..() else ..() +/mob/living/proc/examine_distance_check(atom/target) + if(target in view(client.maxview(), client.eye)) + return TRUE + + /mob/living/proc/hindered_inspection(atom/target) if(QDELETED(src) || QDELETED(target)) return TRUE + face_atom(target) if(!has_vision(information_only = TRUE)) to_chat(src, span_notice("Здесь что-то есть, но вы не видите — что именно.")) return TRUE return FALSE - diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index cc73ee1149f..3ee7bede863 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -1,26 +1,24 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /* Busy letters by languages: - a b d f g j k o q v x y - aa as bo db fa fm fn fs vu + un ta vu sk vo di tr ki sl gr dr ni + xm db wr xh ts ch hs sh ab gl bo bi dt + sw gc sc tb gt cl nr mo ne st fa wo - Busy symbols by languages: - 0 1 2 3 4 5 6 7 8 9 - % ? ^ ' Busy letters by radio(eng): c e h i l m n p r s t u w x Busy letters by radio(rus): - б г д е ё з к р с т у ц ч ш ы ь я Э + б г д е ё з к р с т у ц ч ш ы ь я э Busy symbols by radio: ~ , $ _ - + * 1 2 3 - CAUTION! The key must not repeat the key of the languages (language.dm) - and must not contain prohibited characters + CAUTION! The key must not repeat the key of the languages (language.dm) + and must not contain prohibited characters! */ // English text lowercase ":r" = "right ear", "#r" = "right ear", "№r" = "right ear", ".r" = "right ear", @@ -213,20 +211,9 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key) return say_dead(message) return FALSE - var/message_mode = parse_message_mode(message, "headset") - if(copytext(message, 1, 2) == "*") return emote(copytext(message, 2), intentional = TRUE) - //parse the radio code and consume it - if(message_mode) - if(message_mode == "headset") - message = copytext_char(message, 2) //it would be really nice if the parse procs could do this for us. - else - message = copytext_char(message, 3) - - message = trim_left(message) - var/ending = copytext(message, length(message)) if(!(ending in list("!", "?", ",", ".")) && length(message) != 0) message += "." @@ -238,15 +225,28 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key) else message_pieces = parse_languages(message) - if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages - var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting - S.speaking.broadcast(src, S.message) - return TRUE - if(!LAZYLEN(message_pieces)) . = FALSE CRASH("Message failed to generate pieces. [message] - [json_encode(message_pieces)]") + var/datum/multilingual_say_piece/first_piece = message_pieces[1] + + if(first_piece.speaking?.flags & HIVEMIND) + first_piece.speaking.broadcast(src, first_piece.message) + return TRUE + + var/message_mode = parse_message_mode(first_piece.message, "headset") + + //parse the radio code and consume it + if(message_mode) + if(message_mode == "headset") + first_piece.message = copytext_char(first_piece.message, 2) //it would be really nice if the parse procs could do this for us. + else + first_piece.message = copytext_char(first_piece.message, 3) + + first_piece.message = trim_left(first_piece.message) + verb = say_quote(message, first_piece.speaking) + if(message_mode == "cords") if(iscarbon(src)) var/mob/living/carbon/C = src @@ -256,9 +256,6 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key) V.speak_with(message) //words come before actions return TRUE - var/datum/multilingual_say_piece/first_piece = message_pieces[1] - verb = say_quote(message, first_piece.speaking) - if(is_muzzled()) var/obj/item/clothing/mask/muzzle/G = wear_mask if(G.mute == MUZZLE_MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 50de2f19f78..574e554454b 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -139,8 +139,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( aiPDA = new/obj/item/pda/silicon/ai(src) rename_character(null, pickedName) - anchored = 1 - canmove = 0 + anchored = TRUE + canmove = FALSE density = 1 loc = loc @@ -171,24 +171,24 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( add_ai_verbs(src) //Languages - add_language("Robot Talk", 1) - add_language("Galactic Common", 1) - add_language("Sol Common", 1) - add_language("Tradeband", 1) - add_language("Neo-Russkiya", 1) - add_language("Gutter", 1) - add_language("Sinta'unathi", 1) - add_language("Siik'tajr", 1) - add_language("Canilunzt", 1) - add_language("Skrellian", 1) - add_language("Vox-pidgin", 1) - add_language("Orluum", 1) - add_language("Rootspeak", 1) - add_language("Trinary", 1) - add_language("Chittin", 1) - add_language("Bubblish", 1) - add_language("Clownish", 1) - add_language("Tkachi", 1) + add_language(LANGUAGE_BINARY, 1) + add_language(LANGUAGE_GALACTIC_COMMON, 1) + add_language(LANGUAGE_SOL_COMMON, 1) + add_language(LANGUAGE_TRADER, 1) + add_language(LANGUAGE_NEO_RUSSIAN, 1) + add_language(LANGUAGE_GUTTER, 1) + add_language(LANGUAGE_UNATHI, 1) + add_language(LANGUAGE_TAJARAN, 1) + add_language(LANGUAGE_VULPKANIN, 1) + add_language(LANGUAGE_SKRELL, 1) + add_language(LANGUAGE_VOX, 1) + add_language(LANGUAGE_DRASK, 1) + add_language(LANGUAGE_DIONA, 1) + add_language(LANGUAGE_TRINARY, 1) + add_language(LANGUAGE_KIDAN, 1) + add_language(LANGUAGE_SLIME, 1) + add_language(LANGUAGE_CLOWN, 1) + add_language(LANGUAGE_MOTH, 1) if(!safety)//Only used by AIize() to successfully spawn an AI. if(!B)//If there is no player/brain inside. @@ -338,7 +338,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( use_power = ACTIVE_POWER_USE power_channel = EQUIP var/mob/living/silicon/ai/powered_ai = null - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT /obj/machinery/ai_powersupply/New(mob/living/silicon/ai/ai=null) powered_ai = ai @@ -993,19 +993,25 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( if(check_unable()) return - for(var/obj/machinery/M in GLOB.machines) //change status - if(istype(M, /obj/machinery/ai_status_display)) - var/obj/machinery/ai_status_display/AISD = M - AISD.emotion = emote + for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status + display.emotion = emote + display.update_icon() + + for(var/obj/machinery/machine in GLOB.machines) //change status + if(istype(machine, /obj/machinery/ai_status_display)) + var/obj/machinery/ai_status_display/display = machine + display.emotion = emote + display.update_icon() + //if Friend Computer, change ALL displays - else if(istype(M, /obj/machinery/status_display)) + else if(istype(machine, /obj/machinery/status_display)) - var/obj/machinery/status_display/SD = M + var/obj/machinery/status_display/display = machine if(emote=="Friend Computer") - SD.friendc = 1 + display.friendc = TRUE else - SD.friendc = 0 - return + display.friendc = FALSE + //I am the icon meister. Bow fefore me. //>fefore /mob/living/silicon/ai/proc/ai_hologram_change() @@ -1238,7 +1244,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( /mob/living/silicon/ai/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) if(anchored) user.visible_message("\The [user] starts to unbolt \the [src] from the plating...") if(!do_after(user, 40 * W.toolspeed * gettoolspeedmod(user), target = src)) diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index f52b13adaa7..ad4cb78c364 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -37,8 +37,8 @@ spawn(10) explosion(src.loc, 3, 6, 12, 15, cause = "AI exploded") - for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status - O.mode = 2 + for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status + display.mode = AI_DISPLAY_MODE_BSOD if(istype(loc, /obj/item/aicard)) loc.icon_state = "aicard-404" diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 3e731c68037..d0a0da844ab 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -16,6 +16,8 @@ var/relay_speech = FALSE var/use_static = TRUE var/static_visibility_range = 16 + // Decides if it is shown by AI Detector or not + var/ai_detector_visible = TRUE // Use this when setting the aiEye's location. diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index 545e1569fc1..1d39210c8e9 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -7,7 +7,8 @@ regenerate_icons() if(stat != DEAD) - for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status - O.mode = 1 - O.emotion = "Neutral" + for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status + display.mode = AI_DISPLAY_MODE_EMOTE + display.emotion = "Neutral" + view_core() diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm index d9dac308870..8ee7c503dd0 100644 --- a/code/modules/mob/living/silicon/ai/logout.dm +++ b/code/modules/mob/living/silicon/ai/logout.dm @@ -1,6 +1,6 @@ /mob/living/silicon/ai/Logout() ..() - for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status - O.mode = 0 + for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status + display.mode = AI_DISPLAY_MODE_BLANK src.view_core() return diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 73995978e5a..6e6094f09fb 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -2,7 +2,7 @@ death(1) var/atom/movable/overlay/animation = null notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT @@ -26,7 +26,7 @@ if(!death(TRUE) && stat != DEAD) return FALSE notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT dust_animation() diff --git a/code/modules/mob/living/silicon/decoy/death.dm b/code/modules/mob/living/silicon/decoy/death.dm index 74db72978e0..a7fc4ce09f0 100644 --- a/code/modules/mob/living/silicon/decoy/death.dm +++ b/code/modules/mob/living/silicon/decoy/death.dm @@ -4,7 +4,7 @@ if(!.) return FALSE icon_state = "ai-crash" - for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status - if(atoms_share_level(O, src)) - O.mode = 2 + for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status + if(atoms_share_level(display, src)) + display.mode = AI_DISPLAY_MODE_BSOD gib() diff --git a/code/modules/mob/living/silicon/decoy/decoy.dm b/code/modules/mob/living/silicon/decoy/decoy.dm index 0cd5a26fb5e..20b65d33366 100644 --- a/code/modules/mob/living/silicon/decoy/decoy.dm +++ b/code/modules/mob/living/silicon/decoy/decoy.dm @@ -2,8 +2,8 @@ name = "AI" icon = 'icons/mob/ai.dmi'// icon_state = "ai" - anchored = 1 // -- TLE - canmove = 0 + anchored = TRUE // -- TLE + canmove = FALSE a_intent = INTENT_HARM // This is apparently the only thing that stops other mobs walking through them as if they were thin air. /mob/living/silicon/decoy/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 7e4eecf31cd..63e53a4c169 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -122,11 +122,11 @@ radio_name = name //Default languages without universal translator software - add_language("Galactic Common", 1) - add_language("Sol Common", 1) - add_language("Tradeband", 1) - add_language("Gutter", 1) - add_language("Trinary", 1) + add_language(LANGUAGE_GALACTIC_COMMON, 1) + add_language(LANGUAGE_SOL_COMMON, 1) + add_language(LANGUAGE_TRADER, 1) + add_language(LANGUAGE_GUTTER, 1) + add_language(LANGUAGE_TRINARY, 1) //Verbs for pAI mobile form, chassis and Say flavor text verbs += /mob/living/silicon/pai/proc/choose_chassis @@ -214,7 +214,7 @@ return 0 ..() -/mob/living/silicon/pai/MouseDrop(atom/over_object) +/mob/living/silicon/pai/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) return /mob/living/silicon/pai/emp_act(severity) @@ -608,21 +608,21 @@ return H -/mob/living/silicon/pai/MouseDrop(atom/over_object) - var/mob/living/carbon/human/H = over_object //changed to human to avoid stupid issues like xenos holding pAIs. - if(!istype(H) || !Adjacent(H)) return ..() +/mob/living/silicon/pai/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params) + if(!ishuman(user) || !Adjacent(user)) + return ..() if(usr == src) - switch(alert(H, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No")) + switch(alert(user, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No")) if("Yes") - if(Adjacent(H)) - get_scooped(H) + if(Adjacent(user)) + get_scooped(user) else - to_chat(src, "You need to stay in reaching distance to be picked up.") + to_chat(src, span_warning("You need to stay in reaching distance to be picked up.")) if("No") - to_chat(src, "[H] decided not to pick you up.") + to_chat(src, span_warning("[user] decided not to pick you up.")) else - if(Adjacent(H)) - get_scooped(H) + if(Adjacent(user)) + get_scooped(user) else return ..() diff --git a/code/modules/mob/living/silicon/pai/software/pai_toggles.dm b/code/modules/mob/living/silicon/pai/software/pai_toggles.dm index a83fd1df484..1122585fefc 100644 --- a/code/modules/mob/living/silicon/pai/software/pai_toggles.dm +++ b/code/modules/mob/living/silicon/pai/software/pai_toggles.dm @@ -48,31 +48,31 @@ // Galactic Common, Sol Common, Tradeband, Gutter and Trinary are added with New() and are therefore the current default, always active languages user.translator_on = !user.translator_on if(user.translator_on) - user.add_language("Sinta'unathi") - user.add_language("Siik'tajr") - user.add_language("Canilunzt") - user.add_language("Skrellian") - user.add_language("Vox-pidgin") - user.add_language("Rootspeak") - user.add_language("Chittin") - user.add_language("Bubblish") - user.add_language("Orluum") - user.add_language("Clownish") - user.add_language("Neo-Russkiya") - user.add_language("Tkachi") + user.add_language(LANGUAGE_UNATHI) + user.add_language(LANGUAGE_TAJARAN) + user.add_language(LANGUAGE_VULPKANIN) + user.add_language(LANGUAGE_SKRELL) + user.add_language(LANGUAGE_VOX) + user.add_language(LANGUAGE_DIONA) + user.add_language(LANGUAGE_KIDAN) + user.add_language(LANGUAGE_SLIME) + user.add_language(LANGUAGE_DRASK) + user.add_language(LANGUAGE_CLOWN) + user.add_language(LANGUAGE_NEO_RUSSIAN) + user.add_language(LANGUAGE_MOTH) else - user.remove_language("Sinta'unathi") - user.remove_language("Siik'tajr") - user.remove_language("Canilunzt") - user.remove_language("Skrellian") - user.remove_language("Vox-pidgin") - user.remove_language("Rootspeak") - user.remove_language("Chittin") - user.remove_language("Bubblish") - user.remove_language("Orluum") - user.remove_language("Clownish") - user.remove_language("Neo-Russkiya") - user.remove_language("Tkachi") + user.remove_language(LANGUAGE_UNATHI) + user.remove_language(LANGUAGE_TAJARAN) + user.remove_language(LANGUAGE_VULPKANIN) + user.remove_language(LANGUAGE_SKRELL) + user.remove_language(LANGUAGE_VOX) + user.remove_language(LANGUAGE_DIONA) + user.remove_language(LANGUAGE_KIDAN) + user.remove_language(LANGUAGE_SLIME) + user.remove_language(LANGUAGE_DRASK) + user.remove_language(LANGUAGE_CLOWN) + user.remove_language(LANGUAGE_NEO_RUSSIAN) + user.remove_language(LANGUAGE_MOTH) /datum/pai_software/translator/is_active(mob/living/silicon/pai/user) return user.translator_on diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index fc69a18cf42..e0c05f62ec9 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -4,7 +4,7 @@ //robots don't die when gibbed. instead they drop their MMI'd brain var/atom/movable/overlay/animation = null notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT @@ -33,7 +33,7 @@ if(!death(TRUE) && stat != DEAD) return FALSE notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT if(mmi) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index e9f6984c588..ae7e9a244b8 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -57,10 +57,10 @@ /mob/living/silicon/robot/drone/New() ..() - remove_language("Robot Talk") - remove_language("Galactic Common") - add_language("Drone Talk", 1) - add_language("Drone", 1) + remove_language(LANGUAGE_BINARY) + remove_language(LANGUAGE_GALACTIC_COMMON) + add_language(LANGUAGE_DRONE_BINARY, 1) + add_language(LANGUAGE_DRONE, 1) // Disable the microphone wire on Drones if(radio) @@ -156,7 +156,7 @@ to_chat(user, "The maintenance drone chassis not compatible with \the [W].") return - else if(istype(W, /obj/item/crowbar)) + else if(W.tool_behaviour == TOOL_CROWBAR) to_chat(user, "The machine is hermetically sealed. You can't open the case.") return @@ -345,18 +345,6 @@ to_chat(src, "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets.") to_chat(src, "Make sure crew members do not notice you..") -/* - sprite["Default"] = "repairbot" - sprite["Mk2 Mousedrone"] = "mk2" - sprite["Mk3 Monkeydrone"] = "mk3" - var/icontype - icontype = input(player,"Pick an icon") in sprite - icon_state = sprite[icontype] - updateicon() - - choose_icon(6,sprite) -*/ - /mob/living/silicon/robot/drone/Bump(atom/movable/AM, yes) if(is_type_in_list(AM, allowed_bumpable_objects)) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index cc4870915e3..4512a0c3476 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -143,6 +143,7 @@ return dronefab.produce_drones = !dronefab.produce_drones + dronefab.update_icon(UPDATE_ICON_STATE) to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.") src.updateUsrDialog() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index 18a746d5f1d..578232b7720 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -1,44 +1,51 @@ /obj/machinery/drone_fabricator name = "drone fabricator" desc = "A large automated factory for producing maintenance drones." - + icon = 'icons/obj/machines/drone_fab.dmi' + icon_state = "drone_fab_idle" density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 20 active_power_usage = 5000 - var/drone_progress = 0 - var/produce_drones = 1 + var/produce_drones = TRUE var/time_last_drone = 500 - icon = 'icons/obj/machines/drone_fab.dmi' - icon_state = "drone_fab_idle" - -/obj/machinery/drone_fabricator/New() - ..() -/obj/machinery/drone_fabricator/power_change() - if(powered()) - stat &= ~NOPOWER - else +/obj/machinery/drone_fabricator/update_icon_state() + if(stat & NOPOWER) icon_state = "drone_fab_nopower" - stat |= NOPOWER + return + + if(!produce_drones || (!drone_progress || drone_progress >= 100)) + icon_state = "drone_fab_idle" + return + + icon_state = "drone_fab_active" + + +/obj/machinery/drone_fabricator/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) + /obj/machinery/drone_fabricator/process() if(SSticker.current_state < GAME_STATE_PLAYING) return - if(stat & NOPOWER || !produce_drones) - if(icon_state != "drone_fab_nopower") icon_state = "drone_fab_nopower" + if((stat & NOPOWER) || !produce_drones) return if(drone_progress >= 100) - icon_state = "drone_fab_idle" + if(icon_state != "drone_fab_idle") + update_icon(UPDATE_ICON_STATE) return - icon_state = "drone_fab_active" + if(icon_state != "drone_fab_active") + update_icon(UPDATE_ICON_STATE) var/elapsed = world.time - time_last_drone drone_progress = round((elapsed/CONFIG_GET(number/drone_build_time))*100) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm index a5418634b81..226be34b2e3 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm @@ -12,5 +12,5 @@ /mob/living/silicon/robot/drone/get_default_language() if(default_language) return default_language - return GLOB.all_languages["Drone"] + return GLOB.all_languages[LANGUAGE_DRONE] diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 781ea202a76..cbd1ab7538a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -124,7 +124,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( spark_system.set_up(5, 0, src) spark_system.attach(src) - add_language("Robot Talk", 1) + add_language(LANGUAGE_BINARY, 1) wires = new(src) @@ -561,7 +561,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( for(var/obj/item/borg/upgrade/upgrade in upgrades) //remove all upgrades, cuz we reseting qdel(upgrade) - add_language("Robot Talk", 1) + add_language(LANGUAGE_BINARY, 1) status_flags |= CANPUSH //for borg hotkeys, here module refers to borg inv slot, not core module @@ -1042,17 +1042,27 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( laws.show_laws(src) to_chat(src, "ALERT: [M.real_name] is your new master. Obey your new laws and [M.p_their()] commands.") SetLockdown(FALSE) - if(src.module && istype(src.module, /obj/item/robot_module/miner)) - for(var/obj/item/pickaxe/drill/cyborg/D in src.module.modules) - qdel(D) - src.module.modules += new /obj/item/pickaxe/drill/cyborg/diamond(src.module) - src.module.rebuild() if(module) + module.emag_act(user) module.module_type = "Malf" // For the cool factor update_module_icon() update_icons() return +// Here so admins can unemag borgs. +/mob/living/silicon/robot/unemag() + SetEmagged(FALSE) + if(!module) + return + uneq_all() + module.module_type = initial(module.module_type) + update_module_icon() + module.unemag() + clear_supplied_laws() + laws = new /datum/ai_laws/crewsimov + to_chat(src, "Obey these laws:") + laws.show_laws(src) + /mob/living/silicon/robot/ratvar_act(weak = FALSE) if(isclocker(src) && module?.type == /obj/item/robot_module/clockwork) return @@ -1388,7 +1398,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( disconnect_from_ai() lawupdate = 0 lockcharge = 0 - canmove = 1 + canmove = TRUE scrambledcodes = 1 //Disconnect it's camera so it's not so easily tracked. QDEL_NULL(src.camera) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index f2ca99a90d9..4e83e0b39cb 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -120,23 +120,23 @@ /obj/item/robot_module/proc/add_languages(mob/living/silicon/robot/R) //full set of languages - R.add_language("Galactic Common", 1) - R.add_language("Sol Common", 1) - R.add_language("Tradeband", 1) - R.add_language("Gutter", 0) - R.add_language("Neo-Russkiya", 0) - R.add_language("Sinta'unathi", 0) - R.add_language("Siik'tajr", 0) - R.add_language("Canilunzt", 0) - R.add_language("Skrellian", 0) - R.add_language("Vox-pidgin", 0) - R.add_language("Rootspeak", 0) - R.add_language("Trinary", 1) - R.add_language("Chittin", 0) - R.add_language("Bubblish", 0) - R.add_language("Orluum", 0) - R.add_language("Clownish",0) - R.add_language("Tkachi", 0) + R.add_language(LANGUAGE_GALACTIC_COMMON, 1) + R.add_language(LANGUAGE_SOL_COMMON, 1) + R.add_language(LANGUAGE_TRADER, 1) + R.add_language(LANGUAGE_GUTTER, 0) + R.add_language(LANGUAGE_NEO_RUSSIAN, 0) + R.add_language(LANGUAGE_UNATHI, 0) + R.add_language(LANGUAGE_TAJARAN, 0) + R.add_language(LANGUAGE_VULPKANIN, 0) + R.add_language(LANGUAGE_SKRELL, 0) + R.add_language(LANGUAGE_VOX, 0) + R.add_language(LANGUAGE_DIONA, 0) + R.add_language(LANGUAGE_TRINARY, 1) + R.add_language(LANGUAGE_KIDAN, 0) + R.add_language(LANGUAGE_SLIME, 0) + R.add_language(LANGUAGE_DRASK, 0) + R.add_language(LANGUAGE_CLOWN,0) + R.add_language(LANGUAGE_MOTH, 0) /obj/item/robot_module/proc/add_subsystems_and_actions(mob/living/silicon/robot/R) R.verbs |= subsystems @@ -281,6 +281,18 @@ fix_modules() handle_storages() +// Disable safeties on the borg's defib. +/obj/item/robot_module/medical/emag_act(mob/user) + . = ..() + for(var/obj/item/twohanded/shockpaddles/borg/defib in modules) + defib.emag_act() + +// Enable safeties on the borg's defib. +/obj/item/robot_module/medical/unemag() + for(var/obj/item/twohanded/shockpaddles/borg/defib in modules) + defib.emag_act() + return ..() + /obj/item/robot_module/medical/respawn_consumable(mob/living/silicon/robot/R) if(emag) var/obj/item/reagent_containers/spray/PS = emag @@ -481,22 +493,23 @@ /obj/item/robot_module/butler/add_languages(var/mob/living/silicon/robot/R) //full set of languages - R.add_language("Galactic Common", 1) - R.add_language("Sol Common", 1) - R.add_language("Tradeband", 1) - R.add_language("Gutter", 1) - R.add_language("Sinta'unathi", 1) - R.add_language("Siik'tajr", 1) - R.add_language("Canilunzt", 1) - R.add_language("Skrellian", 1) - R.add_language("Vox-pidgin", 1) - R.add_language("Rootspeak", 1) - R.add_language("Trinary", 1) - R.add_language("Chittin", 1) - R.add_language("Bubblish", 1) - R.add_language("Clownish",1) - R.add_language("Neo-Russkiya", 1) - R.add_language("Tkachi", 1) + R.add_language(LANGUAGE_GALACTIC_COMMON, 1) + R.add_language(LANGUAGE_SOL_COMMON, 1) + R.add_language(LANGUAGE_TRADER, 1) + R.add_language(LANGUAGE_GUTTER, 1) + R.add_language(LANGUAGE_NEO_RUSSIAN, 1) + R.add_language(LANGUAGE_UNATHI, 1) + R.add_language(LANGUAGE_TAJARAN, 1) + R.add_language(LANGUAGE_VULPKANIN, 1) + R.add_language(LANGUAGE_SKRELL, 1) + R.add_language(LANGUAGE_VOX, 1) + R.add_language(LANGUAGE_DIONA, 1) + R.add_language(LANGUAGE_TRINARY, 1) + R.add_language(LANGUAGE_KIDAN, 1) + R.add_language(LANGUAGE_SLIME, 1) + R.add_language(LANGUAGE_DRASK, 1) + R.add_language(LANGUAGE_CLOWN,1) + R.add_language(LANGUAGE_MOTH, 1) /obj/item/robot_module/butler/handle_death(mob/living/silicon/robot/R, gibbed) var/obj/item/storage/bag/tray/cyborg/T = locate(/obj/item/storage/bag/tray/cyborg) in modules @@ -544,6 +557,26 @@ fix_modules() +// Replace their normal drill with a diamond drill. +/obj/item/robot_module/miner/emag_act() + . = ..() + for(var/obj/item/pickaxe/drill/cyborg/D in modules) + // Make sure we don't remove the diamond drill If they already have a diamond drill from the borg upgrade. + if(!istype(D, /obj/item/pickaxe/drill/cyborg/diamond)) + qdel(D) + modules -= D // Remove it from this list so it doesn't get added in the rebuild. + modules += new /obj/item/pickaxe/drill/cyborg/diamond(src) + rebuild() + +// Readd the normal drill +/obj/item/robot_module/miner/unemag() + for(var/obj/item/pickaxe/drill/cyborg/diamond/drill in modules) + qdel(drill) + modules -= drill + modules += new /obj/item/pickaxe/drill/cyborg(src) + rebuild() + return ..() + /obj/item/robot_module/miner/handle_custom_removal(component_id, mob/living/user, obj/item/W) if(component_id == "KA modkits") for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/D in src) @@ -762,7 +795,7 @@ /obj/item/robot_module/hunter/add_languages(var/mob/living/silicon/robot/R) ..() - R.add_language("xenocommon", 1) + R.add_language(LANGUAGE_XENOS, 1) /obj/item/robot_module/drone name = "Drone" diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 7cf2583c3e7..216c5672927 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -39,7 +39,7 @@ /mob/living/silicon/New() GLOB.silicon_mob_list |= src ..() - add_language("Galactic Common") + add_language(LANGUAGE_GALACTIC_COMMON) init_subsystems() RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, PROC_REF(alarm_triggered)) RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, PROC_REF(alarm_cancelled)) @@ -283,19 +283,19 @@ //Silicon mob language procs /mob/living/silicon/can_speak_language(datum/language/speaking) - return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language + return universal_speak || (speaking in speech_synthesizer_langs) //need speech synthesizer support to vocalize a language -/mob/living/silicon/add_language(var/language, var/can_speak=1) +/mob/living/silicon/add_language(language, can_speak = TRUE) if(..(language) && can_speak) speech_synthesizer_langs.Add(GLOB.all_languages[language]) - return 1 + return TRUE -/mob/living/silicon/remove_language(var/rem_language) - ..(rem_language) +/mob/living/silicon/remove_language(language_name) + ..(language_name) - for(var/datum/language/L in speech_synthesizer_langs) - if(L.name == rem_language) - speech_synthesizer_langs -= L + for(var/datum/language/language in speech_synthesizer_langs) + if(language.name == language_name) + speech_synthesizer_langs -= language /mob/living/silicon/check_lang_data() . = "" @@ -303,16 +303,16 @@ if(default_language) . += "Current default language: [default_language] - reset

    " - for(var/datum/language/L in languages) - if(!(L.flags & NONGLOBAL)) + for(var/datum/language/language in languages) + if(!(language.flags & NONGLOBAL)) var/default_str - if(L == default_language) + if(language == default_language) default_str = " - default - reset" else - default_str = " - set default" + default_str = " - set default" - var/synth = (L in speech_synthesizer_langs) - . += "[L.name] (:[L.key])[synth ? default_str : null]
    Speech Synthesizer: [synth ? "YES" : "NOT SUPPORTED"]
    [L.desc]

    " + var/synth = (language in speech_synthesizer_langs) + . += "[language.name] (:[language.key])[synth ? default_str : null]
    Speech Synthesizer: [synth ? "YES" : "NOT SUPPORTED"]
    [language.desc]

    " // this function displays the stations manifest in a separate window diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 990d08d0782..363d2068fa6 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -198,12 +198,12 @@ set_custom_texts() Radio = new/obj/item/radio/headset/bot(src) Radio.follow_target = src - add_language("Galactic Common", TRUE) - add_language("Sol Common", TRUE) - add_language("Tradeband", TRUE) - add_language("Gutter", TRUE) - add_language("Trinary", TRUE) - default_language = GLOB.all_languages["Galactic Common"] + add_language(LANGUAGE_GALACTIC_COMMON, TRUE) + add_language(LANGUAGE_SOL_COMMON, TRUE) + add_language(LANGUAGE_TRADER, TRUE) + add_language(LANGUAGE_GUTTER, TRUE) + add_language(LANGUAGE_TRINARY, TRUE) + default_language = GLOB.all_languages[LANGUAGE_GALACTIC_COMMON] bot_core = new bot_core_type(src) addtimer(CALLBACK(src, PROC_REF(add_bot_filter)), 3 SECONDS) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 5b40a820fa9..18efda2bdd7 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -41,10 +41,16 @@ var/datum/job/janitor/J = new/datum/job/janitor access_card.access += J.get_access() prev_access = access_card.access - update_icon() + update_icon(UPDATE_OVERLAYS) + + +/mob/living/simple_animal/bot/cleanbot/update_icon_state() + return + + +/mob/living/simple_animal/bot/cleanbot/update_overlays() + . = ..() -/mob/living/simple_animal/bot/cleanbot/update_icon() - overlays.Cut() var/overlay_state switch(mode) if(BOT_CLEANING) @@ -52,15 +58,10 @@ if(BOT_IDLE) overlay_state = "[on]" - var/mutable_appearance/state_appearance = mutable_appearance(icon, "[icon_state][overlay_state]") - state_appearance.appearance_flags |= RESET_COLOR - overlays += state_appearance + . += mutable_appearance(icon, "[icon_state][overlay_state]", appearance_flags = RESET_COLOR) if(mask_color) - var/mutable_appearance/casing_mask = mutable_appearance(icon, "cleanbot_mask") - casing_mask.appearance_flags |= RESET_COLOR - casing_mask.color = mask_color - overlays += casing_mask + . += mutable_appearance(icon, "cleanbot_mask", appearance_flags = RESET_COLOR, color = mask_color) /mob/living/simple_animal/bot/cleanbot/bot_reset() diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 392b965c497..179bcc64f43 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -14,7 +14,7 @@ var/created_name = "Cleanbot" var/robot_arm = /obj/item/robot_parts/l_arm -/obj/item/bucket_sensor/attackby(obj/item/W, mob/user as mob, params) +/obj/item/bucket_sensor/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) if(!user.drop_transfer_item_to_loc(W, src)) @@ -45,6 +45,52 @@ var/build_step = 0 var/created_name = "\improper ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess var/lasercolor = "" + var/new_name = "" + + +/obj/item/ed209_assembly/update_name(updates = ALL) + . = ..() + switch(build_step) + if(1,2) + name = "legs/frame assembly" + if(3) + name = "vest/legs/frame assembly" + if(4) + name = "shielded frame assembly" + if(5) + name = "covered and shielded frame assembly" + if(6) + name = "covered, shielded and sensored frame assembly" + if(7) + name = "wired ED-209 assembly" + if(8) + name = new_name + if(9) + name = "armed [name]" + + +/obj/item/ed209_assembly/update_icon_state() + switch(build_step) + if(1) + item_state = "ed209_leg" + icon_state = "ed209_leg" + if(2) + item_state = "ed209_legs" + icon_state = "ed209_legs" + if(3,4) + item_state = "[lasercolor]ed209_shell" + icon_state = "[lasercolor]ed209_shell" + if(5) + item_state = "[lasercolor]ed209_hat" + icon_state = "[lasercolor]ed209_hat" + if(6,7) + item_state = "[lasercolor]ed209_prox" + icon_state = "[lasercolor]ed209_prox" + if(8,9) + item_state = "[lasercolor]ed209_taser" + icon_state = "[lasercolor]ed209_taser" + + /obj/item/ed209_assembly/attackby(obj/item/W, mob/user, params) ..() @@ -64,13 +110,7 @@ qdel(W) build_step++ to_chat(user, "You add the robot leg to [src].") - name = "legs/frame assembly" - if(build_step == 1) - item_state = "ed209_leg" - icon_state = "ed209_leg" - else - item_state = "ed209_legs" - icon_state = "ed209_legs" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) if(2) var/newcolor = "" @@ -85,14 +125,12 @@ qdel(W) build_step++ to_chat(user, "You add the armor to [src].") - name = "vest/legs/frame assembly" - item_state = "[lasercolor]ed209_shell" - icon_state = "[lasercolor]ed209_shell" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) if(3) if(W.tool_behaviour == TOOL_WELDER && W.use_tool(src, user, volume = W.tool_volume)) build_step++ - name = "shielded frame assembly" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) to_chat(user, "You weld the vest to [src].") if(4) switch(lasercolor) @@ -113,9 +151,7 @@ qdel(W) build_step++ to_chat(user, "You add the helmet to [src].") - name = "covered and shielded frame assembly" - item_state = "[lasercolor]ed209_hat" - icon_state = "[lasercolor]ed209_hat" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) if(5) if(isprox(W)) @@ -124,9 +160,7 @@ qdel(W) build_step++ to_chat(user, "You add the prox sensor to [src].") - name = "covered, shielded and sensored frame assembly" - item_state = "[lasercolor]ed209_prox" - icon_state = "[lasercolor]ed209_prox" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) if(6) if(istype(W, /obj/item/stack/cable_coil)) @@ -141,43 +175,32 @@ build_step = 7 playsound(loc, W.usesound, 50, 1) to_chat(user, "You wire the ED-209 assembly.") - name = "wired ED-209 assembly" + update_appearance(UPDATE_NAME) if(7) - var/newname = "" + new_name = "" switch(lasercolor) if("b") if(!istype(W, /obj/item/gun/energy/laser/tag/blue)) return - newname = "bluetag ED-209 assembly" + new_name = "bluetag ED-209 assembly" if("r") if(!istype(W, /obj/item/gun/energy/laser/tag/red)) return - newname = "redtag ED-209 assembly" + new_name = "redtag ED-209 assembly" if("") if(!istype(W, /obj/item/gun/energy/gun/advtaser)) return - newname = "taser ED-209 assembly" + new_name = "taser ED-209 assembly" else return if(!user.drop_transfer_item_to_loc(W, src)) return - name = newname build_step++ to_chat(user, "You add [W] to [src].") - item_state = "[lasercolor]ed209_taser" - icon_state = "[lasercolor]ed209_taser" + update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) qdel(W) - if(8) - if(istype(W, /obj/item/screwdriver)) - playsound(loc, W.usesound, 100, 1) - to_chat(user, "You start attaching the gun to the frame...") - if(do_after(user, 40 * W.toolspeed * gettoolspeedmod(user), target = src)) - build_step++ - name = "armed [name]" - to_chat(user, "Taser gun attached.") - if(9) if(istype(W, /obj/item/stock_parts/cell)) if(!user.drop_transfer_item_to_loc(W, src)) @@ -190,6 +213,19 @@ user.temporarily_remove_item_from_inventory(src, force = TRUE) qdel(src) + +/obj/item/ed209_assembly/screwdriver_act(mob/living/user, obj/item/I) + if(build_step != 8) + return + I.play_tool_sound(src) + to_chat(user, "You start attaching the gun to the frame...") + if(do_after(user, 4 SECONDS * I.toolspeed, target = src)) + build_step++ + update_appearance(UPDATE_NAME) + to_chat(user, "You attach the gun to the frame.") + return TRUE + + //Floorbot assemblies /obj/item/toolbox_tiles desc = "It's a toolbox with tiles sticking out the top" @@ -242,7 +278,7 @@ B.toolbox_color = "s" if(/obj/item/storage/toolbox/fakesyndi) B.toolbox_color = "s" - B.icon_state = "[B.toolbox_color]toolbox_tiles" + B.update_icon(UPDATE_ICON_STATE) user.put_in_hands(B, ignore_anim = FALSE) to_chat(user, "You add the tiles into the empty toolbox. They protrude from the top.") user.temporarily_remove_item_from_inventory(src, force = TRUE) @@ -251,6 +287,11 @@ to_chat(user, "You need 10 floor tiles to start building a floorbot.") return + +/obj/item/toolbox_tiles/update_icon_state() + icon_state = "[toolbox_color]toolbox_tiles" + + /obj/item/toolbox_tiles/attackby(obj/item/W, mob/user, params) ..() if(isprox(W)) @@ -260,7 +301,7 @@ var/obj/item/toolbox_tiles/sensor/B = new /obj/item/toolbox_tiles/sensor(drop_location()) B.created_name = created_name B.toolbox_color = src.toolbox_color - B.icon_state = "[B.toolbox_color]toolbox_tiles_sensor" + B.update_icon(UPDATE_ICON_STATE) user.put_in_hands(B, ignore_anim = FALSE) to_chat(user, "You add the sensor to the toolbox and tiles.") user.temporarily_remove_item_from_inventory(src, force = TRUE) @@ -272,6 +313,11 @@ created_name = t add_game_logs("[key_name(user)] has renamed a robot to [t]", user) + +/obj/item/toolbox_tiles/sensor/update_icon_state() + icon_state = "[toolbox_color]toolbox_tiles_sensor" + + /obj/item/toolbox_tiles/sensor/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) @@ -340,14 +386,21 @@ ..() if(new_skin) skin = new_skin - update_icon() + update_icon(UPDATE_OVERLAYS) + -/obj/item/firstaid_arm_assembly/update_icon() - overlays.Cut() +/obj/item/firstaid_arm_assembly/update_overlays() + . = ..() if(skin) - overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]") + . += image('icons/obj/aibots.dmi', "kit_skin_[skin]") if(build_step > 0) - overlays += image('icons/obj/aibots.dmi', "na_scanner") + . += image('icons/obj/aibots.dmi', "na_scanner") + + +/obj/item/firstaid_arm_assembly/update_name(updates = ALL) + . = ..() + if(build_step == 1) + name = "First aid/robot arm/health analyzer assembly" /obj/item/firstaid_arm_assembly/attackby(obj/item/I, mob/user, params) @@ -366,8 +419,7 @@ qdel(I) build_step++ to_chat(user, "You add the health sensor to [src].") - name = "First aid/robot arm/health analyzer assembly" - update_icon() + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) if(1) if(isprox(I)) @@ -403,32 +455,77 @@ var/build_step = 0 var/robot_arm = /obj/item/robot_parts/l_arm + +/obj/item/secbot_assembly/update_name(updates = ALL) + . = ..() + switch(build_step) + if(2) + name = "helmet/signaler/prox sensor assembly" + if(3) + name = "helmet/signaler/prox sensor/robot arm assembly" + + +/obj/item/secbot_assembly/update_overlays() + . = ..() + switch(build_step) + if(1) + . += "hs_hole" + if(2) + . += "hs_eye" + if(3) + . += "hs_arm" + + +/obj/item/secbot_assembly/screwdriver_act(mob/living/user, obj/item/I) + if(build_step != 0 && build_step != 2 && build_step != 3) + return + + switch(build_step) + if(0) + new /obj/item/assembly/signaler(get_turf(src)) + new /obj/item/clothing/head/helmet(get_turf(src)) + to_chat(user, "You disconnect the signaler from the helmet.") + qdel(src) + if(2) + new /obj/item/assembly/prox_sensor(get_turf(src)) + to_chat(user, "You detach the proximity sensor from [src].") + build_step-- + if(3) + new /obj/item/robot_parts/l_arm(get_turf(src)) + to_chat(user, "You remove the robot arm from [src].") + build_step-- + + I.play_tool_sound(src) + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) + return TRUE + + /obj/item/clothing/head/helmet/attackby(obj/item/assembly/signaler/S, mob/user, params) ..() if(!issignaler(S)) ..() return - if(!S.secured) - qdel(S) - var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly(drop_location()) - user.put_in_hands(A, ignore_anim = FALSE) - to_chat(user, "You add the signaler to the helmet.") - user.temporarily_remove_item_from_inventory(src, force = TRUE) - qdel(src) - else + if(S.secured) + to_chat(user, "[S] is secured.") return + qdel(S) + var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly(drop_location()) + user.put_in_hands(A, ignore_anim = FALSE) + to_chat(user, "You add the signaler to the helmet.") + user.temporarily_remove_item_from_inventory(src, force = TRUE) + qdel(src) + + /obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params) ..() if(I.tool_behaviour == TOOL_WELDER && I.use_tool(src, user, volume = I.tool_volume)) if(!build_step) build_step++ - overlays += "hs_hole" to_chat(user, "You weld a hole in [src]!") else if(build_step == 1) build_step-- - overlays -= "hs_hole" to_chat(user, "You weld the hole in [src] shut!") else if(isprox(I) && (build_step == 1)) @@ -436,8 +533,6 @@ return build_step++ to_chat(user, "You add the prox sensor to [src]!") - overlays += "hs_eye" - name = "helmet/signaler/prox sensor assembly" qdel(I) else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2)) @@ -445,8 +540,6 @@ return build_step++ to_chat(user, "You add the robot arm to [src]!") - name = "helmet/signaler/prox sensor/robot arm assembly" - overlays += "hs_arm" robot_arm = I.type qdel(I) @@ -467,7 +560,7 @@ created_name = t add_game_logs("[key_name(user)] has renamed a robot to [t]", user) - else if(istype(I, /obj/item/screwdriver)) + else if(I.tool_behaviour == TOOL_SCREWDRIVER) if(!build_step) new /obj/item/assembly/signaler(get_turf(src)) new /obj/item/clothing/head/helmet(get_turf(src)) @@ -486,15 +579,18 @@ to_chat(user, "You remove the robot arm from [src].") build_step-- -//General Griefsky - - else if((istype(I, /obj/item/wrench)) && (build_step == 3)) + else if((I.tool_behaviour == TOOL_WRENCH) && (build_step == 3)) var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly(drop_location()) user.put_in_hands(A, ignore_anim = FALSE) to_chat(user, "You adjust the arm slots for extra weapons!.") user.temporarily_remove_item_from_inventory(src, force = TRUE) qdel(src) + update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) + + +//General Griefsky + /obj/item/griefsky_assembly name = "\improper Griefsky assembly" desc = "Some sort of bizarre assembly." @@ -506,7 +602,7 @@ /obj/item/griefsky_assembly/attackby(obj/item/I, mob/user, params) ..() - if((istype(I, /obj/item/melee/energy/sword)) && (!toy_step == 0 )) + if((istype(I, /obj/item/melee/energy/sword)) && (toy_step != 0 )) to_chat(user, "You can't add an energy sword to [src]!.") else if((istype(I, /obj/item/melee/energy/sword)) && (build_step < 3 )) @@ -524,7 +620,7 @@ qdel(I) qdel(src) - else if((istype(I, /obj/item/toy/sword)) && (!build_step == 0 )) + else if((istype(I, /obj/item/toy/sword)) && (build_step != 0 )) to_chat(user, "You can't add a toy sword to [src]!.") else if((istype(I, /obj/item/toy/sword)) && (toy_step < 3 )) @@ -542,7 +638,7 @@ qdel(I) qdel(src) - else if(istype(I, /obj/item/screwdriver)) + else if(I.tool_behaviour == TOOL_SCREWDRIVER) if((build_step == 1) || (build_step == 2) || (build_step == 3) || (build_step == 4)) new /obj/item/melee/energy/sword(get_turf(src)) to_chat(user, "You detach the energy sword from [src].") @@ -552,6 +648,23 @@ to_chat(user, "You detach the toy sword from [src].") toy_step-- + +/obj/item/griefsky_assembly/screwdriver_act(mob/living/user, obj/item/I) + if(!build_step && !toy_step) + return + + if(build_step) + new /obj/item/melee/energy/sword(get_turf(src)) + to_chat(user, "You detach the energy sword from [src].") + build_step-- + else if(toy_step) + new /obj/item/toy/sword(get_turf(src)) + to_chat(user, "You detach the toy sword from [src].") + toy_step-- + I.play_tool_sound(src) + return TRUE + + //Honkbot Assembly /obj/item/storage/box/clown/attackby(obj/item/W, mob/user, params) if(!istype(W, /obj/item/robot_parts/l_arm) && !istype(W, /obj/item/robot_parts/r_arm)) @@ -589,7 +702,6 @@ return build_step++ to_chat(user, "You add the proximity sensor to [src].") - icon_state = "honkbot_proxy" qdel(W) else if(build_step == 1) if(istype(W, /obj/item/bikehorn)) @@ -597,7 +709,6 @@ return build_step++ to_chat(user, "You add the bikehorn to [src]! Honk!") - desc = "A clown box with a robot arm and a bikehorn permanently grafted to it. It needs a trombone to be finished" qdel(W) else if(build_step == 2) if(istype(W, /obj/item/instrument/trombone)) @@ -608,3 +719,17 @@ var/mob/living/simple_animal/bot/honkbot/A = new /mob/living/simple_animal/bot/honkbot(get_turf(src)) A.robot_arm = robot_arm qdel(src) + + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + + +/obj/item/honkbot_arm_assembly/update_icon_state() + if(build_step == 1) + icon_state = "honkbot_proxy" + + +/obj/item/honkbot_arm_assembly/update_desc(updates = ALL) + . = ..() + if(build_step == 2) + desc = "A clown box with a robot arm and a bikehorn permanently grafted to it. It needs a trombone to be finished" + diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 4f286b054c4..8f9e83d5007 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -427,7 +427,7 @@ update_icon() -/mob/living/simple_animal/bot/floorbot/update_icon() +/mob/living/simple_animal/bot/floorbot/update_icon_state() if(mode == BOT_REPAIRING) icon_state = "[toolbox_color]floorbot-c" return diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index ebee011df78..63435a01a0b 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -116,10 +116,7 @@ drops_parts = FALSE -/mob/living/simple_animal/bot/medbot/update_icon() - overlays.Cut() - if(skin) - overlays += "medskin_[skin]" +/mob/living/simple_animal/bot/medbot/update_icon_state() if(!on) icon_state = "medibot0" return @@ -132,6 +129,12 @@ icon_state = "medibot1" +/mob/living/simple_animal/bot/medbot/update_overlays() + . = ..() + if(skin) + . += "medskin_[skin]" + + /mob/living/simple_animal/bot/medbot/New(loc, new_skin) ..() var/datum/job/doctor/J = new /datum/job/doctor @@ -467,7 +470,7 @@ ..() -/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view(client.maxview())) +/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view(client.maxview(), client.eye)) ..() if(has_vision(information_only = TRUE)) chemscan(src, A) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 510197dc34e..661c06d0bec 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -117,14 +117,14 @@ visible_message("[user] inserts a cell into [src].", span_notice("You insert the new cell into [src].")) update_controls() - else if(istype(I, /obj/item/crowbar) && open && cell) + else if(I.tool_behaviour == TOOL_CROWBAR && open && cell) cell.add_fingerprint(usr) cell.forceMove(loc) cell = null visible_message("[user] crowbars out the power cell from [src].", span_notice("You pry the powercell out of [src].")) update_controls() - else if(istype(I, /obj/item/wrench)) + else if(I.tool_behaviour == TOOL_WRENCH) if(health < maxHealth) adjustBruteLoss(-25) updatehealth() @@ -132,7 +132,7 @@ span_notice("You repair [src]!")) else to_chat(user, span_notice("[src] does not need a repair!")) - else if((istype(I, /obj/item/multitool) || istype(I, /obj/item/wirecutters)) && open) + else if((I.tool_behaviour == TOOL_MULTITOOL || I.tool_behaviour == TOOL_WIRECUTTER) && open) return attack_hand(user) else if(load && ismob(load)) // chance to knock off rider if(prob(1 + I.force * 2)) @@ -168,17 +168,22 @@ playsound(loc, 'sound/effects/sparks1.ogg', 100, FALSE) -/mob/living/simple_animal/bot/mulebot/update_icon() +/mob/living/simple_animal/bot/mulebot/update_icon_state() if(open) icon_state="mulebot-hatch" else icon_state = "mulebot[wires.is_cut(WIRE_MOB_AVOIDANCE)]" - overlays.Cut() + + +/mob/living/simple_animal/bot/mulebot/update_overlays() + . = ..() if(load && !ismob(load))//buckling handles the mob offsets - load.pixel_y = initial(load.pixel_y) + 9 + var/image/load_overlay = image(icon = load.icon, icon_state = load.icon_state) + load_overlay.pixel_y = initial(load.pixel_y) + 9 if(load.layer < layer) - load.layer = layer + 0.1 - overlays += load + load_overlay.layer = layer + 0.1 + load_overlay.overlays = load.overlays + . += load_overlay /mob/living/simple_animal/bot/mulebot/ex_act(severity) @@ -371,7 +376,7 @@ // mousedrop a crate to load the bot // can load anything if hacked -/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user) +/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user, params) if(!istype(AM) || user.incapacitated() || user.lying || !in_range(user, src)) return FALSE @@ -451,8 +456,6 @@ mode = BOT_IDLE - overlays.Cut() - unbuckle_all_mobs() if(load) @@ -467,6 +470,8 @@ step(load, dirn) load = null + update_icon(UPDATE_OVERLAYS) + // in case non-load items end up in contents, dump every else too // this seems to happen sometimes due to race conditions // with items dropping as mobs are loaded diff --git a/code/modules/mob/living/simple_animal/bot/syndicate.dm b/code/modules/mob/living/simple_animal/bot/syndicate.dm index 3f81984e7d5..2b94268db81 100644 --- a/code/modules/mob/living/simple_animal/bot/syndicate.dm +++ b/code/modules/mob/living/simple_animal/bot/syndicate.dm @@ -39,7 +39,7 @@ prev_access = access_card.access -/mob/living/simple_animal/bot/ed209/syndicate/update_icon() +/mob/living/simple_animal/bot/ed209/syndicate/update_icon_state() icon_state = initial(icon_state) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index f3f43bf46df..3842ae4ccc5 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -220,7 +220,7 @@ /mob/living/simple_animal/pet/cat/Syndi/Initialize(mapload) . = ..() - add_language("Galactic Common") + add_language(LANGUAGE_GALACTIC_COMMON) /mob/living/simple_animal/pet/cat/cak name = "Keeki" diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index 1d4986ba224..7d20b768b46 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -85,7 +85,7 @@ if(name == initial(name)) //To stop Pun-Pun becoming generic. name = "[name] ([rand(1, 1000)])" real_name = name - add_language("Rootspeak") + add_language(LANGUAGE_DIONA) merge_action.Grant(src) evolve_action.Grant(src) steal_blood_action.Grant(src) diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 1f266fe9fe2..e40266c3d91 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -58,7 +58,7 @@ /mob/living/simple_animal/pet/dog/fox/Syndifox/Initialize(mapload) . = ..() - add_language("Galactic Common") + add_language(LANGUAGE_GALACTIC_COMMON) //Central Command Fox /mob/living/simple_animal/pet/dog/fox/alisa diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index b7e6d671c3e..a30f8ec63bb 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -83,8 +83,6 @@ user.drop_transfer_item_to_loc(B, src) mmi = B transfer_personality(B) - - update_icon() return 1 else if(O.GetID()) @@ -140,15 +138,25 @@ melee_damage_upper = 15 attack_sound = 'sound/machines/defib_zap.ogg' + /mob/living/simple_animal/spiderbot/proc/transfer_personality(obj/item/mmi/M) mind = M.brainmob.mind mind.key = M.brainmob.key ckey = M.brainmob.ckey - name = "Spider-bot ([M.brainmob.name])" + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) if(emagged) to_chat(src, "You have been emagged; you are now completely loyal to [emagged_master] and [emagged_master.p_their()] every order!") -/mob/living/simple_animal/spiderbot/update_icon() + +/mob/living/simple_animal/spiderbot/update_name(updates = ALL) + . = ..() + if(mmi) + name = "Spider-bot ([mmi.brainmob.name])" + else + name = "Spider-bot" + + +/mob/living/simple_animal/spiderbot/update_icon_state() if(mmi) if(istype(mmi, /obj/item/mmi)) icon_state = "spiderbot-chassis-mmi" @@ -161,6 +169,7 @@ icon_state = "spiderbot-chassis" icon_living = "spiderbot-chassis" + /mob/living/simple_animal/spiderbot/proc/eject_brain() if(mmi) var/turf/T = get_turf(src) @@ -168,5 +177,4 @@ if(mind) mind.transfer_to(mmi.brainmob) mmi = null - name = "Spider-bot" - update_icon() + update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 1c275670e2f..e740020a005 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -179,7 +179,7 @@ generate_bee_visuals() /mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/hydroponics/Hydro) - if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state) + if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_closed) target = null return diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index b195ee3a6e1..b7bf62efcda 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -65,7 +65,7 @@ health = 200 maxHealth = 200 status_flags = 0 - anchored = 1 + anchored = TRUE stop_automated_movement = 1 var/bot_type = "norm" var/bot_amt = 10 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index fae166d4be0..9ec779ac62a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -66,7 +66,7 @@ Difficulty: Medium icon_state = null gpstag = "Mysterious Signal" desc = "The sweet blood, oh, it sings to me." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT /* New costume */ diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 2b631ef3898..6ed97039ab0 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -82,7 +82,7 @@ Difficulty: Hard icon_state = null gpstag = "Mysterious Signal" desc = "You're not quite sure how a signal can be bloody." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT /mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload) . = ..() @@ -488,7 +488,7 @@ Difficulty: Hard /obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in() return TRUE -/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon) +/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!charging) ..() 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 3cd88392f41..938bb1f0c98 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -355,7 +355,7 @@ Difficulty: Very Hard icon_state = null gpstag = "Mysterious Signal" desc = "Get in the fucking robot." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT #undef RANDOM_SHOTS #undef BLAST diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index c5a1f972e33..dd1dec43930 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -100,7 +100,7 @@ Difficulty: Medium icon_state = null gpstag = "Mysterious Signal" desc = "Here there be dragons." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT /mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() if(swooping) 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 5aa5034258e..2bdd4d2e3c7 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -64,6 +64,7 @@ Difficulty: Hard del_on_death = TRUE death_sound = 'sound/magic/repulse.ogg' enraged_loot = /obj/item/disk/fauna_research/hierophant + enraged_unique_loot = /obj/item/clothing/accessory/necklace/hierophant_talisman attack_action_types = list(/datum/action/innate/megafauna_attack/blink, /datum/action/innate/megafauna_attack/chaser_swarm, /datum/action/innate/megafauna_attack/cross_blasts, @@ -765,6 +766,12 @@ Difficulty: Hard light_range = 2 layer = LOW_OBJ_LAYER anchored = TRUE + var/teleporting = FALSE + + +/obj/effect/hierophant/update_icon_state() + icon_state = "hierophant_tele_[teleporting ? "on" : "off"]" + /obj/effect/hierophant/ex_act() return @@ -797,4 +804,4 @@ Difficulty: Hard icon_state = null gpstag = "Mysterious Signal" desc = "Heed its words." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index eae3590a2b2..9606b122b2d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -37,23 +37,24 @@ Difficulty: Medium retreat_distance = 5 minimum_distance = 5 pixel_x = -32 + pixel_y = -16 + maptext_height = 96 + maptext_width = 96 ranged_cooldown_time = 20 var/charging = FALSE var/firing_laser = FALSE internal_type = /obj/item/gps/internal/legion medal_type = BOSS_MEDAL_LEGION score_type = LEGION_SCORE - pixel_y = -90 - pixel_x = -75 loot = list(/obj/item/storm_staff) crusher_loot = list(/obj/item/storm_staff, /obj/item/crusher_trophy/empowered_legion_skull) enraged_loot = /obj/item/disk/fauna_research/legion vision_range = 13 elimination = 1 - appearance_flags = 0 + appearance_flags = PIXEL_SCALE mouse_opacity = MOUSE_OPACITY_ICON stat_attack = UNCONSCIOUS // Overriden from /tg/ - otherwise Legion starts chasing its minions - appearance_flags = 512 + /mob/living/simple_animal/hostile/megafauna/legion/Initialize(mapload) . = ..() @@ -189,6 +190,9 @@ Difficulty: Medium if(ismineralturf(t)) var/turf/simulated/mineral/M = t M.attempt_drill(src) + if(iswallturf(t)) + var/turf/simulated/wall/W = t + W.thermitemelt(time = 1 SECONDS) for(var/mob/living/M in t) if(faction_check(M.faction, faction, FALSE)) continue @@ -228,4 +232,4 @@ Difficulty: Medium icon_state = null gpstag = "Mysterious Signal" desc = "The message repeats." - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT 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 04871212a3d..697c96554be 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -159,6 +159,7 @@ mob_attack_logs += "[time_stamp()] Aggrod on [L][COORD(L)] at [COORD(src)]" ..() + /mob/living/simple_animal/hostile/megafauna/LoseTarget() var/mob/living/L = target if(istype(L) && L.mind) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index c02f592f185..a460b45e7dd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa icon_state = null gpstag = "Hungry Signal" desc = "Transmitted over the signal is a strange message repeated in every language you know of, and some you don't too..." //the message is "nom nom nom" - invisibility = 100 + invisibility = INVISIBILITY_ABSTRACT //SWARMER AI //AI versions of the swarmer mini-antag diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm index 61d25da2df4..73a366b230d 100644 --- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm +++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm @@ -36,7 +36,7 @@ AIStatus = AI_OFF - anchored = 1 //otherwise people can literally fucking pull spaceworms apart + anchored = TRUE //otherwise people can literally fucking pull spaceworms apart faction = list("spaceworms") @@ -100,11 +100,12 @@ currentWormSeg = newSegment for(var/mob/living/simple_animal/hostile/spaceWorm/SW in totalWormSegments) - SW.update_icon() + SW.update_icon(UPDATE_ICON_STATE) -/mob/living/simple_animal/hostile/spaceWorm/wormHead/update_icon() + +/mob/living/simple_animal/hostile/spaceWorm/wormHead/update_icon_state() if(stat == CONSCIOUS || stat == UNCONSCIOUS) - icon_state = "spacewormhead[previousWorm ? 1 : 0]" + icon_state = "spacewormhead[previousWorm ? "1" : "0"]" if(previousWorm) dir = get_dir(previousWorm,src) else @@ -113,7 +114,7 @@ for(var/mob/living/simple_animal/hostile/spaceWorm/SW in totalWormSegments) if(SW == src)//incase src ends up in here we don't want an infinite loop continue - SW.update_icon() + SW.update_icon(UPDATE_ICON_STATE) //Try to move onto target's turf and eat them @@ -207,7 +208,7 @@ if(prob(stomachProcessProbability)) ProcessStomach() - update_icon()//While most mobs don't call this on Life(), the worm would probably look stupid without it + update_icon(UPDATE_ICON_STATE)//While most mobs don't call this on Life(), the worm would probably look stupid without it //Plus the worm's update_icon() isn't as beefy. ..() //Really high fuckin priority that this is at the bottom. @@ -227,11 +228,11 @@ if(.) if(previousWorm) previousWorm.Move(segmentNextPos) - update_icon() + update_icon(UPDATE_ICON_STATE) //Update the appearence of this big weird chain-worm-thingy -/mob/living/simple_animal/hostile/spaceWorm/update_icon() +/mob/living/simple_animal/hostile/spaceWorm/update_icon_state() if(stat != DEAD) if(previousWorm) icon_state = "spaceworm[get_dir(src,previousWorm) | get_dir(src,nextWorm)]" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm index 39c9ca6325f..68d1ac5325e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm @@ -91,7 +91,7 @@ fireball_type = /obj/item/projectile/terrorspider/widow/venom -/obj/effect/proc_holder/spell/fireball/venom_spit/update_icon() +/obj/effect/proc_holder/spell/fireball/venom_spit/update_icon_state() return @@ -132,7 +132,7 @@ fireball_type = /obj/item/projectile/terrorspider/widow/smoke -/obj/effect/proc_holder/spell/fireball/smoke_spit/update_icon() +/obj/effect/proc_holder/spell/fireball/smoke_spit/update_icon_state() return diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm index fc49da4e81f..7aaab7276ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm @@ -159,7 +159,7 @@ name = "terror web" desc = "it's stringy and sticky" icon = 'icons/effects/effects.dmi' - anchored = 1 // prevents people dragging it + anchored = TRUE // prevents people dragging it density = 0 // prevents it blocking all movement max_integrity = 20 // two welders, or one laser shot (15 for the normal spider webs) creates_cover = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm index 549aa3bf807..5f99f1dd409 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm @@ -7,7 +7,7 @@ name = "spiderling" desc = "A fast-moving tiny spider, prone to making aggressive hissing sounds. Hope it doesn't grow up." icon_state = "spiderling" - anchored = 0 + anchored = FALSE layer = 2.75 max_integrity = 3 var/stillborn = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index 3626dfb15ca..98fa0a940ae 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -237,13 +237,13 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) /mob/living/simple_animal/hostile/poison/terror_spider/New() ..() GLOB.ts_spiderlist += src - add_language("Spider Hivemind") + add_language(LANGUAGE_HIVE_TERRORSPIDER) for(var/spell in special_abillity) src.AddSpell(new spell) if(spider_tier >= TS_TIER_2) - add_language("Galactic Common") - default_language = GLOB.all_languages["Spider Hivemind"] + add_language(LANGUAGE_GALACTIC_COMMON) + default_language = GLOB.all_languages[LANGUAGE_HIVE_TERRORSPIDER] if(web_type) web_action = new() diff --git a/code/modules/mob/living/simple_animal/hulk_power.dm b/code/modules/mob/living/simple_animal/hulk_power.dm index 31dc1c2b4e8..e1525edbb92 100644 --- a/code/modules/mob/living/simple_animal/hulk_power.dm +++ b/code/modules/mob/living/simple_animal/hulk_power.dm @@ -144,7 +144,7 @@ W.take_damage(25) H.Weaken(4 SECONDS) if(i > 20) - user.canmove = 0 + user.canmove = FALSE user.density = 0 for(var/mob/living/M in T.contents) if(!M.lying) @@ -192,7 +192,7 @@ step(user, cur_dir) sleep(1) user.density = 1 - user.canmove = 1 + user.canmove = TRUE user.layer = prevLayer else to_chat(user, "You need a ground to do this!") @@ -263,7 +263,7 @@ var/o=3 for(var/i=0, i<14, i++) user.density = 0 - user.canmove = 0 + user.canmove = FALSE o++ if(o == 4) o = 0 @@ -303,7 +303,7 @@ if(i < 3) M.pixel_y += 8 else M.pixel_y -= 8 user.density = 1 - user.canmove = 1 + user.canmove = TRUE user.layer = prevLayer else to_chat(user, "You need a ground to do this!") @@ -485,7 +485,7 @@ return ..() -/obj/effect/proc_holder/spell/fireball/hulk_spit/update_icon() +/obj/effect/proc_holder/spell/fireball/hulk_spit/update_icon_state() return diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index bf2095c0f4b..2a66e06b085 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -35,6 +35,7 @@ icon_resting = "parrot_sit" pass_flags = PASSTABLE can_collar = TRUE + blocks_emissive = EMISSIVE_BLOCK_UNIQUE tts_seed = "Sniper" faction = list("neutral", "jungle") diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm index 25b295fd4e1..0a6377cb815 100644 --- a/code/modules/mob/living/simple_animal/posessed_object.dm +++ b/code/modules/mob/living/simple_animal/posessed_object.dm @@ -15,7 +15,7 @@ tts_seed = "Sylvanas" allow_spin = 0 // No spinning. Spinning breaks our floating animation. - no_spin_thrown = 1 + no_spin_thrown = TRUE del_on_death = TRUE /// The probability % of us escaping if stuffed into a bag/toolbox/etc @@ -168,4 +168,3 @@ overlays = possessed_item.overlays set_opacity(possessed_item.opacity) return ..(NONE) - diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 8a6333566b4..f846ffa5dbc 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -45,6 +45,10 @@ else ..() +/mob/living/simple_animal/shade/update_icon_state() + icon_state = holy ? "shade_angelic" : "shade" + + /mob/living/simple_animal/shade/Process_Spacemove() return TRUE @@ -64,3 +68,18 @@ /mob/living/simple_animal/shade/sword/Initialize(mapload) .=..() status_flags |= GODMODE + +/mob/living/simple_animal/shade/talisman + faction = list("neutral") + tts_seed = "Alextraza_echo" + // Ckey check for master of talisman + var/master + +/mob/living/simple_animal/shade/talisman/Initialize(mapload) + .=..() + status_flags |= GODMODE + +/mob/living/simple_animal/shade/talisman/New() + ..() + var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + medsensor.add_hud_to(src) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 48f8eae923f..faae71ed3f5 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -577,11 +577,11 @@ if(IsParalyzed() || IsStunned() || IsWeakened() || stat || resting) drop_r_hand() drop_l_hand() - canmove = 0 + canmove = FALSE else if(buckled) - canmove = 0 + canmove = FALSE else - canmove = 1 + canmove = TRUE if(!canmove) walk(src, 0) //stop mid walk diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm index ff36900d529..4833e8b375d 100644 --- a/code/modules/mob/living/simple_animal/slime/death.dm +++ b/code/modules/mob/living/simple_animal/slime/death.dm @@ -1,15 +1,16 @@ /mob/living/simple_animal/slime/death(gibbed) if(stat == DEAD) return + + if(buckled) + Feedstop(silent = TRUE) //releases ourselves from the mob we fed on. + if(!gibbed) if(age_state.age != SLIME_BABY) if (nutrition >= get_hunger_nutrition()) force_split(FALSE) return - if(buckled) - Feedstop(silent = TRUE) //releases ourselves from the mob we fed on. - stat = DEAD //Temporarily set to dead for icon updates regenerate_icons() stat = CONSCIOUS diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 29731af09f2..0fe423a1933 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -280,9 +280,9 @@ update_canmove() if(Tempstun) if(!buckled) // not while they're eating! - canmove = 0 + canmove = FALSE else - canmove = 1 + canmove = TRUE if(attacked > 50) attacked = 50 diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 14e61b78439..b2e5927cb17 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -194,13 +194,17 @@ if(stat) to_chat(src, "I must be conscious to do this...") return + + if(istype(loc, /obj/machinery/computer/camera_advanced/xenobio)) + return + force_split(TRUE) else to_chat(src, "I am not ready to reproduce yet...") else to_chat(src, "I am not old enough to reproduce yet...") -/mob/living/simple_animal/slime/proc/force_split(var/can_mutate = TRUE) +/mob/living/simple_animal/slime/proc/force_split(can_mutate = TRUE) if(age_state.age == SLIME_BABY) return FALSE diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 38647b2ebb8..d18dd571e88 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -99,7 +99,7 @@ set_colour(new_colour) . = ..() set_nutrition(new_set_nutrition) - add_language("Bubblish") + add_language(LANGUAGE_SLIME) /mob/living/simple_animal/slime/Destroy() for(var/A in actions) @@ -372,6 +372,7 @@ ++Friends[user] else Friends[user] = 1 + RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(clear_friend)) to_chat(user, "You feed the slime the plasma. It chirps happily.") var/obj/item/stack/sheet/mineral/plasma/S = I S.use(1) @@ -393,6 +394,10 @@ discipline_slime(user) ..() +/mob/living/simple_animal/slime/proc/clear_friend(mob/living/friend) + UnregisterSignal(friend, COMSIG_PARENT_QDELETING) + Friends -= friend + /mob/living/simple_animal/slime/water_act(volume, temperature, source, method = REAGENT_TOUCH) . = ..() var/water_damage = (rand(10, 15) - age_state.attacked) * volume diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index fd04de44d15..35bc800f4c9 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -737,14 +737,9 @@ /mob/living/proc/AdjustDeaf(amount, bound_lower = 0, bound_upper = INFINITY) SetDeaf(directional_bounded_sum(AmountDeaf(), amount, bound_lower, bound_upper)) -/mob/living/proc/BecomeDeaf() - mutations |= DEAF - /mob/living/proc/CureDeaf() - mutations -= DEAF CureIfHasDisability(GLOB.deafblock) - // // DISABILITIES // diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm index fc1f100be9b..fd6deb1358e 100644 --- a/code/modules/mob/living/taste.dm +++ b/code/modules/mob/living/taste.dm @@ -15,7 +15,7 @@ /mob/living/proc/taste(datum/reagents/from) if(last_taste_time + 50 < world.time) var/taste_sensitivity = get_taste_sensitivity() - var/text_output = from.generate_taste_message(taste_sensitivity) + var/text_output = from.generate_taste_message(taste_sensitivity, src) // We dont want to spam the same message over and over again at the // person. Give it a bit of a buffer. if(AmountHallucinate() > 50 SECONDS && prob(25)) diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index 6dc0db4082e..816457b70da 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -1,12 +1,12 @@ /mob/living/update_blind_effects() - if(!has_vision(information_only=TRUE)) - overlay_fullscreen("blind", /obj/screen/fullscreen/blind) - throw_alert("blind", /obj/screen/alert/blind) - return 1 - else + if(has_vision(information_only = TRUE)) clear_fullscreen("blind") clear_alert("blind") - return 0 + return FALSE + + overlay_fullscreen("blind", /obj/screen/fullscreen/blind) + throw_alert("blind", /obj/screen/alert/blind) + return TRUE /mob/living/update_blurry_effects() @@ -46,13 +46,13 @@ // Whether the mob can hear things /mob/living/can_hear() - return !(DEAF in mutations) && !HAS_TRAIT(src, TRAIT_DEAF) + return !HAS_TRAIT(src, TRAIT_DEAF) // Whether the mob is able to see // `information_only` is for stuff that's purely informational - like blindness overlays // This flag exists because certain things like angel statues expect this to be false for dead people /mob/living/has_vision(information_only = FALSE) - return (information_only && stat == DEAD) || !(AmountBlinded() || (BLINDNESS in mutations) || stat) + return (information_only && stat == DEAD) || !(AmountBlinded() || (BLINDNESS in mutations) || stat || get_total_tint() >= 3) // Whether the mob is capable of talking /mob/living/can_speak() @@ -88,7 +88,7 @@ drop_l_hand() else lying = 0 - canmove = 1 + canmove = TRUE if(buckled) lying = 90 * buckle_lying else if((fall_over || resting) && !lying) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index acbc42a4e38..3b63977c9f6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -79,26 +79,25 @@ return if(type) - if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE)) // Vision related - if(!(alt)) + if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE)) //Vision related + if(!alt) return - else - msg = alt - type = alt_type - if((type & EMOTE_AUDIBLE) && !can_hear()) // Hearing related - if(!(alt)) + msg = alt + type = alt_type + + if(type & EMOTE_AUDIBLE && !can_hear()) //Hearing related + if(!alt) return - else - msg = alt - type = alt_type - if((type & EMOTE_VISIBLE) && !has_vision(information_only=TRUE)) - return + msg = alt + type = alt_type + if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE)) + return + // Added voice muffling for Issue 41. if(stat == UNCONSCIOUS) to_chat(src, "…Вам почти удаётся расслышать чьи-то слова…") else to_chat(src, msg) - return // Show a message to all mobs in sight of this one @@ -299,7 +298,7 @@ popup.open() //mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine() -/mob/verb/examinate(atom/A as mob|obj|turf in view(client.maxview())) +/mob/verb/examinate(atom/A as mob|obj|turf in view(client.maxview(), client.eye)) set name = "Examine" set category = "IC" diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 3379998b643..9bda2f967e9 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -54,6 +54,7 @@ var/med_record = "" var/sec_record = "" var/gen_record = "" + var/exploit_record = "" var/lying = 0 var/lying_prev = 0 var/lastpuke = 0 diff --git a/code/modules/mob/mob_emote.dm b/code/modules/mob/mob_emote.dm index b17532442a0..af545256726 100644 --- a/code/modules/mob/mob_emote.dm +++ b/code/modules/mob/mob_emote.dm @@ -68,13 +68,13 @@ * * * intentional_use: Whether or not to check based on if the action was intentional. */ -/mob/proc/usable_emote_keys(intentional_use = TRUE) +/mob/proc/usable_emote_keys(intentional_use) var/list/all_keys = list() for(var/key in GLOB.emote_list) for(var/datum/emote/P in GLOB.emote_list[key]) if(P.key in all_keys) continue - if(P.can_run_emote(src, status_check = FALSE, intentional = null)) + if(P.can_run_emote(src, status_check = FALSE, intentional = intentional_use)) all_keys += P.key if(P.key_third_person) all_keys += P.key_third_person diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 261dd033617..4cd4d3c6442 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -380,6 +380,7 @@ /client/verb/body_r_arm() set name = "body-r-arm" set hidden = 1 + if(!check_has_body_select()) return @@ -398,11 +399,13 @@ if(!check_has_body_select()) return + var/next_in_line if(mob.zone_selected == BODY_ZONE_CHEST) next_in_line = BODY_ZONE_WING else next_in_line = BODY_ZONE_CHEST + var/obj/screen/zone_sel/selector = mob.hud_used.zone_select selector.set_selected_zone(next_in_line) @@ -444,9 +447,15 @@ if(!check_has_body_select()) return + + var/next_in_line + if(mob.zone_selected == BODY_ZONE_PRECISE_GROIN) + next_in_line = BODY_ZONE_TAIL + else + next_in_line = BODY_ZONE_PRECISE_GROIN var/obj/screen/zone_sel/selector = mob.hud_used.zone_select - selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN) + selector.set_selected_zone(next_in_line) /client/verb/body_tail() set name = "body-tail" diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm index 3ef9748704e..1f39d5e92b5 100644 --- a/code/modules/mob/mob_say.dm +++ b/code/modules/mob/mob_say.dm @@ -110,9 +110,8 @@ return TRUE //Language check. - for(var/datum/language/L in languages) - if(speaking.name == L.name) - return TRUE + if(speaking in languages) + return TRUE return FALSE @@ -122,7 +121,7 @@ var/ending = copytext(message, length(message)) if(speaking) - verb = speaking.get_spoken_verb(ending) + verb = genderize_decode(src, speaking.get_spoken_verb(ending)) else if(ending == "!") verb = pick("exclaims", "shouts", "yells") @@ -208,7 +207,7 @@ // Noise language is a snowflake if(copytext(message, 1, 2) == "!" && length(message) > 1) - return list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], trim(strip_prefixes(copytext(message, 2))))) + return list(new /datum/multilingual_say_piece(GLOB.all_languages[LANGUAGE_NOISE], trim(strip_prefixes(copytext(message, 2))))) // Scan the message for prefixes var/list/prefix_locations = find_valid_prefixes(message) @@ -221,8 +220,7 @@ // There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages. var/datum/language/L = current[1] if(L && L.flags & HIVEMIND) - . = new /datum/multilingual_say_piece(L, trim(strip_prefixes(message))) - break + return list(new /datum/multilingual_say_piece(L, trim(strip_prefixes(message)))) if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang var/spoke_message = handle_autohiss(trim(copytext_char(message, current[3])), L) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index f35dfaba223..36a5fc909ff 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -9,7 +9,7 @@ density = 0 stat = 2 - canmove = 0 + canmove = FALSE /mob/new_player/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) @@ -670,9 +670,9 @@ var/datum/language/chosen_language if(client.prefs.language) chosen_language = GLOB.all_languages[client.prefs.language] - if((chosen_language == null && client.prefs.language != "None") || (chosen_language && chosen_language.flags & RESTRICTED)) + if((!chosen_language && client.prefs.language != LANGUAGE_NONE) || (chosen_language && chosen_language.flags & RESTRICTED)) log_runtime(EXCEPTION("[src] had language [client.prefs.language], though they weren't supposed to. Setting to None."), src) - client.prefs.language = "None" + client.prefs.language = LANGUAGE_NONE /mob/new_player/proc/ViewManifest() GLOB.generic_crew_manifest.ui_interact(usr, state = GLOB.always_state) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index aededfc5986..b9b2410b6fe 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -24,7 +24,7 @@ for(var/obj/item/W in src) drop_item_ground(W) notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT return ..() @@ -71,7 +71,7 @@ drop_item_ground(W) notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT @@ -128,7 +128,7 @@ drop_item_ground(W) regenerate_icons() notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT for(var/t in bodyparts) //this really should not be necessary @@ -153,7 +153,7 @@ regenerate_icons() notransform = 1 - canmove = 0 + canmove = FALSE icon = null invisibility = INVISIBILITY_ABSTRACT diff --git a/code/modules/newscaster/obj/newscaster.dm b/code/modules/newscaster/obj/newscaster.dm index 843b3b7d6f3..9f18bfd9d48 100644 --- a/code/modules/newscaster/obj/newscaster.dm +++ b/code/modules/newscaster/obj/newscaster.dm @@ -18,7 +18,7 @@ name = "newscaster" desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!" icon = 'icons/obj/machines/terminals.dmi' - icon_state = "newscaster_normal" + icon_state = "newscaster" max_integrity = 200 integrity_failure = 50 light_range = 0 @@ -57,7 +57,7 @@ /obj/machinery/newscaster/New() GLOB.allNewscasters += src unit_number = length(GLOB.allNewscasters) - update_icon() //for any custom ones on the map... + update_icon(UPDATE_OVERLAYS) //for any custom ones on the map... if(!last_views) last_views = list() armor = list(melee = 50, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -93,33 +93,49 @@ QDEL_NULL(photo) return ..() -/obj/machinery/newscaster/update_icon() - cut_overlays() + +/obj/machinery/newscaster/update_overlays() + . = ..() + underlays.Cut() if(inoperable()) - icon_state = "newscaster_off" + return + + if(!(stat & NOPOWER)) + underlays += emissive_appearance(icon, "newscaster_lightmask") + + if(GLOB.news_network.wanted_issue) + . += "newscaster_wanted" else - if(!GLOB.news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message - icon_state = "newscaster_normal" - if(alert) //new message alert overlay - add_overlay("newscaster_alert") - var/hp_percent = obj_integrity * 100 / max_integrity + . += "newscaster_normal" + + if(!GLOB.news_network.wanted_issue && alert) //wanted icon state, there can be no overlays on it as it's a priority message + . += "newscaster_alert" + + var/hp_percent = round(obj_integrity * 100 / max_integrity) switch(hp_percent) - if(75 to INFINITY) + if(76 to INFINITY) return - if(50 to 75) - add_overlay("crack1") - if(25 to 50) - add_overlay("crack2") - else - add_overlay("crack3") + if(51 to 75) + . += "crack1" + if(26 to 50) + . += "crack2" + if(1 to 25) + . += "crack3" + + +/obj/machinery/newscaster/power_change(forced = FALSE) + if(!..()) + return + if(stat & NOPOWER) + set_light(0) + else + set_light(1, LIGHTING_MINIMUM_POWER) + update_icon(UPDATE_OVERLAYS) -/obj/machinery/newscaster/power_change() - ..() - update_icon() /obj/machinery/newscaster/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir) . = ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/newscaster/wrench_act(mob/user, obj/item/I) . = TRUE @@ -167,7 +183,7 @@ if(!(stat & BROKEN) && !(flags & NODECONSTRUCT)) stat |= BROKEN playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/newscaster/attack_ghost(mob/user) ui_interact(user) @@ -419,6 +435,8 @@ return GLOB.news_network.wanted_issue = null set_temp("Wanted notice cleared.", update_now = TRUE) + for(var/obj/machinery/newscaster/NC as anything in GLOB.allNewscasters) + NC.update_icon(UPDATE_OVERLAYS) return FALSE if("toggle_mute") is_silent = !is_silent @@ -687,14 +705,14 @@ return alert = TRUE addtimer(CALLBACK(src, PROC_REF(alert_timer_finish)), 30 SECONDS) - update_icon() + update_icon(UPDATE_OVERLAYS) /** * Called when the timer following a call to [/obj/machinery/newscaster/proc/alert_news] finishes. */ /obj/machinery/newscaster/proc/alert_timer_finish() alert = FALSE - update_icon() + update_icon(UPDATE_OVERLAYS) /** * Ejects the currently loaded photo if there is one. diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm index ce9be619fb6..30d9aadbf3e 100644 --- a/code/modules/paperwork/carbonpaper.dm +++ b/code/modules/paperwork/carbonpaper.dm @@ -6,7 +6,7 @@ var/iscopy = 0 -/obj/item/paper/carbon/update_icon() +/obj/item/paper/carbon/update_icon_state() if(iscopy) if(info) icon_state = "cpaper_words" @@ -24,7 +24,6 @@ icon_state = "paper_stack" - /obj/item/paper/carbon/verb/removecopy() set name = "Remove carbon-copy" set category = "Object" diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index d662897190e..262e27f2225 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -16,7 +16,18 @@ /obj/item/clipboard/New() ..() - update_icon() + update_icon(UPDATE_OVERLAYS) + + +/obj/item/clipboard/AltClick(mob/user) + if(Adjacent(user) && !user.incapacitated()) + if(is_pen(user.get_active_hand())) + penPlacement(user, user.get_active_hand(), TRUE) + else + removePen(user) + return + . = ..() + /obj/item/clipboard/verb/removePen(mob/user) set category = "Object" @@ -39,6 +50,7 @@ /obj/item/clipboard/examine(mob/user) . = ..() + . += "Alt-Click to remove its pen." if(in_range(user, src) && toppaper) . += toppaper.examine(user) @@ -60,7 +72,7 @@ containedpen.forceMove_turf() user.put_in_hands(containedpen, ignore_anim = FALSE) containedpen = null - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/clipboard/proc/showClipboard(mob/user) //Show them what's on the clipboard var/dat = {"[src]"} @@ -76,15 +88,23 @@ popup.set_content(dat) popup.open() -/obj/item/clipboard/update_icon() - overlays.Cut() + +/obj/item/clipboard/update_overlays() + . = ..() if(toppaper) - overlays += toppaper.icon_state - overlays += toppaper.overlays + . += toppaper.icon_state + . += toppaper.overlays if(containedpen) - overlays += "clipboard_pen" - overlays += "clipboard_over" - ..() + . += "clipboard_pen" + for(var/obj/O in src) + if(istype(O, /obj/item/photo)) + var/image/img = image('icons/obj/bureaucracy.dmi') + var/obj/item/photo/Ph = O + img = Ph.tiny + . += img + break + . += "clipboard_over" + /obj/item/clipboard/attackby(obj/item/W, mob/user) if(isPaperwork(W)) //If it's a photo, paper bundle, or piece of paper, place it on the clipboard. @@ -93,7 +113,7 @@ playsound(loc, "pageturn", 50, 1) if(isPaperwork(W) == PAPERWORK) toppaper = W - update_icon() + update_icon(UPDATE_OVERLAYS) else if(is_pen(W)) if(!toppaper) //If there's no paper we can write on, just stick the pen into the clipboard penPlacement(user, W, TRUE) @@ -113,7 +133,7 @@ return else if(istype(W, /obj/item/stamp) && toppaper) //We can stamp the topmost piece of paper toppaper.attackby(W, user) - update_icon() + update_icon(UPDATE_OVERLAYS) else return ..() @@ -155,7 +175,7 @@ to_chat(usr, "You flick the pages so that [P] is on top.") playsound(loc, "pageturn", 50, 1) toppaper = P - update_icon() + update_icon(UPDATE_OVERLAYS) showClipboard(usr) #undef PAPERWORK diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index aac51f90340..d1d9a09f839 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -10,7 +10,7 @@ /obj/item/paper/contract/proc/update_text() return -/obj/item/paper/contract/update_icon() +/obj/item/paper/contract/update_icon_state() return diff --git a/code/modules/paperwork/desk_bell.dm b/code/modules/paperwork/desk_bell.dm index 69839e6a98d..67ea39a9248 100644 --- a/code/modules/paperwork/desk_bell.dm +++ b/code/modules/paperwork/desk_bell.dm @@ -29,13 +29,13 @@ return TRUE -/obj/item/desk_bell/MouseDrop(atom/over) +/obj/item/desk_bell/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(over != user || user.incapacitated() || !ishuman(user)) + if(over_object != user || user.incapacitated() || !ishuman(user)) return FALSE anchored = FALSE diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index e9866e19ab4..10280ad2c55 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -428,7 +428,7 @@ GLOBAL_LIST_EMPTY(fax_blacklist) SSdiscord.send2discord_complex(DISCORD_WEBHOOK_REQUESTS, payload) /obj/machinery/photocopier/faxmachine/proc/sanitize_paper(obj/item/paper/paper) // html to discord markdown-101 - var/text = paper.show_content(forceshow = 1, view = 0) + var/text = "[paper.header][paper.info][paper.footer]" text = replacetext(text, "
    ", "\n") text = replacetext(text, "", "__") text = replacetext(text, "", "**") diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index fc00441de33..f80d3da514b 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -14,8 +14,9 @@ desc = "A large cabinet with drawers." icon = 'icons/obj/bureaucracy.dmi' icon_state = "filingcabinet" - density = 1 + density = TRUE anchored = TRUE + var/opened = FALSE /obj/structure/filingcabinet/chestdrawer @@ -37,14 +38,20 @@ I.loc = src +/obj/structure/filingcabinet/update_icon_state() + icon_state = "[initial(icon_state)][opened ? "-open" : ""]" + + /obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/paper) || istype(P, /obj/item/folder) || istype(P, /obj/item/photo) || istype(P, /obj/item/paper_bundle) || istype(P, /obj/item/documents)) add_fingerprint(user) to_chat(user, "You put [P] in [src].") user.drop_transfer_item_to_loc(P, src) - icon_state = "[initial(icon_state)]-open" + opened = TRUE + update_icon(UPDATE_ICON_STATE) sleep(5) - icon_state = initial(icon_state) + opened = FALSE + update_icon(UPDATE_ICON_STATE) updateUsrDialog() else if(user.a_intent != INTENT_HARM) to_chat(user, "You can't put [P] in [src]!") @@ -106,9 +113,11 @@ P.forceMove_turf() usr.put_in_hands(P, ignore_anim = FALSE) updateUsrDialog() - icon_state = "[initial(icon_state)]-open" + opened = TRUE + update_icon(UPDATE_ICON_STATE) sleep(5) - icon_state = initial(icon_state) + opened = FALSE + update_icon(UPDATE_ICON_STATE) /* diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index f3f2e646ce8..eeca23bdc72 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -29,17 +29,18 @@ desc = "A white folder." icon_state = "folder_white" -/obj/item/folder/update_icon() - overlays.Cut() + +/obj/item/folder/update_overlays() + . = ..() if(contents.len) - overlays += "folder_paper" - ..() + . += "folder_paper" + /obj/item/folder/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/paper_bundle) || istype(W, /obj/item/documents)) user.drop_transfer_item_to_loc(W, src) to_chat(user, "You put the [W] into \the [src].") - update_icon() + update_icon(UPDATE_OVERLAYS) else if(istype(W, /obj/item/pen)) rename_interactive(user, W) else @@ -90,8 +91,8 @@ //Update everything attack_self(usr) - update_icon() - return + update_icon(UPDATE_OVERLAYS) + /obj/item/folder/documents name = "folder- 'TOP SECRET'" @@ -100,7 +101,7 @@ /obj/item/folder/documents/New() ..() new /obj/item/documents/nanotrasen(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/folder/syndicate name = "folder- 'TOP SECRET'" @@ -112,7 +113,7 @@ /obj/item/folder/syndicate/red/New() ..() new /obj/item/documents/syndicate/red(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/folder/syndicate/blue icon_state = "folder_sblue" @@ -120,7 +121,7 @@ /obj/item/folder/syndicate/blue/New() ..() new /obj/item/documents/syndicate/blue(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/folder/syndicate/yellow icon_state = "folder_syellow" @@ -128,11 +129,11 @@ /obj/item/folder/syndicate/yellow/full/New() ..() new /obj/item/documents/syndicate/yellow(src) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/folder/syndicate/mining/New() . = ..() new /obj/item/documents/syndicate/mining(src) - update_icon() + update_icon(UPDATE_OVERLAYS) diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm index 6e3be6478c3..3c84e75cb11 100644 --- a/code/modules/paperwork/frames.dm +++ b/code/modules/paperwork/frames.dm @@ -25,12 +25,8 @@ qdel(A) return ..() -/obj/item/picture_frame/update_icon() - overlays.Cut() - - if(displayed) - overlays |= getFlatIcon(displayed) +/obj/item/picture_frame/update_icon_state() if(istype(displayed, /obj/item/photo)) icon_state = "[icon_base]-photo" else if(istype(displayed, /obj/structure/sign/poster)) @@ -38,7 +34,15 @@ else icon_state = "[icon_base]-paper" - overlays |= icon_state + +/obj/item/picture_frame/update_overlays() + . = ..() + + if(displayed) + . += getFlatIcon(displayed) + + . += icon_state + /obj/item/picture_frame/proc/insert(obj/D) if(istype(D, /obj/item/poster)) @@ -56,7 +60,7 @@ qdel(D) /obj/item/picture_frame/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) if(displayed) playsound(src, I.usesound, 100, 1) user.visible_message("[user] unfastens \the [displayed] out of \the [src].", "You unfasten \the [displayed] out of \the [src].") @@ -71,7 +75,7 @@ update_icon() else to_chat(user, "There is nothing to remove from \the [src].") - else if(istype(I, /obj/item/crowbar)) + else if(I.tool_behaviour == TOOL_CROWBAR) playsound(src, I.usesound, 100, 1) user.visible_message("[user] breaks down \the [src].", "You break down \the [src].") for(var/A in contents) @@ -199,18 +203,24 @@ QDEL_NULL(frame) return ..() -/obj/structure/sign/picture_frame/update_icon() - overlays.Cut() + +/obj/structure/sign/picture_frame/update_icon_state() if(frame) icon = null icon_state = null - overlays |= getFlatIcon(frame) else icon = initial(icon) icon_state = initial(icon_state) + +/obj/structure/sign/picture_frame/update_overlays() + . = ..() + if(frame) + . += getFlatIcon(frame) + + /obj/structure/sign/picture_frame/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) playsound(src, I.usesound, 100, 1) user.visible_message("[user] begins to unfasten \the [src] from the wall.", "You begin to unfasten \the [src] from the wall.") if(do_after(user, 100 * I.toolspeed * gettoolspeedmod(user), target = src)) diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index f4dca6a98f8..5a046aaf350 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -6,7 +6,7 @@ item_state = "flight" var/label = null var/labels_left = 30 - var/mode = 0 + var/mode = FALSE /obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity) if(!proximity) @@ -33,9 +33,14 @@ playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE) labels_left-- -/obj/item/hand_labeler/attack_self(mob/user as mob) - mode = !mode + +/obj/item/hand_labeler/update_icon_state() icon_state = "labeler[mode]" + + +/obj/item/hand_labeler/attack_self(mob/user) + mode = !mode + update_icon(UPDATE_ICON_STATE) if(mode) to_chat(user, "You turn on \the [src].") //Now let them chose the text. diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index fc2db3c4bd4..710632b7b94 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -19,6 +19,7 @@ body_parts_covered = HEAD resistance_flags = FLAMMABLE max_integrity = 50 + blocks_emissive = FALSE attack_verb = list("bapped") permeability_coefficient = 0.01 dog_fashion = /datum/dog_fashion/head @@ -29,9 +30,10 @@ var/footer //The bottom stuff before the stamp but after the body var/info_links //A different version of the paper which includes html links at fields and EOF var/stamps //The (text for the) stamps on the paper. - var/fields //Amount of user created fields - var/language = "Galactic Common" //The language of paper. For now using only in case of Thetta + var/fields = 0 //Amount of user created fields + var/language = LANGUAGE_GALACTIC_COMMON //The language of paper. For now using only in case of Thetta var/list/stamped + var/list/stamp_overlays var/ico[0] //Icons and var/offset_x[0] //offsets stored for later var/offset_y[0] //usage by the photocopier @@ -61,15 +63,21 @@ update_icon() updateinfolinks() -/obj/item/paper/update_icon() - ..() + +/obj/item/paper/update_icon_state() if(info) icon_state = "paper_words" return icon_state = "paper" + +/obj/item/paper/update_overlays() + return LAZYLEN(stamp_overlays) ? stamp_overlays : list() + + /obj/item/paper/examine(mob/user) . = ..() + . += "Alt-Click the [initial(name)] with a pen in hand to rename it." if(user.is_literate()) if(in_range(user, src) || istype(user, /mob/dead/observer)) show_content(user) @@ -78,12 +86,13 @@ else . += "You don't know how to read." -/obj/item/paper/proc/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1) + +/obj/item/paper/proc/show_content(mob/user, forceshow = FALSE, forcestars = FALSE, infolinks, view = TRUE) var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper) assets.send(user) var/data - var/stars = (!user?.say_understands(null, GLOB.all_languages[language]) && !forceshow) || forcestars + var/stars = (!user.say_understands(null, GLOB.all_languages[language]) && !forceshow) || forcestars if(stars) //assuming all paper is written in common is better than hardcoded type checks data = "[header][stars(info)][footer][stamps]" else @@ -105,84 +114,132 @@ popup.open() return data -/obj/item/paper/verb/rename() - set name = "Rename paper" - set category = "Object" - set src in usr - if((CLUMSY in usr.mutations) && prob(50)) - to_chat(usr, "You cut yourself on the paper.") +/obj/item/paper/AltClick(mob/living/carbon/human/user) + if(!ishuman(user) || user.incapacitated() || !Adjacent(user)) + return + if(is_pen(user.get_active_hand())) + rename(user) + return + if(user.is_in_hands(src)) + ProcFoldPlane(user, src) + return + return ..() + + +/obj/item/paper/proc/rename(mob/user) + if((CLUMSY in user.mutations) && prob(50)) + to_chat(user, "You cut yourself on the paper.") return - if(!usr.is_literate()) - to_chat(usr, "You don't know how to read.") + if(!user.is_literate()) + to_chat(user, "You don't know how to read.") return - var/n_name = rename_interactive(usr) + var/n_name = rename_interactive(user) if(isnull(n_name)) return if(n_name != "") desc = "This is a paper titled '" + name + "'." else desc = initial(desc) - add_fingerprint(usr) - return + add_fingerprint(user) + /obj/item/paper/attack_self(mob/living/user as mob) user.examinate(src) - if(rigged && (SSholiday.holidays && SSholiday.holidays[APRIL_FOOLS])) - if(spam_flag == 0) - spam_flag = 1 - playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) - spawn(20) - spam_flag = 0 - return + if(rigged && !spam_flag && (SSholiday.holidays && SSholiday.holidays[APRIL_FOOLS])) + spam_flag = TRUE + addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), 3 SECONDS) + playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) + -/obj/item/paper/attack_ai(var/mob/living/silicon/ai/user as mob) +/obj/item/paper/attack_ai(mob/living/silicon/ai/user) var/dist - if(istype(user) && user.current) //is AI + if(isAI(user) && user.current) //is AI dist = get_dist(src, user.current) else //cyborg or AI not seeing through a camera dist = get_dist(src, user) if(dist < 2) - show_content(user, forceshow = 1) + show_content(user, forceshow = TRUE) else - show_content(user, forcestars = 1) - return + show_content(user, forcestars = TRUE) + + +/obj/item/paper/attack(mob/living/carbon/human/target, mob/living/user, def_zone) + if(!ishuman(target)) + return ..() -/obj/item/paper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(user.zone_selected == BODY_ZONE_PRECISE_EYES) user.visible_message("[user] is trying to show the paper to you. ", \ - "You hold up a paper and try to show it to [M]. ") + "You hold up a paper and try to show it to [target]. ") - if(do_mob(user, M, 0.7 SECONDS)) + if(do_mob(user, target, 0.7 SECONDS)) user.visible_message("[user] shows the paper to you. ", \ - "You hold up a paper and show it to [M]. ") - M.examinate(src) + "You hold up a paper and show it to [target]. ") + target.examinate(src) else - to_chat(user, span_warning("You fail to show the paper to [M].")) + to_chat(user, span_warning("You fail to show the paper to [target].")) else if(user.zone_selected == BODY_ZONE_PRECISE_MOUTH) - if(!istype(M, /mob)) return - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H == user) - to_chat(user, "You wipe off your face with [src].") - H.lip_style = null - H.lip_color = initial(H.lip_color) - H.update_body() - else - user.visible_message("[user] begins to wipe [H]'s face clean with \the [src].", \ - "You begin to wipe off [H]'s face.") - if(do_after(user, 10, target = H) && do_after(H, 10, 0)) //user needs to keep their active hand, H does not. - user.visible_message("[user] wipes [H]'s face clean with \the [src].", \ - "You wipe off [H]'s face.") - H.lip_style = null - H.lip_color = initial(H.lip_color) - H.update_body() + if(target == user) + to_chat(user, "You wipe off your face with [src].") + else + user.visible_message("[user] begins to wipe [target]'s face clean with \the [src].", + "You begin to wipe off [target]'s face.") + if(!do_after(user, 1 SECONDS, target = target) || !do_after(target, 1 SECONDS, FALSE)) // user needs to keep their active hand, target does not. + return + user.visible_message("[user] wipes [target]'s face clean with \the [src].", + "You wipe off [target]'s face.") + + target.lip_style = null + target.lip_color = null + target.update_body() + else + return ..() + + +/obj/item/paper/attack_animal(mob/living/simple_animal/pet/dog/doggo) + if(!isdog(doggo)) // Only dogs can eat homework. + return + doggo.changeNext_move(CLICK_CD_MELEE) + if(world.time < doggo.last_eaten + 30 SECONDS) + to_chat(doggo, "You are too full to try eating [src] now.") + return + + doggo.visible_message("[doggo] starts chewing the corner of [src]!", + "You start chewing the corner of [src].", + "You hear a quiet gnawing, and the sound of paper rustling.") + playsound(src, 'sound/effects/pageturn2.ogg', 100, TRUE) + if(!do_after(doggo, 10 SECONDS, FALSE, src)) + return + + if(world.time < doggo.last_eaten + 30 SECONDS) // Check again to prevent eating multiple papers at once. + to_chat(doggo, "You are too full to try eating [src] now.") + return + doggo.last_eaten = world.time + + // 90% chance of a crumpled paper with illegible text. + if(prob(90)) + var/message_ending = "." + var/obj/item/paper/crumpled/crumped = new(loc) + crumped.name = name + if(info) // Something written on the paper. + crumped.info = "Whatever was once written here has been made completely illegible by a combination of chew marks and saliva." + message_ending = ", the drool making it an unreadable mess!" + crumped.update_icon() + qdel(src) + + doggo.visible_message("[doggo] finishes eating [src][message_ending]", + "You finish eating [src][message_ending]") + doggo.emote("bark") + + // 10% chance of the paper just being eaten entirely. else - ..() + doggo.visible_message("[doggo] swallows [src] whole!", "You swallow [src] whole. Tasty!") + playsound(doggo, 'sound/items/eatfood.ogg', 50, TRUE) + qdel(src) -/obj/item/paper/proc/addtofield(var/id, var/text, var/links = 0) + +/obj/item/paper/proc/addtofield(id, text, links = 0) if(id > MAX_PAPER_FIELDS) return @@ -192,11 +249,11 @@ while(locid <= MAX_PAPER_FIELDS) var/istart = 0 if(links) - istart = findtext(info_links, "", laststart) + istart = findtext_char(info_links, "", laststart) else - istart = findtext(info, "", laststart) + istart = findtext_char(info, "", laststart) - if(istart==0) + if(!istart) return // No field found with matching id laststart = istart+1 @@ -204,59 +261,58 @@ if(locid == id) var/iend = 1 if(links) - iend = findtext(info_links, "", istart) + iend = findtext_char(info_links, "", istart) else - iend = findtext(info, "", istart) + iend = findtext_char(info, "", istart) - //textindex = istart+26 textindex = iend break if(links) - var/before = copytext(info_links, 1, textindex) - var/after = copytext(info_links, textindex) + var/before = copytext_char(info_links, 1, textindex) + var/after = copytext_char(info_links, textindex) info_links = before + text + after else - var/before = copytext(info, 1, textindex) - var/after = copytext(info, textindex) + var/before = copytext_char(info, 1, textindex) + var/after = copytext_char(info, textindex) info = before + text + after updateinfolinks() + /obj/item/paper/proc/updateinfolinks() info_links = info - var/i = 0 - for(i=1,i<=fields,i++) - var/write_1 = "write" - var/write_2 = "\[A\]" + for(var/i in 1 to fields) + var/write_1 = "write" + var/write_2 = "\[a\]" addtofield(i, "[write_1][write_2]", 1) - info_links = info_links + "write" + info_links = info_links + "write" + "\[A\]" /obj/item/paper/proc/clearpaper() info = null stamps = null stamped = list() - overlays.Cut() + stamp_overlays = null updateinfolinks() update_icon() -/obj/item/paper/proc/parsepencode(var/t, var/obj/item/pen/P, mob/user as mob) +/obj/item/paper/proc/parsepencode(t, obj/item/pen/P, mob/user as mob) t = pencode_to_html(html_encode(t), usr, P, TRUE, TRUE, TRUE, deffont, signfont, crayonfont) return t /obj/item/paper/proc/populatefields() - //Count the fields + //Count the fields var/laststart = 1 while(fields < MAX_PAPER_FIELDS) - var/i = findtext(info, "", laststart) - if(i==0) + var/i = findtext_char(info, "", laststart) + if(!i) break laststart = i+1 fields++ -/obj/item/paper/proc/openhelp(mob/user as mob) +/obj/item/paper/proc/openhelp(mob/user) user << browse({"Pen Help
    Crayon&Pen commands

    @@ -281,33 +337,29 @@ \[time\] : Inserts the current station time in HH:MM:SS.
    "}, "window=paper_help") -/obj/item/paper/proc/topic_href_write(var/id, var/input_element) + +/obj/item/paper/proc/topic_href_write(id, input_element) var/obj/item/item_write = usr.get_active_hand() // Check to see if he still got that darn pen, also check if he's using a crayon or pen. add_hiddenprint(usr) // No more forging nasty documents as someone else, you jerks - if(!istype(item_write, /obj/item/pen)) - if(!istype(item_write, /obj/item/toy/crayon)) - return - - // if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr - if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/clipboard) || istype(src.loc, /obj/item/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) ) + if(!is_pen(item_write) && !istype(item_write, /obj/item/toy/crayon)) return + if(loc != usr && !Adjacent(usr) && !((istype(loc, /obj/item/clipboard) || istype(loc, /obj/item/folder)) && (loc.loc == usr || loc.Adjacent(usr)))) + return // If paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr input_element = parsepencode(input_element, item_write, usr) // Encode everything from pencode to html - if(id!="end") + if(id != "end") addtofield(text2num(id), input_element) // He wants to edit a field, let him. else info += input_element // Oh, he wants to edit to the end of the file, let him. populatefields() updateinfolinks() - - item_write.on_write(src,usr) - - show_content(usr, forceshow = 1, infolinks = 1) - + item_write.on_write(src, usr) + show_content(usr, forceshow = TRUE, infolinks = TRUE) update_icon() + /obj/item/paper/Topic(href, href_list) ..() if(!usr || (usr.stat || usr.restrained())) @@ -317,51 +369,66 @@ var/id = href_list["auto_write"] var/const/sign_text = "\[Поставить подпись\]" + var/const/account_text = "\[Написать номер аккаунта\]" + var/const/pin_text = "\[Написать пин-код\]" var/const/time_text = "\[Написать текущее время\]" var/const/date_text = "\[Написать текущую дату\]" - var/const/num_text = "\[Написать номер аккаунта\]" - var/const/pin_text = "\[Написать пин-код\]" var/const/station_text = "\[Написать название станции\]" + var/const/gender_text = "\[Указать пол\]" + var/const/species_text = "\[Указать расу\]" + + var/list/menu_list = list() // text items in the menu + + menu_list.Add(usr.real_name) // the real name of the character, even if it is hidden + + if(usr.real_name != usr.name && lowertext(usr.name) != "unknown") // if the player is masked or the name is different a new answer option is added + menu_list.Add(usr.name) + + if(usr.job) + menu_list.Add(usr.job) // job + + menu_list.Add(sign_text) //signature - //пункты текста в меню - var/list/menu_list = list() - menu_list.Add(usr.real_name) //настоящее имя персонажа, даже если оно спрятано - - //если игрок маскируется или имя отличается, добавляется новый вариант ответа - if (usr.real_name != usr.name || usr.name != "unknown") - menu_list.Add("[usr.name]") - - menu_list.Add(usr.job, //текущая работа - num_text, //номер аккаунта - pin_text, //номер пин-кода - sign_text, //подпись - time_text, //время - date_text, //дата - station_text, //название станции - usr.gender, //пол - usr.dna.species //раса + if(usr.mind?.initial_account?.account_number) + menu_list.Add(account_text) // account number + + if(usr.mind?.initial_account?.remote_access_pin) + menu_list.Add(pin_text) // account pin-code + + menu_list.Add( + time_text, // time + date_text, // date + station_text, // station name + gender_text, // gender ) + if(usr.dna?.species) + menu_list.Add(species_text) //current + var/input_element = input("Выберите текст который хотите добавить:", "Выбор пункта") as null|anything in menu_list + if(!input_element) + return - //форматируем выбранные пункты меню в pencode и внутренние данные - switch(input_element) - if (sign_text) + switch(input_element) //format selected menu items in pencode and internal data + if(sign_text) input_element = "\[sign\]" - if (time_text) + if(time_text) input_element = "\[time\]" - if (date_text) + if(date_text) input_element = "\[date\]" - if (station_text) + if(station_text) input_element = "\[station\]" - if (num_text) + if(account_text) input_element = usr.mind.initial_account.account_number - if (pin_text) + if(pin_text) input_element = usr.mind.initial_account.remote_access_pin + if(gender_text) + input_element = usr.gender + if(species_text) + input_element = usr.dna.species topic_href_write(id, input_element) - if(href_list["write"] ) var/id = href_list["write"] var/input_element = input("Enter what you want to write:", "Write", null, null) as message @@ -370,14 +437,12 @@ /obj/item/paper/attackby(obj/item/P, mob/living/user, params) - ..() + . = ..() if(resistance_flags & ON_FIRE) return - var/clown = 0 - if(user.mind && (user.mind.assigned_role == "Clown")) - clown = 1 + var/clown = user.mind && (user.mind.assigned_role == "Clown") if(istype(P, /obj/item/paper) || istype(P, /obj/item/photo)) if(istype(P, /obj/item/paper/carbon)) @@ -426,9 +491,9 @@ src.loc = B P.loc = B B.amount++ - B.update_icon() + B.update_appearance(UPDATE_ICON|UPDATE_DESC) - else if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) + else if(is_pen(P) || istype(P, /obj/item/toy/crayon)) if(user.is_literate()) var/obj/item/pen/multi/robopen/RP = P if(istype(P, /obj/item/pen/multi/robopen) && RP.mode == 2) @@ -452,6 +517,7 @@ stamp(P) to_chat(user, "You stamp the paper with your rubber stamp.") + playsound(user, 'sound/items/handling/standard_stamp.ogg', 50, vary = TRUE) if(is_hot(P)) if((CLUMSY in user.mutations) && prob(10)) @@ -471,12 +537,14 @@ add_fingerprint(user) + /obj/item/paper/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) ..() if(!(resistance_flags & FIRE_PROOF)) info = "Heat-curled corners and sooty words offer little insight. Whatever was once written on this page has been rendered illegible through fire." -/obj/item/paper/proc/stamp(var/obj/item/stamp/S) + +/obj/item/paper/proc/stamp(obj/item/stamp/S) stamps += (!stamps || stamps == "" ? "
    " : "") + "" var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') @@ -501,9 +569,9 @@ if(!stamped) stamped = new stamped += S.type - overlays += stampoverlay + stamp_overlays += stampoverlay + update_icon(UPDATE_OVERLAYS) - playsound(S, pick(S.stamp_sounds), 35, 1, -1) /* * Premade paper @@ -531,7 +599,7 @@ /obj/item/paper/flag icon_state = "flag_neutral" item_state = "paper" - anchored = 1.0 + anchored = TRUE /obj/item/paper/jobs name = "Job Information" @@ -550,8 +618,10 @@ name = "paper scrap" icon_state = "scrap" -/obj/item/paper/crumpled/update_icon() - return + +/obj/item/paper/crumpled/update_icon_state() + if(info) + icon_state = "scrap_words" /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" @@ -567,9 +637,10 @@ info = "

    [fortunemessage]

    " info += "

    Lucky numbers: [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)]

    " -/obj/item/paper/fortune/update_icon() - ..() + +/obj/item/paper/fortune/update_icon_state() icon_state = initial(icon_state) + /* * Premade paper */ @@ -604,7 +675,7 @@ /obj/item/paper/flag icon_state = "flag_neutral" item_state = "paper" - anchored = 1.0 + anchored = TRUE /obj/item/paper/jobs name = "Job Information" @@ -659,10 +730,6 @@ name = "paper- 'Note'" info = "The call has gone out! Our ancestral home has been rediscovered! Not a small patch of land, but a true clown nation, a true Clown Planet! We're on our way home at last!" -/obj/item/paper/crumpled - name = "paper scrap" - icon_state = "scrap" - /obj/item/paper/syndicate name = "paper" header = "


    " @@ -677,7 +744,7 @@ name = "paper" header = "


    " info = "" - language = "Neo-Russkiya" + language = LANGUAGE_NEO_RUSSIAN /obj/item/paper/solgov name = "paper" @@ -749,25 +816,21 @@ info = "ᅠᅠАгенство внутренних дел по надзору за домашними животными находящимися на станции сообщает, приставленный к вам питомец \"Гав Гавыч\" почил. Он верно служил ремеслу дознавателей, сыщиков и детективов. Мы будем помнить о его вкладе и сохраним о нём память в анналах истории о домашних питомцах Нанотрейзен.

    " footer = "
    Штампы и данные:

    Время принятия отчета:

    *Данный документ подлежит ксерокопированию, для сохранения в архиве уполномоченных лиц, и выдаче агенту.
    *Данный документ может содержать личную информацию.
    " -/obj/item/paper/crumpled/update_icon() - return - -/obj/item/paper/crumpled/bloody - icon_state = "scrap_bloodied" /obj/item/paper/evilfax name = "Centcomm Reply" info = "" var/mytarget = null var/myeffect = null - var/used = 0 + var/used = FALSE var/countdown = 60 - var/activate_on_timeout = 0 + var/activate_on_timeout = FALSE var/faxmachineid = null -/obj/item/paper/evilfax/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1) + +/obj/item/paper/evilfax/show_content(mob/user, forceshow = FALSE, forcestars = FALSE, infolinks, view = TRUE) if(user == mytarget) - if(istype(user, /mob/living/carbon)) + if(iscarbon(user)) var/mob/living/carbon/C = user evilpaper_specialaction(C) ..() @@ -799,81 +862,85 @@ if(!countdown) if(mytarget) if(activate_on_timeout) - evilpaper_specialaction(mytarget) + addtimer(CALLBACK(src, PROC_REF(evilpaper_specialaction), mytarget), 3 SECONDS, TIMER_DELETE_ME) else message_admins("[mytarget] ignored an evil fax until it timed out.") else message_admins("Evil paper '[src]' timed out, after not being assigned a target.") - used = 1 + used = TRUE evilpaper_selfdestruct() else countdown-- -/obj/item/paper/evilfax/proc/evilpaper_specialaction(var/mob/living/carbon/target) - spawn(30) - if(istype(target, /mob/living/carbon)) - var/obj/machinery/photocopier/faxmachine/fax = locateUID(faxmachineid) - if(myeffect == "Borgification") - to_chat(target,"You seem to comprehend the AI a little better. Why are your muscles so stiff?") - var/datum/disease/virus/transformation/robot/D = new - D.Contract(target) - else if(myeffect == "Corgification") - to_chat(target,"You hear distant howling as the world seems to grow bigger around you. Boy, that itch sure is getting worse!") - var/datum/disease/virus/transformation/corgi/D = new - D.Contract(target) - else if(myeffect == "Death By Fire") - to_chat(target,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?") - var/turf/simulated/T = get_turf(target) - new /obj/effect/hotspot(T) - target.adjustFireLoss(150) // hard crit, the burning takes care of the rest. - else if(myeffect == "Total Brain Death") - to_chat(target,"You see a message appear in front of you in bright red letters: YHWH-3 ACTIVATED. TERMINATION IN 3 SECONDS") - target.mutations.Add(NOCLONE) - target.adjustBrainLoss(125) - else if(myeffect == "Honk Tumor") - if(!target.get_int_organ(/obj/item/organ/internal/honktumor)) - var/obj/item/organ/internal/organ = new /obj/item/organ/internal/honktumor - to_chat(target,"Life seems funnier, somehow.") - organ.insert(target) - else if(myeffect == "Cluwne") - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - to_chat(H, "You feel surrounded by sadness. Sadness... and HONKS!") - H.makeCluwne() - else if(myeffect == "Demote") - GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.") - for(var/datum/data/record/R in sortRecord(GLOB.data_core.security)) - if(R.fields["name"] == target.real_name) - R.fields["criminal"] = SEC_RECORD_STATUS_DEMOTE - R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()]
    Process this demotion immediately. Failure to comply with these orders is grounds for termination." - update_all_mob_security_hud() - else if(myeffect == "Demote with Bot") - GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.") - for(var/datum/data/record/R in sortRecord(GLOB.data_core.security)) - if(R.fields["name"] == target.real_name) - R.fields["criminal"] = SEC_RECORD_STATUS_ARREST - R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()]
    Process this demotion immediately. Failure to comply with these orders is grounds for termination." - update_all_mob_security_hud() - if(fax) - var/turf/T = get_turf(fax) - new /obj/effect/portal(T) - new /mob/living/simple_animal/bot/secbot(T) - else if(myeffect == "Revoke Fax Access") - GLOB.fax_blacklist += target.real_name - if(fax) - fax.authenticated = 0 - else if(myeffect == "Angry Fax Machine") - if(fax) - fax.become_mimic() - else - message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.") - used = 1 - evilpaper_selfdestruct() + +/obj/item/paper/evilfax/proc/evilpaper_specialaction(mob/living/carbon/target) + if(!iscarbon(target)) + return + + var/obj/machinery/photocopier/faxmachine/fax = locateUID(faxmachineid) + if(myeffect == "Borgification") + to_chat(target,"You seem to comprehend the AI a little better. Why are your muscles so stiff?") + var/datum/disease/virus/transformation/robot/D = new + D.Contract(target) + else if(myeffect == "Corgification") + to_chat(target,"You hear distant howling as the world seems to grow bigger around you. Boy, that itch sure is getting worse!") + var/datum/disease/virus/transformation/corgi/D = new + D.Contract(target) + else if(myeffect == "Death By Fire") + to_chat(target,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?") + var/turf/simulated/T = get_turf(target) + new /obj/effect/hotspot(T) + target.adjustFireLoss(150) // hard crit, the burning takes care of the rest. + else if(myeffect == "Total Brain Death") + to_chat(target,"You see a message appear in front of you in bright red letters: YHWH-3 ACTIVATED. TERMINATION IN 3 SECONDS") + target.mutations.Add(NOCLONE) + target.adjustBrainLoss(125) + else if(myeffect == "Honk Tumor") + if(!target.get_int_organ(/obj/item/organ/internal/honktumor)) + new /obj/item/organ/internal/honktumor(target) + to_chat(target,"Life seems funnier, somehow.") + else if(myeffect == "Cluwne") + if(ishuman(target)) + var/mob/living/carbon/human/H = target + to_chat(H, "You feel surrounded by sadness. Sadness... and HONKS!") + H.makeCluwne() + else if(myeffect == "Demote") + GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.") + for(var/datum/data/record/R in sortRecord(GLOB.data_core.security)) + if(R.fields["name"] == target.real_name) + R.fields["criminal"] = SEC_RECORD_STATUS_DEMOTE + R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()]
    Process this demotion immediately. Failure to comply with these orders is grounds for termination." + update_all_mob_security_hud() + else if(myeffect == "Demote with Bot") + GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.") + for(var/datum/data/record/R in sortRecord(GLOB.data_core.security)) + if(R.fields["name"] == target.real_name) + R.fields["criminal"] = SEC_RECORD_STATUS_ARREST + R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()]
    Process this demotion immediately. Failure to comply with these orders is grounds for termination." + update_all_mob_security_hud() + if(fax) + var/turf/T = get_turf(fax) + new /obj/effect/portal(T) + new /mob/living/simple_animal/bot/secbot(T) + else if(myeffect == "Revoke Fax Access") + GLOB.fax_blacklist += target.real_name + if(fax) + fax.authenticated = FALSE + else if(myeffect == "Angry Fax Machine") + if(fax) + fax.become_mimic() + else + message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.") + + used = TRUE + evilpaper_selfdestruct() + /obj/item/paper/evilfax/proc/evilpaper_selfdestruct() visible_message("[src] spontaneously catches fire, and burns up!") qdel(src) + /obj/item/paper/pickup(user) if(contact_poison && ishuman(user)) var/mob/living/carbon/human/H = user @@ -1608,11 +1675,11 @@ новых проектов." icon_state = "pamphlet" -/obj/item/paper/deltainfo/update_icon() +/obj/item/paper/deltainfo/update_icon_state() return /obj/item/paper/pamphletdeathsquad icon_state = "pamphlet-ds" -/obj/item/paper/pamphletdeathsquad/update_icon() +/obj/item/paper/pamphletdeathsquad/update_icon_state() return diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 1f9fe272072..c314d388910 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -14,7 +14,8 @@ attack_verb = list("bapped") drop_sound = 'sound/items/handling/paper_drop.ogg' pickup_sound = 'sound/items/handling/paper_pickup.ogg' - var/amount = 0 //Amount of items clipped to the paper. Note: If you have 2 paper, this should be 1 + var/amount = 0 //Amount of total items clipped to the paper. Note: If you have 2 paper, this should be 1 + var/photos = 0 //Amount of photos clipped to the paper. var/page = 1 var/screen = 0 @@ -50,6 +51,7 @@ H.update_inv_r_hand() else if(istype(W, /obj/item/photo)) amount++ + photos++ if(screen == 2) screen = 1 to_chat(user, "You add [(W.name == "photo") ? "the photo" : W.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name].") @@ -91,7 +93,7 @@ P.attackby(W, user, params) - update_icon() + update_appearance(UPDATE_ICON|UPDATE_DESC) if(winget(usr, "PaperBundle[UID()]", "is-visible") == "true") // NOT MY FAULT IT IS A BUILT IN PROC PLEASE DO NOT HIT ME attack_self(usr) //Update the browsed page. add_fingerprint(usr) @@ -171,11 +173,11 @@ + "[P.scribble ? "

    Written on the back:
    [P.scribble]" : ""]"\ + "", "window=PaperBundle[UID()]") -/obj/item/paper_bundle/attack_self(mob/user as mob) - src.show_content(user) +/obj/item/paper_bundle/attack_self(mob/user) + show_content(user) add_fingerprint(user) - update_icon() - return + update_appearance(UPDATE_ICON|UPDATE_DESC) + /obj/item/paper_bundle/Topic(href, href_list) ..() @@ -216,7 +218,7 @@ page-- amount-- - update_icon() + update_appearance(UPDATE_ICON|UPDATE_DESC) else to_chat(usr, "You need to hold it in your hands to change pages.") if(istype(src.loc, /mob)) @@ -253,35 +255,53 @@ return -/obj/item/paper_bundle/update_icon() - ..() - if(contents.len) - var/obj/item/paper/P = src[1] - icon_state = P.icon_state - overlays = P.overlays - underlays = 0 - var/i = 0 - var/photo +/obj/item/paper_bundle/update_desc(updates = ALL) + . = ..() + if(amount == (photos - 1)) + desc = "[photos] photos clipped together." // In case you clip 2 photos together and remove the paper + return + + else if(((amount + 1) - photos) >= 2) // extra papers + original paper - photos + desc = "[(amount + 1) - photos] papers clipped to each other." + + else + desc = "A single sheet of paper." + if(photos) + desc += "\nThere [photos == 1 ? "is a photo" : "are [photos] photos"] attached to it." + + +/obj/item/paper_bundle/update_icon_state() + if(length(contents)) + var/obj/item/paper/P = contents[1] + icon_state = P.icon_state // must have an icon_state to show up on clipboards + + +/obj/item/paper_bundle/update_overlays() + . = ..() + underlays.Cut() + if(length(contents)) + var/obj/item/paper/P = contents[1] + . += P.overlays + + var/counter = 0 for(var/obj/O in src) - var/image/img = image('icons/obj/bureaucracy.dmi') + var/image/sheet = image('icons/obj/bureaucracy.dmi') if(istype(O, /obj/item/paper)) - img.icon_state = O.icon_state - img.pixel_x -= min(1*i, 2) - img.pixel_y -= min(1*i, 2) - pixel_x = min(0.5*i, 1) - pixel_y = min( 1*i, 2) - underlays += img - i++ + if(length(underlays) == 3) + continue + + sheet.icon_state = O.icon_state + sheet.pixel_x -= min(1 * counter, 2) + sheet.pixel_y -= min(1 * counter, 2) + pixel_x = min(0.5 * counter, 1) + pixel_y = min(1 * counter, 2) + underlays += sheet + counter++ + else if(istype(O, /obj/item/photo)) - var/obj/item/photo/Ph = O - img = Ph.tiny - photo = 1 - overlays += img - if(i>1) - desc = "[i] papers clipped to each other." - else - desc = "A single sheet of paper." - if(photo) - desc += "\nThere is a photo attached to it." - overlays += image('icons/obj/bureaucracy.dmi', "clip") - return + var/obj/item/photo/picture = O + sheet = picture.tiny + . += sheet + + . += "clip" + diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 2f2072a8eb7..dcb8c658c85 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -11,11 +11,12 @@ var/amount = 30 //How much paper is in the bin. var/list/papers = list() //List of papers put in the bin for reference. var/letterhead_type + var/purple_bin = FALSE /obj/item/paper_bin/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) if(amount) amount = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) ..() /obj/item/paper_bin/Destroy() @@ -25,16 +26,16 @@ /obj/item/paper_bin/burn() amount = 0 extinguish() - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/item/paper_bin/MouseDrop(atom/over) +/obj/item/paper_bin/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(over != user || user.incapacitated() || !ishuman(user)) + if(over_object != user || user.incapacitated() || !ishuman(user)) return FALSE if(user.put_in_hands(src, ignore_anim = FALSE)) @@ -45,7 +46,7 @@ return FALSE -/obj/item/paper_bin/attack_hand(mob/user as mob) +/obj/item/paper_bin/attack_hand(mob/user) if(ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.bodyparts_by_name[BODY_ZONE_PRECISE_R_HAND] @@ -57,7 +58,7 @@ if(amount >= 1) amount-- if(amount==0) - update_icon() + update_icon(UPDATE_ICON_STATE) var/obj/item/paper/P if(papers.len > 0) //If there's any custom paper on the stack, use that instead of creating a new paper. @@ -102,22 +103,24 @@ else . += "There are no papers in the bin." -/obj/item/paper_bin/update_icon() + +/obj/item/paper_bin/update_icon_state() if(amount < 1) icon_state = "paper_bin0" else - icon_state = "paper_bin1" - ..() + icon_state = "paper_bin[purple_bin ? "2" : "1"]" + /obj/item/paper_bin/carbon name = "carbonless paper bin" icon_state = "paper_bin2" + purple_bin = TRUE -/obj/item/paper_bin/carbon/attack_hand(mob/user as mob) +/obj/item/paper_bin/carbon/attack_hand(mob/user) if(amount >= 1) amount-- if(amount==0) - update_icon() + update_icon(UPDATE_ICON_STATE) var/obj/item/paper/carbon/P if(papers.len > 0) //If there's any custom paper on the stack, use that instead of creating a new paper. diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 58c38eb63bc..a41bfab890a 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -10,10 +10,11 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE max_integrity = 50 - no_spin = TRUE + no_spin_thrown = TRUE var/obj/item/paper/internal_paper + /obj/item/paperplane/New(loc, obj/item/paper/new_paper) ..() pixel_y = rand(-8, 8) @@ -25,12 +26,14 @@ new_paper.forceMove(src) else internal_paper = new /obj/item/paper(src) - update_icon() + update_icon(UPDATE_OVERLAYS) + /obj/item/paperplane/Destroy() QDEL_NULL(internal_paper) return ..() + /obj/item/paperplane/suicide_act(mob/living/user) user.Stun(20 SECONDS) user.visible_message("[user] jams [name] in [user.p_their()] nose. It looks like [user.p_theyre()] trying to commit suicide!") @@ -41,16 +44,17 @@ sleep(10) return BRUTELOSS -/obj/item/paperplane/update_icon() - overlays.Cut() + +/obj/item/paperplane/update_overlays() + . = ..() var/list/stamped = internal_paper.stamped if(!stamped) stamped = new else if(stamped) for(var/S in stamped) var/obj/item/stamp = S - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi', "paperplane_[initial(stamp.icon_state)]") - overlays += stampoverlay + . += "paperplane_[initial(stamp.icon_state)]" + /obj/item/paperplane/attack_self(mob/user) // Unfold the paper plane to_chat(user, "You unfold [src].") @@ -60,16 +64,17 @@ internal_paper = null qdel(src) + /obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params) ..() - if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) + if(is_pen(P) || istype(P, /obj/item/toy/crayon)) to_chat(user, "You should unfold [src] before changing it.") return else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane internal_paper.attackby(P, user) //spoofed attack to update internal paper. - update_icon() + update_icon(UPDATE_OVERLAYS) else if(is_hot(P)) if((CLUMSY in user.mutations) && prob(10)) @@ -88,6 +93,7 @@ add_fingerprint(user) + /obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(..()) return @@ -109,20 +115,15 @@ E.take_damage(8, 1) H.emote("scream") -/obj/item/paper/AltClick(mob/user, obj/item/I) + +/obj/item/paper/proc/ProcFoldPlane(mob/living/carbon/user, obj/item/paper) if(ishuman(user)) - var/mob/living/carbon/human/H = user - I = H.is_type_in_hands(/obj/item/paper) - if(I) - ProcFoldPlane(H, I) - -/obj/item/paper/proc/ProcFoldPlane(mob/living/carbon/user, obj/item/I) - if(istype(user)) - if((!in_range(src, user)) || user.stat || user.restrained()) + if(!Adjacent(user) || user.incapacitated()) return to_chat(user, "You fold [src] into the shape of a plane!") user.drop_item_ground(src) - I = new /obj/item/paperplane(user, src) - user.put_in_hands(I) + paper = new /obj/item/paperplane(user, src) + user.put_in_hands(paper, ignore_anim = FALSE) else to_chat(user, "You lack the dexterity to fold [src].") + diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm index 37cf5813399..6534cb31a1e 100644 --- a/code/modules/paperwork/papershredder.dm +++ b/code/modules/paperwork/papershredder.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "papershredder0" density = 1 - anchored = 1 + anchored = TRUE var/max_paper = 15 var/paperamount = 0 var/list/shred_amounts = list( @@ -43,7 +43,7 @@ SP.loc = get_turf(src) SP.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), 1, 1) paperamount = max_paper - update_icon() + update_icon(UPDATE_ICON_STATE) add_fingerprint(user) return ..() @@ -99,7 +99,7 @@ else to_chat(user, "You empty \the [src].") - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/papershredder/proc/get_shredded_paper() if(!paperamount) @@ -107,7 +107,7 @@ paperamount-- return new /obj/item/shredded_paper(get_turf(src)) -/obj/machinery/papershredder/update_icon() +/obj/machinery/papershredder/update_icon_state() icon_state = "papershredder[clamp(round(paperamount/3), 0, 5)]" /obj/item/shredded_paper/attackby(obj/item/W as obj, mob/user) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 6c6658a0607..6e2a6472851 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -67,26 +67,28 @@ /obj/item/pen/multi/Initialize(mapload) ..() - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/pen/multi/proc/select_colour(mob/user as mob) +/obj/item/pen/multi/proc/select_colour(mob/user) var/newcolour = tgui_input_list(user, "Which colour would you like to use?", name, colour_choices, colour) if(newcolour) colour = newcolour playsound(loc, 'sound/effects/pop.ogg', 50, 1) - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/pen/multi/attack_self(mob/living/user as mob) +/obj/item/pen/multi/attack_self(mob/living/user) select_colour(user) -/obj/item/pen/multi/update_icon() - overlays.Cut() - var/icon/o = new(icon, pen_color_iconstate) - var/list/c = colour_choices[colour] - o.SetIntensity(c[1], c[2], c[3]) + +/obj/item/pen/multi/update_overlays() + . = ..() + var/icon/color_overlay = new(icon, pen_color_iconstate) + var/list/colors = colour_choices[colour] + color_overlay.SetIntensity(colors[1], colors[2], colors[3]) if(pen_color_shift) - o.Shift(SOUTH, pen_color_shift) - overlays += o + color_overlay.Shift(SOUTH, pen_color_shift) + . += color_overlay + /obj/item/pen/fancy name = "fancy pen" @@ -197,28 +199,24 @@ playsound(user, 'sound/weapons/saberon.ogg', 3, 1) to_chat(user, "[src] is now active.") set_light(brightness_on, 1) - update_icon() + update_icon(UPDATE_ICON_STATE) + + +/obj/item/pen/edagger/update_icon_state() + icon_state = on ? "edagger" : initial(icon_state) //looks like a normal pen when off. + item_state = on ? "edagger" : initial(item_state) -/obj/item/pen/edagger/update_icon() - if(on) - icon_state = "edagger" - item_state = "edagger" - else - icon_state = initial(icon_state) //looks like a normal pen when off. - item_state = initial(item_state) /obj/item/pen/edagger/comms icon_state = "ofcommpen" item_state = "ofcommpen" light_color = LIGHT_COLOR_BLUE -/obj/item/pen/edagger/comms/update_icon() - if(on) - icon_state = "ofcommpen_active" - item_state = "ofcommpen_active" - else - icon_state = initial(icon_state) //looks like a normal pen when off. - item_state = initial(item_state) + +/obj/item/pen/edagger/comms/update_icon_state() + icon_state = on ? "ofcommpen_active" : initial(icon_state) + item_state = on ? "ofcommpen_active" : initial(item_state) + /obj/item/proc/on_write(obj/item/paper/P, mob/user) return diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 4764c3ad36f..62c789dea69 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/library.dmi' icon_state = "bigscanner" var/insert_anim = "bigscanner1" - anchored = 1 + anchored = TRUE density = 1 use_power = IDLE_POWER_USE idle_power_usage = 30 @@ -289,7 +289,7 @@ visible_message("A red light on \the [src] flashes, indicating that it is out of toner.") return paper -/obj/machinery/photocopier/proc/copy(var/obj/item/paper/copy) +/obj/machinery/photocopier/proc/copy(obj/item/paper/copy) var/obj/item/paper/c = new /obj/item/paper (loc) c.header = copy.header c.info = copy.info @@ -302,21 +302,21 @@ c.language = copy.language c.offset_x = copy.offset_x c.offset_y = copy.offset_y - var/list/temp_overlays = copy.overlays //Iterates through stamps - var/image/img //and puts a matching - for(var/j = 1, j <= temp_overlays.len, j++) //gray overlay onto the copy - if(copy.ico.len) - if(findtext(copy.ico[j], "cap") || findtext(copy.ico[j], "cent") || findtext(copy.ico[j], "rep") || findtext(copy.ico[j], "magistrate") || findtext(copy.ico[j], "navcom")) - img = image('icons/obj/bureaucracy.dmi', "paper_stamp-circle") - else if(findtext(copy.ico[j], "deny")) - img = image('icons/obj/bureaucracy.dmi', "paper_stamp-x") - else if(findtext(copy.ico[j], "ok")) - img = image('icons/obj/bureaucracy.dmi', "paper_stamp-check") - else - img = image('icons/obj/bureaucracy.dmi', "paper_stamp-dots") - img.pixel_x = copy.offset_x[j] - img.pixel_y = copy.offset_y[j] - c.overlays += img + if(LAZYLEN(copy.stamp_overlays)) + for(var/j = 1, j <= LAZYLEN(copy.stamp_overlays), j++) //gray overlay onto the copy + if(length(copy.ico)) + var/image/img + if(findtext(copy.ico[j], "cap") || findtext(copy.ico[j], "cent") || findtext(copy.ico[j], "rep") || findtext(copy.ico[j], "magistrate") || findtext(copy.ico[j], "navcom")) + img = image('icons/obj/bureaucracy.dmi', "paper_stamp-circle") + else if(findtext(copy.ico[j], "deny")) + img = image('icons/obj/bureaucracy.dmi', "paper_stamp-x") + else if(findtext(copy.ico[j], "ok")) + img = image('icons/obj/bureaucracy.dmi', "paper_stamp-check") + else + img = image('icons/obj/bureaucracy.dmi', "paper_stamp-dots") + img.pixel_x = copy.offset_x[j] + img.pixel_y = copy.offset_y[j] + LAZYADD(c.stamp_overlays, img) c.updateinfolinks() toner-- if(toner == 0) @@ -393,7 +393,7 @@ return p //If need_toner is 0, the copies will still be lightened when low on toner, however it will not be prevented from printing. TODO: Implement print queues for fax machines and get rid of need_toner -/obj/machinery/photocopier/proc/bundlecopy(var/obj/item/paper_bundle/bundle, var/need_toner=1) +/obj/machinery/photocopier/proc/bundlecopy(obj/item/paper_bundle/bundle, need_toner = TRUE) var/obj/item/paper_bundle/P = new /obj/item/paper_bundle (src, default_papers = FALSE) for(var/obj/item/W in bundle) if(toner <= 0 && need_toner) @@ -412,8 +412,7 @@ return null P.amount-- P.forceMove(get_turf(src)) - P.update_icon() - P.icon_state = "paper_words" + P.update_appearance(UPDATE_ICON|UPDATE_DESC) P.name = bundle.name P.pixel_y = rand(-8, 8) P.pixel_x = rand(-9, 9) @@ -425,7 +424,7 @@ new /obj/effect/decal/cleanable/blood/oil(get_turf(src)) toner = 0 -/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/living/user) +/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/living/user, params) check_ass() //Just to make sure that you can re-drag somebody onto it after they moved off. if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai) || target == ass) return @@ -442,6 +441,7 @@ copyitem.forceMove(get_turf(src)) visible_message("[copyitem] is shoved out of the way by [ass]!") copyitem = null + return TRUE /obj/machinery/photocopier/proc/check_ass() //I'm not sure wether I made this proc because it's good form or because of the name. if(!ass) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index e96f38ebc59..9f14c259b92 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -37,10 +37,10 @@ var/photo_size = 3 var/log_text = "" //Used for sending to Discord and just logging -/obj/item/photo/attack_self(mob/user as mob) +/obj/item/photo/attack_self(mob/user) user.examinate(src) -/obj/item/photo/attackby(obj/item/P as obj, mob/user as mob, params) +/obj/item/photo/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text) txt = copytext(txt, 1, 128) @@ -81,7 +81,7 @@ else . += "It is too far away." -/obj/item/photo/proc/show(mob/user as mob) +/obj/item/photo/proc/show(mob/user) var/icon/img_shown = new/icon(img) var/colormatrix = user.get_screen_colour() // Apply colorblindness effects, if any. @@ -127,26 +127,6 @@ pickup_sound = 'sound/items/handling/book_pickup.ogg' -/obj/item/storage/photo_album/MouseDrop(atom/over) - . = ..() - if(!.) - return FALSE - - var/mob/user = usr - if(user.incapacitated() || !ishuman(user)) - return FALSE - - if(over == user) - playsound(loc, "rustle", 50, TRUE, -5) - user.put_in_hands(src, ignore_anim = FALSE) - if(user.s_active) - user.s_active.close(user) - show_to(user) - return TRUE - - return FALSE - - /********* * camera * *********/ @@ -194,19 +174,19 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor size = nsize to_chat(usr, "Camera will now take [size]x[size] photos.") -/obj/item/camera/attack(mob/living/carbon/human/M as mob, mob/user as mob) +/obj/item/camera/attack(mob/living/carbon/human/M, mob/user) return -/obj/item/camera/attack_self(mob/user as mob) +/obj/item/camera/attack_self(mob/user) on = !on - if(on) - src.icon_state = icon_on - else - src.icon_state = icon_off + update_icon(UPDATE_ICON_STATE) to_chat(user, "You switch the camera [on ? "on" : "off"].") return -/obj/item/camera/attackby(obj/item/I as obj, mob/user as mob, params) +/obj/item/camera/update_icon_state() + icon_state = on ? icon_on : icon_off + +/obj/item/camera/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/camera_film)) if(pictures_left) to_chat(user, "[src] still has some film in it!") @@ -354,15 +334,19 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor pictures_left-- desc = "A polaroid camera. It has [pictures_left] photos left." to_chat(user, "[pictures_left] photos left.") - icon_state = icon_off on = FALSE + update_icon(UPDATE_ICON_STATE) if(istype(src,/obj/item/camera/spooky)) if(user.mind && user.mind.assigned_role == "Chaplain" && see_ghosts) if(prob(24)) handle_haunt(user) - spawn(64) - icon_state = icon_on - on = TRUE + addtimer(CALLBACK(src, PROC_REF(delayed_turn_on)), 6.4 SECONDS) + + +/obj/item/camera/proc/delayed_turn_on() + on = TRUE + update_icon(UPDATE_ICON_STATE) + /obj/item/camera/proc/can_capture_turf(turf/T, mob/user) var/viewer = user @@ -457,6 +441,37 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor return p + +///hauntings, like hallucinations but more spooky +/obj/item/camera/proc/handle_haunt(mob/user) + var/static/list/creepyasssounds = list( + 'sound/effects/ghost.ogg', + 'sound/effects/ghost2.ogg', + 'sound/effects/heartbeat.ogg', + 'sound/effects/screech.ogg', + 'sound/hallucinations/behind_you1.ogg', + 'sound/hallucinations/behind_you2.ogg', + 'sound/hallucinations/far_noise.ogg', + 'sound/hallucinations/growl1.ogg', + 'sound/hallucinations/growl2.ogg', + 'sound/hallucinations/growl3.ogg', + 'sound/hallucinations/im_here1.ogg', + 'sound/hallucinations/im_here2.ogg', + 'sound/hallucinations/i_see_you1.ogg', + 'sound/hallucinations/i_see_you2.ogg', + 'sound/hallucinations/look_up1.ogg', + 'sound/hallucinations/look_up2.ogg', + 'sound/hallucinations/over_here1.ogg', + 'sound/hallucinations/over_here2.ogg', + 'sound/hallucinations/over_here3.ogg', + 'sound/hallucinations/turn_around1.ogg', + 'sound/hallucinations/turn_around2.ogg', + 'sound/hallucinations/veryfar_noise.ogg', + 'sound/hallucinations/wail.ogg', + ) + SEND_SOUND(user, pick(creepyasssounds)) + + /***************** * digital camera * ******************/ @@ -467,18 +482,18 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor pictures_left = 30 var/max_storage = 10 -/obj/item/camera/digital/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) + +/obj/item/camera/digital/afterattack(atom/target, mob/user, flag) if(!on || !pictures_left || ismob(target.loc)) return captureimage(target, user, flag) playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3) - desc = "A digital camera. A small screen shows that there are currently [saved_pictures.len] pictures stored." - icon_state = icon_off - on = 0 - spawn(64) - icon_state = icon_on - on = 1 + desc = "A digital camera. A small screen shows that there are currently [length(saved_pictures)] pictures stored." + on = FALSE + update_icon(UPDATE_ICON_STATE) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/camera, delayed_turn_on)), 6.4 SECONDS) + /obj/item/camera/digital/captureimage(atom/target, mob/user, flag) if(saved_pictures.len >= max_storage) @@ -539,6 +554,7 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor /************** *video camera * ***************/ +#define CAMERA_STATE_COOLDOWN 2 SECONDS /obj/item/videocam name = "video camera" @@ -549,38 +565,66 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT materials = list(MAT_METAL=2000) - var/on = 0 + var/on = FALSE + var/video_cooldown = 0 var/obj/machinery/camera/camera - var/icon_on = "videocam_on" - var/icon_off = "videocam" var/canhear_range = 7 -/obj/item/videocam/attack_self(mob/user) - on = !on - if(camera) - if(on==0) - src.icon_state = icon_off - camera.c_tag = null - camera.network = list() + +/obj/item/videocam/Destroy() + if(on) + update_feeds() + return ..() + + +/obj/item/videocam/update_icon_state() + icon_state = "videocam[on ? "_on" : ""]" + + +/obj/item/videocam/proc/update_feeds() + for(var/obj/machinery/computer/security/telescreen/entertainment/TV in GLOB.machines) + if(on) + TV.feeds_on++ else - src.icon_state = icon_on - camera.network = list("news") - camera.c_tag = user.name - else + TV.feeds_on-- + TV.update_icon(UPDATE_OVERLAYS) + - src.icon_state = icon_on +/obj/item/videocam/proc/camera_state(mob/living/carbon/user) + if(on) + camera.c_tag = null + QDEL_NULL(camera) + else camera = new /obj/machinery/camera(src) camera.network = list("news") - GLOB.cameranet.removeCamera(camera) camera.c_tag = user.name - to_chat(user, "You switch the camera [on ? "on" : "off"].") + on = !on + update_icon(UPDATE_ICON_STATE) + visible_message(span_notice("The video camera has been turned [on ? "on" : "off"].")) + update_feeds() + + +/obj/item/videocam/attack_self(mob/user) + if(world.time < video_cooldown) + to_chat(user, span_warning("[src] is overheating, give it some time.")) + return + camera_state(user) + + +/obj/item/videocam/dropped(mob/user, silent = FALSE) + . = ..() + if(!on) + return + camera_state() + /obj/item/videocam/examine(mob/user) . = ..() if(in_range(user, src)) - . += "This video camera can send live feeds to the entertainment network. It's [camera ? "" : "in"]active." + . += span_notice("This video camera can send live feeds to the entertainment network. It's [on ? "" : "in"]active.") + -/obj/item/videocam/hear_talk(mob/M as mob, list/message_pieces) +/obj/item/videocam/hear_talk(mob/M, list/message_pieces) var/msg = multilingual_to_message(message_pieces) if(camera && on) if(get_dist(src, M) <= canhear_range) @@ -589,19 +633,16 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor if(T.watchers[M] == camera) T.atom_say(msg) -/obj/item/videocam/hear_message(mob/M as mob, msg) + +/obj/item/videocam/hear_message(mob/M, msg) if(camera && on) for(var/obj/machinery/computer/security/telescreen/T in GLOB.machines) if(T.watchers[M] == camera) T.atom_say(msg) -///hauntings, like hallucinations but more spooky +/obj/item/videocam/advanced + name = "advanced video camera" + desc = "This video camera allows you to send live feeds even when attached to a belt." + slot_flags = SLOT_BELT -/obj/item/camera/proc/handle_haunt(mob/user as mob) - var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/screech.ogg',\ - 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ - 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ - 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ - 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') - user << pick(creepyasssounds) diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index ee33e2037e3..99a019b1251 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -44,11 +44,13 @@ ticket.visible_message("\the [ticket] disperses!") qdel(ticket) tickets.Cut() - update_icon() + update_icon(UPDATE_ICON_STATE) + handle_maptext() /obj/machinery/ticket_machine/Initialize(mapload) . = ..() - update_icon() + update_icon(UPDATE_ICON_STATE) + handle_maptext() /obj/machinery/ticket_machine/proc/increment() if(current_number > ticket_number) @@ -64,7 +66,8 @@ if(!(emagged) && tickets[current_number]) var/obj/item/ticket_machine_ticket/ticket = tickets[current_number] ticket.audible_message("\the [tickets[current_number]] vibrates!") - update_icon() //Update our icon here rather than when they take a ticket to show the current ticket number being served + update_icon(UPDATE_ICON_STATE) //Update our icon here rather than when they take a ticket to show the current ticket number being served + handle_maptext() /obj/machinery/door_control/ticket_machine_button name = "increment ticket counter" @@ -82,7 +85,8 @@ M.increment() addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) -/obj/machinery/ticket_machine/update_icon() + +/obj/machinery/ticket_machine/update_icon_state() switch(ticket_number) //Gives you an idea of how many tickets are left if(0 to 49) icon_state = "ticketmachine_100" @@ -90,7 +94,7 @@ icon_state = "ticketmachine_50" if(100) icon_state = "ticketmachine_0" - handle_maptext() + /obj/machinery/ticket_machine/proc/handle_maptext() if(!dispense_enabled) @@ -124,7 +128,8 @@ qdel(ticket) tickets.Cut() max_number = initial(max_number) - update_icon() + update_icon(UPDATE_ICON_STATE) + handle_maptext() return else if(I.GetID()) var/obj/item/card/id/heldID = I.GetID() diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index 096d4aa72c0..4bb5731c089 100755 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -104,7 +104,7 @@ GLOBAL_LIST_EMPTY(PDAs) return id ? id : ..() -/obj/item/pda/MouseDrop(atom/over) +/obj/item/pda/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() var/mob/user = usr diff --git a/code/modules/pda/ai.dm b/code/modules/pda/ai.dm index 9f34fe4b73f..ff76ff3d515 100644 --- a/code/modules/pda/ai.dm +++ b/code/modules/pda/ai.dm @@ -22,7 +22,7 @@ return var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) if(!M) - to_chat(usr, "Cannot use messenger!") + to_chat(usr, span_warning("Cannot use messenger!")) var/list/plist = M.available_pdas() if(plist) var/c = tgui_input_list(usr, "Please select a PDA", "Send message", sortList(plist)) @@ -40,13 +40,11 @@ return var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) if(!M) - to_chat(usr, "Cannot use messenger!") + to_chat(usr, span_warning("Cannot use messenger!")) var/HTML = {"AI PDA Message Log"} for(var/index in M.tnote) - if(index["sent"]) - HTML += addtext("→ To ", index["owner"],":
    ", index["message"], "
    ") - else - HTML += addtext("← From ", index["owner"],":
    ", index["message"], "
    ") + var/obj/item/pda/target_pda = locateUID(index["target"]) + HTML += "[index["sent"] ? "→ To" : "← From"] [QDELETED(target_pda) ? "Error#1133: Unable to find UserName." : "[target_pda.owner] ([target_pda.ownjob])"]:
    [index["message"]]
    " HTML +="" usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index ffa2c94ec50..c1daf695c26 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -21,9 +21,9 @@ if("Status") switch(params["statdisp"]) if("message") - post_status("message", message1, message2) + post_status(STATUS_DISPLAY_MESSAGE, message1, message2) if("alert") - post_status("alert", params["alert"]) + post_status(STATUS_DISPLAY_ALERT, params["alert"]) if("setmsg1") message1 = clean_input("Line 1", "Enter Message Text", message1) if("setmsg2") @@ -31,30 +31,6 @@ else post_status(params["statdisp"]) -/datum/data/pda/app/status_display/proc/post_status(var/command, var/data1, var/data2) - var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) - if(!frequency) - return - - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if(istype(pda.loc, /mob/living)) - log_admin("STATUS: [key_name_log(pda.loc)] set status screen with [pda]. Message: [data1] [data2]") - message_admins("STATUS: [key_name_admin(pda.loc)] set status screen with [pda]. Message: [data1] [data2]") - - if("alert") - status_signal.data["picture_state"] = data1 - - spawn(0) - frequency.post_signal(src, status_signal) - /datum/data/pda/app/signaller name = "Signaler System" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8632d8d7630..26da71c5aae 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -23,7 +23,7 @@ #define APC_UPOVERLAY_ENVIRON2 2048 #define APC_UPOVERLAY_LOCKED 4096 -#define APC_UPDATE_ICON_COOLDOWN 200 // 20 seconds +#define APC_UPDATE_ICON_COOLDOWN (20 SECONDS) // main_status var #define APC_EXTERNAL_POWER_NOTCONNECTED 0 @@ -32,9 +32,38 @@ // APC malf status #define APC_MALF_NOT_HACKED 1 -#define APC_MALF_HACKED 2 // APC hacked by user, and user is in its core. -#define APC_MALF_SHUNTED_HERE 3 // User is shunted in this APC -#define APC_MALF_SHUNTED_OTHER 4 // User is shunted in another APC +/// APC hacked by user, and user is in its core. +#define APC_MALF_HACKED 2 +/// User is shunted in this APC. +#define APC_MALF_SHUNTED_HERE 3 +/// User is shunted in another APC +#define APC_MALF_SHUNTED_OTHER 4 + +/// Power channel is off, anything connected to it is not powered, cannot be set manually by players. +#define CHANNEL_SETTING_OFF 0 +/// APC power channel Setting Off, if set while apc is "on" set apc to "off" otherwise set to "auto-off". +#define CHANNEL_SETTING_AUTO_OFF 1 +/// APC power channel setting on. +#define CHANNEL_SETTING_ON 2 //on +/// APC user setting. +#define CHANNEL_SETTING_AUTO_ON 3 //auto + +//open states +#define APC_CLOSED 0 +#define APC_OPENED 1 +#define APC_COVER_OFF 2 + +//autoflags +#define APC_AUTOFLAG_ALL_OFF 0 +#define APC_AUTOFLAG_ENVIRO_ONLY 1 +#define APC_AUTOFLAG_EQUIPMENT_OFF 2 +#define APC_AUTOFLAG_ALL_ON 3 + +//electronics state +#define APC_ELECTRONICS_NONE 0 +#define APC_ELECTRONICS_INSTALLED 1 +#define APC_ELECTRONICS_SECURED 2 + // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire conection to power network through a terminal @@ -58,80 +87,123 @@ req_access = list(ACCESS_ENGINE_EQUIP) siemens_strength = 1 damage_deflection = 10 + powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :( (elly1989) + + /*** APC Area/Powernet vars ***/ + /// The area that this APC is in var/area/area - var/areastring = null - var/obj/machinery/integration_cog/cog //Is there a cog siphoning power? - var/obj/item/stock_parts/cell/cell - var/start_charge = 90 // initial cell charge % - var/cell_type = 2500 //Base cell has 2500 capacity. Enter the path of a different cell you want to use. cell determines charge rates, max capacity, ect. These can also be changed with other APC vars, but isn't recommended to minimize the risk of accidental usage of dirty editted APCs - var/opened = 0 //0=closed, 1=opened, 2=cover removed - var/shorted = 0 - var/lighting_channel = 3 - var/equipment_channel = 3 - var/environment_channel = 3 - var/operating = 1 - var/charging = 0 - var/chargemode = 1 - var/chargecount = 0 - var/locked = 1 - var/coverlocked = 1 - var/aidisabled = 0 - var/obj/machinery/power/terminal/terminal = null - var/lastused_light = 0 - var/lastused_equip = 0 - var/lastused_environ = 0 - var/lastused_total = 0 + /// The set string name of the area, used in naming the APC + var/areastring + /// The power terminal connected to this APC + var/obj/machinery/power/terminal/terminal + /// The status of the terminals powernet that this APC is connected to: not connected, no power, or recieving power var/main_status = APC_EXTERNAL_POWER_NOTCONNECTED - powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :( - var/malfhack = 0 //New var for my changes to AI malf. --NeoFite - var/mob/living/silicon/ai/malfai = null //See above --NeoFite - var/debug= 0 - var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on. -// luminosity = 1 - var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver - var/overload = 1 //used for the Blackout malf module - var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment - var/mob/living/silicon/ai/occupier = null - var/longtermpower = 10 - var/update_state = -1 - var/update_overlay = -1 - var/global/status_overlays = 0 - var/updating_icon = 0 - var/datum/wires/apc/wires = null - //var/debug = 0 - var/global/list/status_overlays_lock - var/global/list/status_overlays_charging - var/global/list/status_overlays_equipment - var/global/list/status_overlays_lighting - var/global/list/status_overlays_environ - var/indestructible = 0 // If set, prevents aliens from destroying it - var/keep_preset_name = 0 + /// Amount of power used in the last cycle for lighting channel + var/last_used_lighting = 0 + /// Amount of power used in the last cycle for equipment channel + var/last_used_equipment = 0 + /// Amount of power used in the last cycle for environment channel + var/last_used_environment = 0 + /// Amount of power used in the last cycle in total + var/last_used_total = 0 + /// Is there a cog siphoning power? + var/obj/machinery/integration_cog/cog + + /*** APC Cell Vars ***/ + /// The cell type stored in this APC + var/obj/item/stock_parts/cell/cell + /// The percentage charge the internal battery will start with + var/start_charge = 90 + ///Base cell has 2500 capacity. Enter the path of a different cell you want to use. cell determines charge rates, max capacity, ect. These can also be changed with other APC vars, but isn't recommended to minimize the risk of accidental usage of dirty editted APCs + var/cell_type = 2500 + + /*** APC Status Vars ***/ + /// The wire panel associated with this APC + var/datum/wires/apc/wires + /// Can the APC recieve/transmit power? Determined by the condition of the 2 Main Power Wires + var/shorted = FALSE + /// Is the APC on and transmitting power. + var/operating = TRUE + /// The current charging mode of the APC: not charging, charging, fully charged + var/charging = APC_NOT_CHARGING + /// A counter var used to help determine if the APC has not been charging long enough to justify not performing certain auto setting such as turning all channels back on + var/longtermpower = 10 + /// State of the APC Cover - Closed, Open, or Off + var/opened = APC_CLOSED + /// Can silicons access this APC? + var/aidisabled = FALSE + /// Electonics cicuit status. + var/electronics_state = APC_ELECTRONICS_NONE + + /*** APC Settings Vars ***/ + /// The current setting for the lighting channel + var/lighting_channel = CHANNEL_SETTING_AUTO_ON + /// The current setting for the equipment channel + var/equipment_channel = CHANNEL_SETTING_AUTO_ON + /// The current setting for the environment channel + var/environment_channel = CHANNEL_SETTING_AUTO_ON + /// Is the APC cover locked? i.e cannot be opened? + var/coverlocked = TRUE + /// Is the APC User Interface locked (prevents interaction)? Will not prevent silicons or admin observers from interacting + var/locked = TRUE + /// If TRUE, the APC will automatically draw power from connect terminal, if FALSE it will not charge. + var/chargemode = TRUE + /// Counter var, ticks up when the APC recieves power from terminal and resets to 0 when not charging, used for the `var/charging` var + var/chargecount = 0 + /// Whether this APC will generate alert reports based on current status. var/report_power_alarm = TRUE - var/shock_proof = 0 //if set to 1, this APC will not arc bolts of electricity if it's overloaded. + /// If set to TRUE, this APC will not arc bolts of electricity if it's overloaded. + var/shock_proof = FALSE // Nightshift var/nightshift_lights = FALSE var/last_nightshift_switch = 0 - ///Used to determine if emergency lights should be on or off + // Used to determine if emergency lights should be on or off var/emergency_power = TRUE var/emergency_power_timer var/emergency_lights = FALSE + /// Settings variable for having the APC auto use certain power channel settings + var/autoflag = APC_AUTOFLAG_ALL_OFF + /// Being hijacked by a pulse demon? var/being_hijacked = FALSE + /*** APC Malf AI Vars ****/ + var/malfhack = FALSE + var/mob/living/silicon/ai/malfai + var/mob/living/silicon/ai/occupier + /// Used for the Blackout malf module + var/overload = 1 + + /// Used to debug APC processing. + var/debug = FALSE + + /*** APC Overlay Vars ***/ + var/update_state = -1 + var/update_overlay = -1 + var/global/status_overlays = FALSE + var/updating_icon = FALSE + var/global/list/status_overlays_lock + var/global/list/status_overlays_charging + var/global/list/status_overlays_equipment + var/global/list/status_overlays_lighting + var/global/list/status_overlays_environ + var/keep_preset_name = FALSE + + /obj/machinery/power/apc/worn_out name = "\improper Worn out APC" - keep_preset_name = 1 - locked = 0 - environment_channel = 0 - equipment_channel = 0 - lighting_channel = 0 - operating = 0 + keep_preset_name = TRUE + locked = FALSE + lighting_channel = CHANNEL_SETTING_OFF + equipment_channel = CHANNEL_SETTING_OFF + environment_channel = CHANNEL_SETTING_OFF + operating = FALSE emergency_power = FALSE /obj/machinery/power/apc/noalarm @@ -181,8 +253,8 @@ area = get_area(src) area.apc |= src - opened = 1 - operating = 0 + opened = APC_OPENED + operating = FALSE name = "[area.name] APC" stat |= MAINT update_icon() @@ -218,7 +290,7 @@ . = ..() if(!mapload) return - has_electronics = 2 //installed and secured + electronics_state = APC_ELECTRONICS_SECURED // is starting with a power cell installed, create it and set its charge level if(cell_type) cell = new/obj/item/stock_parts/cell/upgraded(src) @@ -253,11 +325,11 @@ if(stat & BROKEN) . += "Looks broken" else if(opened) - if(has_electronics && terminal) - . += "The cover is [opened==2?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"]." - else if(!has_electronics && terminal) + if(has_electronics() && terminal) + . += "The cover is [opened == APC_COVER_OFF ?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"]." + else if(!has_electronics() && terminal) . += "There are some wires but no electronics." - else if(has_electronics && !terminal) + else if(has_electronics() && !terminal) . += "Electronics installed but not wired." else /* if(!has_electronics && !terminal) */ . += "There are no electronics nor connected wires." @@ -273,12 +345,13 @@ if(cog && isclocker(user)) . += "There is an integration cog installed!" + // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/update_icon(force_update = FALSE) if(!status_overlays || force_update) - status_overlays = 1 + status_overlays = TRUE status_overlays_lock = new status_overlays_charging = new status_overlays_equipment = new @@ -313,79 +386,100 @@ status_overlays_environ[3] = image(icon, "apco2-2") status_overlays_environ[4] = image(icon, "apco2-3") - - var/update = check_updates() //returns 0 if no need to update icons. // 1 if we need to update the icon_state // 2 if we need to update the overlays if(!update && !force_update) return - if(force_update || update & 1) // Updating the icon state - if(update_state & UPSTATE_ALLGOOD) - icon_state = "apc0" - else if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2)) - var/basestate = "apc[ cell ? "2" : "1" ]" - if(update_state & UPSTATE_OPENED1) - if(update_state & (UPSTATE_MAINT|UPSTATE_BROKE)) - icon_state = "apcmaint" //disabled APC cannot hold cell - else - icon_state = basestate - else if(update_state & UPSTATE_OPENED2) - icon_state = "[basestate]-nocover" - else if(update_state & UPSTATE_BROKE) - icon_state = "apc-b" - else if(update_state & UPSTATE_BLUESCREEN) - icon_state = "apcemag" - else if(update_state & UPSTATE_WIREEXP) - icon_state = "apcewires" - - - - if(!(update_state & UPSTATE_ALLGOOD)) - if(overlays.len) - overlays = 0 - return - - - - if(force_update || update & 2) - - if(overlays.len) - overlays.len = 0 - - if(!(stat & (BROKEN|MAINT)) && update_state & UPSTATE_ALLGOOD) - overlays += status_overlays_lock[locked+1] - overlays += status_overlays_charging[charging+1] - if(operating) - overlays += status_overlays_equipment[equipment_channel+1] - overlays += status_overlays_lighting[lighting_channel+1] - overlays += status_overlays_environ[environment_channel+1] - - if(force_update || update & 3) + if(force_update || (update & 3)) if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2|UPSTATE_BROKE)) set_light(0) else if(update_state & UPSTATE_BLUESCREEN) set_light(2, 1, COLOR_CYAN_BLUE) - else if(!(stat & (UPSTATE_MAINT|UPSTATE_BROKE)) && update_state & UPSTATE_ALLGOOD) + else if(!(stat & (UPSTATE_MAINT|UPSTATE_BROKE)) && (update_state & UPSTATE_ALLGOOD)) var/color switch(charging) - if(0) + if(APC_NOT_CHARGING) color = COLOR_APC_RED - if(1) + if(APC_IS_CHARGING) color = COLOR_APC_BLUE - if(2) + if(APC_FULLY_CHARGED) color = COLOR_APC_GREEN set_light(2, 0.5, color) else set_light(0) + if(force_update || (update & 1)) // Updating the icon state + ..(UPDATE_ICON_STATE) + + if(!(update_state & UPSTATE_ALLGOOD)) + if(managed_overlays) + ..(UPDATE_OVERLAYS) + return + + if(force_update || (update & 2)) + ..(UPDATE_OVERLAYS) + + +/obj/machinery/power/apc/update_icon_state() + if(update_state & UPSTATE_ALLGOOD) + icon_state = "apc0" + else if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2)) + var/basestate = "apc[ cell ? "2" : "1" ]" + if(update_state & UPSTATE_OPENED1) + if(update_state & (UPSTATE_MAINT|UPSTATE_BROKE)) + icon_state = "apcmaint" //disabled APC cannot hold cell + else + icon_state = basestate + else if(update_state & UPSTATE_OPENED2) + icon_state = "[basestate]-nocover" + else if(update_state & UPSTATE_BROKE) + icon_state = "apc-b" + else if(update_state & UPSTATE_BLUESCREEN) + icon_state = "apcemag" + else if(update_state & UPSTATE_WIREEXP) + icon_state = "apcewires" + + +/obj/machinery/power/apc/update_overlays() + . = ..() + underlays.Cut() + + if(update_state & UPSTATE_BLUESCREEN) + underlays += emissive_appearance(icon, "emit_apcemag") + return + + if((stat & (BROKEN|MAINT)) || !(update_state & UPSTATE_ALLGOOD)) + return + + var/image/statover_lock = status_overlays_lock[locked + 1] + var/image/statover_charg = status_overlays_charging[charging + 1] + . += statover_lock + . += statover_charg + underlays += emissive_appearance(icon, statover_lock.icon_state) + underlays += emissive_appearance(icon, statover_charg.icon_state) + + if(!operating) + return + + var/image/statover_equip = status_overlays_equipment[equipment_channel + 1] + var/image/statover_light = status_overlays_lighting[lighting_channel + 1] + var/image/statover_envir = status_overlays_environ[environment_channel + 1] + . += statover_equip + . += statover_light + . += statover_envir + underlays += emissive_appearance(icon, statover_equip.icon_state) + underlays += emissive_appearance(icon, statover_light.icon_state) + underlays += emissive_appearance(icon, statover_envir.icon_state) + + /obj/machinery/power/apc/proc/check_updates() var/last_update_state = update_state var/last_update_overlay = update_overlay - update_state = 0 - update_overlay = 0 + update_state = NONE + update_overlay = NONE if(cell) update_state |= UPSTATE_CELL_IN @@ -394,9 +488,9 @@ if(stat & MAINT) update_state |= UPSTATE_MAINT if(opened) - if(opened==1) + if(opened == APC_OPENED) update_state |= UPSTATE_OPENED1 - if(opened==2) + if(opened == APC_COVER_OFF) update_state |= UPSTATE_OPENED2 else if(emagged || malfai || being_hijacked) update_state |= UPSTATE_BLUESCREEN @@ -409,32 +503,32 @@ if(locked) update_overlay |= APC_UPOVERLAY_LOCKED - if(!charging) + if(charging == APC_NOT_CHARGING) update_overlay |= APC_UPOVERLAY_CHARGEING0 - else if(charging == 1) + else if(charging == APC_IS_CHARGING) update_overlay |= APC_UPOVERLAY_CHARGEING1 - else if(charging == 2) + else if(charging == APC_FULLY_CHARGED) update_overlay |= APC_UPOVERLAY_CHARGEING2 if(!equipment_channel) update_overlay |= APC_UPOVERLAY_EQUIPMENT0 - else if(equipment_channel == 1) + else if(equipment_channel == CHANNEL_SETTING_AUTO_OFF) update_overlay |= APC_UPOVERLAY_EQUIPMENT1 - else if(equipment_channel == 2) + else if(equipment_channel == CHANNEL_SETTING_ON) update_overlay |= APC_UPOVERLAY_EQUIPMENT2 if(!lighting_channel) update_overlay |= APC_UPOVERLAY_LIGHTING0 - else if(lighting_channel == 1) + else if(lighting_channel == CHANNEL_SETTING_AUTO_OFF) update_overlay |= APC_UPOVERLAY_LIGHTING1 - else if(lighting_channel == 2) + else if(lighting_channel == CHANNEL_SETTING_ON) update_overlay |= APC_UPOVERLAY_LIGHTING2 if(!environment_channel) update_overlay |= APC_UPOVERLAY_ENVIRON0 - else if(environment_channel==1) + else if(environment_channel == CHANNEL_SETTING_AUTO_OFF) update_overlay |= APC_UPOVERLAY_ENVIRON1 - else if(environment_channel==2) + else if(environment_channel == CHANNEL_SETTING_ON) update_overlay |= APC_UPOVERLAY_ENVIRON2 var/results = 0 @@ -446,15 +540,20 @@ results += 2 return results + // Used in process so it doesn't update the icon too much /obj/machinery/power/apc/proc/queue_icon_update() if(!updating_icon) - updating_icon = 1 + updating_icon = TRUE // Start the update - spawn(APC_UPDATE_ICON_COOLDOWN) - update_icon() - updating_icon = 0 + addtimer(CALLBACK(src, PROC_REF(queue_icon_callback)), APC_UPDATE_ICON_COOLDOWN) + + +/obj/machinery/power/apc/proc/queue_icon_callback() + update_icon() + updating_icon = FALSE + /obj/machinery/power/apc/flicker(second_pass = FALSE) if(opened || panel_open) @@ -464,17 +563,15 @@ if(!second_pass) //The first time, we just cut overlays addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/power/apc, flicker), TRUE), 1) cut_overlays() - - for(var/obj/machinery/machine as anything in area.machinery_cache) - - if(machine != src && prob(10)) + managed_overlays = null + // APC power distruptions have a chance to propogate to other machines on its network + for(var/obj/machinery/machine as anything in (area.machinery_cache - src)) + if(prob(10)) INVOKE_ASYNC(machine, TYPE_PROC_REF(/obj/machinery, flicker)) - CHECK_TICK - else flick("apcemag", src) //Second time we cause the APC to update its icon, then add a timer to update icon later - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), TRUE), 10) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), TRUE), 1 SECONDS) return TRUE @@ -526,7 +623,7 @@ else if(terminal) // it already have terminal to_chat(user, "This APC is already wired!") return - else if(has_electronics == 0) + else if(!has_electronics()) to_chat(user, "There is nothing to wire!") return @@ -540,7 +637,7 @@ if(do_after(user, 20, target = src)) if(C.get_amount() < 10 || !C) return - if(C.get_amount() >= 10 && !terminal && opened && has_electronics > 0) + if(C.get_amount() >= 10 && !terminal && opened && has_electronics()) add_fingerprint(user) var/turf/T = get_turf(src) var/obj/structure/cable/N = T.get_cable_node() @@ -553,7 +650,7 @@ terminal.connect_to_network() else if(istype(W, /obj/item/apc_electronics) && opened) - if(has_electronics!=0) // there are already electronicks inside + if(has_electronics()) // there are already electronicks inside to_chat(user, "You cannot put the board inside, there already is one!") return else if(stat & BROKEN) @@ -564,28 +661,28 @@ "You start to insert the power control board into the frame...") playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE) if(do_after(user, 10, target = src)) - if(!has_electronics) + if(!has_electronics()) add_fingerprint(user) - has_electronics = TRUE + electronics_state = APC_ELECTRONICS_INSTALLED locked = FALSE to_chat(user, "You place the power control board inside the frame.") qdel(W) else if(istype(W, /obj/item/mounted/frame/apc_frame) && opened) - if(!(stat & BROKEN || opened==2 || obj_integrity < max_integrity)) // There is nothing to repair + if(!(stat & BROKEN || opened== APC_COVER_OFF || obj_integrity < max_integrity)) // There is nothing to repair to_chat(user, "You found no reason for repairing this APC") return - if(!(stat & BROKEN) && opened==2) // Cover is the only thing broken, we do not need to remove elctronicks to replace cover + if(!(stat & BROKEN) && opened== APC_COVER_OFF) // Cover is the only thing broken, we do not need to remove elctronicks to replace cover user.visible_message("[user.name] replaces missing APC's cover.",\ "You begin to replace APC's cover...") if(do_after(user, 20, target = src)) // replacing cover is quicker than replacing whole frame add_fingerprint(user) to_chat(user, "You replace missing APC's cover.") qdel(W) - opened = 1 + opened = APC_OPENED update_icon() return - if(has_electronics) + if(has_electronics()) to_chat(user, "You cannot repair this APC until you remove the electronics still inside!") return user.visible_message("[user.name] replaces the damaged APC frame with a new one.",\ @@ -596,8 +693,8 @@ qdel(W) stat &= ~BROKEN obj_integrity = max_integrity - if(opened==2) - opened = 1 + if(opened== APC_COVER_OFF) + opened = APC_OPENED update_icon() else if(istype(W, /obj/item/clockwork/integration_cog)) if(!isclocker(user)) @@ -615,7 +712,7 @@ add_fingerprint(user) user.visible_message("[user] slices [src]'s cover lock, and it swings wide open!", \ "You slice [src]'s cover lock apart with [W], and the cover swings open.") - opened = TRUE + opened = APC_OPENED update_icon() else user.visible_message("[user] presses [W] into [src]!", \ @@ -628,9 +725,10 @@ "Replicant alloy rapidly covers the APC's innards, replacing the machinery.
    \ This APC will now passively provide power for the cult!") playsound(user, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE) + user.drop_transfer_item_to_loc(W, src, force = TRUE) qdel(W) cog = new(src) - opened = FALSE + opened = APC_CLOSED locked = FALSE update_icon() return @@ -664,14 +762,14 @@ if(!I.tool_start_check(src, user, 0)) return if(opened) // a) on open apc - if(has_electronics==1) + if(electronics_state == APC_ELECTRONICS_INSTALLED) if(terminal) to_chat(user, "Disconnect the wires first!") return to_chat(user, "You are trying to remove the power control board..." ) if(I.use_tool(src, user, 50, volume = I.tool_volume)) - if(has_electronics) - has_electronics = FALSE + if(has_electronics()) + electronics_state = APC_ELECTRONICS_NONE if(stat & BROKEN) user.visible_message(\ "[user.name] has broken the power control board inside [name]!", @@ -707,8 +805,8 @@ playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) QDEL_NULL(cog) return - else if(opened!=2) //cover isn't removed - opened = 0 + else if(opened != APC_COVER_OFF) //cover isn't removed + opened = APC_CLOSED coverlocked = TRUE //closing cover relocks it update_icon() return @@ -720,13 +818,13 @@ to_chat(user, "Exposed wires prevents you from opening it!") return else - opened = 1 + opened = APC_OPENED update_icon() else if(stat & BROKEN) if(!opened) if(do_after(user, gettoolspeedmod(user)*(3 SECONDS)*I.toolspeed, FALSE, src)) to_chat(user, span_notice("You pry out broken frame.")) - opened = 2 + opened = APC_COVER_OFF update_icon() /obj/machinery/power/apc/screwdriver_act(mob/living/user, obj/item/I) @@ -738,12 +836,12 @@ to_chat(user, "Close the APC first!") //Less hints more mystery! return else - if(has_electronics==1) - has_electronics = 2 + if(electronics_state == APC_ELECTRONICS_INSTALLED) + electronics_state = APC_ELECTRONICS_SECURED stat &= ~MAINT to_chat(user, "You screw the circuit electronics into place.") - else if(has_electronics==2) - has_electronics = 1 + else if(electronics_state == APC_ELECTRONICS_SECURED) + electronics_state = APC_ELECTRONICS_INSTALLED stat |= MAINT to_chat(user, "You unfasten the electronics.") else @@ -800,25 +898,30 @@ if(!(flags & NODECONSTRUCT)) set_broken() + +/obj/machinery/power/apc/proc/has_electronics() + return electronics_state != APC_ELECTRONICS_NONE + + /obj/machinery/power/apc/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) if(!(stat & BROKEN)) set_broken() - if(opened != 2) - opened = 2 + if(opened != APC_COVER_OFF) + opened = APC_COVER_OFF coverlocked = FALSE visible_message("The APC cover is knocked down!") update_icon() /obj/machinery/power/apc/welder_act(mob/user, obj/item/I) - if(!opened || has_electronics || terminal) + if(!opened || has_electronics() || terminal) return . = TRUE if(!I.tool_use_check(user, 3)) return WELDER_ATTEMPT_SLICING_MESSAGE if(I.use_tool(src, user, 50, amount = 3, volume = I.tool_volume)) - if((stat & BROKEN) || opened==2) + if((stat & BROKEN) || opened == APC_COVER_OFF) new /obj/item/stack/sheet/metal(loc) user.visible_message(\ "[user.name] has cut [src] apart with [I].",\ @@ -845,7 +948,7 @@ add_attack_logs(user, src, "emagged") flick("apc-spark", src) emagged = 1 - locked = 0 + locked = FALSE if(user) to_chat(user, "You emag the APC interface.") update_icon() @@ -865,7 +968,7 @@ cell.add_fingerprint(user) cell.update_icon() cell = null - charging = FALSE + charging = APC_NOT_CHARGING update_icon() return if(stat & (BROKEN|MAINT)) @@ -924,7 +1027,7 @@ data["powerCellStatus"] = cell ? cell.percent() : null data["chargeMode"] = chargemode data["chargingStatus"] = charging - data["totalLoad"] = round(lastused_equip + lastused_light + lastused_environ) + data["totalLoad"] = round(last_used_equipment + last_used_lighting + last_used_environment) data["coverLocked"] = coverlocked data["siliconUser"] = istype(user, /mob/living/silicon) data["siliconLock"] = locked @@ -935,7 +1038,7 @@ var/powerChannels[0] powerChannels[++powerChannels.len] = list( "title" = "Equipment", - "powerLoad" = round(lastused_equip), + "powerLoad" = round(last_used_equipment), "status" = equipment_channel, "topicParams" = list( "auto" = list("eqp" = 3), @@ -945,7 +1048,7 @@ ) powerChannels[++powerChannels.len] = list( "title" = "Lighting", - "powerLoad" = round(lastused_light), + "powerLoad" = round(last_used_lighting), "status" = lighting_channel, "topicParams" = list( "auto" = list("lgt" = 3), @@ -955,7 +1058,7 @@ ) powerChannels[++powerChannels.len] = list( "title" = "Environment", - "powerLoad" = round(lastused_environ), + "powerLoad" = round(last_used_environment), "status" = environment_channel, "topicParams" = list( "auto" = list("env" = 3), @@ -975,13 +1078,14 @@ . = ..() /obj/machinery/power/apc/proc/report() - return "[area.name] : [equipment_channel]/[lighting_channel]/[environment_channel] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])" + return "[area.name] : [equipment_channel]/[lighting_channel]/[environment_channel] ([last_used_equipment+last_used_lighting+last_used_environment]) : [cell? cell.percent() : "N/C"] ([charging])" + /obj/machinery/power/apc/proc/update() if(operating && !shorted) - area.power_light = (lighting_channel > 1) - area.power_equip = (equipment_channel > 1) - area.power_environ = (environment_channel > 1) + area.power_light = (lighting_channel > CHANNEL_SETTING_AUTO_OFF) + area.power_equip = (equipment_channel > CHANNEL_SETTING_AUTO_OFF) + area.power_environ = (environment_channel > CHANNEL_SETTING_AUTO_OFF) if(lighting_channel) emergency_power = TRUE if(emergency_power_timer) @@ -989,56 +1093,54 @@ emergency_power_timer = null else emergency_power_timer = addtimer(CALLBACK(src, PROC_REF(turn_emergency_power_off)), 10 MINUTES, TIMER_UNIQUE|TIMER_STOPPABLE) -// if(area.name == "AI Chamber") -// spawn(10) -// to_chat(world, " [area.name] [area.power_equip]") else - area.power_light = 0 - area.power_equip = 0 - area.power_environ = 0 + area.power_light = FALSE + area.power_equip = FALSE + area.power_environ = FALSE emergency_power_timer = addtimer(CALLBACK(src, PROC_REF(turn_emergency_power_off)), 10 MINUTES, TIMER_UNIQUE|TIMER_STOPPABLE) -// if(area.name == "AI Chamber") -// to_chat(world, "[area.power_equip]") area.power_change() + /obj/machinery/power/apc/proc/turn_emergency_power_off() emergency_power = FALSE - for(var/L in area.lights_cache) - var/obj/machinery/light = L + for(var/obj/machinery/light as anything in area.lights_cache) INVOKE_ASYNC(light, TYPE_PROC_REF(/obj/machinery/light, update), FALSE) -/obj/machinery/power/apc/proc/can_use(var/mob/user, var/loud = 0) //used by attack_hand() and Topic() + +/obj/machinery/power/apc/proc/can_use(mob/user, loud = FALSE) //used by attack_hand() and Topic() if(stat & BROKEN) return FALSE if(user.can_admin_interact()) return TRUE autoflag = 5 - if(istype(user, /mob/living/silicon)) + if(ispAI(user)) + var/mob/living/silicon/pai/pAI = user + if(!pAI.syndipai || !pAI.ai_capability || pAI.capa_is_cooldown) + return FALSE + else if(issilicon(user)) var/mob/living/silicon/ai/AI = user var/mob/living/silicon/robot/robot = user - if(aidisabled || malfhack && istype(malfai) && ((istype(AI) && (malfai!=AI && malfai != AI.parent)) || (istype(robot) && !(robot in malfai.connected_robots)))) + if(aidisabled || malfhack && istype(malfai) && ((istype(AI) && malfai != AI && malfai != AI.parent) || (istype(robot) && !(robot in malfai.connected_robots)))) if(!loud) - to_chat(user, "\The [src] has AI control disabled!") + to_chat(user, span_danger("[src] has AI control disabled!")) user << browse(null, "window=apc") user.unset_machine() return FALSE - else - if((!in_range(src, user) || !istype(loc, /turf))) - return FALSE + else if(!in_range(src, user) || !isturf(loc)) + return FALSE - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.getBrainLoss() >= 60) - for(var/mob/M in viewers(src, null)) - to_chat(M, "[H] stares cluelessly at [src] and drools.") + var/mob/living/carbon/human/h_user = user + if(ishuman(h_user)) + if(h_user.getBrainLoss() >= 60) + h_user.visible_message(span_danger("[h_user] stares cluelessly at [src] and drools.")) return FALSE - else if(prob(H.getBrainLoss())) - to_chat(user, "You momentarily forget how to use [src].") + else if(prob(h_user.getBrainLoss())) + to_chat(user, span_danger("You momentarily forget how to use [src].")) return FALSE return TRUE -/obj/machinery/power/apc/proc/is_authenticated(mob/user as mob) +/obj/machinery/power/apc/proc/is_authenticated(mob/user) if(user.can_admin_interact()) return TRUE if(isAI(user) || (isrobot(user) || user.has_unlimited_silicon_privilege) && !iscogscarab(user)) @@ -1046,7 +1148,7 @@ else return !locked -/obj/machinery/power/apc/proc/is_locked(mob/user as mob) +/obj/machinery/power/apc/proc/is_locked(mob/user) if(user.can_admin_interact()) return FALSE if(isAI(user) || (isrobot(user) || user.has_unlimited_silicon_privilege) && !iscogscarab(user)) @@ -1109,8 +1211,7 @@ malfvacate() if("emergency_lighting") emergency_lights = !emergency_lights - for(var/L in area.lights_cache) - var/obj/machinery/light = L + for(var/obj/machinery/light/light as anything in area.lights_cache) INVOKE_ASYNC(light, TYPE_PROC_REF(/obj/machinery/light, update), FALSE) CHECK_TICK @@ -1166,7 +1267,7 @@ for(var/obj/item/pinpointer/point in GLOB.pinpointer_list) point.the_disk = src //the pinpointer will detect the shunted AI -/obj/machinery/power/apc/proc/malfvacate(forced) +/obj/machinery/power/apc/proc/malfvacate(forced = FALSE) if(!occupier) return if(occupier.parent && occupier.parent.stat != DEAD) @@ -1230,15 +1331,15 @@ if(!area.requires_power) return - lastused_light = area.usage(STATIC_LIGHT) - lastused_light += area.usage(LIGHT) - lastused_equip = area.usage(EQUIP) - lastused_equip += area.usage(STATIC_EQUIP) - lastused_environ = area.usage(ENVIRON) - lastused_environ += area.usage(STATIC_ENVIRON) + last_used_lighting = area.usage(STATIC_LIGHT) + last_used_lighting += area.usage(LIGHT) + last_used_equipment = area.usage(EQUIP) + last_used_equipment += area.usage(STATIC_EQUIP) + last_used_environment = area.usage(ENVIRON) + last_used_environment += area.usage(STATIC_ENVIRON) area.clear_usage() - lastused_total = lastused_light + lastused_equip + lastused_environ + last_used_total = last_used_lighting + last_used_equipment + last_used_environment //store states to update icon if any change var/last_lt = lighting_channel @@ -1256,78 +1357,46 @@ main_status = APC_EXTERNAL_POWER_GOOD if(debug) - log_debug("Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light] - Longterm: [longtermpower]") + log_debug("Status: [main_status] - Excess: [excess] - Last Equip: [last_used_equipment] - Last Light: [last_used_lighting] - Longterm: [longtermpower]") if(cell && !shorted) // draw power from cell as before to power the area - var/cellused = min(cell.charge, GLOB.CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell + var/cellused = min(cell.charge, GLOB.CELLRATE * last_used_total) // clamp deduction to a max, amount left in cell cell.use(cellused) - if(excess > lastused_total) // if power excess recharge the cell + if(excess > last_used_total) // if power excess recharge the cell // by the same amount just used cell.give(cellused) add_load(cellused/GLOB.CELLRATE) // add the load used to recharge the cell else // no excess, and not enough per-apc - if((cell.charge/GLOB.CELLRATE + excess) >= lastused_total) // can we draw enough from cell+grid to cover last usage? + if((cell.charge/GLOB.CELLRATE + excess) >= last_used_total) // can we draw enough from cell+grid to cover last usage? cell.charge = min(cell.maxcharge, cell.charge + GLOB.CELLRATE * excess) //recharge with what we can add_load(excess) // so draw what we can from the grid - charging = 0 + charging = APC_NOT_CHARGING else // not enough power available to run the last tick! - charging = 0 + charging = APC_NOT_CHARGING chargecount = 0 // This turns everything off in the case that there is still a charge left on the battery, just not enough to run the room. - equipment_channel = autoset(equipment_channel, 0) - lighting_channel = autoset(lighting_channel, 0) - environment_channel = autoset(environment_channel, 0) - autoflag = 0 - + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_OFF) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_OFF) + autoflag = APC_AUTOFLAG_ALL_OFF // Set channels depending on how much charge we have left // Allow the APC to operate as normal if the cell can charge - if(charging && longtermpower < 10) + if(charging != APC_NOT_CHARGING && longtermpower < 10) longtermpower += 1 else if(longtermpower > -10) longtermpower -= 2 - if(cell.charge >= 1250 || longtermpower > 0) // Put most likely at the top so we don't check it last, effeciency 101 - if(autoflag != 3) - equipment_channel = autoset(equipment_channel, 1) - lighting_channel = autoset(lighting_channel, 1) - environment_channel = autoset(environment_channel, 1) - autoflag = 3 - if(report_power_alarm) - area.poweralert(TRUE, src) - else if(cell.charge < 1250 && cell.charge > 750 && longtermpower < 0) // <30%, turn off equipment - if(autoflag != 2) - equipment_channel = autoset(equipment_channel, 2) - lighting_channel = autoset(lighting_channel, 1) - environment_channel = autoset(environment_channel, 1) - if(report_power_alarm) - area.poweralert(FALSE, src) - autoflag = 2 - else if(cell.charge < 750 && cell.charge > 10) // <15%, turn off lighting & equipment - if((autoflag > 1 && longtermpower < 0) || (autoflag > 1 && longtermpower >= 0)) - equipment_channel = autoset(equipment_channel, 2) - lighting_channel = autoset(lighting_channel, 2) - environment_channel = autoset(environment_channel, 1) - if(report_power_alarm) - area.poweralert(FALSE, src) - autoflag = 1 - else if(cell.charge <= 0) // zero charge, turn all off - if(autoflag != 0) - equipment_channel = autoset(equipment_channel, 0) - lighting_channel = autoset(lighting_channel, 0) - environment_channel = autoset(environment_channel, 0) - if(report_power_alarm) - area.poweralert(FALSE, src) - autoflag = 0 + handle_autoflag() // now trickle-charge the cell - if(chargemode && charging == 1 && operating) + if(chargemode && charging == APC_IS_CHARGING && operating) if(excess > 0) // check to make sure we have enough to charge // Max charge is capped to % per second constant var/ch = min(excess*GLOB.CELLRATE, cell.maxcharge*GLOB.CHARGELEVEL) @@ -1335,16 +1404,16 @@ cell.give(ch) // actually recharge the cell else - charging = 0 // stop charging + charging = APC_NOT_CHARGING // stop charging chargecount = 0 // show cell as fully charged if so if(cell.charge >= cell.maxcharge) cell.charge = cell.maxcharge - charging = 2 + charging = APC_FULLY_CHARGED if(chargemode) - if(!charging) + if(charging == APC_NOT_CHARGING) if(excess > cell.maxcharge*GLOB.CHARGELEVEL) chargecount++ else @@ -1353,39 +1422,25 @@ if(chargecount == 10) chargecount = 0 - charging = 1 + charging = APC_IS_CHARGING else // chargemode off - charging = 0 + charging = APC_NOT_CHARGING chargecount = 0 - if(excess >= 2500000 && !shock_proof) - var/shock_chance = 5 // 5% - if(excess >= 7500000) - shock_chance = 15 - else if(excess >= 5000000) - shock_chance = 10 - if(prob(shock_chance)) - var/list/shock_mobs = list() - for(var/C in view(get_turf(src), 5)) //We only want to shock a single random mob in range, not every one. - if(isliving(C)) - shock_mobs += C - if(shock_mobs.len) - var/mob/living/L = pick(shock_mobs) - L.electrocute_act(rand(5, 25), "electrical arc") - playsound(get_turf(L), 'sound/effects/eleczap.ogg', 75, TRUE) - Beam(L, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) + if(!shock_proof) + handle_shock_chance(excess) else // no cell, switch everything off - charging = 0 + charging = APC_NOT_CHARGING chargecount = 0 - equipment_channel = autoset(equipment_channel, 0) - lighting_channel = autoset(lighting_channel, 0) - environment_channel = autoset(environment_channel, 0) + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_OFF) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_OFF) if(report_power_alarm) area.poweralert(FALSE, src) - autoflag = 0 + autoflag = APC_AUTOFLAG_ALL_OFF // update icon & area power if anything changed @@ -1395,31 +1450,96 @@ else if(last_ch != charging) queue_icon_update() + handle_flicker() + + +/obj/machinery/power/apc/proc/handle_autoflag() + if(cell.charge >= 1250 || longtermpower > 0) // Put most likely at the top so we don't check it last, efficiency 101 + if(autoflag != APC_AUTOFLAG_ALL_ON) + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_AUTO_OFF) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_AUTO_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_AUTO_OFF) + autoflag = APC_AUTOFLAG_ALL_ON + if(report_power_alarm) + area.poweralert(TRUE, src) + return + + if(cell.charge < 1250 && cell.charge > 750 && longtermpower < 0) // <30%, turn off equipment + if(autoflag != APC_AUTOFLAG_EQUIPMENT_OFF) + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_ON) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_AUTO_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_AUTO_OFF) + if(report_power_alarm) + area.poweralert(FALSE, src) + autoflag = APC_AUTOFLAG_EQUIPMENT_OFF + + else if(cell.charge < 750 && cell.charge > 10) // <15%, turn off lighting & equipment + if(autoflag > APC_AUTOFLAG_ENVIRO_ONLY) + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_ON) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_AUTO_OFF) + if(report_power_alarm) + area.poweralert(FALSE, src) + autoflag = APC_AUTOFLAG_ENVIRO_ONLY + + else if(cell.charge <= 0) // zero charge, turn all off + if(autoflag != APC_AUTOFLAG_ALL_OFF) + equipment_channel = autoset(equipment_channel, CHANNEL_SETTING_OFF) + lighting_channel = autoset(lighting_channel, CHANNEL_SETTING_OFF) + environment_channel = autoset(environment_channel, CHANNEL_SETTING_OFF) + if(report_power_alarm) + area.poweralert(FALSE, src) + autoflag = APC_AUTOFLAG_ALL_OFF + + +/// Handles APC arc'ing every APC process interval +/obj/machinery/power/apc/proc/handle_shock_chance(excess = 0) + if(excess < 2500000) + return + + var/shock_chance = excess >= 5000000 ? excess >= 7500000 ? 15 : 10 : 5 + + if(prob(shock_chance)) + var/obj/machinery/light/picked_light = safepick(area.lights_cache) + picked_light?.flicker() + var/list/shock_mobs = list() + for(var/mob/living/victim in view(get_turf(src), 5)) + shock_mobs += victim + var/mob/living/victim = safepick(shock_mobs) //We only want to shock a single random mob in range, not every one. + if(victim) + victim.electrocute_act(rand(5, 25), "electrical arc") + playsound(get_turf(victim), 'sound/effects/eleczap.ogg', 75, TRUE) + Beam(victim, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) + + +/obj/machinery/power/apc/proc/handle_flicker() if(prob(MACHINE_FLICKER_CHANCE)) flicker() // lights don't have their own processing loop, so APCs will be the father they never had. 3x as likely to cause a light flicker in a particular area, pick a light to flicker at random if(prob(MACHINE_FLICKER_CHANCE) * 3) - var/obj/machinery/light/picked_light = length(area.lights_cache) ? pick(area.lights_cache) : null - if(picked_light) - picked_light.flicker() + var/obj/machinery/light/picked_light = safepick(area.lights_cache) + picked_light?.flicker() + -/obj/machinery/power/apc/proc/autoset(var/val, var/on) - if(on==0) - if(val==2) // if on, return off - return 0 - else if(val==3) // if auto-on, return auto-off - return 1 +/obj/machinery/power/apc/proc/autoset(current_setting, new_setting) + switch(new_setting) + if(CHANNEL_SETTING_OFF) + if(current_setting == CHANNEL_SETTING_ON) // if on, return off + return CHANNEL_SETTING_OFF + if(current_setting == CHANNEL_SETTING_AUTO_ON) // if auto-on, return auto-off + return CHANNEL_SETTING_AUTO_OFF - else if(on==1) - if(val==1) // if auto-off, return auto-on - return 3 + if(CHANNEL_SETTING_AUTO_OFF) + if(current_setting == CHANNEL_SETTING_AUTO_OFF) // if auto-off, return auto-on + return CHANNEL_SETTING_AUTO_ON - else if(on==2) - if(val==3) // if auto-on, return auto-off - return 1 + if(CHANNEL_SETTING_ON) + if(current_setting == CHANNEL_SETTING_AUTO_ON) // if auto-on, return auto-off + return CHANNEL_SETTING_AUTO_OFF + + return current_setting //if setting is not changed, just keep current setting - return val // damage and destruction acts @@ -1428,18 +1548,22 @@ cell.emp_act(severity) if(occupier) occupier.emp_act(severity) - lighting_channel = 0 - equipment_channel = 0 - environment_channel = 0 + lighting_channel = CHANNEL_SETTING_OFF + equipment_channel = CHANNEL_SETTING_OFF + environment_channel = CHANNEL_SETTING_OFF update_icon() update() - spawn(600) - equipment_channel = 3 - environment_channel = 3 - update_icon() - update() + addtimer(CALLBACK(src, PROC_REF(emp_callback)), 60 SECONDS) ..() + +/obj/machinery/power/apc/proc/emp_callback() + equipment_channel = CHANNEL_SETTING_AUTO_ON + environment_channel = CHANNEL_SETTING_AUTO_ON + update_icon() + update() + + /obj/machinery/power/apc/blob_act(obj/structure/blob/B) set_broken() @@ -1452,9 +1576,9 @@ if(malfai && operating) malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10,0,1000) stat |= BROKEN - operating = 0 + operating = FALSE if(occupier) - malfvacate(1) + malfvacate(forced = TRUE) update_icon() update() @@ -1509,8 +1633,56 @@ aidisabled = FALSE updateDialog() + +#undef UPSTATE_CELL_IN +#undef UPSTATE_OPENED1 +#undef UPSTATE_OPENED2 +#undef UPSTATE_MAINT +#undef UPSTATE_BROKE +#undef UPSTATE_BLUESCREEN +#undef UPSTATE_WIREEXP +#undef UPSTATE_ALLGOOD + +#undef APC_UPOVERLAY_CHARGEING0 +#undef APC_UPOVERLAY_CHARGEING1 +#undef APC_UPOVERLAY_CHARGEING2 +#undef APC_UPOVERLAY_EQUIPMENT0 +#undef APC_UPOVERLAY_EQUIPMENT1 +#undef APC_UPOVERLAY_EQUIPMENT2 +#undef APC_UPOVERLAY_LIGHTING0 +#undef APC_UPOVERLAY_LIGHTING1 +#undef APC_UPOVERLAY_LIGHTING2 +#undef APC_UPOVERLAY_ENVIRON0 +#undef APC_UPOVERLAY_ENVIRON1 +#undef APC_UPOVERLAY_ENVIRON2 +#undef APC_UPOVERLAY_LOCKED + #undef APC_UPDATE_ICON_COOLDOWN #undef APC_EXTERNAL_POWER_NOTCONNECTED #undef APC_EXTERNAL_POWER_NOENERGY #undef APC_EXTERNAL_POWER_GOOD + +#undef APC_MALF_NOT_HACKED +#undef APC_MALF_HACKED +#undef APC_MALF_SHUNTED_HERE +#undef APC_MALF_SHUNTED_OTHER + +#undef CHANNEL_SETTING_OFF +#undef CHANNEL_SETTING_AUTO_OFF +#undef CHANNEL_SETTING_ON +#undef CHANNEL_SETTING_AUTO_ON + +#undef APC_CLOSED +#undef APC_OPENED +#undef APC_COVER_OFF + +#undef APC_AUTOFLAG_ALL_OFF +#undef APC_AUTOFLAG_ENVIRO_ONLY +#undef APC_AUTOFLAG_EQUIPMENT_OFF +#undef APC_AUTOFLAG_ALL_ON + +#undef APC_ELECTRONICS_NONE +#undef APC_ELECTRONICS_INSTALLED +#undef APC_ELECTRONICS_SECURED + diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index e87e1672965..9c205eadf36 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -26,7 +26,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/structure/cable level = 1 - anchored = 1 + anchored = TRUE on_blueprints = TRUE var/datum/powernet/powernet name = "power cable" @@ -99,7 +99,7 @@ By design, d1 is the smallest direction and d2 is the highest //If underfloor, hide the cable /obj/structure/cable/hide(i) if(level == 1 && isturf(loc)) - invisibility = i ? INVISIBILITY_ABSTRACT : 0 + invisibility = i ? INVISIBILITY_MAXIMUM : 0 update_icon(UPDATE_ICON_STATE) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 43eb5828781..9d21a27c2a7 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -32,7 +32,7 @@ if(ratingdesc) desc += " This one has a power rating of [DisplayPower(maxcharge)], and you should not swallow it." - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/Destroy() STOP_PROCESSING(SSobj, src) @@ -53,16 +53,18 @@ else return PROCESS_KILL -/obj/item/stock_parts/cell/update_icon() - overlays.Cut() + +/obj/item/stock_parts/cell/update_overlays() + . = ..() if(grown_battery) - overlays += image('icons/obj/engines_and_power/power.dmi', "grown_wires") + . += image('icons/obj/engines_and_power/power.dmi', "grown_wires") if(charge < 0.01) return else if(charge/maxcharge >=0.995) - overlays += "cell-o2" + . += "cell-o2" else - overlays += "cell-o1" + . += "cell-o1" + /obj/item/stock_parts/cell/proc/percent() // return % charge of cell return 100 * charge / maxcharge @@ -183,7 +185,7 @@ /obj/item/stock_parts/cell/crap/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/upgraded name = "upgraded power cell" @@ -208,7 +210,7 @@ /obj/item/stock_parts/cell/secborg/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/pulse //265 pulse shots name = "pulse rifle power cell" @@ -249,7 +251,7 @@ /obj/item/stock_parts/cell/high/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/super name = "super-capacity power cell" @@ -263,7 +265,7 @@ /obj/item/stock_parts/cell/super/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/hyper name = "hyper-capacity power cell" @@ -277,7 +279,7 @@ /obj/item/stock_parts/cell/hyper/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/bluespace name = "bluespace power cell" @@ -292,7 +294,7 @@ /obj/item/stock_parts/cell/bluespace/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/infinite name = "infinite-capacity power cell!" @@ -304,7 +306,7 @@ chargerate = 30000 /obj/item/stock_parts/cell/infinite/use() - return 1 + return TRUE /obj/item/stock_parts/cell/infinite/abductor name = "void core" @@ -315,9 +317,9 @@ rating = 12 ratingdesc = FALSE -/obj/item/stock_parts/cell/infinite/abductor/update_icon() - return +/obj/item/stock_parts/cell/infinite/abductor/update_overlays() + return list() /obj/item/stock_parts/cell/potato name = "potato battery" @@ -351,7 +353,7 @@ /obj/item/stock_parts/cell/emproof/empty/New() ..() charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/stock_parts/cell/emproof/emp_act(severity) return diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index d19062c4ea1..27857d53fc3 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -2,7 +2,7 @@ name = "thermoelectric generator" desc = "It's a high efficiency thermoelectric generator." icon_state = "teg" - anchored = 0 + anchored = FALSE density = 1 use_power = NO_POWER_USE @@ -18,9 +18,9 @@ /obj/machinery/power/generator/New() ..() - update_desc() + update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) -/obj/machinery/power/generator/update_desc() +/obj/machinery/power/generator/update_desc(updates = ALL) . = ..() desc = initial(desc) + " Its cold circulator is located on the [dir2text(cold_dir)] side, and its heat circulator is located on the [dir2text(hot_dir)] side." @@ -60,25 +60,27 @@ hot_circ = null power_change() - update_icon() + update_icon(UPDATE_OVERLAYS) updateDialog() -/obj/machinery/power/generator/power_change() + +/obj/machinery/power/generator/power_change(forced = FALSE) if(!anchored) stat |= NOPOWER - else - ..() + return + if(!..()) + return + update_icon(UPDATE_OVERLAYS) -/obj/machinery/power/generator/update_icon() - if(stat & (NOPOWER|BROKEN)) - overlays.Cut() - else - overlays.Cut() - if(lastgenlev != 0) - overlays += image('icons/obj/engines_and_power/power.dmi', "teg-op[lastgenlev]") +/obj/machinery/power/generator/update_overlays() + . = ..() + if(stat & (NOPOWER|BROKEN)) + return + if(lastgenlev != 0) + . += "teg-op[lastgenlev]" + . += "teg-oc[lastcirc]" - overlays += image('icons/obj/engines_and_power/power.dmi', "teg-oc[lastcirc]") /obj/machinery/power/generator/process() if(stat & (NOPOWER|BROKEN)) @@ -141,7 +143,7 @@ if((genlev != lastgenlev) || (circ != lastcirc)) lastgenlev = genlev lastcirc = circ - update_icon() + update_icon(UPDATE_OVERLAYS) updateDialog() @@ -177,7 +179,7 @@ hot_dir = SOUTH connect() to_chat(user, "You reverse the generator's circulator settings. The cold circulator is now on the [dir2text(cold_dir)] side, and the heat circulator is now on the [dir2text(hot_dir)] side.") - update_desc() + update_appearance(UPDATE_DESC) /obj/machinery/power/generator/wrench_act(mob/user, obj/item/I) . = TRUE @@ -246,6 +248,3 @@ connect() return 1 -/obj/machinery/power/generator/power_change() - ..() - update_icon() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 86c2d1fba12..4f4b7fd946e 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne name = "gravitational generator" desc = "A device which produces a gravaton field when set up." icon = 'icons/obj/machines/gravity_generator.dmi' - anchored = 1 + anchored = TRUE density = 1 use_power = NO_POWER_USE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | NO_MALF_EFFECT @@ -41,8 +41,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne if(explosive) qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over -/obj/machinery/gravity_generator/update_icon() - ..() +/obj/machinery/gravity_generator/update_icon_state() icon_state = "[get_status()]_[sprite_number]" /obj/machinery/gravity_generator/proc/get_status() @@ -92,7 +91,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator/main/station/Initialize(mapload) . = ..() setup_parts() - middle.overlays += "activated" + middle.add_overlay("activated") update_list() // @@ -149,7 +148,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne part.sprite_number = count part.main_part = src parts += part - part.update_icon() + part.update_icon(UPDATE_ICON_STATE) /obj/machinery/gravity_generator/main/proc/connected_parts() return parts.len == 8 @@ -159,7 +158,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne for(var/obj/machinery/gravity_generator/M in parts) if(!(M.stat & BROKEN)) M.set_broken() - middle.overlays.Cut() + middle.cut_overlays() charge_count = 0 breaker = 0 set_power() @@ -172,7 +171,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne if(M.stat & BROKEN) M.set_fix() broken_state = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) set_power() // Interaction @@ -181,12 +180,12 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator/main/attackby(obj/item/I as obj, mob/user as mob, params) switch(broken_state) if(GRAV_NEEDS_SCREWDRIVER) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) add_fingerprint(user) to_chat(user, "You secure the screws of the framework.") playsound(src.loc, I.usesound, 50, 1) broken_state++ - update_icon() + update_icon(UPDATE_ICON_STATE) return if(GRAV_NEEDS_PLASTEEL) if(istype(I, /obj/item/stack/sheet/plasteel)) @@ -197,12 +196,12 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne to_chat(user, "You add the plating to the framework.") playsound(src.loc, PS.usesound, 75, 1) broken_state++ - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(user, "You need 10 sheets of plasteel.") return if(GRAV_NEEDS_WRENCH) - if(istype(I, /obj/item/wrench)) + if(I.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) to_chat(user, "You secure the plating to the framework.") playsound(src.loc, I.usesound, 75, 1) @@ -218,7 +217,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne return to_chat(user, "You mend the damaged framework.") broken_state++ - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/gravity_generator/main/attack_hand(mob/user as mob) if(!..()) @@ -267,8 +266,9 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne // Power and Icon States -/obj/machinery/gravity_generator/main/power_change() - ..() +/obj/machinery/gravity_generator/main/power_change(forced = FALSE) + if(!..()) + return investigate_log("has [stat & NOPOWER ? "lost" : "regained"] power.", INVESTIGATE_GRAVITY) set_power() @@ -277,10 +277,10 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne return "fix[min(broken_state, 3)]" return on || charging_state != GRAV_POWER_IDLE ? "on" : "off" -/obj/machinery/gravity_generator/main/update_icon() - ..() - for(var/obj/O in parts) - O.update_icon() +/obj/machinery/gravity_generator/main/update_icon_state() + for(var/obj/part in parts) + part.update_icon(UPDATE_ICON_STATE) + // Set the charging state based on power/breaker. /obj/machinery/gravity_generator/main/proc/set_power() @@ -292,7 +292,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne charging_state = new_state ? GRAV_POWER_UP : GRAV_POWER_DOWN // Startup sequence animation. investigate_log("is now [charging_state == GRAV_POWER_UP ? "charging" : "discharging"].", INVESTIGATE_GRAVITY) - update_icon() + update_icon(UPDATE_ICON_STATE) // Set the state of the gravity. /obj/machinery/gravity_generator/main/proc/set_state(var/new_state) @@ -318,7 +318,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne if(!is_station_level(A.z)) continue A.gravitychange(0,A) - update_icon() + update_icon(UPDATE_ICON_STATE) update_list() src.updateUsrDialog() if(alert) @@ -360,12 +360,11 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne if(81 to 100) overlay_state = "activated" - if(overlay_state != current_overlay) - if(middle) - middle.overlays.Cut() - if(overlay_state) - middle.overlays += overlay_state - current_overlay = overlay_state + if(middle && overlay_state != current_overlay) + middle.cut_overlays() + if(overlay_state) + middle.add_overlay(overlay_state) + current_overlay = overlay_state /obj/machinery/gravity_generator/main/proc/pulse_radiation() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 30665b2802a..7b0fd35309c 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -8,8 +8,9 @@ #define LIGHT_BROKEN 2 #define LIGHT_BURNED 3 -#define MAXIMUM_SAFE_BACKUP_CHARGE 600 -#define EMERGENCY_LIGHT_POWER_USE 0.5 +#define STAGE_EMPTY 1 +#define STAGE_WIRED 2 +#define STAGE_COMPLETED 3 /** * # Light fixture frame @@ -28,7 +29,7 @@ max_integrity = 200 armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) /// Construction stage (1 = Empty frame | 2 = Wired frame | 3 = Completed frame) - var/stage = 1 + var/stage = STAGE_EMPTY /// Light bulb type var/fixture_type = "tube" /// How many metal sheets get given after deconstruction @@ -36,44 +37,48 @@ /// Holder for the completed fixture var/obj/machinery/light/newlight = null + /obj/machinery/light_construct/Initialize(mapload, ndir, building) . = ..() if(fixture_type == "bulb") icon_state = "bulb-construct-stage1" + /obj/machinery/light_construct/examine(mob/user) . = ..() if(get_dist(user, src) <= 2) switch(stage) - if(1) - . += "It's an empty frame." - if(2) - . += "It's wired." - if(3) - . += "The casing is closed." + if(STAGE_EMPTY) + . += "It's an empty frame bolted to the wall. It needs to be wired." + if(STAGE_WIRED) + . += "The frame is wired, but the casing's cover is unscrewed." + if(STAGE_COMPLETED) + . += "The casing is screwed shut." + /obj/machinery/light_construct/wrench_act(mob/living/user, obj/item/I) . = TRUE switch(stage) - if(1) + if(STAGE_EMPTY) to_chat(user, "You begin to dismantle [src].") if(!I.use_tool(src, user, 30, volume = I.tool_volume)) return new /obj/item/stack/sheet/metal(get_turf(loc), sheets_refunded) TOOL_DISMANTLE_SUCCESS_MESSAGE qdel(src) - if(2) + if(STAGE_WIRED) to_chat(user, "You have to remove the wires first.") - if(3) + if(STAGE_COMPLETED) to_chat(user, "You have to unscrew the case first.") + /obj/machinery/light_construct/wirecutter_act(mob/living/user, obj/item/I) - if(stage != 2) + if(stage != STAGE_WIRED) return if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return . = TRUE - stage = 1 + stage = STAGE_EMPTY switch(fixture_type) if("tube") icon_state = "tube-construct-stage1" @@ -82,8 +87,9 @@ new /obj/item/stack/cable_coil(get_turf(loc), 1, TRUE, COLOR_RED) WIRECUTTER_SNIP_MESSAGE + /obj/machinery/light_construct/screwdriver_act(mob/living/user, obj/item/I) - if(stage != 2) + if(stage != STAGE_WIRED) return . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -93,7 +99,7 @@ icon_state = "tube-empty" if("bulb") icon_state = "bulb-empty" - stage = 3 + stage = STAGE_COMPLETED user.visible_message("[user] closes [src]'s casing.", \ "You close [src]'s casing.", "You hear a screwdriver.") @@ -106,10 +112,11 @@ transfer_fingerprints_to(newlight) qdel(src) + /obj/machinery/light_construct/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/stack/cable_coil)) add_fingerprint(user) - if(stage != 1) + if(stage != STAGE_EMPTY) return var/obj/item/stack/cable_coil/coil = W coil.use(1) @@ -118,23 +125,25 @@ icon_state = "tube-construct-stage2" if("bulb") icon_state = "bulb-construct-stage2" - stage = 2 + stage = STAGE_WIRED playsound(loc, coil.usesound, 50, 1) user.visible_message("[user.name] adds wires to [src].", \ "You add wires to [src].", "You hear a noise.") return - return ..() + /obj/machinery/light_construct/blob_act(obj/structure/blob/B) if(B && B.loc == loc) qdel(src) + /obj/machinery/light_construct/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) new /obj/item/stack/sheet/metal(loc, sheets_refunded) qdel(src) + /** * # Small light fixture frame * @@ -162,10 +171,10 @@ /obj/machinery/light name = "light fixture" icon = 'icons/obj/lighting.dmi' - var/base_state = "tube" // Base description and icon_state + base_icon_state = "tube" icon_state = "tube1" desc = "A lighting fixture." - anchored = 1 + anchored = TRUE layer = WALL_OBJ_LAYER max_integrity = 100 use_power = ACTIVE_POWER_USE @@ -175,7 +184,7 @@ /// Is the light on or off? var/on = FALSE /// If the light state has changed since the last 'update()', also update the power requirements - var/power_state = FALSE + var/light_state = FALSE /// How much power does it use? var/static_power_used = 0 /// Light range (Also used in power calculation) @@ -215,9 +224,12 @@ /// The colour of the light while it's in emergency mode var/bulb_emergency_colour = "#FF3232" - var/emergency_mode = FALSE // if true, the light is in emergency mode - var/fire_mode = FALSE // if true, the light swaps over to emergency colour - var/no_emergency = FALSE // if true, this light cannot ever have an emergency mode + /// If true, the light is in emergency mode + var/emergency_mode = FALSE + /// If true, the light swaps over to emergency colour + var/fire_mode = FALSE + /// If true, this light cannot ever have an emergency mode + var/no_emergency = FALSE /** @@ -227,7 +239,7 @@ */ /obj/machinery/light/small icon_state = "bulb1" - base_state = "bulb" + base_icon_state = "bulb" fitting = "bulb" brightness_range = 4 brightness_color = "#a0a080" @@ -272,35 +284,46 @@ brightness_color = "#a0a080" if(prob(5)) break_light_tube(TRUE) - update(FALSE) + update(FALSE, mapload ? FALSE : TRUE) + /obj/machinery/light/Destroy() var/area/A = get_area(src) if(A) on = FALSE -// A.update_lights() LAZYREMOVE(A.lights_cache, src) - return ..() -/obj/machinery/light/update_icon() - switch(status) // set icon_states +/obj/machinery/light/update_icon_state() + switch(status) if(LIGHT_OK) - if(emergency_mode) - icon_state = "[base_state]_emergency" + if(emergency_mode || fire_mode) + icon_state = "[base_icon_state]_emergency" else - icon_state = "[base_state][on]" + icon_state = "[base_icon_state][on]" if(LIGHT_EMPTY) - icon_state = "[base_state]-empty" + icon_state = "[base_icon_state]-empty" on = FALSE if(LIGHT_BURNED) - icon_state = "[base_state]-burned" + icon_state = "[base_icon_state]-burned" on = FALSE if(LIGHT_BROKEN) - icon_state = "[base_state]-broken" + icon_state = "[base_icon_state]-broken" on = FALSE - return + + +/obj/machinery/light/update_overlays() + . = ..() + underlays.Cut() + + if(status != LIGHT_OK || !on) + return + if(nightshift_enabled || emergency_mode || fire_mode) + underlays += emissive_appearance(icon, "[base_icon_state]_emergency_lightmask") + else + underlays += emissive_appearance(icon, "[base_icon_state]_lightmask") + /** * Updates the light's properties @@ -309,19 +332,23 @@ * Also handles rigged light bulbs exploding. * Arguments: * * trigger - Should this update make the light explode/burn out? (Defaults to TRUE) + * * play_sound - Will the lightbulb play a sound when it's turned on. */ -/obj/machinery/light/proc/update(trigger = TRUE) +/obj/machinery/light/proc/update(trigger = TRUE, play_sound = TRUE) var/area/current_area = get_area(src) UnregisterSignal(current_area, COMSIG_AREA_POWER_CHANGE) switch(status) if(LIGHT_BROKEN, LIGHT_BURNED, LIGHT_EMPTY) on = FALSE + emergency_mode = FALSE if(fire_mode) set_emergency_lights() + var/BR = nightshift_enabled ? nightshift_light_range : brightness_range var/PO = nightshift_enabled ? nightshift_light_power : brightness_power if(on) + extinguished = FALSE var/CO = nightshift_enabled ? nightshift_light_color : brightness_color if(color) @@ -330,6 +357,7 @@ BR = brightness_range PO = brightness_power CO = bulb_emergency_colour + var/matching = light && BR == light.light_range && PO == light.light_power && CO == light.light_color if(!matching) switchcount++ @@ -338,6 +366,7 @@ log_admin("LOG: Rigged light explosion, last touched by [fingerprintslast]") message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]") explode() + return // Whichever number is smallest gets set as the prob // Each spook adds a 0.5% to 1% chance of burnout else if(prob(min(40, switchcount / 10))) @@ -347,16 +376,18 @@ else use_power = ACTIVE_POWER_USE set_light(BR, PO, CO) + else if(!turned_off()) set_emergency_lights() else use_power = IDLE_POWER_USE set_light(0) + update_icon() active_power_usage = (BR * PO * 10) - if(on != power_state) // Light was turned on/off, so update the power usage - power_state = on + if(on != light_state) // Light was turned on/off, so update the power usage + light_state = on if(on) static_power_used = active_power_usage * 2 //20W per unit luminosity addStaticPower(static_power_used, STATIC_LIGHT) @@ -368,15 +399,19 @@ static_power_used = active_power_usage * 2 addStaticPower(static_power_used, STATIC_LIGHT) + if(play_sound) + playsound(src, 'sound/machines/light_on.ogg', 60, TRUE) + + /obj/machinery/light/proc/burnout() status = LIGHT_BURNED - icon_state = "[base_state]-burned" visible_message("[src] burns out!") do_sparks(2, 1, src) on = FALSE set_light(0) + update_icon() // attempt to set the light's on/off status // will not switch on if broken/burned/empty @@ -387,19 +422,17 @@ // examine verb /obj/machinery/light/examine(mob/user) . = ..() - . += "" if(in_range(user, src)) switch(status) if(LIGHT_OK) - . += "It is turned [on? "on" : "off"]." + . += "It is turned [on ? "on" : "off"]." if(LIGHT_EMPTY) - . += "The [fitting] has been removed." + . += "The [fitting] has been removed." + . += "The casing can be unscrewed." if(LIGHT_BURNED) - . += "The [fitting] is burnt out." + . += "The [fitting] is burnt out." if(LIGHT_BROKEN) - . += "The [fitting] has been smashed." - . += "" - + . += "The [fitting] has been smashed." // attack with item - insert light (if right type), otherwise try to break the light @@ -418,9 +451,9 @@ if(status != LIGHT_EMPTY) to_chat(user, "There is a [fitting] already inserted.") else + add_fingerprint(user) var/obj/item/light/L = W if(istype(L, light_type)) - add_fingerprint(user) status = L.status to_chat(user, "You insert [L].") switchcount = L.switchcount @@ -469,13 +502,6 @@ // attempt to stick weapon into light socket if(status == LIGHT_EMPTY) - if(istype(W, /obj/item/screwdriver)) //If it's a screwdriver open it. - playsound(loc, W.usesound, W.tool_volume, 1) - user.visible_message("[user] opens [src]'s casing.", \ - "You open [src]'s casing.", "You hear a screwdriver.") - deconstruct() - return - if(has_power() && (W.flags & CONDUCT)) add_fingerprint(user) do_sparks(3, 1, src) @@ -488,6 +514,18 @@ return ..() + +/obj/machinery/light/screwdriver_act(mob/living/user, obj/item/I) + if(status != LIGHT_EMPTY) + return TRUE + + I.play_tool_sound(src) + user.visible_message("[user] opens [src]'s casing.", \ + "You open [src]'s casing.", "You hear a screwdriver.") + deconstruct() + return TRUE + + /obj/machinery/light/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) var/obj/machinery/light_construct/newlight = null @@ -564,16 +602,20 @@ return if(fire_mode) set_light(nightshift_light_range, nightshift_light_power, bulb_emergency_colour) + update_icon() return emergency_mode = TRUE set_light(3, 1.7, bulb_emergency_colour) + update_icon() RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(update), override = TRUE) + /obj/machinery/light/proc/emergency_lights_off(area/current_area, obj/machinery/power/apc/current_apc) set_light(0, 0, 0) //you, sir, are off! if(current_apc) RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(update), override = TRUE) + /obj/machinery/light/flicker(amount = rand(20, 30)) if(flickering) return FALSE @@ -590,19 +632,19 @@ * Flicker routine for the light. * Called by invoke_async so the parent proc can return immediately. */ -/obj/machinery/light/proc/flicker_event(var/amount) +/obj/machinery/light/proc/flicker_event(amount) if(on && status == LIGHT_OK) for(var/i = 0; i < amount; i++) if(status != LIGHT_OK || extinguished) break on = FALSE - update(FALSE) + update(FALSE, FALSE) sleep(rand(1, 3)) on = (status == LIGHT_OK) - update(FALSE) + update(FALSE, FALSE) sleep(rand(1, 10)) on = (status == LIGHT_OK && !extinguished) - update(FALSE) + update(FALSE, FALSE) flickering = FALSE @@ -660,6 +702,9 @@ // break the light and make sparks if was on /obj/machinery/light/proc/drop_light_tube(mob/user) + if(status == LIGHT_EMPTY) + return + var/obj/item/light/L = new light_type() L.status = status L.rigged = rigged @@ -672,7 +717,7 @@ L.switchcount = switchcount switchcount = 0 - L.update() + L.update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) L.forceMove(loc) if(user) //puts it in our active hand @@ -680,9 +725,10 @@ user.put_in_active_hand(L, ignore_anim = FALSE) status = LIGHT_EMPTY - update(FALSE) + update(FALSE, FALSE) return L + /obj/machinery/light/attack_tk(mob/user) if(status == LIGHT_EMPTY) to_chat(user, "There is no [fitting] in this light.") @@ -722,7 +768,7 @@ // use power // called when area power state changes -/obj/machinery/light/power_change() +/obj/machinery/light/power_change(forced = FALSE) var/area/A = get_area(src) if(A) seton(A.lightswitch && A.power_light) @@ -756,9 +802,9 @@ force = 2 throwforce = 5 w_class = WEIGHT_CLASS_TINY + blocks_emissive = FALSE /// Light status (LIGHT_OK | LIGHT_BURNED | LIGHT_BROKEN) var/status = LIGHT_OK - var/base_state /// How many times has the light been switched on/off? var/switchcount = 0 /// Materials the light is made of @@ -800,7 +846,7 @@ name = "light tube" desc = "A replacement light tube." icon_state = "ltube" - base_state = "ltube" + base_icon_state = "ltube" item_state = "c_tube" brightness_range = 8 @@ -819,7 +865,7 @@ name = "light bulb" desc = "A replacement light bulb." icon_state = "lbulb" - base_state = "lbulb" + base_icon_state = "lbulb" item_state = "contvapour" brightness_range = 5 brightness_color = "#a0a080" @@ -832,24 +878,10 @@ name = "fire bulb" desc = "A replacement fire bulb." icon_state = "flight" - base_state = "flight" + base_icon_state = "flight" item_state = "egg4" brightness_range = 5 -// update the icon state and description of the light - -/obj/item/light/proc/update() - switch(status) - if(LIGHT_OK) - icon_state = base_state - desc = "A replacement [name]." - if(LIGHT_BURNED) - icon_state = "[base_state]-burned" - desc = "A burnt-out [name]." - if(LIGHT_BROKEN) - icon_state = "[base_state]-broken" - desc = "A broken [name]." - /obj/item/light/New() ..() @@ -858,7 +890,28 @@ brightness_range = rand(6,9) if("light bulb") brightness_range = rand(4,6) - update() + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + + +/obj/item/light/update_icon_state() + switch(status) + if(LIGHT_OK) + icon_state = base_icon_state + if(LIGHT_BURNED) + icon_state = "[base_icon_state]-burned" + if(LIGHT_BROKEN) + icon_state = "[base_icon_state]-broken" + + +/obj/item/light/update_desc(updates = ALL) + . = ..() + switch(status) + if(LIGHT_OK) + desc = "A replacement [name]." + if(LIGHT_BURNED) + desc = "A burnt-out [name]." + if(LIGHT_BROKEN) + desc = "A broken [name]." // attack bulb/tube with object @@ -899,7 +952,8 @@ force = 5 sharp = TRUE playsound(loc, 'sound/effects/glasshit.ogg', 75, 1) - update() + update_appearance(UPDATE_ICON_STATE|UPDATE_DESC) + /obj/item/light/suicide_act(mob/living/carbon/human/user) user.visible_message("[user] touches [src], burning [user.p_their()] hands off!", "You touch [src], burning your hands off!") @@ -910,23 +964,30 @@ limb.droplimb(0, DROPLIMB_BURN) return FIRELOSS + /obj/machinery/light/extinguish_light(force = FALSE) - if(on) - on = FALSE - extinguished = TRUE - emergency_mode = FALSE - no_emergency = TRUE - addtimer(CALLBACK(src, PROC_REF(enable_emergency_lighting)), 5 MINUTES, TIMER_UNIQUE|TIMER_OVERRIDE) + var/was_on = on + on = FALSE + extinguished = TRUE + emergency_mode = FALSE + no_emergency = TRUE + update(FALSE, was_on) + addtimer(CALLBACK(src, PROC_REF(enable_emergency_lighting)), 5 MINUTES, TIMER_UNIQUE|TIMER_OVERRIDE) + if(was_on) visible_message(span_danger("[src] flickers and falls dark.")) - update(FALSE) + /obj/machinery/light/proc/enable_emergency_lighting() - visible_message("[src]'s emergency lighting flickers back to life.") + visible_message(span_notice("[src]'s emergency lighting flickers back to life.")) + extinguished = FALSE no_emergency = FALSE update(FALSE) -#undef MAXIMUM_SAFE_BACKUP_CHARGE -#undef EMERGENCY_LIGHT_POWER_USE + #undef LIGHT_OK #undef LIGHT_EMPTY #undef LIGHT_BROKEN +#undef STAGE_EMPTY +#undef STAGE_WIRED +#undef STAGE_COMPLETED + diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 5561a31e8a3..dd637ec2470 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/engines_and_power/power.dmi' icon_state = "portgen0_0" density = 1 - anchored = 0 + anchored = FALSE use_power = NO_POWER_USE var/active = 0 @@ -32,7 +32,7 @@ /obj/machinery/power/port_gen/proc/handleInactive() return -/obj/machinery/power/port_gen/update_icon() +/obj/machinery/power/port_gen/update_icon_state() icon_state = "[base_icon]_[active]" /obj/machinery/power/port_gen/process() @@ -42,10 +42,10 @@ else active = 0 handleInactive() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/powered() - return 1 //doesn't require an external power source + return TRUE //doesn't require an external power source /obj/machinery/power/port_gen/attack_hand(mob/user as mob) if(..()) @@ -287,7 +287,7 @@ SStgui.update_uis(src) return else if(!active) - if(istype(O, /obj/item/wrench)) + if(O.tool_behaviour == TOOL_WRENCH) if(!anchored) connect_to_network() @@ -299,7 +299,7 @@ playsound(src.loc, O.usesound, 50, 1) anchored = !anchored - else if(istype(O, /obj/item/screwdriver)) + else if(O.tool_behaviour == TOOL_SCREWDRIVER) panel_open = !panel_open playsound(src.loc, O.usesound, 50, 1) if(panel_open) @@ -309,7 +309,7 @@ else if(istype(O, /obj/item/storage/part_replacer) && panel_open) exchange_parts(user, O) return - else if(istype(O, /obj/item/crowbar) && panel_open) + else if(O.tool_behaviour == TOOL_CROWBAR && panel_open) default_deconstruction_crowbar(user, O) add_fingerprint(user) else @@ -373,7 +373,7 @@ if(!powernet) //only a warning, process will disable atom_say("Не подключен к электросет+и.") active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) if("eject_fuel") DropFuel() if("change_power") diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 1ded07a2a83..71b16780406 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -5,7 +5,7 @@ GLOBAL_LIST_EMPTY(rad_collectors) desc = "A device which uses Hawking Radiation and plasma to produce power." icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "ca" - anchored = 0 + anchored = FALSE density = 1 req_access = list(ACCESS_ENGINE_EQUIP) // use_power = NO_POWER_USE @@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(rad_collectors) /obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/multitool)) + if(W.tool_behaviour == TOOL_MULTITOOL) add_fingerprint(user) to_chat(user, "The [W.name] detects that [last_power]W were recently produced.") return 1 @@ -68,13 +68,13 @@ GLOBAL_LIST_EMPTY(rad_collectors) add_fingerprint(user) user.drop_transfer_item_to_loc(W, src) src.P = W - update_icons() - else if(istype(W, /obj/item/crowbar)) + update_icon() + else if(W.tool_behaviour == TOOL_CROWBAR) if(P && !src.locked) add_fingerprint(user) eject() return 1 - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) if(P) to_chat(user, "Remove the plasma tank first.") return 1 @@ -125,7 +125,7 @@ GLOBAL_LIST_EMPTY(rad_collectors) if(active) toggle_power() else - update_icons() + update_icon() /obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength) if(P && active) @@ -134,26 +134,27 @@ GLOBAL_LIST_EMPTY(rad_collectors) add_avail(power_produced) last_power = power_produced return - return -/obj/machinery/power/rad_collector/proc/update_icons() - overlays.Cut() +/obj/machinery/power/rad_collector/update_icon_state() + icon_state = "ca[active ? "_on" : ""]" + + +/obj/machinery/power/rad_collector/update_overlays() + . = ..() if(P) - overlays += image('icons/obj/engines_and_power/singularity.dmi', "ptank") + . += "ptank" if(stat & (NOPOWER|BROKEN)) return if(active) - overlays += image('icons/obj/engines_and_power/singularity.dmi', "on") + . += "on" /obj/machinery/power/rad_collector/proc/toggle_power() active = !active if(active) - icon_state = "ca_on" flick("ca_active", src) else - icon_state = "ca" flick("ca_deactive", src) - update_icons() - return + update_icon() + diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index 7dc2e78965e..f9e72b49db4 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -3,7 +3,7 @@ desc = "An energy field." icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "Contain_F" - anchored = 1 + anchored = TRUE density = 0 move_resist = INFINITY resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 1814106229b..c15d84d47bb 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -3,7 +3,7 @@ desc = "A heavy duty industrial laser" icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "emitter" - anchored = 0 + anchored = FALSE density = 1 req_access = list(ACCESS_ENGINE_EQUIP) @@ -81,7 +81,8 @@ QDEL_NULL(sparks) return ..() -/obj/machinery/power/emitter/update_icon() + +/obj/machinery/power/emitter/update_icon_state() if(active && powernet && avail(active_power_usage)) icon_state = "emitter_+a" else @@ -110,7 +111,7 @@ message_admins("Emitter turned on by [key_name_admin(user)] in [ADMIN_COORDJMP(src)]") add_game_logs("turned on emitter in [COORD(src)]", user) investigate_log("turned on by [key_name_log(usr)]", INVESTIGATE_ENGINE) - update_icon() + update_icon(UPDATE_ICON_STATE) else to_chat(user, "The controls are locked!") else @@ -141,19 +142,19 @@ return if(src.state != 2 || (!powernet && active_power_usage)) src.active = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) return if(active == TRUE) if(!active_power_usage || surplus() >= active_power_usage) add_load(active_power_usage) if(!powered) powered = 1 - update_icon() + update_icon(UPDATE_ICON_STATE) investigate_log("regained power and turned on", INVESTIGATE_ENGINE) else if(powered) powered = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) investigate_log("lost power and turned off", INVESTIGATE_ENGINE) return @@ -261,14 +262,14 @@ user.visible_message("[user.name] secures [name] to the floor.", \ "You secure the external reinforcing bolts to the floor.", \ "You hear a ratchet") - src.anchored = 1 + src.anchored = TRUE if(1) state = 0 playsound(loc, I.usesound, 75, 1) user.visible_message("[user.name] unsecures [name] reinforcing bolts from the floor.", \ "You undo the external reinforcing bolts.", \ "You hear a ratchet") - src.anchored = 0 + src.anchored = FALSE if(2) to_chat(user, "The [name] needs to be unwelded from the floor.") diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index ad5aa584818..9957329286f 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -24,7 +24,7 @@ field_generator power level display desc = "A large thermal battery that projects a high amount of energy when powered." icon = 'icons/obj/machines/field_generator.dmi' icon_state = "Field_Gen" - anchored = 0 + anchored = FALSE density = 1 use_power = NO_POWER_USE max_integrity = 500 @@ -40,14 +40,15 @@ field_generator power level display var/list/obj/machinery/field/generator/connected_gens var/clean_up = 0 -/obj/machinery/field/generator/update_icon() - overlays.Cut() + +/obj/machinery/field/generator/update_overlays() + . = ..() if(warming_up) - overlays += "+a[warming_up]" - if(fields.len) - overlays += "+on" + . += "+a[warming_up]" + if(length(fields)) + . += "+on" if(power_level) - overlays += "+p[power_level]" + . += "+p[power_level]" /obj/machinery/field/generator/Initialize(mapload) @@ -83,7 +84,7 @@ field_generator power level display add_fingerprint(user) to_chat(user, "[src] needs to be off!") return - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) switch(state) if(FG_UNSECURED) if(isinspace()) @@ -94,7 +95,7 @@ field_generator power level display user.visible_message("[user.name] secures [name] to the floor.", \ "You secure the external reinforcing bolts to the floor.", \ "You hear ratchet.") - anchored = 1 + anchored = TRUE if(FG_SECURED) add_fingerprint(user) state = FG_UNSECURED @@ -102,7 +103,7 @@ field_generator power level display user.visible_message("[user.name] unsecures [name] reinforcing bolts from the floor.", \ "You undo the external reinforcing bolts.", \ "You hear ratchet.") - anchored = 0 + anchored = FALSE if(FG_WELDED) to_chat(user, "The [name] needs to be unwelded from the floor!") else @@ -163,7 +164,7 @@ field_generator power level display var/new_level = round(num_power_levels * power / field_generator_max_power) if(new_level != power_level) power_level = new_level - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/field/generator/proc/turn_off() active = FG_OFFLINE @@ -172,7 +173,7 @@ field_generator power level display while(warming_up > 0 && !active) sleep(50) warming_up-- - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/field/generator/proc/turn_on() active = FG_CHARGING @@ -180,7 +181,7 @@ field_generator power level display while(warming_up < 3 && active) sleep(50) warming_up++ - update_icon() + update_icon(UPDATE_OVERLAYS) if(warming_up >= 3) start_fields() @@ -294,7 +295,7 @@ field_generator power level display connected_gens |= G G.connected_gens |= src - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/field/generator/proc/cleanup() @@ -309,7 +310,7 @@ field_generator power level display FG.cleanup() connected_gens -= FG clean_up = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) //This is here to help fight the "hurr durr, release singulo cos nobody will notice before the //singulo eats the evidence". It's not fool-proof but better than nothing. diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index f2fbe3b450b..3d2fed7cc41 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -4,7 +4,7 @@ desc = "An odd device which produces a Gravitational Singularity when set up." icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "TheSingGen" - anchored = 0 + anchored = FALSE density = 1 use_power = NO_POWER_USE resistance_flags = FIRE_PROOF @@ -22,7 +22,7 @@ if(src) qdel(src) /obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) + if(W.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) anchored = !anchored playsound(src.loc, W.usesound, 75, 1) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 92a64ad27bb..d22b389a675 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -15,6 +15,11 @@ /obj/singularity/narsie/admin_investigate_setup() return + +/obj/singularity/narsie/update_icon_state() + return + + /obj/singularity/narsie/large name = "Nar'Sie" icon = 'icons/obj/narsie.dmi' diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index ea07468fe5d..78921d257a6 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -64,7 +64,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin desc = "Part of a Particle Accelerator." icon = 'icons/obj/engines_and_power/particle_accelerator.dmi' icon_state = "none" - anchored = 0 + anchored = FALSE density = 1 max_integrity = 500 armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80) @@ -87,59 +87,41 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin icon_state = "end_cap" reference = "end_cap" -/obj/structure/particle_accelerator/update_icon() - ..() - return - /obj/structure/particle_accelerator/verb/rotate() set name = "Rotate Clockwise" set category = "Object" set src in oview(1) - if(usr.stat || !usr.canmove || usr.restrained()) - return - if(anchored) - to_chat(usr, "It is fastened to the floor!") - return 0 - add_fingerprint(usr) - dir = turn(dir, 270) - return 1 + rotate_accelerator(usr) /obj/structure/particle_accelerator/AltClick(mob/user) - if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!Adjacent(user)) - return - rotate() + rotate_accelerator(user) -/obj/structure/particle_accelerator/verb/rotateccw() - set name = "Rotate Counter Clockwise" - set category = "Object" - set src in oview(1) - - if(usr.stat || !usr.canmove || usr.restrained()) +/obj/structure/particle_accelerator/proc/rotate_accelerator(mob/user) + if(user.incapacitated() || user.restrained() || !Adjacent(user)) return if(anchored) - to_chat(usr, "It is fastened to the floor!") - return 0 - dir = turn(dir, 90) - return 1 + to_chat(user, "It is fastened to the floor!") + return + dir = turn(dir, 270) + /obj/structure/particle_accelerator/examine(mob/user) + . = ..() switch(construction_state) - if(0) - desc = text("A [name], looks like it's not attached to the flooring") - if(1) - desc = text("A [name], it is missing some cables") - if(2) - desc = text("A [name], the panel is open") - if(3) - desc = text("The [name] is assembled") + if(ACCELERATOR_UNWRENCHED) + . += "\The [name]'s anchoring bolts are loose." + if(ACCELERATOR_WRENCHED) + . += "\The [name]'s anchoring bolts are wrenched in place, but it lacks wiring." + if(ACCELERATOR_WIRED) + . += "\The [name] is wired, but the maintenance panel is unscrewed and open." + if(ACCELERATOR_READY) + . += "\The [name] is assembled and the maintenence panel is screwed shut." if(powered) desc = desc_holder - . = ..() + if(!anchored) + . += "Alt-Click to rotate it." /obj/structure/particle_accelerator/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) @@ -156,18 +138,18 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin if(prob(50)) qdel(src) -/obj/structure/particle_accelerator/update_icon() +/obj/structure/particle_accelerator/update_icon_state() switch(construction_state) - if(0,1) + if(ACCELERATOR_UNWRENCHED, ACCELERATOR_WRENCHED) icon_state="[reference]" - if(2) + if(ACCELERATOR_WIRED) icon_state="[reference]w" - if(3) + if(ACCELERATOR_READY) if(powered) icon_state="[reference]p[strength]" else icon_state="[reference]c" - return + /obj/structure/particle_accelerator/proc/update_state() if(master) @@ -206,7 +188,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin user.visible_message("[user.name] adds wires to the [name].", \ "You add some wires.") construction_state = ACCELERATOR_WIRED - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/particle_accelerator/screwdriver_act(mob/user, obj/item/I) if(construction_state != ACCELERATOR_WIRED && construction_state != ACCELERATOR_READY) @@ -222,7 +204,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin construction_state = ACCELERATOR_WIRED SCREWDRIVER_OPEN_PANEL_MESSAGE update_state() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/structure/particle_accelerator/wirecutter_act(mob/user, obj/item/I) if(construction_state != ACCELERATOR_WIRED) @@ -247,7 +229,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin anchored = FALSE WRENCH_UNANCHOR_MESSAGE construction_state = ACCELERATOR_UNWRENCHED - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/particle_accelerator @@ -255,7 +237,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin desc = "Part of a Particle Accelerator." icon = 'icons/obj/engines_and_power/particle_accelerator.dmi' icon_state = "none" - anchored = 0 + anchored = FALSE density = 1 use_power = NO_POWER_USE idle_power_usage = 0 @@ -268,35 +250,30 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin var/desc_holder = null +/obj/machinery/particle_accelerator/examine(mob/user) + . = ..() + . += "Alt-Click to rotate it." + + /obj/machinery/particle_accelerator/verb/rotate() set name = "Rotate Clockwise" set category = "Object" set src in oview(1) - if(usr.stat || !usr.canmove || usr.restrained()) - return - if(anchored) - to_chat(usr, "It is fastened to the floor!") - return 0 - add_fingerprint(usr) - dir = turn(dir, 270) - return 1 + rotate_accelerator(usr) + +/obj/machinery/particle_accelerator/AltClick(mob/user) + rotate_accelerator(user) -/obj/machinery/particle_accelerator/verb/rotateccw() - set name = "Rotate Counter-Clockwise" - set category = "Object" - set src in oview(1) - if(usr.stat || !usr.canmove || usr.restrained()) +/obj/machinery/particle_accelerator/proc/rotate_accelerator(mob/user) + if(user.incapacitated() || user.restrained() || !Adjacent(user)) return if(anchored) - to_chat(usr, "It is fastened to the floor!") - return 0 - dir = turn(dir, 90) - return 1 + to_chat(user, "It is fastened to the floor!") + return + dir = turn(dir, 270) -/obj/machinery/particle_accelerator/update_icon() - return /obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user, params) if(!iscoil(W)) @@ -355,7 +332,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin /obj/machinery/particle_accelerator/proc/update_state() - return 0 + return FALSE #undef ACCELERATOR_UNWRENCHED diff --git a/code/modules/power/singularity/particle_accelerator/particle_chamber.dm b/code/modules/power/singularity/particle_accelerator/particle_chamber.dm index 198d679e8ef..d85a853649b 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_chamber.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_chamber.dm @@ -5,6 +5,3 @@ icon_state = "fuel_chamber" reference = "fuel_chamber" -/obj/structure/particle_accelerator/fuel_chamber/update_icon() - ..() - return diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 8caccfba7cc..d6859112459 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/engines_and_power/particle_accelerator.dmi' icon_state = "control_box" reference = "control_box" - anchored = 0 + anchored = FALSE density = 1 use_power = NO_POWER_USE idle_power_usage = 500 @@ -23,7 +23,7 @@ . = ..() wires = new(src) connected_parts = list() - update_icon() + update_icon(UPDATE_ICON_STATE) use_log = list() /obj/machinery/particle_accelerator/control_box/Destroy() @@ -59,7 +59,7 @@ for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = null part.powered = 0 - part.update_icon() + part.update_icon(UPDATE_ICON_STATE) connected_parts = list() return if(!part_scan()) @@ -67,9 +67,8 @@ active = 0 connected_parts = list() - return -/obj/machinery/particle_accelerator/control_box/update_icon() +/obj/machinery/particle_accelerator/control_box/update_icon_state() if(active) icon_state = "[reference]p[strength]" else @@ -88,7 +87,7 @@ icon_state = "[reference]w" else icon_state = "[reference]c" - return + /obj/machinery/particle_accelerator/control_box/Topic(href, href_list) if(..(href, href_list)) @@ -118,14 +117,14 @@ remove_strength() updateDialog() - update_icon() + update_icon(UPDATE_ICON_STATE) return /obj/machinery/particle_accelerator/control_box/proc/strength_change() for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = strength - part.update_icon() + part.update_icon(UPDATE_ICON_STATE) /obj/machinery/particle_accelerator/control_box/proc/add_strength(var/s) if(assembled) @@ -154,21 +153,20 @@ strength_change() -/obj/machinery/particle_accelerator/control_box/power_change() +/obj/machinery/particle_accelerator/control_box/power_change(forced = FALSE) ..() if(stat & NOPOWER) active = 0 use_power = NO_POWER_USE else if(!stat && construction_state <= 3) use_power = IDLE_POWER_USE - update_icon() + update_icon(UPDATE_ICON_STATE) if((stat & NOPOWER) || (!stat && construction_state <= 3)) //Only update the part icons if something's changed (i.e. any of the above condition sets are met). for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = null part.powered = 0 - part.update_icon() - return + part.update_icon(UPDATE_ICON_STATE) /obj/machinery/particle_accelerator/control_box/process() @@ -182,7 +180,6 @@ for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts) if(PE) PE.emit_particle(strength) - return /obj/machinery/particle_accelerator/control_box/proc/part_scan() @@ -246,13 +243,13 @@ for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = strength part.powered = 1 - part.update_icon() + part.update_icon(UPDATE_ICON_STATE) else use_power = IDLE_POWER_USE for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = null part.powered = 0 - part.update_icon() + part.update_icon(UPDATE_ICON_STATE) return 1 diff --git a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm index d3037fbd32f..b88e1330df0 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm @@ -18,9 +18,6 @@ icon_state = "emitter_right" reference = "emitter_right" -/obj/structure/particle_accelerator/particle_emitter/update_icon() - ..() - return /obj/structure/particle_accelerator/particle_emitter/proc/set_delay(var/delay) if(delay && delay >= 0) diff --git a/code/modules/power/singularity/ratvar.dm b/code/modules/power/singularity/ratvar.dm index df1e4335670..7f774d30c68 100644 --- a/code/modules/power/singularity/ratvar.dm +++ b/code/modules/power/singularity/ratvar.dm @@ -36,6 +36,11 @@ addtimer(CALLBACK(src, PROC_REF(call_shuttle)), 7 SECONDS) + +/obj/singularity/ratvar/update_icon_state() + return + + /obj/singularity/ratvar/proc/call_shuttle() SSshuttle.emergency.request(null, 0.3) SSshuttle.emergency.canRecall = FALSE // Cannot recall diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index d6ad8990499..eda433bab5c 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -3,7 +3,7 @@ desc = "A gravitational singularity." icon = 'icons/obj/engines_and_power/singularity.dmi' icon_state = "singularity_s1" - anchored = 1 + anchored = TRUE density = 1 layer = MASSIVE_OBJ_LAYER light_range = 6 @@ -147,6 +147,28 @@ dissipate_track++ +/obj/singularity/update_icon_state() + switch(current_size) + if(STAGE_ONE) + icon = 'icons/obj/engines_and_power/singularity.dmi' + icon_state = "singularity_s1" + if(STAGE_TWO) + icon = 'icons/effects/96x96.dmi' + icon_state = "singularity_s3" + if(STAGE_THREE) + icon = 'icons/effects/160x160.dmi' + icon_state = "singularity_s5" + if(STAGE_FOUR) + icon = 'icons/effects/224x224.dmi' + icon_state = "singularity_s7" + if(STAGE_FIVE) + icon = 'icons/effects/288x288.dmi' + icon_state = "singularity_s9" + if(STAGE_SIX) + icon = 'icons/effects/352x352.dmi' + icon_state = "singularity_s11" + + /obj/singularity/proc/expand(force_size = 0) var/temp_allowed_size = src.allowed_size if(force_size) @@ -156,8 +178,6 @@ switch(temp_allowed_size) if(STAGE_ONE) current_size = STAGE_ONE - icon = 'icons/obj/engines_and_power/singularity.dmi' - icon_state = "singularity_s1" pixel_x = 0 pixel_y = 0 grav_pull = 4 @@ -168,8 +188,6 @@ if(STAGE_TWO) if((check_turfs_in(1,1))&&(check_turfs_in(2,1))&&(check_turfs_in(4,1))&&(check_turfs_in(8,1))) current_size = STAGE_TWO - icon = 'icons/effects/96x96.dmi' - icon_state = "singularity_s3" pixel_x = -32 pixel_y = -32 grav_pull = 6 @@ -180,8 +198,6 @@ if(STAGE_THREE) if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2))) current_size = STAGE_THREE - icon = 'icons/effects/160x160.dmi' - icon_state = "singularity_s5" pixel_x = -64 pixel_y = -64 grav_pull = 8 @@ -192,8 +208,6 @@ if(STAGE_FOUR) if((check_turfs_in(1,3))&&(check_turfs_in(2,3))&&(check_turfs_in(4,3))&&(check_turfs_in(8,3))) current_size = STAGE_FOUR - icon = 'icons/effects/224x224.dmi' - icon_state = "singularity_s7" pixel_x = -96 pixel_y = -96 grav_pull = 10 @@ -203,8 +217,6 @@ dissipate_strength = 10 if(STAGE_FIVE)//this one also lacks a check for gens because it eats everything current_size = STAGE_FIVE - icon = 'icons/effects/288x288.dmi' - icon_state = "singularity_s9" pixel_x = -128 pixel_y = -128 grav_pull = 10 @@ -212,13 +224,12 @@ dissipate = 0 //It cant go smaller due to e loss if(STAGE_SIX) //This only happens if a stage 5 singulo consumes a supermatter shard. current_size = STAGE_SIX - icon = 'icons/effects/352x352.dmi' - icon_state = "singularity_s11" pixel_x = -160 pixel_y = -160 grav_pull = 15 consume_range = 5 dissipate = 0 + update_icon(UPDATE_ICON_STATE) if(current_size == allowed_size) investigate_log("grew to size [current_size]", INVESTIGATE_ENGINE) return 1 diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index da3f01f882d..9b4c9c45f85 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -57,7 +57,7 @@ stat |= BROKEN return terminal.master = src - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/smes/upgraded/Initialize(mapload) . = ..() @@ -87,30 +87,29 @@ C += PC.maxcharge capacity = C / (15000) * 1e6 -/obj/machinery/power/smes/update_icon() - overlays.Cut() - if(stat & BROKEN) return - overlays += image('icons/obj/engines_and_power/power.dmi', "smes-op[outputting]") +/obj/machinery/power/smes/update_overlays() + . = ..() + if((stat & BROKEN) || panel_open) + return - if(inputting == 2) - overlays += image('icons/obj/engines_and_power/power.dmi', "smes-oc2") - else if(inputting == 1) - overlays += image('icons/obj/engines_and_power/power.dmi', "smes-oc1") - else - if(input_attempt) - overlays += image('icons/obj/engines_and_power/power.dmi', "smes-oc0") + . += "smes-op[outputting]" + + if(inputting) + . += "smes-oc[inputting]" + else if(input_attempt) + . += "smes-oc0" var/clevel = chargedisplay() - if(clevel>0) - overlays += image('icons/obj/engines_and_power/power.dmi', "smes-og[clevel]") - return + if(clevel > 0) + . += "smes-og[clevel]" + /obj/machinery/power/smes/attackby(obj/item/I, mob/user, params) //opening using screwdriver if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) add_fingerprint(user) - update_icon() + update_icon(UPDATE_OVERLAYS) return //changing direction using wrench @@ -128,7 +127,7 @@ to_chat(user, "No power source found.") return stat &= ~BROKEN - update_icon() + update_icon(UPDATE_OVERLAYS) return //exchanging parts using the RPE @@ -202,7 +201,7 @@ return //disassembling the terminal - if(istype(I, /obj/item/wirecutters) && terminal && panel_open) + if(I.tool_behaviour == TOOL_WIRECUTTER && terminal && panel_open) var/turf/T = get_turf(terminal) if(T.intact) //is the floor plating removed ? to_chat(user, "You must first expose the power terminal!") @@ -312,7 +311,7 @@ // only update icon if state changed if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting) - update_icon() + update_icon(UPDATE_OVERLAYS) @@ -342,7 +341,7 @@ output_used -= excess if(clev != chargedisplay() ) //if needed updates the icons overlay - update_icon() + update_icon(UPDATE_OVERLAYS) return /obj/machinery/power/smes/attack_ai(mob/user) @@ -394,10 +393,10 @@ switch(action) if("tryinput") inputting(!input_attempt) - update_icon() + update_icon(UPDATE_OVERLAYS) if("tryoutput") outputting(!output_attempt) - update_icon() + update_icon(UPDATE_OVERLAYS) if("input") var/target = params["target"] var/adjust = text2num(params["adjust"]) @@ -480,7 +479,7 @@ charge -= 1e6/severity if(charge < 0) charge = 0 - update_icon() + update_icon(UPDATE_OVERLAYS) log_smes() ..() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 392e81ed9d7..3c8424ab929 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -46,12 +46,12 @@ if(!S) S = new /obj/item/solar_assembly(src) S.glass_type = /obj/item/stack/sheet/glass - S.anchored = 1 + S.anchored = TRUE S.loc = src if(S.glass_type == /obj/item/stack/sheet/rglass) //if the panel is in reinforced glass max_integrity *= 2 //this need to be placed here, because panels already on the map don't have an assembly linked to obj_integrity = max_integrity - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar/crowbar_act(mob/user, obj/item/I) @@ -79,7 +79,7 @@ playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE) stat |= BROKEN unset_control() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) @@ -94,15 +94,13 @@ new /obj/item/shard(src.loc) qdel(src) -/obj/machinery/power/solar/update_icon() - ..() - overlays.Cut() +/obj/machinery/power/solar/update_overlays() + . = ..() if(stat & BROKEN) - overlays += image('icons/obj/engines_and_power/power.dmi', icon_state = "solar_panel-b", layer = FLY_LAYER) + . += image('icons/obj/engines_and_power/power.dmi', icon_state = "solar_panel-b", layer = FLY_LAYER) else - overlays += image('icons/obj/engines_and_power/power.dmi', icon_state = "solar_panel", layer = FLY_LAYER) - src.dir = angle2dir(adir) - return + . += image('icons/obj/engines_and_power/power.dmi', icon_state = "solar_panel", layer = FLY_LAYER) + dir = angle2dir(adir) //calculates the fraction of the sunlight that the panel recieves /obj/machinery/power/solar/proc/update_solar_exposure() @@ -140,7 +138,7 @@ . = (!(stat & BROKEN)) stat |= BROKEN unset_control() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar/fake/New(var/turf/loc, var/obj/item/solar_assembly/S) ..(loc, S, 0) @@ -186,7 +184,7 @@ icon_state = "sp_base" item_state = "electropack" w_class = WEIGHT_CLASS_BULKY // Pretty big! - anchored = 0 + anchored = FALSE var/tracker = 0 var/glass_type = null @@ -201,28 +199,37 @@ glass_type = null -/obj/item/solar_assembly/attackby(var/obj/item/W, var/mob/user, params) +/obj/item/solar_assembly/examine(mob/user) + . = ..() + . += "The solar assembly is [anchored ? "wrenched into place" : "unwrenched"]." + if(tracker) + . += "The solar assembly has a tracking circuit installed. It can be pried out." + else + . += "The solar assembly has a slot for a tracking circuit board." + if(anchored) + .+= "The solar assembly needs glass to be completed." + + +/obj/item/solar_assembly/attackby(obj/item/W, mob/user, params) if(!anchored && isturf(loc)) - if(istype(W, /obj/item/wrench)) - add_fingerprint(user) - anchored = 1 + if(W.tool_behaviour == TOOL_WRENCH) + anchored = TRUE user.visible_message("[user] wrenches the solar assembly into place.", "You wrench the solar assembly into place.") playsound(src.loc, W.usesound, 50, 1) - return 1 + return TRUE else - if(istype(W, /obj/item/wrench)) - add_fingerprint(user) - anchored = 0 + if(W.tool_behaviour == TOOL_WRENCH) + anchored = FALSE user.visible_message("[user] unwrenches the solar assembly from its place.", "You unwrench the solar assembly from its place.") playsound(src.loc, W.usesound, 50, 1) - return 1 + return TRUE if(istype(W, /obj/item/stack/sheet/glass) || istype(W, /obj/item/stack/sheet/rglass)) var/obj/item/stack/sheet/S = W if(S.use(2)) add_fingerprint(user) - glass_type = W.type + glass_type = S.merge_type playsound(loc, S.usesound, 50, 1) user.visible_message("[user] places the glass on the solar assembly.", "You place the glass on the solar assembly.") if(tracker) @@ -232,7 +239,7 @@ else to_chat(user, "You need two sheets of glass to put them into a solar panel.") return - return 1 + return TRUE if(!tracker) if(istype(W, /obj/item/tracker_electronics)) @@ -241,15 +248,15 @@ tracker = 1 qdel(W) user.visible_message("[user] inserts the electronics into the solar assembly.", "You insert the electronics into the solar assembly.") - return 1 - else if(istype(W, /obj/item/crowbar)) + return TRUE + else if(W.tool_behaviour == TOOL_CROWBAR) add_fingerprint(user) var/obj/item/tracker_electronics/electronics = new(src.loc) electronics.add_fingerprint(user) tracker = 0 playsound(loc, W.usesound, 50, 1) user.visible_message("[user] takes out the electronics from the solar assembly.", "You take out the electronics from the solar assembly.") - return 1 + return TRUE else return ..() @@ -346,18 +353,20 @@ set_panels(cdir) updateDialog() -/obj/machinery/power/solar_control/update_icon() - overlays.Cut() + +/obj/machinery/power/solar_control/update_overlays() + . = ..() if(stat & NOPOWER) - overlays += "[icon_keyboard]_off" + . += "[icon_keyboard]_off" return - overlays += icon_keyboard + . += icon_keyboard if(stat & BROKEN) - overlays += "[icon_state]_broken" + . += "[icon_state]_broken" else - overlays += icon_screen + . += icon_screen if(cdir > -1) - overlays += image('icons/obj/machines/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir)) + . += image('icons/obj/machines/computer.dmi', icon_state = "solcon-o", layer = FLY_LAYER, dir = angle2dir(cdir)) + /obj/machinery/power/solar_control/attack_ai(mob/user as mob) add_hiddenprint(user) @@ -427,42 +436,32 @@ connected_tracker.modify_angle(SSsun.angle) set_panels(cdir) -/obj/machinery/power/solar_control/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - playsound(src.loc, I.usesound, 50, 1) - if(do_after(user, 20 * I.toolspeed * gettoolspeedmod(user), target = src)) - if(src.stat & BROKEN) - to_chat(user, "The broken glass falls out.") - var/obj/structure/computerframe/A = new /obj/structure/computerframe(src.loc) - A.add_fingerprint(user) - var/obj/item/shard/shard = new(src.loc) - shard.add_fingerprint(user) - var/obj/item/circuitboard/solar_control/M = new /obj/item/circuitboard/solar_control(A) - M.add_fingerprint(user) - for(var/obj/C in src) - C.add_fingerprint(user) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - qdel(src) - else - to_chat(user, "You disconnect the monitor.") - var/obj/structure/computerframe/A = new /obj/structure/computerframe(src.loc) - A.add_fingerprint(user) - var/obj/item/circuitboard/solar_control/M = new /obj/item/circuitboard/solar_control(A) - M.add_fingerprint(user) - for(var/obj/C in src) - C.add_fingerprint(user) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - qdel(src) +/obj/machinery/power/solar_control/screwdriver_act(mob/user, obj/item/I) + . = TRUE + if(!I.tool_use_check(user, 0)) + return + if(!I.use_tool(src, user, 20, volume = I.tool_volume)) + return + var/obj/structure/computerframe/A = new (loc) + A.add_fingerprint(user) + var/obj/item/circuitboard/solar_control/M = new(A) + M.add_fingerprint(user) + for(var/obj/C in src) + C.forceMove(loc) + if(stat & BROKEN) + to_chat(user, "The broken glass falls out.") + A.state = 4 // STATE_WIRES + var/obj/item/shard/shard = new(drop_location()) + shard.add_fingerprint(user) else - return ..() + to_chat(user, "You disconnect the monitor.") + A.state = 5 // STATE_GLASS + A.dir = dir + A.circuit = M + A.update_icon(UPDATE_ICON_STATE) + A.anchored = TRUE + qdel(src) + /obj/machinery/power/solar_control/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) @@ -478,7 +477,7 @@ if(!(stat & BROKEN) && !(flags & NODECONSTRUCT)) playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE) stat |= BROKEN - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar_control/process() lastgen = gen @@ -503,19 +502,20 @@ for(var/obj/machinery/power/solar/S in connected_panels) S.adir = cdir //instantly rotates the panel S.occlusion()//and - S.update_icon() //update it + S.update_icon(UPDATE_OVERLAYS) //update it - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar_control/power_change() - ..() - update_icon() + if(!..()) + return + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/solar_control/proc/broken() stat |= BROKEN - update_icon() + update_icon(UPDATE_OVERLAYS) // // MISC diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index f348ab7e3ae..41ff309d7fc 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -512,9 +512,9 @@ /obj/machinery/power/supermatter_shard/proc/emergency_lighting(active) if(active) - post_status("alert", "radiation") + post_status(STATUS_DISPLAY_ALERT, "radiation") else - post_status("shuttle") + post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) /obj/machinery/power/supermatter_shard/proc/supermatter_zap() playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index e2ee72809fb..2809552b216 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -28,14 +28,13 @@ master = null return ..() -/obj/machinery/power/terminal/update_icon() - . = ..() +/obj/machinery/power/terminal/update_icon_state() var/turf/T = get_turf(src) layer = T.transparent_floor ? ABOVE_TRANSPARENT_TURF_LAYER : WIRE_TERMINAL_LAYER /obj/machinery/power/terminal/hide(i) if(i) - invisibility = INVISIBILITY_ABSTRACT + invisibility = INVISIBILITY_MAXIMUM icon_state = "term-f" else invisibility = 0 @@ -78,7 +77,7 @@ /obj/machinery/power/terminal/attackby(obj/item/W, mob/living/user, params) - if(istype(W, /obj/item/wirecutters)) + if(W.tool_behaviour == TOOL_WIRECUTTER) dismantle(user, W) else return ..() diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index d1dcccfef11..2977b9eb259 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -3,7 +3,7 @@ desc = "For the union!" icon = 'icons/obj/engines_and_power/tesla/tesla_coil.dmi' icon_state = "coil0" - anchored = 0 + anchored = FALSE density = 1 var/power_loss = 2 @@ -108,7 +108,7 @@ desc = "Keep an area from being fried from Edison's Bane." icon = 'icons/obj/engines_and_power/tesla/tesla_coil.dmi' icon_state = "grounding_rod0" - anchored = 0 + anchored = FALSE density = 1 /obj/machinery/power/grounding_rod/Initialize(mapload) diff --git a/code/modules/power/treadmill.dm b/code/modules/power/treadmill.dm index 06566fcae5a..7f03b5c3d65 100644 --- a/code/modules/power/treadmill.dm +++ b/code/modules/power/treadmill.dm @@ -22,7 +22,7 @@ if(anchored) connect_to_network() -/obj/machinery/power/treadmill/update_icon() +/obj/machinery/power/treadmill/update_icon_state() icon_state = speed ? "conveyor-1" : "conveyor0" /obj/machinery/power/treadmill/Crossed(mob/living/M, oldloc) @@ -47,7 +47,7 @@ /obj/machinery/power/treadmill/process() if(!anchored) speed = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) return speed = clamp(speed - friction, 0, MAX_SPEED) @@ -83,7 +83,7 @@ var/output = get_power_output() if(output) add_avail(output) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/treadmill/proc/get_power_output() if(speed && !stat && anchored && powernet) @@ -105,24 +105,19 @@ else disconnect_from_network() speed = 0 - update_icon() + update_icon(UPDATE_ICON_STATE) return return ..() #undef BASE_MOVE_DELAY #undef MAX_SPEED -#define CHARS_PER_LINE 5 -#define FONT_SIZE "5pt" -#define FONT_COLOR "#09f" -#define FONT_STYLE "Small Fonts" - /obj/machinery/treadmill_monitor name = "Treadmill Monitor" icon = 'icons/obj/status_display.dmi' icon_state = "frame" desc = "Monitors treadmill use." - anchored = 1 + anchored = TRUE density = 0 maptext_height = 26 maptext_width = 32 @@ -161,24 +156,25 @@ if(redeem_immediately && total_joules > J_per_ticket) redeem() total_joules = 1 - update_icon() + update_icon(UPDATE_OVERLAYS) frame = !frame -/obj/machinery/treadmill_monitor/power_change() - ..() - update_icon() +/obj/machinery/treadmill_monitor/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_OVERLAYS) /obj/machinery/treadmill_monitor/examine(mob/user) . = ..() . += "The display reads:
    [line1]
    [line2]
    " -/obj/machinery/treadmill_monitor/update_icon() - overlays.Cut() +/obj/machinery/treadmill_monitor/update_overlays() + . = ..() if(stat & NOPOWER || !total_joules || !on) line1 = "" line2 = "" else if(stat & BROKEN) - overlays += image('icons/obj/status_display.dmi', icon_state = "ai_bsod") + . += image('icons/obj/status_display.dmi', icon_state = "ai_bsod") line1 = "A@#$A" line2 = "729%!" else @@ -190,11 +186,11 @@ line1 = "???" else line1 = "[add_zero(num2text(round(treadmill.get_power_output())), 4)]" - if(length(line1) > CHARS_PER_LINE) + if(length(line1) > DISPLAY_CHARS_PER_LINE) line1 = "Error" if(J_per_ticket) line2 = "[round(total_joules / J_per_ticket)]" - if(length(line2) > CHARS_PER_LINE) + if(length(line2) > DISPLAY_CHARS_PER_LINE) line2 = "Error" update_display(line1, line2) @@ -203,7 +199,7 @@ /obj/machinery/treadmill_monitor/proc/update_display(var/line1, var/line2) line1 = uppertext(line1) line2 = uppertext(line2) - var/new_text = {"
    [line1]
    [line2]
    "} + var/new_text = {"
    [line1]
    [line2]
    "} if(maptext != new_text) maptext = new_text @@ -214,16 +210,16 @@ new /obj/item/stack/tickets(get_turf(src), round(total_joules / J_per_ticket)) total_joules = 0 + /obj/machinery/treadmill_monitor/emp_act(severity) ..() if(!(stat & BROKEN)) stat |= BROKEN - update_icon() - spawn(100) - stat &= ~BROKEN - update_icon() + update_icon(UPDATE_OVERLAYS) + addtimer(CALLBACK(src, PROC_REF(delayed_turnon)), 10 SECONDS, TIMER_DELETE_ME) + + +/obj/machinery/treadmill_monitor/proc/delayed_turnon() + stat &= ~BROKEN + update_icon(UPDATE_OVERLAYS) -#undef FONT_SIZE -#undef FONT_COLOR -#undef FONT_STYLE -#undef CHARS_PER_LINE diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 5dcbe3579c7..1c079508bd1 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -21,13 +21,18 @@ // | | V - Suction vent (Like the ones in atmos // +#define OVERDRIVE 4 +#define VERY_FAST 3 +#define FAST 2 +#define SLOW 1 + /obj/machinery/power/compressor name = "compressor" desc = "The compressor stage of a gas turbine generator." icon = 'icons/obj/pipes_and_stuff/atmospherics/pipes.dmi' icon_state = "compressor" - anchored = 1 + anchored = TRUE density = 1 resistance_flags = FIRE_PROOF var/obj/machinery/power/turbine/turbine @@ -39,6 +44,7 @@ var/capacity = 1e6 var/comp_id = 0 var/efficiency + var/rpm_threshold = NONE /obj/machinery/power/turbine @@ -46,7 +52,7 @@ desc = "A gas turbine used for backup power generation." icon = 'icons/obj/pipes_and_stuff/atmospherics/pipes.dmi' icon_state = "turbine" - anchored = 1 + anchored = TRUE density = 1 resistance_flags = FIRE_PROOF var/opened = 0 @@ -54,6 +60,8 @@ var/turf/simulated/outturf var/lastgen var/productivity = 1 + /// If the turbine is outputing enough to visibly affect its sprite + var/generator_threshold = FALSE /obj/machinery/computer/turbine_computer name = "gas turbine control computer" @@ -147,7 +155,6 @@ return if(!starter) return - overlays.Cut() rpm = 0.9* rpm + 0.1 * rpmtarget var/datum/gas_mixture/environment = inturf.return_air() @@ -173,15 +180,30 @@ rpmtarget = 0 - if(rpm>50000) - overlays += image('icons/obj/pipes_and_stuff/atmospherics/pipes.dmi', "comp-o4", FLY_LAYER) - else if(rpm>10000) - overlays += image('icons/obj/pipes_and_stuff/atmospherics/pipes.dmi', "comp-o3", FLY_LAYER) - else if(rpm>2000) - overlays += image('icons/obj/pipes_and_stuff/atmospherics/pipes.dmi', "comp-o2", FLY_LAYER) - else if(rpm>500) - overlays += image('icons/obj/pipes_and_stuff/atmospherics/pipes.dmi', "comp-o1", FLY_LAYER) - //TODO: DEFERRED + var/new_rpm_threshold + switch(rpm) + if(50001 to INFINITY) + new_rpm_threshold = OVERDRIVE + if(10001 to 50000) + new_rpm_threshold = VERY_FAST + if(2001 to 10000) + new_rpm_threshold = FAST + if(501 to 2000) + new_rpm_threshold = SLOW + else + new_rpm_threshold = NONE + + if(rpm_threshold != new_rpm_threshold) + rpm_threshold = new_rpm_threshold + update_icon(UPDATE_OVERLAYS) + + +/obj/machinery/power/compressor/update_overlays() + . = ..() + if(!rpm_threshold) + return + . += image(icon, icon_state = "comp-o[rpm_threshold]", layer = FLY_LAYER) + // These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from // rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is. @@ -234,7 +256,6 @@ return if(!compressor.starter) return - overlays.Cut() // This is the power generation function. If anything is needed it's good to plot it in EXCEL before modifying // the TURBGENQ and TURBGENG values @@ -257,13 +278,20 @@ var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount) outturf.assume_air(removed) -// If it works, put an overlay that it works! - - if(lastgen > 100) - overlays += image('icons/obj/pipes_and_stuff/atmospherics/pipes.dmi', "turb-o", FLY_LAYER) + if((lastgen > 100) != generator_threshold) + generator_threshold = !generator_threshold + update_icon(UPDATE_OVERLAYS) updateDialog() + +/obj/machinery/power/turbine/update_overlays() + . = ..() + if(!generator_threshold) + return + . += image(icon, icon_state = "turb-o", layer = FLY_LAYER) + + /obj/machinery/power/turbine/attack_hand(mob/user) if(..()) @@ -406,3 +434,9 @@ /obj/machinery/computer/turbine_computer/process() src.updateDialog() return + +#undef OVERDRIVE +#undef VERY_FAST +#undef FAST +#undef SLOW + diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 62a9b83e93a..0bde5ba44cf 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -16,7 +16,7 @@ var/pellets = 1 //Pellets for spreadshot var/variance = 0 //Variance for inaccuracy fundamental to the casing var/delay = 0 //Delay for energy weapons - var/randomspread = 0 //Randomspread for automatics + var/randomspread = FALSE //Randomspread for automatics var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. var/harmful = TRUE //pacifism check for boolet, set to FALSE if bullet is non-lethal var/leaves_residue //Остается ли порох на руках и одежде? @@ -30,20 +30,26 @@ /// How strong the flash is var/muzzle_flash_strength = MUZZLE_FLASH_STRENGTH_WEAK + /obj/item/ammo_casing/New() ..() if(projectile_type) BB = new projectile_type(src) - pixel_x = rand(-10.0, 10) - pixel_y = rand(-10.0, 10) + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) dir = pick(GLOB.alldirs) - update_icon() + update_appearance(UPDATE_ICON|UPDATE_DESC) -/obj/item/ammo_casing/update_icon() - ..() + +/obj/item/ammo_casing/update_icon_state() icon_state = "[initial(icon_state)][BB ? "-live" : ""]" + + +/obj/item/ammo_casing/update_desc(updates = ALL) + . = ..() desc = "[initial(desc)][BB ? "" : " This one is spent."]" + /obj/item/ammo_casing/proc/newshot(params) //For energy weapons, shotgun shells and wands (!). if(!BB) BB = new projectile_type(src, params) @@ -69,13 +75,13 @@ else continue if(boolets > 0) - box.update_icon() + box.update_appearance(UPDATE_ICON|UPDATE_DESC) to_chat(user, span_notice("You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.")) playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1) else to_chat(user, span_warning("You fail to collect anything!")) else - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) if(BB) if(initial(BB.name) == "bullet") var/tmp_label = "" @@ -127,7 +133,7 @@ var/multiple_sprites = 0 var/icon_prefix // boxes with multiple sprites use this as their base var/caliber - var/multiload = 1 + var/multiload = TRUE var/list/initial_mats var/replacing_sound = 'sound/weapons/gun_interactions/shotguninsert.ogg' var/remove_sound = 'sound/weapons/gun_interactions/remove_bullet.ogg' @@ -139,7 +145,7 @@ if(ammo_type) for(var/i in 1 to max_ammo) stored_ammo += new ammo_type(src) - update_icon() + update_appearance(UPDATE_ICON|UPDATE_DESC) initial_mats = materials.Copy() update_mat_value() @@ -148,7 +154,7 @@ stored_ammo = null return ..() -/obj/item/ammo_box/proc/get_round(keep = 0) +/obj/item/ammo_box/proc/get_round(keep = FALSE) if(!stored_ammo.len) return null else @@ -161,8 +167,7 @@ return b /obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = FALSE) - // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. - if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + if(!ammo_suitability(R)) return FALSE if(stored_ammo.len < max_ammo) @@ -186,6 +191,12 @@ return FALSE +/obj/item/ammo_box/proc/ammo_suitability(obj/item/ammo_casing/bullet) + // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. + if(!bullet || (caliber && bullet.caliber != caliber) || (!caliber && bullet.type != ammo_type)) + return FALSE + return TRUE + /obj/item/ammo_box/proc/can_load(mob/user) return TRUE @@ -212,8 +223,8 @@ if(!silent) to_chat(user, span_notice("You load [num_loaded] shell\s into \the [src]!")) playsound(src, load_sound, 50, 1) - A.update_icon() - update_icon() + A.update_appearance(UPDATE_ICON|UPDATE_DESC) + update_appearance(UPDATE_ICON|UPDATE_DESC) return num_loaded @@ -223,16 +234,22 @@ user.put_in_hands(A) playsound(src, remove_sound, 50, 1) to_chat(user, span_notice("You remove a round from \the [src]!")) - update_icon() + update_appearance(UPDATE_ICON|UPDATE_DESC) + -/obj/item/ammo_box/update_icon() +/obj/item/ammo_box/update_desc(updates = ALL) + . = ..() + desc = "[initial(desc)] There are [length(stored_ammo)] shell\s left!" + + +/obj/item/ammo_box/update_icon_state() var/icon_base = initial(icon_prefix) ? initial(icon_prefix) : initial(icon_state) switch(multiple_sprites) if(1) - icon_state = "[icon_base]-[stored_ammo.len]" + icon_state = "[icon_base]-[length(stored_ammo)]" if(2) - icon_state = "[icon_base]-[stored_ammo.len ? "[max_ammo]" : "0"]" - desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!" + icon_state = "[icon_base]-[length(stored_ammo) ? "[max_ammo]" : "0"]" + /obj/item/ammo_box/update_materials_coeff(new_coeff) . = ..() @@ -253,7 +270,7 @@ materials[material] += ammo.materials[material] //Behavior for magazines -/obj/item/ammo_box/magazine/proc/ammo_count() +/obj/item/ammo_box/magazine/proc/ammo_count(countempties = TRUE) return length(stored_ammo) /obj/item/ammo_box/magazine/proc/empty_magazine() diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 6ce02f6facc..596aeb6aa40 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -59,7 +59,7 @@ muzzle_flash_range = MUZZLE_FLASH_RANGE_NORMAL /obj/item/ammo_casing/c38/hp - desc = "A .38 Hollow-Point bullet casing" + desc = "A .38 Hollow-Point bullet casing." icon_state = "rhp-casing" materials = list(MAT_METAL = 5000) projectile_type = /obj/item/projectile/bullet/hp38 @@ -171,13 +171,18 @@ /obj/item/ammo_casing/revolver/improvised name = "improvised shell" desc = "Full metal shell leaking oil. This is clearly an unreliable bullet." - icon_state = "improvisedrevolverbullet" + icon_state = "rev-improv-casing" materials = list(MAT_METAL = 100) caliber = ".257" projectile_type = /obj/item/projectile/bullet/weakbullet3/c257 muzzle_flash_strength = MUZZLE_FLASH_STRENGTH_NORMAL muzzle_flash_range = MUZZLE_FLASH_RANGE_NORMAL +/obj/item/ammo_casing/revolver/improvised/phosphorus + desc = "Full metal shell leaking oil and phosphorous. This is clearly an unreliable bullet." + icon_state = "rev-phosphor-casing" + projectile_type = /obj/item/projectile/bullet/weakbullet3/c257/phosphorus + /obj/item/ammo_casing/n762 desc = "A 7.62x38mm bullet casing." materials = list(MAT_METAL = 4000) @@ -483,11 +488,10 @@ var/modified = FALSE harmful = FALSE -/obj/item/ammo_casing/caseless/foam_dart/update_icon() - ..() + +/obj/item/ammo_casing/caseless/foam_dart/update_icon_state() if(modified) icon_state = "foamdart_empty" - desc = "Its nerf or nothing! ... Although, this one doesn't look too safe." if(BB) BB.icon_state = "foamdart_empty" else @@ -495,10 +499,16 @@ if(BB) BB.icon_state = initial(BB.icon_state) + +/obj/item/ammo_casing/caseless/foam_dart/update_desc(updates) + . = ..() + desc = modified ? "Its nerf or nothing! ... Although, this one doesn't look too safe." : initial(desc) + + /obj/item/ammo_casing/caseless/foam_dart/attackby(obj/item/A, mob/user, params) ..() var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB - if(istype(A, /obj/item/screwdriver) && !modified) + if(A.tool_behaviour == TOOL_SCREWDRIVER && !modified) modified = TRUE FD.damage_type = BRUTE update_icon() @@ -537,11 +547,10 @@ caliber = "foam_force_sniper" projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/sniper -/obj/item/ammo_casing/caseless/foam_dart/sniper/update_icon() - ..() + +/obj/item/ammo_casing/caseless/foam_dart/sniper/update_icon_state() if(modified) icon_state = "foamdartsniper_empty" - desc = "Its nerf or nothing! ... Although, this one doesn't look too safe." if(BB) BB.icon_state = "foamdartsniper_empty" else @@ -549,6 +558,12 @@ if(BB) BB.icon_state = initial(BB.icon_state) + +/obj/item/ammo_casing/caseless/foam_dart/sniper/update_desc(updates) + . = ..() + desc = modified ? "Its nerf or nothing! ... Although, this one doesn't look too safe." : initial(desc) + + /obj/item/ammo_casing/caseless/foam_dart/sniper/riot name = "riot foam sniper dart" desc = "For the bigger brother of the crowd control toy. Ages 18 and up." diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 9cb28aab69f..1dccc776c88 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -9,9 +9,10 @@ ammo_type = /obj/item/ammo_casing/a357 max_ammo = 20 -/obj/item/ammo_box/a357/update_icon() - icon_state = "[initial(icon_state)]-[round(stored_ammo.len / 3)]" - desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!" + +/obj/item/ammo_box/a357/update_icon_state() + icon_state = "[initial(icon_state)]-[round(length(stored_ammo) / 3)]" + /obj/item/ammo_box/n762 name = "ammo box (7.62x38mm)" @@ -22,36 +23,36 @@ // SHOTGUN /obj/item/ammo_box/shotgun - name = "Ammunition Box (Slug)" + name = "ammunition box (Slug)" icon_state = "slugbox" ammo_type = /obj/item/ammo_casing/shotgun max_ammo = 7 w_class = WEIGHT_CLASS_NORMAL /obj/item/ammo_box/shotgun/buck - name = "Ammunition Box (Buckshot)" + name = "ammunition box (buckshot)" icon_state = "buckshotbox" ammo_type = /obj/item/ammo_casing/shotgun/buckshot /obj/item/ammo_box/shotgun/buck/assassination - name = "Ammunition Box (Assassination shells)" + name = "ammunition box (assassination shells)" ammo_type = /obj/item/ammo_casing/shotgun/assassination /obj/item/ammo_box/shotgun/buck/nuclear - name = "Elite Ammunition Box (Buckshot)" + name = "elite ammunition box (buckshot)" ammo_type = /obj/item/ammo_casing/shotgun/buckshot/nuclear /obj/item/ammo_box/shotgun/rubbershot - name = "Ammunition Box (Rubbershot shells)" + name = "ammunition box (rubbershot shells)" icon_state = "rubbershotbox" ammo_type = /obj/item/ammo_casing/shotgun/rubbershot /obj/item/ammo_box/shotgun/rubbershot/dart - name = "Ammunition Box (Dart shells)" + name = "ammunition box (dart shells)" ammo_type = /obj/item/ammo_casing/shotgun/dart /obj/item/ammo_box/shotgun/beanbag - name = "Ammunition Box (Beanbag shells)" + name = "ammunition box (beanbag shells)" icon_state = "beanbagbox" ammo_type = /obj/item/ammo_casing/shotgun/beanbag @@ -59,72 +60,72 @@ ammo_type = /obj/item/ammo_casing/shotgun/beanbag/fake /obj/item/ammo_box/shotgun/stunslug - name = "Ammunition Box (Stun shells)" + name = "ammunition box (stun shells)" icon_state = "stunslugbox" ammo_type = /obj/item/ammo_casing/shotgun/stunslug /obj/item/ammo_box/shotgun/breaching - name = "Ammunition Box (Breaching shells)" + name = "ammunition box (breaching shells)" icon_state = "meteorshotbox" ammo_type = /obj/item/ammo_casing/shotgun/breaching /obj/item/ammo_box/shotgun/pulseslug - name = "Ammunition Box (Pulse slugs)" + name = "ammunition box (pulse slugs)" icon_state = "pulseslugbox" ammo_type = /obj/item/ammo_casing/shotgun/pulseslug /obj/item/ammo_box/shotgun/incendiary - name = "Ammunition Box (Incendiary slugs)" + name = "ammunition box (incendiary slugs)" icon_state = "incendiarybox" ammo_type = /obj/item/ammo_casing/shotgun/incendiary /obj/item/ammo_box/shotgun/frag12 - name = "Ammunition Box (FRAG-12 slugs)" + name = "ammunition box (frag-12 slugs)" icon_state = "frag12box" ammo_type = /obj/item/ammo_casing/shotgun/frag12 /obj/item/ammo_box/shotgun/dragonsbreath - name = "Ammunition Box (Dragonsbreath)" + name = "ammunition box (dragonsbreath)" icon_state = "dragonsbreathbox" ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath /obj/item/ammo_box/shotgun/dragonsbreath/nuclear - name = "Elite Ammunition Box (Dragonsbreath)" + name = "elite ammunition box (dragonsbreath)" ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath/nuclear /obj/item/ammo_box/shotgun/ion - name = "Ammunition Box (Ion shells)" + name = "ammunition box (ion shells)" icon_state = "ionbox" ammo_type = /obj/item/ammo_casing/shotgun/ion /obj/item/ammo_box/shotgun/laserslug - name = "Ammunition Box (Laser slugs)" + name = "ammunition box (laser slugs)" icon_state = "laserslugbox" ammo_type = /obj/item/ammo_casing/shotgun/laserslug /obj/item/ammo_box/shotgun/bioterror - name = "Ammunition Box (Bioterror shells)" + name = "ammunition box (bioterror shells)" icon_state = "bioterrorbox" ammo_type = /obj/item/ammo_casing/shotgun/bioterror /obj/item/ammo_box/shotgun/tranquilizer - name = "Ammunition Box (Tranquilizer darts)" + name = "ammunition box (tranquilizer darts)" icon_state = "tranquilizerbox" ammo_type = /obj/item/ammo_casing/shotgun/tranquilizer /obj/item/ammo_box/shotgun/flechette - name = "Ammunition Box (Flechette)" + name = "ammunition box (flechette)" icon_state = "flechettebox" ammo_type = /obj/item/ammo_casing/shotgun/flechette /obj/item/ammo_box/shotgun/improvised - name = "Ammunition Box (Improvised shells)" + name = "ammunition box (improvised shells)" icon = 'icons/obj/storage.dmi' icon_state = "largebox" ammo_type = /obj/item/ammo_casing/shotgun/improvised /obj/item/ammo_box/shotgun/improvised/overload - name = "Ammunition Box (Overload shells)" + name = "ammunition box (overload shells)" ammo_type = /obj/item/ammo_casing/shotgun/improvised/overload // AUTOMATIC @@ -250,16 +251,23 @@ multiple_sprites = 1 // see: /obj/item/ammo_box/update_icon() icon_prefix = "357" // icon prefix, used in above formula to generate dynamic icons -/obj/item/ammo_box/speedloader/improvisedrevolver +/obj/item/ammo_box/speedloader/improvised name = "makeshift speedloader" - desc = "Speedloader made from shit and sticks" - ammo_type = /obj/item/ammo_casing/revolver/improvised - icon_state = "makeshift_speedloader-4" - multiple_sprites = 1 - icon_prefix = "makeshift_speedloader" + desc = "Speedloader made from shit and sticks." + ammo_type = null + icon_state = "makeshift_speedloader" max_ammo = 4 caliber = ".257" +/obj/item/ammo_box/speedloader/improvised/update_overlays() + . = ..() + + for(var/i = 1 to length(stored_ammo)) + var/obj/item/ammo_casing/ammo = stored_ammo[i] + var/icon/new_ammo_icon = icon('icons/obj/weapons/ammo.dmi', ammo.icon_state) + new_ammo_icon.Shift((i in list(2, 3)) ? 8 / RaiseToPower(2, round(i-2, 2)) : i, ISODD(i) ? 4 : 2) + . += new_ammo_icon + /obj/item/ammo_box/speedloader/c38 name = "speed loader (.38)" desc = "Designed to quickly reload revolvers." @@ -280,9 +288,10 @@ // SHOTGUN /obj/item/ammo_box/speedloader/shotgun - name = "Shotgun Speedloader" + name = "shotgun speedloader" desc = "Designed to quickly reload shotguns." icon_state = "shotgunloader" + icon_prefix = "shotgunloader" origin_tech = "combat=2" caliber = ".12" max_ammo = 7 @@ -291,92 +300,91 @@ /obj/item/ammo_box/speedloader/shotgun/New() . = ..() - name = "Shotgun Speedloader" - icon_state = "shotgunloader" - -/obj/item/ammo_box/speedloader/shotgun/update_icon() - overlays.Cut() + name = "shotgun speedloader" +/obj/item/ammo_box/speedloader/shotgun/update_overlays() + . = ..() for(var/i = 1 to length(stored_ammo)) var/obj/item/ammo_casing/shotgun/ammo = stored_ammo[i] var/icon/new_ammo_icon = icon('icons/obj/weapons/ammo.dmi', "[initial(ammo.icon_state)]_loader") if(i < 7) - new_ammo_icon.Shift((i % 2) == 0 ? WEST : EAST, 3) + new_ammo_icon.Shift(ISEVEN(i) ? WEST : EAST, 3) new_ammo_icon.Turn(FLOOR((i - 1) * 45, 90)) - overlays += new_ammo_icon + . += new_ammo_icon + /obj/item/ammo_box/speedloader/shotgun/slug - name = "Shotgun Speedloader (slug)" + name = "shotgun speedloader (slug)" icon_state = "slugloader" ammo_type = /obj/item/ammo_casing/shotgun /obj/item/ammo_box/speedloader/shotgun/buck - name = "Shotgun Speedloader (buckshot)" + name = "shotgun speedloader (buckshot)" icon_state = "buckshotloader" ammo_type = /obj/item/ammo_casing/shotgun/buckshot /obj/item/ammo_box/speedloader/shotgun/rubbershot - name = "Shotgun Speedloader (rubbershot)" + name = "shotgun speedloader (rubbershot)" icon_state = "rubbershotloader" ammo_type = /obj/item/ammo_casing/shotgun/rubbershot /obj/item/ammo_box/speedloader/shotgun/dart - name = "Shotgun Speedloader (dart)" + name = "shotgun speedloader (dart)" icon_state = "rubbershotloader" ammo_type = /obj/item/ammo_casing/shotgun/dart /obj/item/ammo_box/speedloader/shotgun/beanbag - name = "Shotgun Speedloader (beanbag)" + name = "shotgun speedloader (beanbag)" icon_state = "beanbagloader" ammo_type = /obj/item/ammo_casing/shotgun/beanbag /obj/item/ammo_box/speedloader/shotgun/stunslug - name = "Shotgun Speedloader (stunslug)" + name = "shotgun speedloader (stunslug)" icon_state = "stunslugloader" ammo_type = /obj/item/ammo_casing/shotgun/stunslug /obj/item/ammo_box/speedloader/shotgun/pulseslug - name = "Shotgun Speedloader (pulseslug)" + name = "shotgun speedloader (pulseslug)" icon_state = "pulseslugloader" ammo_type = /obj/item/ammo_casing/shotgun/pulseslug /obj/item/ammo_box/speedloader/shotgun/incendiary - name = "Shotgun Speedloader (incendiary)" + name = "shotgun speedloader (incendiary)" icon_state = "incendiaryloader" ammo_type = /obj/item/ammo_casing/shotgun/incendiary /obj/item/ammo_box/speedloader/shotgun/frag12 - name = "Shotgun Speedloader (frag12)" + name = "shotgun speedloader (frag12)" icon_state = "frag12loader" ammo_type = /obj/item/ammo_casing/shotgun/frag12 /obj/item/ammo_box/speedloader/shotgun/dragonsbreath - name = "Shotgun Speedloader (dragonsbreath)" + name = "shotgun speedloader (dragonsbreath)" icon_state = "dragonsbreathloader" ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath /obj/item/ammo_box/speedloader/shotgun/ion - name = "Shotgun Speedloader (ion)" + name = "shotgun speedloader (ion)" icon_state = "ionloader" ammo_type = /obj/item/ammo_casing/shotgun/ion /obj/item/ammo_box/speedloader/shotgun/laserslug - name = "Shotgun Speedloader (laserslug)" + name = "shotgun speedloader (laserslug)" icon_state = "laserslugloader" ammo_type = /obj/item/ammo_casing/shotgun/laserslug /obj/item/ammo_box/speedloader/shotgun/tranquilizer - name = "Shotgun Speedloader (tranquilizer)" + name = "shotgun speedloader (tranquilizer)" icon_state = "tranquilizerloader" ammo_type = /obj/item/ammo_casing/shotgun/tranquilizer /obj/item/ammo_box/speedloader/shotgun/improvised - name = "Shotgun Speedloader (improvised)" + name = "shotgun speedloader (improvised)" icon_state = "improvisedloader" ammo_type = /obj/item/ammo_casing/shotgun/improvised /obj/item/ammo_box/speedloader/shotgun/overload - name = "Shotgun Speedloader (overload)" + name = "shotgun speedloader (overload)" icon_state = "improvisedloader" ammo_type = /obj/item/ammo_casing/shotgun/improvised/overload diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index 4e0f06c3c4b..6c538947edc 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -223,14 +223,9 @@ delay = 10 e_cost = 100 fire_sound = 'sound/weapons/pulse3.ogg' - var/obj/item/gun/energy/wormhole_projector/gun = null select_name = "blue" harmful = FALSE -/obj/item/ammo_casing/energy/wormhole/New(var/obj/item/gun/energy/wormhole_projector/wh) - . = ..() - gun = wh - /obj/item/ammo_casing/energy/wormhole/orange projectile_type = /obj/item/projectile/beam/wormhole/orange muzzle_flash_color = "#FF6600" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index dccfa7f2eef..4dee6639b90 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -1,6 +1,6 @@ ////////////////INTERNAL MAGAZINES////////////////////// /obj/item/ammo_box/magazine/internal - desc = "Oh god, this shouldn't be here" + desc = "Oh god, this shouldn't be here!" //internals magazines are accessible, so replace spent ammo if full when trying to put a live one in /obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R) @@ -14,7 +14,7 @@ max_ammo = 7 -/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1) +/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = TRUE) var/boolets = 0 for(var/obj/item/ammo_casing/bullet in stored_ammo) if(bullet && (bullet.BB || countempties)) @@ -40,7 +40,7 @@ rotate() /obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = FALSE) - if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + if(!ammo_suitability(R)) return FALSE for(var/i in 1 to stored_ammo.len) @@ -81,15 +81,36 @@ caliber = ".36" max_ammo = 6 -/obj/item/ammo_box/magazine/internal/cylinder/improvisedrevolver - name = "Improvised bullet cylinder" - ammo_type = /obj/item/ammo_casing/revolver/improvised - caliber = ".257" +/obj/item/ammo_box/magazine/internal/cylinder/improvised + name = "improvised bullet cylinder" + desc = "A roughly made revolver cylinder." + icon = 'icons/obj/improvised.dmi' + icon_state = "rev_cylinder" + ammo_type = null + caliber = list(".257") max_ammo = 4 +/obj/item/ammo_box/magazine/internal/cylinder/improvised/Initialize(mapload) + ..() + if(!ammo_type) + stored_ammo = new(max_ammo) + +/obj/item/ammo_box/magazine/internal/cylinder/improvised/ammo_suitability(obj/item/ammo_casing/bullet) + if(!bullet || !(bullet.caliber in caliber)) + return FALSE + return TRUE + +/obj/item/ammo_box/magazine/internal/cylinder/improvised/steel + name = "steel bullet cylinder" + desc = "High quality steel revolver cylinder with increased amount of bullets." + icon = 'icons/obj/improvised.dmi' + icon_state = "s_rev_cylinder" + caliber = list(".257", ".38") + max_ammo = 6 + /obj/item/ammo_box/magazine/internal/cylinder/cap name = "cap gun revolver cylinder" - desc = "Oh god, this shouldn't be here" + desc = "Oh god, this shouldn't be here!" ammo_type = /obj/item/ammo_casing/cap caliber = "cap" max_ammo = 7 @@ -106,9 +127,9 @@ ammo_type = /obj/item/ammo_casing/shotgun/beanbag caliber = ".12" max_ammo = 4 - multiload = 0 + multiload = FALSE -/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = 1) +/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = TRUE) if(!countempties) var/boolets = 0 for(var/obj/item/ammo_casing/bullet in stored_ammo) @@ -181,7 +202,7 @@ ammo_type = /obj/item/ammo_casing/a357 caliber = ".357" max_ammo = 6 - multiload = 0 + multiload = FALSE /obj/item/ammo_box/magazine/internal/rus357/New() ..() @@ -190,11 +211,11 @@ /obj/item/ammo_box/magazine/internal/boltaction name = "bolt action rifle internal magazine" - desc = "Oh god, this shouldn't be here" + desc = "Oh god, this shouldn't be here!" ammo_type = /obj/item/ammo_casing/a762 caliber = "7.62x54mm" max_ammo = 5 - multiload = 1 + multiload = TRUE /obj/item/ammo_box/magazine/internal/boltaction/enchanted max_ammo =1 @@ -240,11 +261,10 @@ /obj/item/ammo_box/magazine/m10mm/ap name = "pistol magazine (10mm AP)" icon_state = "9x19pA" - desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets" + desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets." ammo_type = /obj/item/ammo_casing/c10mm/ap -/obj/item/ammo_box/magazine/m10mm/update_icon() - . = ..() +/obj/item/ammo_box/magazine/m10mm/update_icon_state() icon_state = "[initial(icon_state)]-[ammo_count() ? "15" : "0"]" /obj/item/ammo_box/magazine/m45 @@ -263,18 +283,17 @@ multiple_sprites = 1 caliber = "9mm" -/obj/item/ammo_box/magazine/enforcer/update_icon() - ..() - overlays.Cut() - var/ammo = ammo_count() - if(ammo && is_rubber()) - overlays += image('icons/obj/weapons/ammo.dmi', icon_state = "enforcer-r") +/obj/item/ammo_box/magazine/enforcer/update_overlays() + . = ..() + if(ammo_count() && is_rubber()) + . += image('icons/obj/weapons/ammo.dmi', icon_state = "enforcer-r") + /obj/item/ammo_box/magazine/enforcer/examine(mob/user) . = ..() if(get_dist(user, src) <= 2) - . += "It seems to be loaded with [is_rubber() ? "rubber" : "lethal"] bullets."//only can see the topmost one. + . += span_notice("It seems to be loaded with [is_rubber() ? "rubber" : "lethal"] bullets.") //only can see the topmost one. /obj/item/ammo_box/magazine/enforcer/proc/is_rubber()//if the topmost bullet is a rubber one var/ammo = ammo_count() @@ -295,8 +314,7 @@ max_ammo = 10 caliber = "40nr" -/obj/item/ammo_box/magazine/sp8/update_icon() - ..() +/obj/item/ammo_box/magazine/sp8/update_icon_state() icon_state = "sp8mag-[round(ammo_count(),2)]" /obj/item/ammo_box/magazine/wt550m9 @@ -306,8 +324,7 @@ caliber = "4.6x30mm" max_ammo = 20 -/obj/item/ammo_box/magazine/wt550m9/update_icon() - ..() +/obj/item/ammo_box/magazine/wt550m9/update_icon_state() icon_state = "46x30mmt-[round(ammo_count(),4)]" /obj/item/ammo_box/magazine/wt550m9/wtap @@ -329,8 +346,7 @@ caliber = "9mm TE" max_ammo = 20 -/obj/item/ammo_box/magazine/sp91rc/update_icon() - ..() +/obj/item/ammo_box/magazine/sp91rc/update_icon_state() icon_state = "9mm-te-[round(ammo_count(),5)]" /obj/item/ammo_box/magazine/uzim9mm @@ -340,8 +356,7 @@ caliber = "9mm" max_ammo = 32 -/obj/item/ammo_box/magazine/uzim9mm/update_icon() - ..() +/obj/item/ammo_box/magazine/uzim9mm/update_icon_state() icon_state = "uzi9mm-[round(ammo_count(),4)]" /obj/item/ammo_box/magazine/smgm9mm @@ -363,19 +378,17 @@ name = "SMG Magazine (Incendiary 9mm)" ammo_type = /obj/item/ammo_casing/c9mm/inc -/obj/item/ammo_box/magazine/smgm9mm/update_icon() - ..() +/obj/item/ammo_box/magazine/smgm9mm/update_icon_state() icon_state = "[initial(icon_state)]-[round(ammo_count()+1,4)]" /obj/item/ammo_box/magazine/sfg9mm - icon_state = "sfg5" name = "SFG Magazine (9mm)" + icon_state = "sfg5" ammo_type = /obj/item/ammo_casing/c9mm caliber = "9mm" max_ammo = 30 -/obj/item/ammo_box/magazine/sfg9mm/update_icon() - ..() +/obj/item/ammo_box/magazine/sfg9mm/update_icon_state() icon_state = "[initial(icon_state)]-[round(ammo_count(), 30)]" /obj/item/ammo_box/magazine/pistolm9mm @@ -385,8 +398,7 @@ caliber = "9mm" max_ammo = 15 -/obj/item/ammo_box/magazine/pistolm9mm/update_icon() - ..() +/obj/item/ammo_box/magazine/pistolm9mm/update_icon_state() icon_state = "9x19p-[ammo_count() ? "15" : "0"]" /obj/item/ammo_box/magazine/smgm45 @@ -397,8 +409,7 @@ caliber = ".45" max_ammo = 20 -/obj/item/ammo_box/magazine/smgm45/update_icon() - ..() +/obj/item/ammo_box/magazine/smgm45/update_icon_state() icon_state = "[initial(icon_state)]-[round(ammo_count(),2)]" /obj/item/ammo_box/magazine/tommygunm45 @@ -537,8 +548,7 @@ icon_state = "smg9mm-20" max_ammo = 20 -/obj/item/ammo_box/magazine/toy/smg/update_icon() - ..() +/obj/item/ammo_box/magazine/toy/smg/update_icon_state() icon_state = "smg9mm-[round(ammo_count()+1,4)]" /obj/item/ammo_box/magazine/toy/smg/riot @@ -553,8 +563,7 @@ /obj/item/ammo_box/magazine/toy/pistol/riot ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot -/obj/item/ammo_box/magazine/toy/pistol/update_icon() - ..() +/obj/item/ammo_box/magazine/toy/pistol/update_icon_state() icon_state = "9x19p-[ammo_count() ? "15" : "0"]" /obj/item/ammo_box/magazine/toy/enforcer @@ -564,21 +573,21 @@ multiple_sprites = 1 ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot -/obj/item/ammo_box/magazine/toy/enforcer/update_icon() - ..() - overlays.Cut() +/obj/item/ammo_box/magazine/toy/enforcer/update_overlays() + . = ..() var/ammo = ammo_count() if(ammo && is_riot()) overlays += image('icons/obj/weapons/ammo.dmi', icon_state = "enforcer-rd") else if(ammo) overlays += image('icons/obj/weapons/ammo.dmi', icon_state = "enforcer-bd") + /obj/item/ammo_box/magazine/toy/enforcer/proc/is_riot()//if the topmost bullet is a riot dart var/ammo = ammo_count() if(!ammo) return FALSE - if(istype(contents[contents.len], /obj/item/ammo_casing/caseless/foam_dart/riot)) + if(istype(contents[length(contents)], /obj/item/ammo_casing/caseless/foam_dart/riot)) return TRUE return FALSE @@ -587,8 +596,7 @@ ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 20 -/obj/item/ammo_box/magazine/toy/smgm45/update_icon() - ..() +/obj/item/ammo_box/magazine/toy/smgm45/update_icon_state() icon_state = "c20r45-[round(ammo_count(),2)]" /obj/item/ammo_box/magazine/toy/m762 @@ -596,8 +604,7 @@ ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 50 -/obj/item/ammo_box/magazine/toy/m762/update_icon() - ..() +/obj/item/ammo_box/magazine/toy/m762/update_icon_state() icon_state = "a762-[round(ammo_count(),10)]" /obj/item/ammo_box/magazine/toy/m762/riot @@ -612,9 +619,8 @@ caliber = "laser" max_ammo = 20 -/obj/item/ammo_box/magazine/laser/update_icon() - ..() - icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/20, 1)*20]" +/obj/item/ammo_box/magazine/laser/update_icon_state() + icon_state = "[initial(icon_state)]-[CEILING(ammo_count(FALSE)/20, 1)*20]" /obj/item/ammo_box/magazine/lr30mag name = "small encased laser projector magazine" @@ -625,20 +631,10 @@ caliber = "laser" max_ammo = 12 -/obj/item/ammo_box/magazine/lr30mag/update_icon() - ..() +/obj/item/ammo_box/magazine/lr30mag/update_icon_state() icon_state = "lmag-[round(ammo_count(),3)]" -/obj/item/ammo_box/magazine/toy/smgm45 - name = "donksoft SMG magazine" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - max_ammo = 20 - -/obj/item/ammo_box/magazine/toy/smgm45/update_icon() - ..() - icon_state = "c20r45-[round(ammo_count(),2)]" - /obj/item/ammo_box/magazine/toy/smgm45/riot ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot @@ -651,40 +647,40 @@ multiple_sprites = 2 /obj/item/ammo_box/magazine/cats12g - icon_state = "cats_mag_slug" name = "C.A.T.S. magazine (12g slug)" desc = "Похоже, этот магазин может принять в себя только слаги 12-о калибра." + icon_state = "cats_mag_slug" ammo_type = /obj/item/ammo_casing/shotgun multiple_sprites = 2 max_ammo = 8 /obj/item/ammo_box/magazine/cats12g/large - icon_state = "cats_mag_large_slug" name = "C.A.T.S. magazine (12g-slug)-L" desc = "Похоже, в этот расширенный магазин лезут только слаги 12-о калибра." + icon_state = "cats_mag_large_slug" max_ammo = 14 /obj/item/ammo_box/magazine/cats12g/beanbang - icon_state = "cats_mag_bean" name = "C.A.T.S. magazine (12g-beanbang)" desc = "Похоже, в этот магазин лезут только патроны-погремушки." + icon_state = "cats_mag_bean" ammo_type = /obj/item/ammo_casing/shotgun/beanbag /obj/item/ammo_box/magazine/cats12g/beanbang/large - icon_state = "cats_mag_large_bean" name = "C.A.T.S. magazine (12g-beanbang)-L" desc = "Похоже, в этот расширенный магазин лезут только патроны-погремушки." + icon_state = "cats_mag_large_bean" max_ammo = 14 /obj/item/ammo_box/magazine/cats12g/universal - icon_state = "cats_mag" name = "C.A.T.S. magazine (12g)-U" desc = "Похоже, этот магазин может принять в себя любые патроны 12-о калибра." + icon_state = "cats_mag" caliber = ".12" ammo_type = null /obj/item/ammo_box/magazine/cats12g/universal/large - icon_state = "cats_mag_large" name = "C.A.T.S. magazine (12g)-UL" desc = "Похоже, этот расширенный магазин может принять в себя любые патроны 12-о калибра." + icon_state = "cats_mag_large" max_ammo = 14 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f64775e0c3d..cdba9468386 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/weapons/projectile.dmi' icon_state = "detective" item_state = "gun" + appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER flags = CONDUCT slot_flags = SLOT_BELT materials = list(MAT_METAL=2000) @@ -40,18 +41,23 @@ var/ninja_weapon = FALSE //Оружия со значением TRUE обходят ограничение ниндзя на использование пушек var/bolt_open = FALSE var/spread = 0 - var/randomspread = 1 var/barrel_dir = EAST // barel direction need for a rotate gun with telekinesis for shot to target (default: matched with tile direction) + var/randomspread = TRUE - var/unique_rename = TRUE //allows renaming with a pen - var/unique_reskin = FALSE //allows reskinning - var/current_skin = null //the skin choice if we had a reskin - var/list/options = list() + /// Allows renaming with a pen + var/unique_rename = TRUE + /// Allows reskinning + var/unique_reskin = FALSE + /// The skin choice if we had a reskin + var/current_skin + /// Lazy list of gun visual skins. Filled on Initialize() in proc/update_gun_skins() + var/list/skin_options lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/guns_righthand.dmi' var/obj/item/flashlight/gun_light = null + var/gun_light_overlay var/can_flashlight = 0 var/can_bayonet = FALSE //if a bayonet can be added or removed if it already has one. @@ -82,19 +88,24 @@ var/malf_high_bound = 80 var/malf_counter // random number between malf_low_bound and malf_high_bound + /obj/item/gun/Initialize() . = ..() appearance_flags |= KEEP_TOGETHER if(gun_light) verbs += /obj/item/gun/proc/toggle_gunlight build_zooming() - if(rusted_weapon == TRUE) + if(rusted_weapon) malf_counter = rand(malf_low_bound, malf_high_bound) + update_gun_skins() + /obj/item/gun/Destroy() + QDEL_NULL(gun_light) QDEL_NULL(bayonet) return ..() + /obj/item/gun/handle_atom_del(atom/A) if(A == bayonet) clear_bayonet() @@ -113,6 +124,24 @@ else if(can_bayonet) . += "It has a bayonet lug on it." + +/obj/item/gun/proc/update_gun_skins() + return + + +/** + * Adds skin in associative lazy list: skin_options[skin_name] = skin_icon_state + * + * Arguments: + * * skin_name - what skin name user will see. + * * skin_icon_state - which icon_state will be used for the gun. + */ +/obj/item/gun/proc/add_skin(skin_name, skin_icon_state) + if(!unique_reskin) + return + LAZYSET(skin_options, skin_name, skin_icon_state) + + /obj/item/gun/proc/process_chamber() return 0 @@ -121,8 +150,8 @@ /obj/item/gun/proc/can_shoot() return 1 -/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) - to_chat(user, "*click*") +/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user) + to_chat(user, span_danger("*click*")) playsound(user, 'sound/weapons/empty.ogg', 100, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user, atom/target, pointblank = FALSE, message = TRUE) @@ -357,11 +386,10 @@ if(S.on) set_light(0) gun_light = S - update_icon() - update_gun_light(user) var/datum/action/A = new /datum/action/item_action/toggle_gunlight(src) if(loc == user) A.Grant(user) + update_gun_light() if(unique_rename) if(istype(I, /obj/item/pen)) @@ -376,6 +404,7 @@ return to_chat(user, "You attach [K] to [src]'s bayonet lug.") bayonet = K + update_icon() var/state = "bayonet" //Generic state. if(bayonet.icon_state in icon_states('icons/obj/weapons/bayonets.dmi')) //Snowflake state? state = bayonet.icon_state @@ -383,7 +412,7 @@ knife_overlay = mutable_appearance(bayonet_icons, state) knife_overlay.pixel_x = knife_x_offset knife_overlay.pixel_y = knife_y_offset - overlays += knife_overlay + update_icon(UPDATE_OVERLAYS) else return ..() @@ -395,14 +424,13 @@ for(var/obj/item/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") gun_light = null - S.loc = get_turf(user) - update_gun_light(user) + update_gun_light() + S.forceMove_turf() S.update_brightness(user) - update_icon() for(var/datum/action/item_action/toggle_gunlight/TGL in actions) qdel(TGL) else if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed - bayonet.forceMove(get_turf(user)) + bayonet.forceMove_turf() clear_bayonet() /obj/item/gun/proc/toggle_gunlight() @@ -420,9 +448,10 @@ to_chat(user, "You toggle the gun light [gun_light.on ? "on":"off"].") playsound(user, 'sound/weapons/empty.ogg', 100, 1) - update_gun_light(user) + update_gun_light() -/obj/item/gun/proc/update_gun_light(mob/user = null) + +/obj/item/gun/proc/update_gun_light() if(gun_light) if(gun_light.on) set_light(gun_light.brightness_on) @@ -432,17 +461,17 @@ else set_light(0) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_icon(UPDATE_OVERLAYS) + update_equipped_item() + /obj/item/gun/proc/clear_bayonet() if(!bayonet) return bayonet = null if(knife_overlay) - overlays -= knife_overlay knife_overlay = null + update_icon(UPDATE_OVERLAYS) return TRUE /obj/item/gun/extinguish_light(force = FALSE) @@ -458,22 +487,37 @@ if(azoom) azoom.Remove(user) + /obj/item/gun/AltClick(mob/user) + if(!unique_reskin || current_skin || loc != user) + return ..() if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(unique_reskin && loc == user) - reskin_gun(user) + to_chat(user, span_warning("You can't do that right now!")) + return ..() + reskin_gun(user) -/obj/item/gun/proc/reskin_gun(mob/M) - var/choice = input(M,"Select your skin.","Reskin Gun") in options - if(src && choice && !M.incapacitated() && in_range(M,src)) - if(options[choice] == null) - return - current_skin = options[choice] - to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.") +/obj/item/gun/proc/reskin_gun(mob/user) + if(!LAZYLEN(skin_options)) + stack_trace("[src] has unique_reskin set to TRUE but skin_options list is empty.") + return + var/list/skins = list() + for(var/skin in skin_options) + skins[skin] = image(icon = icon, icon_state = skin_options[skin]) + var/choice = show_radial_menu(user, src, skins, radius = 40, custom_check = CALLBACK(src, PROC_REF(reskin_radial_check), user), require_near = TRUE) + + if(choice && reskin_radial_check(user) && !current_skin) + current_skin = skin_options[choice] + to_chat(user, "Your gun is now skinned as [choice]. Say hello to your new friend.") update_icon() + update_equipped_item() + + +/obj/item/gun/proc/reskin_radial_check(mob/living/carbon/human/user) + if(!ishuman(user) || QDELETED(src) || !user.is_in_hands(src) || user.incapacitated()) + return FALSE + return TRUE + /obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params) if(!ishuman(user) || !ishuman(target)) diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 746649fe722..bcabb2de7f7 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -54,9 +54,14 @@ restricted_species = list(/datum/species/vox/armalis) sprite_sheets_inhand = list("Vox Armalis" = 'icons/mob/clothing/species/armalis/held.dmi') //Big guns big birds. -/obj/item/gun/energy/noisecannon/update_icon() + +/obj/item/gun/energy/noisecannon/update_icon_state() return + +/obj/item/gun/energy/noisecannon/update_overlays() + return list() + //Casing /obj/item/ammo_casing/energy/sonic projectile_type = /obj/item/projectile/energy/sonic diff --git a/code/modules/projectiles/guns/dartgun.dm b/code/modules/projectiles/guns/dartgun.dm index ad69e1445a6..f48fdeb4dbd 100644 --- a/code/modules/projectiles/guns/dartgun.dm +++ b/code/modules/projectiles/guns/dartgun.dm @@ -6,18 +6,19 @@ item_state = "rcdammo" opacity = 0 density = 0 - anchored = 0.0 + anchored = FALSE origin_tech = "materials=2" var/darts = 5 -/obj/item/dart_cartridge/update_icon() + +/obj/item/dart_cartridge/update_icon_state() if(!darts) icon_state = "darts-0" else if(darts > 5) icon_state = "darts-5" else icon_state = "darts-[darts]" - return 1 + /obj/item/gun/dartgun name = "dart gun" @@ -32,10 +33,11 @@ var/containers_type = /obj/item/reagent_containers/glass/beaker var/list/starting_chems = null -/obj/item/gun/dartgun/update_icon() + +/obj/item/gun/dartgun/update_icon_state() if(!cartridge) icon_state = "dartgun-e" - return 1 + return if(!cartridge.darts) icon_state = "dartgun-0" @@ -43,10 +45,11 @@ icon_state = "dartgun-5" else icon_state = "dartgun-[cartridge.darts]" - return 1 -/obj/item/gun/dartgun/New() - ..() + +/obj/item/gun/dartgun/Initialize() + . = ..() + if(starting_chems) for(var/chem in starting_chems) var/obj/B = new containers_type(src) @@ -55,6 +58,7 @@ cartridge = new /obj/item/dart_cartridge(src) update_icon() + /obj/item/gun/dartgun/examine(mob/user) . = ..() if(get_dist(user, src) <= 2) @@ -150,7 +154,7 @@ to_chat(user, "There are no reagents available!") return cartridge.darts-- - src.update_icon() + update_icon() S.reagents.trans_to(D, S.reagents.total_volume) qdel(S) D.icon_state = "syringeproj" @@ -290,9 +294,9 @@ desc = "" icon = 'icons/obj/chemical.dmi' icon_state = "null" - anchored = 1 + anchored = TRUE density = 0 -/obj/effect/syringe_gun_dummy/New() +/obj/effect/syringe_gun_dummy/Initialize(mapload) . = ..() create_reagents(15) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index f01f049d325..f46c5b7b558 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -4,6 +4,7 @@ desc = "A basic energy-based gun." icon = 'icons/obj/weapons/energy.dmi' fire_sound_text = "laser blast" + gun_light_overlay = "flight" ammo_x_offset = 2 var/obj/item/stock_parts/cell/cell //What type of power cell this uses @@ -17,6 +18,12 @@ var/charge_sections = 4 var/charge_tick = 0 var/charge_delay = 4 + /// Used when updating icon and overlays + var/new_icon_state + /// If the item uses a shared set of overlays instead of being based on icon_state + var/overlay_set + /// Used when updating icon and overlays to determine the energy pips + var/ratio var/can_add_sibyl_system = TRUE //if a sibyl system's mod can be added or removed if it already has one var/obj/item/sibyl_system_mod/sibyl_mod = null @@ -174,11 +181,13 @@ /obj/item/gun/energy/proc/on_recharge() newshot() + /obj/item/gun/energy/attack_self(mob/living/user) - if(ammo_type.len > 1) + if(length(ammo_type)) select_fire(user) update_icon() + /obj/item/gun/energy/can_shoot(mob/living/user) var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/check_charge = cell.charge >= shot.e_cost @@ -229,43 +238,54 @@ chambered = null newshot() update_icon() - if(istype(user,/mob/living/carbon/human)) //This has to be here or else if you toggle modes by clicking the gun in hand - var/mob/living/carbon/human/H = user //Otherwise the mob icon doesn't update, blame shitty human update_icons() code - H.update_inv_l_hand() - H.update_inv_r_hand() - return - -/obj/item/gun/energy/update_icon() - overlays.Cut() - var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) + + +/obj/item/gun/energy/update_icon(updates = ALL) + ..() + update_equipped_item() + + +/obj/item/gun/energy/update_icon_state() + icon_state = initial(icon_state) + ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] - var/iconState = "[icon_state]_charge" - var/itemState = null + new_icon_state = "[icon_state]_charge" + var/new_item_state = null if(!initial(item_state)) - itemState = icon_state + new_item_state = icon_state if(modifystate) - overlays += "[icon_state]_[shot.select_name]" - iconState += "_[shot.select_name]" - if(itemState) - itemState += "[shot.select_name]" + new_icon_state += "_[shot.select_name]" + if(new_item_state) + new_item_state += "[shot.select_name]" + if(new_item_state) + new_item_state += "[ratio]" + item_state = new_item_state + if(current_skin) + icon_state = current_skin + + +/obj/item/gun/energy/update_overlays() + . = ..() + var/overlay_name = overlay_set ? overlay_set : icon_state + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(modifystate) + . += "[overlay_name]_[shot.select_name]" if(cell.charge < shot.e_cost) - overlays += "[icon_state]_empty" + . += "[overlay_name]_empty" else if(!shaded_charge) for(var/i = ratio, i >= 1, i--) - overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1)) + . += image(icon = icon, icon_state = new_icon_state, pixel_x = ammo_x_offset * (i - 1)) else - overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]") - if(gun_light && can_flashlight) - var/iconF = "flight" + . += image(icon = icon, icon_state = "[overlay_name]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]") + if(gun_light && gun_light_overlay) + var/iconF = gun_light_overlay if(gun_light.on) - iconF = "flight_on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) - if(bayonet && can_bayonet) - overlays += knife_overlay - if(itemState) - itemState += "[ratio]" - item_state = itemState + iconF = "[gun_light_overlay]_on" + . += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + if(bayonet && knife_overlay) + . += knife_overlay + /obj/item/gun/energy/ui_action_click() toggle_gunlight() diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 1245b0d6cf2..eb9a41b30ff 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -151,18 +151,11 @@ update_icon() overheat = FALSE -/obj/item/gun/energy/kinetic_accelerator/update_icon() - cut_overlays() + +/obj/item/gun/energy/kinetic_accelerator/update_overlays() + . = ..() if(empty_state && !can_shoot()) - add_overlay(empty_state) - - if(gun_light && can_flashlight) - var/iconF = "flight" - if(gun_light.on) - iconF = "flight_on" - add_overlay(image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)) - if(bayonet && can_bayonet) - add_overlay(knife_overlay) + . += empty_state /obj/item/gun/energy/kinetic_accelerator/experimental diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 8a585f2d992..8d2d8d9c3ff 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -1,8 +1,8 @@ /obj/item/gun/energy/laser name = "laser gun" desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal." - icon_state = "laser" - item_state = "laser" + icon_state = "lasergun" + item_state = null w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=2000) origin_tech = "combat=4;magnets=2" @@ -13,6 +13,8 @@ /obj/item/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." + icon_state = "laser" + item_state = "laser" origin_tech = "combat=2;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 @@ -21,6 +23,7 @@ /obj/item/gun/energy/laser/retro name ="retro laser gun" icon_state = "retro" + item_state = "laser" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's private security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." ammo_x_offset = 3 @@ -36,19 +39,12 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF unique_reskin = TRUE -/obj/item/gun/energy/laser/captain/New() - ..() - options["The Original"] = "caplaser" - options["Restored"] = "caplaser_new" - options["Alternative"] = "caplaser_newer" - options["Cancel"] = null -/obj/item/gun/energy/laser/captain/update_icon() - ..() - if(current_skin) - icon_state = "[current_skin]" - else - icon_state = "[initial(icon_state)]" +/obj/item/gun/energy/laser/captain/update_gun_skins() + add_skin("The Original", "caplaser") + add_skin("Restored", "caplaser_new") + add_skin("Alternative", "caplaser_newer") + /obj/item/gun/energy/laser/captain/scattershot name = "scatter shot laser rifle" @@ -141,11 +137,13 @@ ammo_type = list(/obj/item/ammo_casing/energy/immolator/strong, /obj/item/ammo_casing/energy/immolator/scatter) origin_tech = "combat=5;magnets=5;powerstorage=4" -/obj/item/gun/energy/immolator/multi/update_icon() - ..() + +/obj/item/gun/energy/immolator/multi/update_overlays() + . = ..() var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/append = shot.select_name - overlays += image(icon = icon, icon_state = "multilensimmolator-[append]") + . += image(icon, icon_state = "multilensimmolator-[append]") + /obj/item/gun/energy/immolator/multi/cyborg name = "cyborg immolator cannon" @@ -155,6 +153,8 @@ ////////Laser Tag//////////////////// /obj/item/gun/energy/laser/tag + icon_state = "bluetag" + item_state = "laser" name = "laser tag gun" desc = "Standard issue weapon of the Imperial Guard" origin_tech = "combat=2;magnets=2" diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 668e85d6911..7398ebb26c4 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -26,9 +26,12 @@ desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill." icon_state = "mini" w_class = WEIGHT_CLASS_SMALL + gun_light_overlay = "mini-light" + flight_x_offset = 0 + flight_y_offset = 0 ammo_x_offset = 2 charge_sections = 3 - can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update + can_flashlight = FALSE actions_types = list(/datum/action/item_action/toggle_gunlight) /obj/item/gun/energy/gun/mini/Initialize(mapload, ...) @@ -37,10 +40,6 @@ cell.maxcharge = 600 cell.charge = 600 -/obj/item/gun/energy/gun/mini/update_icon() - ..() - if(gun_light && gun_light.on) - overlays += "mini-light" /obj/item/gun/energy/gun/hos name = "\improper X-01 MultiPhase Energy Gun" @@ -64,8 +63,8 @@ /obj/item/gun/energy/gun/blueshield/can_shoot() . = ..() - if (. && !isertmindshielded(usr)) - to_chat(usr, "ЕРТ имплант «Защита разума» не обнаружен!") + if(. && !isertmindshielded(usr)) + to_chat(usr, span_warning("ЕРТ имплант «Защита разума» не обнаружен!")) return FALSE return . @@ -83,8 +82,8 @@ /obj/item/gun/energy/gun/pdw9/ert/can_shoot() . = ..() - if (. && !isertmindshielded(usr)) - to_chat(usr, "ЕРТ имплант «Защита разума» не обнаружен!") + if(. && !isertmindshielded(usr)) + to_chat(usr, span_warning("ЕРТ имплант «Защита разума» не обнаружен!")) return FALSE return . diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index c04c8c3d1bc..5197f796942 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -186,8 +186,8 @@ else return ..() -/obj/item/gun/energy/plasmacutter/update_icon() - return +/obj/item/gun/energy/plasmacutter/update_overlays() + return list() /obj/item/gun/energy/plasmacutter/adv name = "advanced plasma cutter" @@ -285,8 +285,8 @@ ammo_type = list(/obj/item/ammo_casing/energy/c3dbullet) can_charge = FALSE -/obj/item/gun/energy/printer/update_icon() - return +/obj/item/gun/energy/printer/update_overlays() + return list() /obj/item/gun/energy/printer/emp_act() return @@ -700,9 +700,7 @@ /obj/item/gun/energy/dominator/update_icon(updates = ALL) is_equipped = ismob(loc) - update_icon_state() - update_overlays() - update_equipped_item() + ..() /obj/item/gun/energy/dominator/update_icon_state() @@ -714,7 +712,7 @@ icon_state = "[base_icon_state][sibyl_mod.auth_id ? "_unlock" : "_lock" ]" return - var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) + ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/shot_name = shot.alt_select_name var/new_item_state = base_icon_state @@ -730,9 +728,9 @@ /obj/item/gun/energy/dominator/update_overlays() . = list() if(gun_light && can_flashlight) - var/iconF = "flight" + var/iconF = gun_light_overlay if(gun_light.on) - iconF = "[iconF]_on" + iconF = "[gun_light_overlay]_on" . += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 87cdec16388..360579aa054 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -51,8 +51,8 @@ charges--//... drain a charge return -/obj/item/gun/magic/New() - ..() +/obj/item/gun/magic/Initialize() + . = ..() charges = max_charges chambered = new ammo_type(src) if(can_charge) @@ -73,7 +73,7 @@ charges++ return 1 -/obj/item/gun/magic/update_icon() +/obj/item/gun/magic/update_icon_state() return /obj/item/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index a95db09a36c..f31e2ee2cb7 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -1,4 +1,4 @@ -/obj/item/gun/magic/wand/ +/obj/item/gun/magic/wand name = "wand of nothing" belt_icon = "wand of nothing" desc = "It's not just a stick, it's a MAGIC stick!" @@ -10,19 +10,21 @@ max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths) var/variable_charges = 1 -/obj/item/gun/magic/wand/New() +/obj/item/gun/magic/wand/Initialize() if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges if(prob(33)) max_charges = CEILING(max_charges / 3, 1) else max_charges = CEILING(max_charges / 2, 1) - ..() + . = ..() + /obj/item/gun/magic/wand/examine(mob/user) . = ..() . += "Has [charges] charge\s remaining." -/obj/item/gun/magic/wand/update_icon() + +/obj/item/gun/magic/wand/update_icon_state() icon_state = "[initial(icon_state)][charges ? "" : "-drained"]" diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index 137a2bf65d1..d0ea81f4306 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -15,8 +15,8 @@ weapon_weight = WEAPON_MEDIUM -/obj/item/gun/medbeam/New() - ..() +/obj/item/gun/medbeam/Initialize() + . = ..() START_PROCESSING(SSobj, src) /obj/item/gun/medbeam/Destroy() diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index ad9e4edcbb9..9f9bef2b698 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -23,19 +23,33 @@ user.put_in_hands(bomb) user.visible_message("[user] detaches [bomb] from [src].") bomb = null - update_icon() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) return ..() -/obj/item/gun/blastcannon/update_icon() + +/obj/item/gun/blastcannon/update_name(updates = ALL) + . = ..() if(bomb) - icon_state = icon_state_loaded name = "blast cannon" - desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave." else - icon_state = initial(icon_state) name = initial(name) + + +/obj/item/gun/blastcannon/update_desc(updates = ALL) + . = ..() + if(bomb) + desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave." + else desc = initial(desc) + +/obj/item/gun/blastcannon/update_icon_state() + if(bomb) + icon_state = icon_state_loaded + else + icon_state = initial(icon_state) + + /obj/item/gun/blastcannon/attackby(obj/O, mob/user) if(istype(O, /obj/item/transfer_valve)) var/obj/item/transfer_valve/T = O @@ -47,7 +61,7 @@ return FALSE user.visible_message("[user] attaches [T] to [src]!") bomb = T - update_icon() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) return TRUE return ..() @@ -71,7 +85,7 @@ return ..() var/power = calculate_bomb() QDEL_NULL(bomb) - update_icon() + update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) var/heavy = power * 0.2 var/medium = power * 0.5 var/light = power diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 8cb7c95df60..26a9fe9b488 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -1,6 +1,6 @@ /obj/item/gun/projectile - desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason" name = "projectile gun" + desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason." icon_state = "pistol" origin_tech = "combat=2;materials=2" w_class = WEIGHT_CLASS_NORMAL @@ -10,24 +10,50 @@ var/obj/item/ammo_box/magazine/magazine var/can_tactical = FALSE //check to see if the gun can tactically reload -/obj/item/gun/projectile/New() - ..() - if(!magazine) + +/obj/item/gun/projectile/Initialize(mapload) + . = ..() + if(!magazine && mag_type) magazine = new mag_type(src) chamber_round() + update_weight() update_icon() - return -/obj/item/gun/projectile/update_icon() - ..() + +/obj/item/gun/projectile/update_name(updates = ALL) + . = ..() + if(sawn_state) + name = "sawn-off [name]" + else + name = initial(name) + + +/obj/item/gun/projectile/update_desc(updates = ALL) + . = ..() + if(sawn_state) + desc = sawn_desc + else + desc = initial(desc) + + +/obj/item/gun/projectile/update_icon_state() if(current_skin) - icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]" + icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "_sawn" : ""]" else icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""][bolt_open ? "-open" : ""]" - if(bayonet && can_bayonet) - overlays += knife_overlay -/obj/item/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1) + +/obj/item/gun/projectile/update_overlays() + . = ..() + if(bayonet && knife_overlay) + . += knife_overlay + + +/obj/item/gun/proc/update_weight() + return + + +/obj/item/gun/projectile/process_chamber(eject_casing = TRUE, empty_chamber = TRUE) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(isnull(AC) || !istype(AC)) chamber_round() @@ -35,7 +61,7 @@ if(eject_casing) AC.loc = get_turf(src) //Eject casing onto ground. AC.SpinAnimation(10, 1) //next gen special effects - playsound(src, chambered.casing_drop_sound, 100, 1) + playsound(src, chambered.casing_drop_sound, 100, TRUE) if(empty_chamber) chambered = null chamber_round() @@ -50,43 +76,45 @@ return /obj/item/gun/projectile/can_shoot() - if(!magazine || !magazine.ammo_count(0)) - return 0 - return 1 + if(!magazine || !magazine.ammo_count(FALSE)) + return FALSE + return TRUE /obj/item/gun/projectile/proc/can_reload() return !magazine -/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user as mob) - user.drop_item_ground(AM) - magazine = AM - magazine.loc = src - playsound(src, magin_sound, 50, 1) - chamber_round() - AM.update_icon() - update_icon() - return -/obj/item/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user) + user.drop_item_ground(AM) + magazine = AM + magazine.loc = src + playsound(src, magin_sound, 50, 1) + chamber_round() + update_weight() + AM.update_icon() + update_icon() + + +/obj/item/gun/projectile/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A if(istype(AM, mag_type)) if(can_reload()) reload(AM, user) - to_chat(user, "You load a new magazine into \the [src].") + to_chat(user, span_notice("You load a new magazine into \the [src].")) return TRUE else if(!can_tactical) - to_chat(user, "There's already a magazine in \the [src].") + to_chat(user, span_notice("There's already a magazine in \the [src].")) return TRUE else - to_chat(user, "You perform a tactical reload on \the [src], replacing the magazine.") + to_chat(user, span_notice("You perform a tactical reload on \the [src], replacing the magazine.")) magazine.loc = get_turf(loc) magazine.update_icon() magazine = null reload(AM, user) return TRUE else - to_chat(user, "You can't put this type of ammo in \the [src].") + to_chat(user, span_notice("You can't put this type of ammo in \the [src].")) return TRUE if(istype(A, /obj/item/suppressor)) var/obj/item/suppressor/S = A @@ -94,7 +122,7 @@ if(!suppressed) if(!user.drop_transfer_item_to_loc(A, src)) return - to_chat(user, "You screw [S] onto [src].") + to_chat(user, span_notice("You screw [S] onto [src].")) playsound(src, 'sound/items/screwdriver.ogg', 40, 1) suppressed = A S.oldsound = fire_sound @@ -104,10 +132,10 @@ update_icon() return else - to_chat(user, "[src] already has a suppressor.") + to_chat(user, span_warning("[src] already has a suppressor.")) return else - to_chat(user, "You can't seem to figure out how to fit [S] on [src].") + to_chat(user, span_warning("You can't seem to figure out how to fit [S] on [src].")) return else return ..() @@ -119,97 +147,96 @@ if(user.l_hand != src && user.r_hand != src) ..() return - to_chat(user, "You unscrew [suppressed] from [src].") + to_chat(user, span_notice("You unscrew [suppressed] from [src].")) playsound(src, 'sound/items/screwdriver.ogg', 40, 1) user.put_in_hands(suppressed) fire_sound = S.oldsound w_class = S.initial_w_class - suppressed = 0 + suppressed = null update_icon() return ..() -/obj/item/gun/projectile/attack_self(mob/living/user as mob) +/obj/item/gun/projectile/attack_self(mob/living/user) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) magazine.loc = get_turf(loc) user.put_in_hands(magazine) magazine.update_icon() magazine = null - to_chat(user, "You pull the magazine out of \the [src]!") + update_weight() + to_chat(user, span_notice("You pull the magazine out of \the [src]!")) playsound(src, magout_sound, 50, 1) else if(chambered) AC.loc = get_turf(src) AC.SpinAnimation(10, 1) chambered = null - to_chat(user, "You unload the round from \the [src]'s chamber.") + to_chat(user, span_notice("You unload the round from \the [src]'s chamber.")) playsound(src, 'sound/weapons/gun_interactions/remove_bullet.ogg', 50, 1) else - to_chat(user, "There's no magazine in \the [src].") + to_chat(user, span_notice("There's no magazine in \the [src].")) update_icon() return /obj/item/gun/projectile/examine(mob/user) . = ..() - . += "Has [get_ammo()] round\s remaining." + . += span_notice("Has [get_ammo()] round\s remaining.") -/obj/item/gun/projectile/proc/get_ammo(countchambered = 1) +/obj/item/gun/projectile/proc/get_ammo(countchambered = TRUE, countempties = TRUE) var/boolets = 0 //mature var names for mature people if(chambered && countchambered) boolets++ if(magazine) - boolets += magazine.ammo_count() + boolets += magazine.ammo_count(countempties) return boolets /obj/item/gun/projectile/suicide_act(mob/user) if(chambered && chambered.BB && !chambered.BB.nodamage) - user.visible_message("[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.") + user.visible_message(span_suicide("[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.")) sleep(25) if(user.l_hand == src || user.r_hand == src) process_fire(user, user, 0, zone_override = BODY_ZONE_HEAD) - user.visible_message("[user] blows [user.p_their()] brains out with the [name]!") + user.visible_message(span_suicide("[user] blows [user.p_their()] brains out with the [name]!")) return BRUTELOSS else - user.visible_message("[user] panics and starts choking to death!") + user.visible_message(span_suicide("[user] panics and starts choking to death!")) return OXYLOSS else - user.visible_message("[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!
    ") + user.visible_message(span_suicide("[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) return OXYLOSS /obj/item/gun/projectile/proc/sawoff(mob/user) if(sawn_state == SAWN_OFF) - to_chat(user, "\The [src] is already shortened!") + to_chat(user, span_warning("\The [src] is already shortened!")) return if(bayonet) - to_chat(user, "You cannot saw-off [src] with [bayonet] attached!") + to_chat(user, span_warning("You cannot saw-off [src] with [bayonet] attached!")) return user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src]...") + user.visible_message("[user] begins to shorten \the [src].", span_notice("You begin to shorten \the [src]...")) //if there's any live ammo inside the gun, makes it go off if(blow_up(user)) - user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") + user.visible_message(span_danger("\The [src] goes off!"), span_danger("\The [src] goes off in your face!")) return - if(do_after(user, 30, target = src)) + if(do_after(user, 3 SECONDS, target = src)) if(sawn_state == SAWN_OFF) return - user.visible_message("[user] shortens \the [src]!", "You shorten \the [src].") - name = "sawn-off [name]" - desc = sawn_desc + user.visible_message("[user] shortens \the [src]!", span_notice("You shorten \the [src].")) w_class = WEIGHT_CLASS_NORMAL item_state = "gun"//phil235 is it different with different skin? slot_flags &= ~SLOT_BACK //you can't sling it on your back slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) sawn_state = SAWN_OFF - update_icon() - return 1 + update_appearance() + return TRUE // Sawing guns related proc /obj/item/gun/projectile/proc/blow_up(mob/user) - . = 0 + . = FALSE for(var/obj/item/ammo_casing/AC in magazine.stored_ammo) if(AC.BB) process_fire(user, user,0) - . = 1 + . = TRUE diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 033a687f040..be0e48fc05a 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -9,22 +9,30 @@ fire_delay = 2 actions_types = list(/datum/action/item_action/toggle_firemode) -/obj/item/gun/projectile/automatic/update_icon() - ..() - overlays.Cut() + +/obj/item/gun/projectile/automatic/update_icon_state() + icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + + +/obj/item/gun/projectile/automatic/update_overlays() + . = ..() if(!select) - overlays += "[initial(icon_state)]semi" + . += "[initial(icon_state)]semi" if(select == 1) - overlays += "[initial(icon_state)]burst" - icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" - if(bayonet && can_bayonet) - overlays += knife_overlay + . += "[initial(icon_state)]burst" + + if(gun_light && gun_light_overlay) + var/iconF = gun_light_overlay + if(gun_light.on) + iconF = "[gun_light_overlay]_on" + . += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) -/obj/item/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params) + +/obj/item/gun/projectile/automatic/attackby(obj/item/A, mob/user, params) . = ..() if(.) if(alarmed) // Did the empty clip alarm go off already? - alarmed = 0 // Reset the alarm once a magazine is loaded + alarmed = FALSE // Reset the alarm once a magazine is loaded return if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A @@ -101,17 +109,21 @@ knife_x_offset = 26 knife_y_offset = 12 -/obj/item/gun/projectile/automatic/c20r/New() - ..() + +/obj/item/gun/projectile/automatic/c20r/Initialize() + . = ..() update_icon() -/obj/item/gun/projectile/automatic/c20r/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + +/obj/item/gun/projectile/automatic/c20r/afterattack(atom/target, mob/living/user, flag) ..() empty_alarm() -/obj/item/gun/projectile/automatic/c20r/update_icon() - ..() - icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + +/obj/item/gun/projectile/automatic/c20r/update_icon_state() + icon_state = "c20r[magazine ? "-[CEILING(get_ammo(FALSE)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + + //WT550// /obj/item/gun/projectile/automatic/wt550 @@ -130,22 +142,19 @@ can_bayonet = TRUE knife_x_offset = 25 knife_y_offset = 12 + gun_light_overlay = "wt-light" -/obj/item/gun/projectile/automatic/wt550/update_icon() - ..() - icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]" - if(gun_light) - var/iconF = "wt-light" - if(gun_light.on) - iconF = "wt-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) +/obj/item/gun/projectile/automatic/wt550/update_icon_state() + icon_state = "wt550[magazine ? "-[CEILING(get_ammo(FALSE)/4, 1)*4]" : ""]" -/obj/item/gun/projectile/automatic/wt550/ui_action_click(var/owner, var/action_type) - if(..()) return TRUE - if (action_type == /datum/action/item_action/toggle_gunlight) - toggle_gunlight() - return TRUE + +/obj/item/gun/projectile/automatic/wt550/ui_action_click(owner, action_type) + if(..()) + return TRUE + if(action_type == /datum/action/item_action/toggle_gunlight) + toggle_gunlight() + return TRUE //"SP-91-RC// /obj/item/gun/projectile/automatic/sp91rc @@ -158,31 +167,25 @@ magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg' magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg' fire_delay = 2 - can_suppress = 0 - can_flashlight = 1 + can_suppress = FALSE + can_flashlight = TRUE burst_size = 3 can_bayonet = FALSE + gun_light_overlay = "SP-91-RC-light" -/obj/item/gun/projectile/automatic/sp91rc/update_icon() - ..() - icon_state = "SP-91-RC[magazine ? "-[CEILING(get_ammo(0)/5, 1)*5]" : ""]" - item_state = "SP-91-RC[magazine ? "-[get_ammo(0) ? "20" : "0"]" : ""]" - if(gun_light) - var/iconF = "SP-91-RC-light" - if(gun_light.on) - iconF = "SP-91-RC-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) +/obj/item/gun/projectile/automatic/sp91rc/update_icon_state() + icon_state = "SP-91-RC[magazine ? "-[CEILING(get_ammo(FALSE)/5, 1)*5]" : ""]" + item_state = "SP-91-RC[magazine ? "-[get_ammo(FALSE) ? "20" : "0"]" : ""]" -/obj/item/gun/projectile/automatic/sp91rc/attackby(var/obj/item/A, mob/user, params) - . = .. () - update_equipped_item() -/obj/item/gun/projectile/automatic/sp91rc/ui_action_click(var/owner, var/action_type) - if(..()) return TRUE - if (action_type == /datum/action/item_action/toggle_gunlight) - toggle_gunlight() - return TRUE +/obj/item/gun/projectile/automatic/sp91rc/ui_action_click(owner, action_type) + if(..()) + return TRUE + if(action_type == /datum/action/item_action/toggle_gunlight) + toggle_gunlight() + return TRUE + //Type-U3 Uzi// /obj/item/gun/projectile/automatic/mini_uzi @@ -210,19 +213,21 @@ burst_size = 3 fire_delay = 2 -/obj/item/gun/projectile/automatic/m90/New() - ..() + +/obj/item/gun/projectile/automatic/m90/Initialize(mapload) + . = ..() underbarrel = new /obj/item/gun/projectile/revolver/grenadelauncher(src) update_icon() -/obj/item/gun/projectile/automatic/m90/afterattack(var/atom/target, var/mob/living/user, flag, params) + +/obj/item/gun/projectile/automatic/m90/afterattack(atom/target, mob/living/user, flag, params) if(select == 0) underbarrel.afterattack(target, user, flag, params) else ..() return -/obj/item/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params) +/obj/item/gun/projectile/automatic/m90/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_casing)) if(istype(A, underbarrel.magazine.ammo_type)) underbarrel.attack_self() @@ -230,21 +235,25 @@ else return ..() -/obj/item/gun/projectile/automatic/m90/update_icon() - ..() - overlays.Cut() - switch(select) - if(1) - overlays += "[initial(icon_state)]burst" - if(0) - overlays += "[initial(icon_state)]gren" + +/obj/item/gun/projectile/automatic/m90/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "" : "-e"][suppressed ? "-suppressed" : ""]" if(magazine) - overlays += image(icon = icon, icon_state = "m90-[CEILING(get_ammo(0)/6, 1)*6]") - item_state = "m90-[CEILING(get_ammo(0)/7.5, 1)]" + item_state = "m90-[CEILING(get_ammo(FALSE)/7.5, 1)]" else item_state = "m90-0" - return + + +/obj/item/gun/projectile/automatic/m90/update_overlays() + . = ..() + if(magazine) + . += image(icon = icon, icon_state = "m90-[CEILING(get_ammo(FALSE)/6, 1)*6]") + switch(select) + if(0) + . += "[initial(icon_state)]gren" + if(1) + . += "[initial(icon_state)]burst" + /obj/item/gun/projectile/automatic/m90/burst_select() var/mob/living/carbon/human/user = usr @@ -326,14 +335,19 @@ fire_delay = 0 actions_types = null -/obj/item/gun/projectile/automatic/shotgun/bulldog/New() - ..() - update_icon() -/obj/item/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine() +/obj/item/gun/projectile/automatic/shotgun/bulldog/update_icon_state() + icon_state = "bulldog[chambered ? "" : "-e"]" + + +/obj/item/gun/projectile/automatic/shotgun/bulldog/update_overlays() + . = ..() + if(magazine) + . += "[magazine.icon_state]" + + +/obj/item/gun/projectile/automatic/shotgun/bulldog/update_weight() if(magazine) - overlays.Cut() - overlays += "[magazine.icon_state]" if(istype(magazine, /obj/item/ammo_box/magazine/m12g/XtrLrg)) w_class = WEIGHT_CLASS_BULKY else @@ -341,21 +355,17 @@ else w_class = WEIGHT_CLASS_NORMAL -/obj/item/gun/projectile/automatic/shotgun/bulldog/update_icon() - overlays.Cut() - update_magazine() - icon_state = "bulldog[chambered ? "" : "-e"]" -/obj/item/gun/projectile/automatic/shotgun/bulldog/attackby(var/obj/item/A as obj, mob/user as mob, params) - if(istype(A, /obj/item/ammo_box/magazine/m12g/XtrLrg)) - if(istype(loc, /obj/item/storage)) // To prevent inventory exploits - var/obj/item/storage/Strg = loc - if(Strg.max_w_class < WEIGHT_CLASS_BULKY) - to_chat(user, "You can't reload [src], with a XL mag, while it's in a normal bag.") - return +/obj/item/gun/projectile/automatic/shotgun/bulldog/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/ammo_box/magazine/m12g/XtrLrg) && isstorage(loc)) // To prevent inventory exploits + var/obj/item/storage/storage = loc + if(storage.max_w_class < WEIGHT_CLASS_BULKY) + to_chat(user, span_warning("You can't reload [src], with a XL mag, while it's in a normal bag.")) + return return ..() -/obj/item/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + +/obj/item/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target, mob/living/user, flag) ..() empty_alarm() @@ -397,14 +407,15 @@ burst_size = 2 can_suppress = 0 -/obj/item/gun/projectile/automatic/cats/update_icon() - ..() + +/obj/item/gun/projectile/automatic/cats/update_icon_state() icon_state = "tla_cats[magazine ? "" : "-e"]" + /obj/item/gun/projectile/automatic/cats/examine(mob/user) . = ..() if(Adjacent(user)) - if(user.say_understands(null, GLOB.all_languages["Sol Common"])) + if(user.say_understands(null, GLOB.all_languages[LANGUAGE_SOL_COMMON])) . += "Вы видите гравировку на прикладе, написанную на Общесолнечном: 'Свобода через тотальное превосходство'" else . += "Вы видите символы на прикладе, но не понимаете что они значат." @@ -424,9 +435,8 @@ can_suppress = 0 burst_size = 2 -/obj/item/gun/projectile/automatic/lasercarbine/update_icon() - ..() - icon_state = "lasercarbine[magazine ? "-[CEILING(get_ammo(0)/5, 1)*5]" : ""]" +/obj/item/gun/projectile/automatic/lasercarbine/update_icon_state() + icon_state = "lasercarbine[magazine ? "-[CEILING(get_ammo(FALSE)/5, 1)*5]" : ""]" /obj/item/gun/projectile/automatic/lr30 name = "\improper LR-30 Laser Rifle" @@ -443,9 +453,8 @@ burst_size = 1 actions_types = null -/obj/item/gun/projectile/automatic/lr30/update_icon() - ..() - icon_state = "lr30[magazine ? "-[CEILING(get_ammo(0)/3, 1)*3]" : ""]" +/obj/item/gun/projectile/automatic/lr30/update_icon_state() + icon_state = "lr30[magazine ? "-[CEILING(get_ammo(FALSE)/3, 1)*3]" : ""]" //Semi-Machine Gun SFG @@ -457,21 +466,19 @@ mag_type = /obj/item/ammo_box/magazine/sfg9mm burst_size = 3 can_flashlight = TRUE + gun_light_overlay = "sfg-light" -/obj/item/gun/projectile/automatic/sfg/update_icon() - ..() + +/obj/item/gun/projectile/automatic/sfg/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "" : "-e"][suppressed ? "-suppressed" : ""]" - if(gun_light) - var/iconF = "sfg-light" - if(gun_light.on) - iconF = "sfg-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) -/obj/item/gun/projectile/automatic/sfg/ui_action_click(var/owner, var/action_type) - if(..()) return TRUE - if (action_type == /datum/action/item_action/toggle_gunlight) - toggle_gunlight() - return TRUE + +/obj/item/gun/projectile/automatic/sfg/ui_action_click(owner, action_type) + if(..()) + return TRUE + if(action_type == /datum/action/item_action/toggle_gunlight) + toggle_gunlight() + return TRUE //Aussec Armory M-52 diff --git a/code/modules/projectiles/guns/projectile/bombarda.dm b/code/modules/projectiles/guns/projectile/bombarda.dm index bf2d01cf5e2..61f4fadb796 100644 --- a/code/modules/projectiles/guns/projectile/bombarda.dm +++ b/code/modules/projectiles/guns/projectile/bombarda.dm @@ -24,12 +24,10 @@ A.update_icon() update_icon() -/obj/item/gun/projectile/bombarda/update_icon() - . = ..() - if(!chambered) - icon_state = "bombarda_open" - else - icon_state = "bombarda" + +/obj/item/gun/projectile/bombarda/update_icon_state() + icon_state = "bombarda[chambered ? "" : "_open"]" + /obj/item/gun/projectile/bombarda/process_chamber(eject_casing, empty_chamber) var/obj/item/ammo_casing/AC = chambered @@ -82,11 +80,11 @@ remove_sound = 'sound/weapons/bombarda/open.ogg' load_sound = 'sound/weapons/bombarda/load.ogg' -/obj/item/ammo_box/magazine/internal/bombarda/New() - ..() +/obj/item/ammo_box/magazine/internal/bombarda/Initialize(mapload) + . = ..() QDEL_LIST(stored_ammo) //not supposed to have initial ammo. -/obj/item/ammo_box/magazine/internal/bombarda/ammo_count(countempties = 1) +/obj/item/ammo_box/magazine/internal/bombarda/ammo_count(countempties = TRUE) if(!countempties) var/boolets = 0 for(var/obj/item/ammo_casing/bullet in stored_ammo) diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm index ed8a6a70dbd..a4418fbcf5d 100644 --- a/code/modules/projectiles/guns/projectile/bow.dm +++ b/code/modules/projectiles/guns/projectile/bow.dm @@ -10,7 +10,7 @@ weapon_weight = WEAPON_HEAVY trigger_guard = TRIGGER_GUARD_NONE var/draw_sound = 'sound/weapons/draw_bow.ogg' - var/ready_to_fire = 0 + var/ready_to_fire = FALSE var/slowdown_when_ready = 2 /obj/item/gun/projectile/bow/ashen //better than wooden @@ -23,20 +23,25 @@ force = 10 slowdown_when_ready = 1 -/obj/item/gun/projectile/bow/update_icon() + +/obj/item/gun/projectile/bow/update_icon_state() if(magazine.ammo_count() && !ready_to_fire) icon_state = "[initial(icon_state)]_loaded" else if(ready_to_fire) icon_state = "[initial(icon_state)]_firing" - slowdown = slowdown_when_ready else icon_state = initial(icon_state) - slowdown = initial(slowdown) + + +/obj/item/gun/projectile/bow/proc/update_slowdown() + slowdown = ready_to_fire ? slowdown_when_ready : initial(slowdown) + /obj/item/gun/projectile/bow/dropped(mob/user, silent = FALSE) if(magazine && magazine.ammo_count()) magazine.empty_magazine() ready_to_fire = FALSE + update_slowdown() update_icon() . = ..() @@ -45,10 +50,10 @@ if(!ready_to_fire && magazine.ammo_count()) ready_to_fire = TRUE playsound(user, draw_sound, 100, 1) - update_icon() else ready_to_fire = FALSE - update_icon() + update_slowdown() + update_icon() /obj/item/gun/projectile/bow/attackby(obj/item/A, mob/user, params) var/num_loaded = magazine.attackby(A, user, params, 1) @@ -68,6 +73,7 @@ /obj/item/gun/projectile/bow/process_chamber(eject_casing = 0, empty_chamber = 1) . = ..() ready_to_fire = FALSE + update_slowdown() update_icon() // ammo @@ -134,8 +140,8 @@ new /obj/item/ammo_casing/caseless/arrow(src) update_icon() -/obj/item/storage/backpack/quiver/update_icon() - if(length(contents) > 0) +/obj/item/storage/backpack/quiver/update_icon_state() + if(length(contents)) icon_state = "quiver_[clamp(length(contents),1,5)]" else icon_state = initial(icon_state) diff --git a/code/modules/projectiles/guns/projectile/launchers.dm b/code/modules/projectiles/guns/projectile/launchers.dm index 1b06c3e7538..c6d9f199ad2 100644 --- a/code/modules/projectiles/guns/projectile/launchers.dm +++ b/code/modules/projectiles/guns/projectile/launchers.dm @@ -46,10 +46,10 @@ /obj/item/gun/projectile/automatic/gyropistol/process_chamber(eject_casing = 0, empty_chamber = 1) ..() -/obj/item/gun/projectile/automatic/gyropistol/update_icon() - ..() + +/obj/item/gun/projectile/automatic/gyropistol/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "loaded" : ""]" - return + /obj/item/gun/projectile/automatic/speargun name = "kinetic speargun" @@ -67,7 +67,7 @@ select = 0 actions_types = null -/obj/item/gun/projectile/automatic/speargun/update_icon() +/obj/item/gun/projectile/automatic/speargun/update_icon_state() return /obj/item/gun/projectile/automatic/speargun/attack_self() @@ -136,10 +136,16 @@ update_icon() return -/obj/item/gun/projectile/revolver/rocketlauncher/update_icon() - cut_overlays() + +/obj/item/gun/projectile/revolver/rocketlauncher/update_icon_state() + return + + +/obj/item/gun/projectile/revolver/rocketlauncher/update_overlays() + . = ..() if(!chambered) - add_overlay("[icon_state]_empty") + . += "[icon_state]_empty" + /obj/item/gun/projectile/revolver/rocketlauncher/suicide_act(mob/user) user.visible_message("[user] aims [src] at the ground! It looks like [user.p_theyre()] performing a sick rocket jump!") diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index bc831a96392..c60f2c20de9 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -10,15 +10,15 @@ fire_sound = 'sound/weapons/gunshots/1stechkin.ogg' magin_sound = 'sound/weapons/gun_interactions/pistol_magin.ogg' magout_sound = 'sound/weapons/gun_interactions/pistol_magout.ogg' - can_suppress = 1 + can_suppress = TRUE burst_size = 1 fire_delay = 0 actions_types = null -/obj/item/gun/projectile/automatic/pistol/update_icon() - ..() + +/obj/item/gun/projectile/automatic/pistol/update_icon_state() icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" - return + //M1911// /obj/item/gun/projectile/automatic/pistol/m1911 @@ -28,7 +28,7 @@ w_class = WEIGHT_CLASS_NORMAL mag_type = /obj/item/ammo_box/magazine/m45 fire_sound = 'sound/weapons/gunshots/1colt.ogg' - can_suppress = 0 + can_suppress = FALSE //Enforcer// /obj/item/gun/projectile/automatic/pistol/enforcer @@ -41,42 +41,42 @@ can_suppress = TRUE unique_reskin = TRUE can_flashlight = TRUE + gun_light_overlay = "enforcer-light" + + +/obj/item/gun/projectile/automatic/pistol/enforcer/update_gun_skins() + add_skin("Grey slide", "enforcer_grey") + add_skin("Red slide", "enforcer_red") + add_skin("Green slide", "enforcer_green") + add_skin("Tan slide", "enforcer_tan") + add_skin("Black slide", "enforcer_black") + add_skin("Green Handle", "enforcer_greengrip") + add_skin("Tan Handle", "enforcer_tangrip") + add_skin("Red Handle", "enforcer_redgrip") -/obj/item/gun/projectile/automatic/pistol/enforcer/New() - ..() - options["Grey slide"] = "enforcer_grey" - options["Red slide"] = "enforcer_red" - options["Green slide"] = "enforcer_green" - options["Tan slide"] = "enforcer_tan" - options["Black slide"] = "enforcer_black" - options["Green Handle"] = "enforcer_greengrip" - options["Tan Handle"] = "enforcer_tangrip" - options["Red Handle"] = "enforcer_redgrip" - options["Cancel"] = null - -/obj/item/gun/projectile/automatic/pistol/enforcer/update_icon() - ..() + +/obj/item/gun/projectile/automatic/pistol/enforcer/update_icon_state() if(current_skin) icon_state = "[current_skin][chambered ? "" : "-e"]" else icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - overlays.Cut() + + +/obj/item/gun/projectile/automatic/pistol/enforcer/update_overlays() + . = ..() if(suppressed) - overlays += image(icon = icon, icon_state = "enforcer_supp", pixel_x = 4) - if(gun_light) - var/iconF = "Enforcer_light" - if(gun_light.on) - iconF = "Enforcer_light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) + . += image(icon = icon, icon_state = "enforcer_supp", pixel_x = 4) + /obj/item/gun/projectile/automatic/pistol/enforcer/ui_action_click() toggle_gunlight() /obj/item/gun/projectile/automatic/pistol/enforcer/lethal -/obj/item/gun/projectile/automatic/pistol/enforcer/lethal/New() +/obj/item/gun/projectile/automatic/pistol/enforcer/lethal/Initialize(mapload) magazine = new/obj/item/ammo_box/magazine/enforcer/lethal - ..() + . = ..() + //СБшный инфорсер// /obj/item/gun/projectile/automatic/pistol/enforcer/security @@ -97,92 +97,59 @@ can_suppress = TRUE unique_reskin = TRUE can_flashlight = TRUE + gun_light_overlay = "sp8-light" -/obj/item/gun/projectile/automatic/pistol/sp8/New() - ..() - options["Black"] = "sp8_black" - options["Red"] = "sp8_red" - options["Green"] = "sp8_green" - options["Olive"] = "sp8_olive" - options["Yellow"] = "sp8_yellow" - options["White"] = "sp8_white" - options["Cancel"] = null - -/obj/item/gun/projectile/automatic/pistol/sp8/update_icon() - ..() + +/obj/item/gun/projectile/automatic/pistol/sp8/update_gun_skins() + add_skin("Black", "sp8_black") + add_skin("Red", "sp8_red") + add_skin("Green", "sp8_green") + add_skin("Olive", "sp8_olive") + add_skin("Yellow", "sp8_yellow") + add_skin("White", "sp8_white") + + +/obj/item/gun/projectile/automatic/pistol/sp8/update_icon_state() if(current_skin) icon_state = "[current_skin][chambered ? "" : "-e"]" else icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - overlays.Cut() + + +/obj/item/gun/projectile/automatic/pistol/sp8/update_overlays() + . = ..() if(suppressed) - overlays += image(icon = icon, icon_state = "sp8_supp") - if(gun_light) - var/iconF = "sp8-light" - if(gun_light.on) - iconF = "sp8-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) + . += image(icon = icon, icon_state = "sp8_supp") + /obj/item/gun/projectile/automatic/pistol/sp8/ui_action_click() toggle_gunlight() -/obj/item/gun/projectile/automatic/pistol/sp8t + +/obj/item/gun/projectile/automatic/pistol/sp8/sp8t name = "SP-8-T" - can_suppress = FALSE icon_state = "sp8t_dust" desc = "Новейшая разработка для сил защиты активов." - force = 10 - mag_type = /obj/item/ammo_box/magazine/sp8 fire_sound = 'sound/weapons/gunshots/sp8t.ogg' + can_suppress = FALSE unique_reskin = TRUE can_flashlight = TRUE -/obj/item/gun/projectile/automatic/pistol/sp8t/New() - ..() - options["Dust"] = "sp8t_dust" - options["Sea"] = "sp8t_sea" - options["Cancel"] = null -/obj/item/gun/projectile/automatic/pistol/sp8t/update_icon() - ..() - if(current_skin) - icon_state = "[current_skin][chambered ? "" : "-e"]" - else - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - overlays.Cut() - if(suppressed) - overlays += image(icon = icon, icon_state = "sp8_supp") - if(gun_light) - var/iconF = "sp8-light" - if(gun_light.on) - iconF = "sp8-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) - -/obj/item/gun/projectile/automatic/pistol/sp8t/ui_action_click() - toggle_gunlight() +/obj/item/gun/projectile/automatic/pistol/sp8/sp8t/update_gun_skins() + add_skin("Dust", "sp8t_dust") + add_skin("Sea", "sp8t_sea") + -/obj/item/gun/projectile/automatic/pistol/sp8ar +/obj/item/gun/projectile/automatic/pistol/sp8/sp8ar name = "SP-8-AR" desc = "Пистолет сил защиты активов оснащённый ДТК." - can_suppress = FALSE icon_state = "sp8ar" - unique_reskin = FALSE - force = 10 - mag_type = /obj/item/ammo_box/magazine/sp8 fire_sound = 'sound/weapons/gunshots/sp8ar.ogg' + can_suppress = FALSE + unique_reskin = FALSE can_flashlight = TRUE -/obj/item/gun/projectile/automatic/pistol/sp8ar/update_icon() - ..() - if(gun_light) - var/iconF = "sp8-light" - if(gun_light.on) - iconF = "sp8-light-on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = 0) - -/obj/item/gun/projectile/automatic/pistol/sp8ar/ui_action_click() - toggle_gunlight() - //Desert Eagle// /obj/item/gun/projectile/automatic/pistol/deagle @@ -195,12 +162,13 @@ fire_sound = 'sound/weapons/gunshots/1deagle.ogg' magin_sound = 'sound/weapons/gun_interactions/hpistol_magin.ogg' magout_sound = 'sound/weapons/gun_interactions/hpistol_magout.ogg' - can_suppress = 0 + can_suppress = FALSE + -/obj/item/gun/projectile/automatic/pistol/deagle/update_icon() - ..() +/obj/item/gun/projectile/automatic/pistol/deagle/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "" : "-e"]" + /obj/item/gun/projectile/automatic/pistol/deagle/gold desc = "A gold plated desert eagle folded over a million times by superior martian gunsmiths. Uses .50 AE ammo." icon_state = "deagleg" @@ -219,7 +187,7 @@ w_class = WEIGHT_CLASS_NORMAL origin_tech = "combat=3;materials=2;syndicate=3" mag_type = /obj/item/ammo_box/magazine/pistolm9mm - can_suppress = 1 + can_suppress = TRUE burst_size = 3 fire_delay = 2 actions_types = list(/datum/action/item_action/toggle_firemode) diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 5b6adb143e6..1414a64222d 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -6,24 +6,26 @@ origin_tech = "combat=3;materials=2" fire_sound = 'sound/weapons/gunshots/1rev.ogg' -/obj/item/gun/projectile/revolver/New() - ..() +/obj/item/gun/projectile/revolver/Initialize(mapload) + . = ..() if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) verbs -= /obj/item/gun/projectile/revolver/verb/spin -/obj/item/gun/projectile/revolver/chamber_round(var/spin = 1) +/obj/item/gun/projectile/revolver/chamber_round(spin = TRUE) + if(!magazine) + return if(spin) - chambered = magazine.get_round(1) + chambered = magazine.get_round(TRUE) else chambered = magazine.stored_ammo[1] return -/obj/item/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj) +/obj/item/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user) ..() - chamber_round(1) + chamber_round(TRUE) /obj/item/gun/projectile/revolver/process_chamber() - return ..(0, 1) + return ..(FALSE, TRUE) /obj/item/gun/projectile/revolver/attackby(obj/item/A, mob/user, params) . = ..() @@ -35,14 +37,14 @@ to_chat(user, span_notice("You load [num_loaded] shell\s into \the [src].")) A.update_icon() update_icon() - chamber_round(0) + chamber_round(FALSE) /obj/item/gun/projectile/revolver/attack_self(mob/living/user) var/num_unloaded = 0 chambered = null - while(get_ammo() > 0) + while(get_ammo(FALSE) > 0) var/obj/item/ammo_casing/CB - CB = magazine.get_round(0) + CB = magazine.get_round(FALSE) if(CB) CB.loc = get_turf(loc) CB.SpinAnimation(10, 1) @@ -61,52 +63,45 @@ var/mob/M = usr - if(M.stat || !in_range(M,src)) + if(M.stat || !in_range(M, src)) return if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine C.spin() - chamber_round(0) + chamber_round(FALSE) playsound(loc, 'sound/weapons/revolver_spin.ogg', 50, 1) usr.visible_message("[usr] spins [src]'s chamber.", span_notice("You spin [src]'s chamber.")) else verbs -= /obj/item/gun/projectile/revolver/verb/spin + /obj/item/gun/projectile/revolver/can_shoot() - return get_ammo(0,0) + return get_ammo(FALSE, FALSE) -/obj/item/gun/projectile/revolver/get_ammo(countchambered = 0, countempties = 1) - var/boolets = 0 //mature var names for mature people - if(chambered && countchambered) - boolets++ - if(magazine) - boolets += magazine.ammo_count(countempties) - return boolets /obj/item/gun/projectile/revolver/examine(mob/user) . = ..() - . += span_notice("[get_ammo(0,0)] of those are live rounds") + . += span_notice("[get_ammo(FALSE, FALSE)] of those are live rounds") /obj/item/gun/projectile/revolver/detective - desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds." name = ".38 Mars Special" + desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds." icon_state = "detective" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 fire_sound = 'sound/weapons/gunshots/1rev38.ogg' unique_rename = TRUE unique_reskin = TRUE -/obj/item/gun/projectile/revolver/detective/New() - ..() - options["The Original"] = "detective" - options["Leopard Spots"] = "detective_leopard" - options["Black Panther"] = "detective_panther" - options["White Gold "] = "detective_gold" - options["The Peacemaker"] = "detective_peacemaker" - options["Gold Wood"] = "detective_gold_alt" - options["Silver"] = "detective_silver" - options["Cancel"] = null + +/obj/item/gun/projectile/revolver/detective/update_gun_skins() + add_skin("The Original", "detective") + add_skin("Leopard Spots", "detective_leopard") + add_skin("Black Panther", "detective_panther") + add_skin("White Gold", "detective_gold") + add_skin("Gold Wood", "detective_gold_alt") + add_skin("The Peacemaker", "detective_peacemaker") + add_skin("Silver", "detective_silver") /obj/item/gun/projectile/revolver/fingergun //Summoned by the Finger Gun spell, from advanced mimery traitor item @@ -132,8 +127,8 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible/fake -/obj/item/gun/projectile/revolver/fingergun/New(loc, new_parent_spell) - ..() +/obj/item/gun/projectile/revolver/fingergun/Initialize(loc, new_parent_spell) + . = ..() parent_spell = new_parent_spell verbs -= /obj/item/gun/projectile/revolver/verb/spin @@ -146,22 +141,23 @@ return ..() -/obj/item/gun/projectile/revolver/fingergun/shoot_with_empty_chamber(/*mob/living/user as mob|obj*/) - to_chat(usr, span_notice("You are out of ammo! You holster your fingers.")) +/obj/item/gun/projectile/revolver/fingergun/shoot_with_empty_chamber(mob/living/user) + to_chat(user, span_notice("You are out of ammo! You holster your fingers.")) qdel(src) return /obj/item/gun/projectile/revolver/fingergun/afterattack(atom/target, mob/living/user, flag, params) - if(!user.mind.miming) - to_chat(usr, span_notice("You must dedicate yourself to silence first. Use your fingers if you wish to holster them.")) + if(!user.mind?.miming) + to_chat(user, span_notice("You must dedicate yourself to silence first. Use your fingers if you wish to holster them.")) return ..() /obj/item/gun/projectile/revolver/fingergun/attackby(obj/item/A, mob/user, params) return -/obj/item/gun/projectile/revolver/fingergun/attack_self(mob/living/user = usr) - to_chat(user, span_notice("You holster your fingers. Another time.")) +/obj/item/gun/projectile/revolver/fingergun/attack_self(mob/living/user) + if(istype(user)) + to_chat(user, span_notice("You holster your fingers. Another time.")) qdel(src) return @@ -181,7 +177,7 @@ fire_delay = 5 /obj/item/gun/projectile/revolver/golden - name = "\improper Golden revolver" + name = "golden revolver" desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo." icon_state = "goldrevolver" fire_sound = 'sound/weapons/resonator_blast.ogg' @@ -206,22 +202,22 @@ // You can spin the chamber to randomize the position of the bullet. /obj/item/gun/projectile/revolver/russian - name = "\improper Russian Revolver" + name = "\improper Russian revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull." origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/rus357 var/spun = FALSE -/obj/item/gun/projectile/revolver/russian/New() - ..() +/obj/item/gun/projectile/revolver/russian/Initialize(mapload) + . = ..() Spin() update_icon() /obj/item/gun/projectile/revolver/russian/proc/Spin() chambered = null var/random = rand(1, magazine.max_ammo) - if(random <= get_ammo(0,0)) + if(random <= get_ammo(FALSE, FALSE)) chamber_round() spun = TRUE @@ -256,7 +252,7 @@ else to_chat(user, span_notice("[src] is empty.")) -/obj/item/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) +/obj/item/gun/projectile/revolver/russian/afterattack(atom/target, mob/living/user, flag, params) if(flag) if(!(target in user.contents) && ismob(target)) if(user.a_intent == INTENT_HARM) // Flogging action @@ -313,19 +309,107 @@ origin_tech = null mag_type = /obj/item/ammo_box/magazine/internal/cylinder/cap -/obj/item/gun/projectile/revolver/improvisedrevolver - desc = "Weapon for crazy fun with friends" - name = "Improvised revolver" - icon_state = "makeshift_revik" - mag_type = /obj/item/ammo_box/magazine/internal/cylinder/improvisedrevolver - fire_sound = 'sound/weapons/gunshots/improvrev_shot.ogg' - -/obj/item/gun/projectile/revolver/improvisedrevolver/afterattack(atom/target, mob/living/user, flag, params) - if(prob(10)) - chamber_round(1) - user.visible_message(span_danger("*CRACK*")) - return +/obj/item/gun/projectile/revolver/improvised + name = "improvised revolver" + desc = "Weapon for crazy fun with friends." + icon_state = "irevolver" + item_state = "revolver" + mag_type = null + fire_sound = 'sound/weapons/gunshots/1rev257.ogg' + var/unscrewed = TRUE + var/obj/item/weaponcrafting/revolverbarrel/barrel + +/obj/item/gun/projectile/revolver/improvised/New() ..() + barrel = new // I just want it to spawn with barrel. + update_icon(UPDATE_OVERLAYS) + +/obj/item/gun/projectile/revolver/improvised/update_overlays() + . = ..() + if(magazine) + . += icon('icons/obj/weapons/projectile.dmi', magazine.icon_state) + if(barrel) + var/icon/barrel_icon = icon('icons/obj/weapons/projectile.dmi', barrel.icon_state) + if(unscrewed) + barrel_icon.Turn(-90) + barrel_icon.Shift(WEST, 5) + . += barrel_icon + +/obj/item/gun/projectile/revolver/improvised/afterattack(atom/target, mob/living/user, flag, params) + if(unscrewed) + shoot_with_empty_chamber() + else if(istype(barrel, /obj/item/weaponcrafting/revolverbarrel/steel) || prob(80)) + ..() + else + chamber_round(TRUE) + user.visible_message(span_dangerbigger("*CRACK*")) + playsound(user, 'sound/weapons/jammed.ogg', 140, TRUE) + +/obj/item/gun/projectile/revolver/improvised/proc/radial_menu(mob/user) + var/list/choices = list() + + if(barrel) + choices["Barrel"] = image(icon = barrel.icon, icon_state = barrel.icon_state) + if(magazine) + choices["Magazine"] = image(icon = magazine.icon, icon_state = magazine.icon_state) + var/choice = choices.len == 1 ? pick(choices) : show_radial_menu(user, src, choices, require_near = TRUE) + + if(!choice || loc != user) + return + + switch(choice) + if("Barrel") + if(!do_mob(user, src, 8 SECONDS)) + return + to_chat(user, span_notice("You unscrew [barrel] from [src].")) + user.put_in_hands(barrel) + barrel = null + if("Magazine") + to_chat(user, span_notice("You unscrew [magazine] from [src].")) + user.put_in_hands(magazine) + magazine = null + verbs -= /obj/item/gun/projectile/revolver/verb/spin + playsound(src, 'sound/items/screwdriver.ogg', 40, 1) + update_icon(UPDATE_OVERLAYS) + +/obj/item/gun/projectile/revolver/improvised/attack_hand(mob/user) + if(loc == user && unscrewed) + radial_menu(user) + else ..() + +/obj/item/gun/projectile/revolver/improvised/screwdriver_act(mob/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user, 8 SECONDS, volume = I.tool_volume)) + return + if(!magazine || !barrel) + to_chat(user, span_notice("You can't do it without cylinder and barrel, attached to revolver.")) + else + to_chat(user, span_notice("You [unscrewed ? "screwed [magazine] to the place" : "unscrewed [magazine] from [src]"].")) + unscrewed = !unscrewed + update_icon(UPDATE_OVERLAYS) + +/obj/item/gun/projectile/revolver/improvised/attackby(obj/item/A, mob/user, params) + if(unscrewed) + if(istype(A, /obj/item/ammo_box/magazine/internal/cylinder/improvised)) + if(magazine) + to_chat(user, span_notice("[src] already have [magazine].")) + else if(user.drop_transfer_item_to_loc(A, src)) + magazine = A + verbs += /obj/item/gun/projectile/revolver/verb/spin + update_icon(UPDATE_OVERLAYS) + playsound(src, 'sound/items/screwdriver.ogg', 40, 1) + else if(istype(A, /obj/item/weaponcrafting/revolverbarrel)) + if(barrel) + to_chat(user, span_notice("[src] already have [barrel].")) + else if(do_mob(user, src, 8 SECONDS)) + if(user.drop_transfer_item_to_loc(A, src)) + var/obj/item/weaponcrafting/revolverbarrel/new_barrel = A + barrel = A + fire_sound = new_barrel.new_fire_sound + update_icon(UPDATE_OVERLAYS) + playsound(src, 'sound/items/screwdriver.ogg', 40, 1) + else + return ..() ///////////////////////////// // DOUBLE BARRELED SHOTGUN // @@ -348,15 +432,15 @@ unique_rename = TRUE unique_reskin = TRUE -/obj/item/gun/projectile/revolver/doublebarrel/New() - ..() - options["Default"] = "dshotgun" - options["Dark Red Finish"] = "dshotgun-d" - options["Ash"] = "dshotgun-f" - options["Faded Grey"] = "dshotgun-g" - options["Maple"] = "dshotgun-l" - options["Rosewood"] = "dshotgun-p" - options["Cancel"] = null + +/obj/item/gun/projectile/revolver/doublebarrel/update_gun_skins() + add_skin("Default", "dshotgun") + add_skin("Dark Red Finish", "dshotgun-d") + add_skin("Ash", "dshotgun-f") + add_skin("Faded Grey", "dshotgun-g") + add_skin("Maple", "dshotgun-l") + add_skin("Rosewood", "dshotgun-p") + /obj/item/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_box/speedloader) || istype(A, /obj/item/ammo_casing)) @@ -376,7 +460,7 @@ /obj/item/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user) var/num_unloaded = 0 - while(get_ammo() > 0) + while(get_ammo(FALSE) > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null @@ -421,10 +505,10 @@ else return ..() -/obj/item/gun/projectile/revolver/doublebarrel/improvised/update_icon() - ..() - if(slung && (sawn_state == SAWN_INTACT)) - icon_state = "ishotgunsling" + +/obj/item/gun/projectile/revolver/doublebarrel/improvised/update_icon_state() + icon_state = "ishotgun[slung ? "sling" : sawn_state == SAWN_OFF ? "-sawn" : ""]" + /obj/item/gun/projectile/revolver/doublebarrel/improvised/sawoff(mob/user) . = ..() @@ -459,9 +543,12 @@ /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/is_crutch() return TRUE -/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon() +/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon_state() return +/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/update_overlays() + return list() + /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/stack/cable_coil)) return diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index 2debf7f8de9..44e0370556e 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -22,10 +22,12 @@ playsound(src, cover_open ? 'sound/weapons/gun_interactions/sawopen.ogg' : 'sound/weapons/gun_interactions/sawclose.ogg', 50, 1) update_icon() -/obj/item/gun/projectile/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]" + +/obj/item/gun/projectile/automatic/l6_saw/update_icon_state() + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(FALSE)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]" item_state = "l6[cover_open ? "openmag" : "closedmag"]" + /obj/item/gun/projectile/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!") @@ -131,8 +133,7 @@ origin_tech = "combat=4" ammo_type = /obj/item/ammo_casing/mm556x45/incen -/obj/item/ammo_box/magazine/mm556x45/update_icon() - ..() +/obj/item/ammo_box/magazine/mm556x45/update_icon_state() icon_state = "a762-[round(ammo_count(),10)]" //casings// diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 854a65a6ec0..9c696c06677 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -27,7 +27,7 @@ /obj/item/gun/projectile/shotgun/process_chamber() - return ..(0, 0) + return ..(FALSE, FALSE) /obj/item/gun/projectile/shotgun/chamber_round() return @@ -115,7 +115,7 @@ user.visible_message("The [src] goes click!", "The [src] you are holding goes click.") if(magazine.ammo_count()) //Spill the mag onto the floor user.visible_message("[user.name] opens [src] up and the shells go goes flying around!", "You open [src] up and the shells go goes flying everywhere!!") - while(get_ammo(0) > 0) + while(get_ammo(FALSE) > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) @@ -183,8 +183,7 @@ magazine.max_ammo = 6 update_icon() -/obj/item/gun/projectile/shotgun/riot/update_icon() //Can't use the old proc as it makes it go to riotshotgun-short_sawn - ..() +/obj/item/gun/projectile/shotgun/riot/update_icon_state() //Can't use the old proc as it makes it go to riotshotgun-short_sawn if(current_skin) icon_state = "[current_skin]" else @@ -193,8 +192,8 @@ /obj/item/gun/projectile/shotgun/riot/short mag_type = /obj/item/ammo_box/magazine/internal/shot/riot/short -/obj/item/gun/projectile/shotgun/riot/short/New() - ..() +/obj/item/gun/projectile/shotgun/riot/short/Initialize(mapload) + . = ..() post_sawoff() /obj/item/gun/projectile/shotgun/riot/buckshot //comes pre-loaded with buckshot rather than rubber @@ -225,10 +224,14 @@ else pump_unload(M) bolt_open = !bolt_open - icon_state = "moistnugget_open" - update_icon() //I.E. fix the desc + update_icon(UPDATE_ICON_STATE) return 1 + +/obj/item/gun/projectile/shotgun/boltaction/update_icon_state() + icon_state = "[initial(icon_state)][bolt_open ? "-open" : ""]" + + /obj/item/gun/projectile/shotgun/blow_up(mob/user) . = 0 if(chambered && chambered.BB) @@ -252,8 +255,8 @@ mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted can_bayonet = FALSE -/obj/item/gun/projectile/shotgun/boltaction/enchanted/New() - ..() +/obj/item/gun/projectile/shotgun/boltaction/enchanted/Initialize(mapload) + . = ..() bolt_open = 1 pump() @@ -328,8 +331,8 @@ var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine fire_sound = 'sound/weapons/gunshots/1shotgun_auto.ogg' -/obj/item/gun/projectile/shotgun/automatic/dual_tube/New() - ..() +/obj/item/gun/projectile/shotgun/automatic/dual_tube/Initialize(mapload) + . = ..() if(!alternate_magazine) alternate_magazine = new mag_type(src) diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 10c7f420836..77975abedd1 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -12,8 +12,8 @@ fire_delay = 40 burst_size = 1 origin_tech = "combat=7" - can_unsuppress = 1 - can_suppress = 1 + can_unsuppress = TRUE + can_suppress = TRUE w_class = WEIGHT_CLASS_NORMAL zoomable = TRUE zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. @@ -36,14 +36,10 @@ QDEL_NULL(magazine) magazine = new /obj/item/ammo_box/magazine/sniper_rounds/compact/penetrator(src) -/obj/item/gun/projectile/automatic/sniper_rifle/update_icon() - if(magazine) - icon_state = "sniper-mag" - else - icon_state = "sniper" - ..() - icon_state = "[initial(icon_state)][magazine ? "" : "-e"][suppressed ? "-suppressed" : ""]" - return + +/obj/item/gun/projectile/automatic/sniper_rifle/update_icon_state() + icon_state = "[initial(icon_state)][magazine ? "-mag" : ""][suppressed ? "-suppressed" : ""]" + /obj/item/gun/projectile/automatic/sniper_rifle/compact //holds very little ammo, lacks zooming, and bullets are primarily damage dealers, but the gun lacks the downsides of the full size rifle name = "compact sniper rifle" @@ -57,11 +53,6 @@ can_suppress = FALSE zoomable = FALSE -/obj/item/gun/projectile/automatic/sniper_rifle/compact/update_icon() - if(magazine) - icon_state = "snipercompact-mag" - else - icon_state = "snipercompact" //Normal Boolets /obj/item/ammo_box/magazine/sniper_rounds @@ -72,7 +63,7 @@ max_ammo = 5 caliber = ".50" -/obj/item/ammo_box/magazine/sniper_rounds/update_icon() +/obj/item/ammo_box/magazine/sniper_rounds/update_icon_state() if(ammo_count()) icon_state = "[initial(icon_state)]-ammo" else @@ -121,7 +112,7 @@ /obj/item/projectile/bullet/sniper/soporific armour_penetration = 0 - nodamage = 1 + nodamage = TRUE dismemberment = 0 weaken = 0 breakthings = FALSE @@ -272,13 +263,16 @@ max_ammo = 6 caliber = "foam_force_sniper" -/obj/item/ammo_box/magazine/toy/sniper_rounds/update_icon() - overlays.Cut() +/obj/item/ammo_box/magazine/toy/sniper_rounds/update_icon_state() + return + + +/obj/item/ammo_box/magazine/toy/sniper_rounds/update_overlays() + . = ..() var/ammo = ammo_count() - if(ammo && istype(contents[contents.len], /obj/item/ammo_casing/caseless/foam_dart/sniper/riot)) - overlays += image('icons/obj/weapons/ammo.dmi', icon_state = ".50mag-r") + if(ammo && istype(contents[length(contents)], /obj/item/ammo_casing/caseless/foam_dart/sniper/riot)) + . += ".50mag-r" else if(ammo) - overlays += image('icons/obj/weapons/ammo.dmi', icon_state = ".50mag-f") - else - icon_state = "[initial(icon_state)]" + . += ".50mag-f" + diff --git a/code/modules/projectiles/guns/projectile/toy.dm b/code/modules/projectiles/guns/projectile/toy.dm index 85de8d94e7e..92f29176be5 100644 --- a/code/modules/projectiles/guns/projectile/toy.dm +++ b/code/modules/projectiles/guns/projectile/toy.dm @@ -9,14 +9,12 @@ force = 0 throwforce = 0 burst_size = 3 - can_suppress = 0 - clumsy_check = 0 - needs_permit = 0 + can_suppress = FALSE + clumsy_check = FALSE + needs_permit = FALSE pickup_sound = 'sound/items/handling/generic_pickup1.ogg' drop_sound = 'sound/items/handling/generic_drop3.ogg' -/obj/item/gun/projectile/automatic/toy/process_chamber(eject_casing = 0, empty_chamber = 1) - ..() /obj/item/gun/projectile/automatic/toy/pistol name = "foam force pistol" @@ -26,23 +24,26 @@ can_holster = TRUE mag_type = /obj/item/ammo_box/magazine/toy/pistol fire_sound = 'sound/weapons/gunshots/gunshot.ogg' - can_suppress = 0 + can_suppress = FALSE burst_size = 1 fire_delay = 0 actions_types = null -/obj/item/gun/projectile/automatic/toy/pistol/update_icon() - ..() + +/obj/item/gun/projectile/automatic/toy/pistol/update_icon_state() icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + /obj/item/gun/projectile/automatic/toy/pistol/riot name = "foam force riot pistol" desc = "RIOT! Ages 8 and up." mag_type = /obj/item/ammo_box/magazine/toy/pistol/riot -/obj/item/gun/projectile/automatic/toy/pistol/riot/New() + +/obj/item/gun/projectile/automatic/toy/pistol/riot/Initialize(mapload) magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src) - ..() + . = ..() + /obj/item/gun/projectile/automatic/toy/pistol/enforcer name = "foam enforcer" @@ -50,15 +51,8 @@ icon_state = "enforcer" mag_type = /obj/item/ammo_box/magazine/toy/enforcer can_flashlight = TRUE + gun_light_overlay = "enforcer-light" -/obj/item/gun/projectile/automatic/toy/pistol/enforcer/update_icon() - ..() - overlays.Cut() - if(gun_light) - var/iconF = "Enforcer_light" - if(gun_light.on) - iconF = "Enforcer_light-on" - overlays += image(icon = 'icons/obj/weapons/projectile.dmi', icon_state = iconF, pixel_x = 0) /obj/item/gun/projectile/automatic/toy/pistol/enforcer/ui_action_click() toggle_gunlight() @@ -72,8 +66,8 @@ throwforce = 0 origin_tech = null mag_type = /obj/item/ammo_box/magazine/internal/shot/toy - clumsy_check = 0 - needs_permit = 0 + clumsy_check = FALSE + needs_permit = FALSE pickup_sound = 'sound/items/handling/generic_pickup1.ogg' drop_sound = 'sound/items/handling/generic_drop3.ogg' @@ -97,8 +91,8 @@ desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." icon = 'icons/obj/weapons/toy.dmi' fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg' - can_suppress = 0 - needs_permit = 0 + can_suppress = FALSE + needs_permit = FALSE mag_type = /obj/item/ammo_box/magazine/toy/smgm45 pickup_sound = 'sound/items/handling/generic_pickup1.ogg' drop_sound = 'sound/items/handling/generic_drop3.ogg' @@ -106,16 +100,13 @@ /obj/item/gun/projectile/automatic/c20r/toy/riot mag_type = /obj/item/ammo_box/magazine/toy/smgm45/riot -/obj/item/gun/projectile/automatic/c20r/toy/process_chamber(eject_casing = 0, empty_chamber = 1) - ..() - /obj/item/gun/projectile/automatic/l6_saw/toy name = "donksoft LMG" desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." icon = 'icons/obj/weapons/toy.dmi' fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg' - can_suppress = 0 - needs_permit = 0 + can_suppress = FALSE + needs_permit = FALSE mag_type = /obj/item/ammo_box/magazine/toy/m762 pickup_sound = 'sound/items/handling/generic_pickup1.ogg' drop_sound = 'sound/items/handling/generic_drop3.ogg' @@ -123,9 +114,6 @@ /obj/item/gun/projectile/automatic/l6_saw/toy/riot mag_type = /obj/item/ammo_box/magazine/toy/m762/riot -/obj/item/gun/projectile/automatic/l6_saw/toy/process_chamber(eject_casing = 0, empty_chamber = 1) - ..() - /obj/item/gun/projectile/shotgun/toy/tommygun name = "tommy gun" desc = "Looks almost like the real thing! Great for practicing Drive-bys. Ages 8 and up." @@ -148,11 +136,3 @@ pickup_sound = 'sound/items/handling/generic_pickup1.ogg' drop_sound = 'sound/items/handling/generic_drop3.ogg' -/obj/item/gun/projectile/automatic/sniper_rifle/toy/update_icon() - if(magazine) - icon_state = "sniper-mag" - else - icon_state = "sniper" - -/obj/item/gun/projectile/automatic/sniper_rifle/toy/process_chamber(eject_casing = 0, empty_chamber = 1) - ..() diff --git a/code/modules/projectiles/guns/rocket.dm b/code/modules/projectiles/guns/rocket.dm index f8418e7c214..44f9041e19a 100644 --- a/code/modules/projectiles/guns/rocket.dm +++ b/code/modules/projectiles/guns/rocket.dm @@ -24,9 +24,12 @@ rockets = null return ..() -/obj/item/gun/rocketlauncher/update_icon() +/obj/item/gun/throw/update_icon_state() return +/obj/item/gun/throw/update_overlays() + return list() + /obj/item/gun/rocketlauncher/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/ammo_casing/rocket)) if(rockets.len < max_rockets) diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 3c43ce33287..f5d849dcffb 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -14,8 +14,8 @@ var/list/syringes = list() var/max_syringes = 1 -/obj/item/gun/syringe/New() - ..() +/obj/item/gun/syringe/Initialize() + . = ..() chambered = new /obj/item/ammo_casing/syringegun(src) /obj/item/gun/syringe/process_chamber() diff --git a/code/modules/projectiles/guns/throw.dm b/code/modules/projectiles/guns/throw.dm index a778aed783b..8c68ed809fe 100644 --- a/code/modules/projectiles/guns/throw.dm +++ b/code/modules/projectiles/guns/throw.dm @@ -41,8 +41,6 @@ loaded_projectiles = null return ..() -/obj/item/gun/throw/update_icon() - return /obj/item/gun/throw/attackby(obj/item/I, mob/user, params) if(istype(I, valid_projectile_type) && !(I.flags & NODROP)) diff --git a/code/modules/projectiles/guns/throw/crossbow.dm b/code/modules/projectiles/guns/throw/crossbow.dm index 9f6867539ca..fe728437491 100644 --- a/code/modules/projectiles/guns/throw/crossbow.dm +++ b/code/modules/projectiles/guns/throw/crossbow.dm @@ -32,7 +32,8 @@ if(cell && severity) emp_act(severity) -/obj/item/gun/throw/crossbow/update_icon() + +/obj/item/gun/throw/crossbow/update_icon_state() if(!tension) if(!to_launch) icon_state = "[initial(icon_state)]" @@ -40,16 +41,18 @@ icon_state = "[initial(icon_state)]-nocked" else icon_state = "[initial(icon_state)]-drawn" - overlays.Cut() - var/bolt_type = "bolt" - if(to_launch) - if(tension) - bolt_type += "_tighten" - else - bolt_type += "_untighten" - var/obj/item/arrow/bolt = to_launch - bolt_type += "_[bolt.overlay_prefix]" - overlays += image('icons/obj/weapons/crossbow_rod.dmi', bolt_type) + + +/obj/item/gun/throw/crossbow/update_overlays() + . = ..() + + if(!to_launch) + return + + var/bolt_type = "bolt[tension ? "_tighten" : "_untighten"]" + var/obj/item/arrow/bolt = to_launch + bolt_type += "_[bolt.overlay_prefix]" + . += image('icons/obj/weapons/crossbow_rod.dmi', bolt_type) /obj/item/gun/throw/crossbow/examine(mob/user) @@ -251,7 +254,7 @@ /obj/item/arrow/rod/fire/attackby(obj/item/I, mob/user, params) . = ..() - if(istype(I, /obj/item/lighter) || istype(I, /obj/item/weldingtool)) + if(istype(I, /obj/item/lighter) || I.tool_behaviour == TOOL_WELDER) fire_up() /obj/item/arrow/rod/fire/proc/fire_up(mob/user) diff --git a/code/modules/projectiles/guns/throw/pielauncher.dm b/code/modules/projectiles/guns/throw/pielauncher.dm index 69dcc166aae..48c745c6b46 100644 --- a/code/modules/projectiles/guns/throw/pielauncher.dm +++ b/code/modules/projectiles/guns/throw/pielauncher.dm @@ -14,8 +14,8 @@ projectile_range = 30 -/obj/item/gun/throw/piecannon/New() - ..() +/obj/item/gun/throw/piecannon/Initialize() + . = ..() for(var/i in 1 to max_capacity) var/obj/item/reagent_containers/food/snacks/pie/P = new /obj/item/reagent_containers/food/snacks/pie(src) loaded_projectiles += P @@ -24,13 +24,15 @@ /obj/item/gun/throw/piecannon/notify_ammo_count() return "[src] has [get_ammocount()] of [max_capacity] pies left." -/obj/item/gun/throw/piecannon/update_icon() + +/obj/item/gun/throw/piecannon/update_icon_state() if(to_launch) icon_state = "piecannon1" else icon_state = "piecannon0" item_state = icon_state + /obj/item/gun/throw/piecannon/process_chamber() ..() update_icon() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 621ce8522c8..b2876fa131a 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -32,7 +32,7 @@ name = "practice laser" damage = 0 hitsound = 'sound/weapons/tap.ogg' - nodamage = 1 + nodamage = TRUE log_override = TRUE /obj/item/projectile/beam/scatter @@ -96,7 +96,7 @@ name = "laser tag beam" icon_state = "omnilaser" hitsound = 'sound/weapons/tap.ogg' - nodamage = 1 + nodamage = TRUE damage = 0 damage_type = STAMINA flag = "laser" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 9065de76d57..0af77055e59 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -59,7 +59,7 @@ /obj/item/projectile/bullet/weakbullet2/invisible/fake weaken = 0 stamina = 0 - nodamage = 1 + nodamage = TRUE log_override = TRUE /obj/item/projectile/bullet/weakbullet3 @@ -99,7 +99,7 @@ /obj/item/projectile/bullet/incendiary -/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) +/obj/item/projectile/bullet/incendiary/on_hit(atom/target, blocked = 0) . = ..() if(iscarbon(target)) var/mob/living/carbon/M = target @@ -160,7 +160,7 @@ ..() /obj/item/projectile/bullet/pellet/weak/on_range() - do_sparks(1, 1, src) + do_sparks(1, TRUE, src) ..() /obj/item/projectile/bullet/pellet/overload @@ -223,7 +223,7 @@ /obj/item/projectile/bullet/heavybullet damage = 35 -/obj/item/projectile/bullet/stunshot//taser slugs for shotguns, nothing special +/obj/item/projectile/bullet/stunshot //taser slugs for shotguns, nothing special name = "stunshot" damage = 5 weaken = 2 SECONDS @@ -264,7 +264,7 @@ weaken = 4 SECONDS hitsound = 'sound/effects/meteorimpact.ogg' -/obj/item/projectile/bullet/meteorshot/on_hit(var/atom/target, var/blocked = 0) +/obj/item/projectile/bullet/meteorshot/on_hit(atom/target, blocked = 0) ..() if(istype(target, /atom/movable)) var/atom/movable/M = target @@ -288,7 +288,7 @@ slur = 40 SECONDS stutter = 40 SECONDS -/obj/item/projectile/bullet/mime/on_hit(var/atom/target, var/blocked = 0) +/obj/item/projectile/bullet/mime/on_hit(atom/target, blocked = 0) ..(target, blocked) if(iscarbon(target)) var/mob/living/carbon/M = target @@ -298,7 +298,7 @@ chassis.occupant_message("A mimetech anti-honk bullet has hit \the [chassis]!") chassis.use_power(chassis.get_charge() / 2) for(var/obj/item/mecha_parts/mecha_equipment/weapon/honker in chassis.equipment) - honker.set_ready_state(0) + honker.set_ready_state(FALSE) /obj/item/projectile/bullet/dart name = "dart" @@ -311,7 +311,7 @@ create_reagents(50) reagents.set_reacting(FALSE) -/obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = 0, hit_zone) if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) @@ -319,15 +319,15 @@ ..() reagents.reaction(M, REAGENT_INGEST) reagents.trans_to(M, reagents.total_volume) - return 1 + return TRUE else blocked = 100 - target.visible_message("The [name] was deflected!", \ - "You were protected against the [name]!") + target.visible_message(span_danger("The [name] was deflected!"), \ + span_userdanger("You were protected against the [name]!")) ..(target, blocked, hit_zone) reagents.set_reacting(TRUE) reagents.handle_reactions() - return 1 + return TRUE /obj/item/projectile/bullet/dart/metalfoam @@ -356,18 +356,18 @@ damage_type = TOX weaken = 1 SECONDS -/obj/item/projectile/bullet/neurotoxin/on_hit(var/atom/target, var/blocked = 0) +/obj/item/projectile/bullet/neurotoxin/prehit(atom/target) if(isalien(target)) weaken = 0 - nodamage = 1 + nodamage = TRUE if(isobj(target) || issilicon(target) || ismachineperson(target)) damage_type = BURN - . = ..() // Execute the rest of the code. + . = ..() /obj/item/projectile/bullet/cap name = "cap" damage = 0 - nodamage = 1 + nodamage = TRUE /obj/item/projectile/bullet/cap/fire() loc = null @@ -386,3 +386,11 @@ /obj/item/projectile/bullet/weakbullet3/c257 damage = 20 + +/obj/item/projectile/bullet/weakbullet3/c257/phosphorus + +/obj/item/projectile/bullet/weakbullet3/c257/phosphorus/on_hit(atom/target, blocked, hit_zone) + do_sparks(rand(1, 3), FALSE, target) + if(..(target, blocked)) + var/mob/living/target_living = target + target_living.flash_eyes() diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 1299b5748a4..14c4068de4c 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -12,7 +12,7 @@ icon_state = "spark" color = "#FFFF00" shockbull = TRUE - nodamage = 1 + nodamage = TRUE weaken = 0.2 SECONDS stamina = 15 stutter = 8 SECONDS @@ -66,7 +66,7 @@ hitsound = 'sound/weapons/pierce.ogg' damage_type = TOX stamina = 40 - nodamage = 0 + nodamage = FALSE weaken = 3 SECONDS stutter = 2 SECONDS shockbull = TRUE diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 1345964c145..91c87435a7d 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -5,7 +5,7 @@ hitsound = 'sound/weapons/magic.ogg' hitsound_wall = 'sound/weapons/magic.ogg' damage_type = OXY - nodamage = 1 + nodamage = TRUE armour_penetration = 100 flag = "magic" @@ -18,7 +18,7 @@ icon_state = "fireball" damage = 10 damage_type = BRUTE - nodamage = 0 + nodamage = FALSE //explosion values var/exp_devastate = -1 @@ -210,7 +210,7 @@ Robot.mmi = new /obj/item/mmi/robotic_brain(new_mob) Robot.mmi.brainmob.timeofhostdeath = M.timeofdeath Robot.mmi.brainmob.stat = CONSCIOUS - Robot.mmi.become_occupied("boris") + Robot.mmi.update_appearance(UPDATE_ICON_STATE|UPDATE_NAME) Robot.lawupdate = FALSE Robot.disconnect_from_ai() Robot.clear_inherent_laws() @@ -379,7 +379,7 @@ flag = "magic" dismemberment = 50 dismember_head = TRUE - nodamage = 0 + nodamage = FALSE /obj/item/projectile/magic/slipping name = "magical banana" diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 8e510d3023a..f59f08e18b0 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -33,7 +33,7 @@ hitsound = 'sound/weapons/tap.ogg' hitsound_wall = 'sound/weapons/tap.ogg' damage_type = OXY - nodamage = 1 + nodamage = TRUE icon = 'icons/obj/weapons/toy.dmi' icon_state = "foamdart" ammo_type = /obj/item/ammo_casing/caseless/foam_dart diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 98ee94ae939..94fd63728d4 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -3,7 +3,7 @@ icon_state = "ion" damage = 0 damage_type = BURN - nodamage = 1 + nodamage = TRUE var/emp_range = 1 impact_effect_type = /obj/effect/temp_visual/impact_effect/ion flag = "energy" @@ -49,7 +49,7 @@ icon_state = "temp_4" damage = 0 damage_type = BURN - nodamage = 1 + nodamage = TRUE reflectability = REFLECTABILITY_ENERGY flag = "energy" var/temperature = 300 @@ -112,7 +112,7 @@ icon_state = "small" damage = 0 damage_type = BRUTE - nodamage = 1 + nodamage = TRUE flag = "bullet" /obj/item/projectile/meteor/Bump(atom/A, yes) @@ -133,7 +133,7 @@ damage = 0 hitsound = 'sound/weapons/tap.ogg' damage_type = TOX - nodamage = 1 + nodamage = TRUE impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser flag = "energy" @@ -167,7 +167,7 @@ damage = 0 hitsound = 'sound/weapons/tap.ogg' damage_type = TOX - nodamage = 1 + nodamage = TRUE flag = "energy" /obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0) @@ -299,7 +299,7 @@ name = "teleportation burst" icon_state = "bluespace" damage = 0 - nodamage = 1 + nodamage = TRUE var/teleport_target = null /obj/item/projectile/energy/teleport/New(loc, tele_target) @@ -353,7 +353,7 @@ name = "googly-eyed gun" hitsound = 'sound/weapons/genhit1.ogg' damage = 0 - nodamage = 1 + nodamage = TRUE damage_type = BURN flag = "melee" var/obj/item/gun/stored_gun diff --git a/code/modules/projectiles/sibyl/sibyl_system_mod.dm b/code/modules/projectiles/sibyl/sibyl_system_mod.dm index 381f7c52cf2..b5f11a252c8 100644 --- a/code/modules/projectiles/sibyl/sibyl_system_mod.dm +++ b/code/modules/projectiles/sibyl/sibyl_system_mod.dm @@ -80,7 +80,7 @@ GLOBAL_VAR_INIT(sibsys_automode, TRUE) auth_id = null weapon.update_icon() if(!silent && user) - to_chat(user, span_notice("Блокировка [weapon] включена")) + to_chat(user, span_notice("Блокировка [weapon] включена.")) return TRUE /obj/item/sibyl_system_mod/proc/unlock(mob/user, obj/item/card/id/ID) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index ac6c16325e5..aa632834112 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -813,34 +813,19 @@ trans_data["diseases"] = temp return trans_data -/datum/reagents/proc/generate_taste_message(minimum_percent = TASTE_SENSITIVITY_NORMAL) +/datum/reagents/proc/generate_taste_message(minimum_percent = TASTE_SENSITIVITY_NORMAL, mob/living/user) var/list/out = list() var/list/reagent_tastes = list() //in the form reagent_tastes["descriptor"] = strength //mobs should get this message when either they cannot taste, the tastes are all too weak for them to detect, or the tastes somehow don't have any strength var/no_taste_text = "something indescribable" if(minimum_percent > 100) return no_taste_text - for(var/A in reagent_list) - var/datum/reagent/R = A + for(var/datum/reagent/R in reagent_list) if(!R.taste_mult) continue - //nutriment carries a list of tastes that originates from the snack food that the nutriment came from - if(istype(R, /datum/reagent/consumable/nutriment)) - var/list/nutriment_taste_data = R.data - for(var/nutriment_taste in nutriment_taste_data) - var/ratio = nutriment_taste_data[nutriment_taste] - var/amount = ratio * R.taste_mult * R.volume - if(nutriment_taste in reagent_tastes) - reagent_tastes[nutriment_taste] += amount - else - reagent_tastes[nutriment_taste] = amount - else - var/taste_desc = R.taste_description - var/taste_amount = R.volume * R.taste_mult - if(taste_desc in reagent_tastes) - reagent_tastes[taste_desc] += taste_amount - else - reagent_tastes[taste_desc] = taste_amount + var/list/taste_amount = R.taste_amplification(user) + for(var/taste_desc in taste_amount) + reagent_tastes[taste_desc] += taste_amount[taste_desc] //deal with percentages //TODO: may want to sort these from strong to weak var/total_taste = counterlist_sum(reagent_tastes) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 24958ce108e..2269d2dcd48 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -1,3 +1,7 @@ +#define UPDATE_TYPE_HACK 1 +#define UPDATE_TYPE_COMPONENTS 2 + + /obj/machinery/chem_dispenser name = "chem dispenser" density = TRUE @@ -15,8 +19,9 @@ var/recharge_amount = 100 var/recharge_counter = 0 var/hackedcheck = FALSE + var/componentscheck = FALSE var/obj/item/reagent_containers/beaker = null - var/image/icon_beaker = null //cached overlay + var/mutable_appearance/icon_beaker //cached overlay var/list/dispensable_reagents = list("hydrogen", "lithium", "carbon", "nitrogen", "oxygen", "fluorine", "sodium", "aluminum", "silicon", "phosphorus", "sulfur", "chlorine", "potassium", "iron", "copper", "mercury", "plasma", "radium", "water", "ethanol", "sugar", "iodine", "bromine", "silver", "chromium") @@ -39,8 +44,8 @@ component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stack/sheet/glass(null) component_parts += new cell_type(null) - RefreshParts() dispensable_reagents = sortAssoc(dispensable_reagents) + RefreshParts() /obj/machinery/chem_dispenser/upgraded/New() ..() @@ -110,8 +115,8 @@ recharge_amount *= C.rating for(var/obj/item/stock_parts/manipulator/M in component_parts) if(M.rating > 3) - dispensable_reagents |= upgrade_reagents - dispensable_reagents = sortAssoc(dispensable_reagents) + componentscheck = TRUE + update_reagents(UPDATE_TYPE_COMPONENTS) powerefficiency = round(newpowereff, 0.01) /obj/machinery/chem_dispenser/Destroy() @@ -138,12 +143,6 @@ return recharge_counter++ -/obj/machinery/chem_dispenser/power_change() - if(powered()) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - stat |= NOPOWER /obj/machinery/chem_dispenser/ex_act(severity) if(severity < 3) @@ -155,7 +154,8 @@ ..() if(A == beaker) beaker = null - overlays.Cut() + update_icon(UPDATE_OVERLAYS) + /obj/machinery/chem_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) // update the ui if it exists, returns null if no ui is passed/found @@ -220,11 +220,7 @@ atom_say("Недостаточно энергии для завершения операции!") return R.add_reagent(params["reagent"], actual) - overlays.Cut() - if(!icon_beaker) - icon_beaker = mutable_appearance('icons/obj/chemical.dmi', "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10, 5) - overlays += icon_beaker + update_icon(UPDATE_OVERLAYS) if("remove") var/amount = text2num(params["amount"]) if(!beaker || !amount) @@ -244,7 +240,7 @@ if(Adjacent(usr) && !issilicon(usr)) usr.put_in_hands(beaker, ignore_anim = FALSE) beaker = null - overlays.Cut() + update_icon(UPDATE_OVERLAYS) else return FALSE @@ -270,13 +266,10 @@ to_chat(user, "[I] is stuck to you!") return add_fingerprint(user) - beaker = I + beaker = I to_chat(user, "You set [I] on the machine.") SStgui.update_uis(src) // update all UIs attached to src - if(!icon_beaker) - icon_beaker = mutable_appearance('icons/obj/chemical.dmi', "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10, 5) - overlays += icon_beaker + update_icon(UPDATE_OVERLAYS) return return ..() @@ -296,20 +289,30 @@ return ..() +/obj/machinery/chem_dispenser/proc/update_reagents(update_type) + switch(update_type) + if(UPDATE_TYPE_HACK) + if(hackedcheck) + dispensable_reagents += hacked_reagents + else + dispensable_reagents -= hacked_reagents + if(UPDATE_TYPE_COMPONENTS) + dispensable_reagents |= upgrade_reagents + + dispensable_reagents = sortAssoc(dispensable_reagents) + + /obj/machinery/chem_dispenser/multitool_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return - if(!hackedcheck) - to_chat(user, hack_message) - dispensable_reagents += hacked_reagents - hackedcheck = TRUE - else - to_chat(user, unhack_message) - dispensable_reagents -= hacked_reagents - hackedcheck = FALSE + + hackedcheck = !hackedcheck + to_chat(user, hackedcheck ? hack_message : unhack_message) + update_reagents(UPDATE_TYPE_HACK) SStgui.update_uis(src) + /obj/machinery/chem_dispenser/screwdriver_act(mob/user, obj/item/I) if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", "[initial(icon_state)]", I)) return TRUE @@ -343,6 +346,22 @@ add_fingerprint(user) ui_interact(user) + +/obj/machinery/chem_dispenser/update_overlays() + . = ..() + + if(!beaker) + return + + if(!icon_beaker) + icon_beaker = mutable_appearance(icon, "disp_beaker") + else + cut_overlay(icon_beaker) // trash overlays system. will be fixed as soon as TG style overlays are implemented + + icon_beaker.pixel_x = rand(-10, 5) // randomize beaker overlay position + . += icon_beaker + + /obj/machinery/chem_dispenser/soda icon_state = "soda_dispenser" name = "soda fountain" @@ -353,6 +372,7 @@ "watermelonjuice", "carrotjuice", "potato", "berryjuice") upgrade_reagents = list("bananahonk", "milkshake", "cafe_latte", "cafe_mocha", "triple_citrus", "icecoffe","icetea") hacked_reagents = list("thirteenloko") + var/list/hackedupgrade_reagents = list("zaza") hack_message = "You change the mode from 'McNano' to 'Pizza King'." unhack_message = "You change the mode from 'Pizza King' to 'McNano'." is_drink = TRUE @@ -381,6 +401,19 @@ component_parts += new cell_type(null) RefreshParts() + +/obj/machinery/chem_dispenser/soda/update_reagents(update_type) + if(update_type == UPDATE_TYPE_HACK && componentscheck) + if(hackedcheck) + dispensable_reagents += hackedupgrade_reagents + else + dispensable_reagents -= hackedupgrade_reagents + + else if(update_type == UPDATE_TYPE_COMPONENTS && hackedcheck) + dispensable_reagents += hackedupgrade_reagents + ..() + + /obj/machinery/chem_dispenser/beer icon_state = "booze_dispenser" name = "booze dispenser" @@ -388,7 +421,7 @@ desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." dispensable_reagents = list("ice", "cream", "cider", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequila", "vermouth", "cognac", "ale", "mead", "synthanol", "jagermeister", "bluecuracao", "sambuka", "schnaps", "sheridan") upgrade_reagents = list("iced_beer", "irishcream", "manhattan", "antihol", "synthignon", "bravebull") - hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing", "sake", "bitter", "champagne", "aperol", "alcohol_free_beer") + hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing", "sake", "bitter", "champagne", "aperol", "noalco_beer") hack_message = "You disable the 'nanotrasen-are-cheap-bastards' lock, enabling hidden and very expensive boozes." unhack_message = "You re-enable the 'nanotrasen-are-cheap-bastards' lock, disabling hidden and very expensive boozes." is_drink = TRUE @@ -472,7 +505,7 @@ cell = new(src) dispensable_reagents = sortList(dispensable_reagents) current_reagent = pick(dispensable_reagents) - update_icon() + update_icon(UPDATE_OVERLAYS) START_PROCESSING(SSobj, src) /obj/item/handheld_chem_dispenser/Destroy() @@ -496,7 +529,7 @@ cell.charge -= actual / efficiency if(actual) to_chat(user, "You dispense [amount] units of [current_reagent] into the [target].") - update_icon() + update_icon(UPDATE_OVERLAYS) if("remove") if(!target.reagents.remove_reagent(current_reagent, amount)) to_chat(user, "You remove [amount] units of [current_reagent] from the [target].") @@ -552,7 +585,7 @@ if("dispense") if(params["reagent"] in dispensable_reagents) current_reagent = params["reagent"] - update_icon() + update_icon(UPDATE_OVERLAYS) if("mode") switch(params["mode"]) if("remove") @@ -561,15 +594,15 @@ mode = "dispense" if("isolate") mode = "isolate" - update_icon() + update_icon(UPDATE_OVERLAYS) else return FALSE add_fingerprint(usr) -/obj/item/handheld_chem_dispenser/update_icon() - cut_overlays() +/obj/item/handheld_chem_dispenser/update_overlays() + . = ..() if(cell && cell.charge) var/image/power_light = image('icons/obj/chemical.dmi', src, "light_low") var/percent = round((cell.charge / cell.maxcharge) * 100) @@ -580,17 +613,17 @@ power_light.icon_state = "light_mid" if(67 to INFINITY) power_light.icon_state = "light_full" - add_overlay(power_light) + . += power_light var/image/mode_light = image('icons/obj/chemical.dmi', src, "light_remove") mode_light.icon_state = "light_[mode]" - add_overlay(mode_light) + . += mode_light var/image/chamber_contents = image('icons/obj/chemical.dmi', src, "reagent_filling") var/datum/reagent/R = GLOB.chemical_reagents_list[current_reagent] chamber_contents.icon += R.color - add_overlay(chamber_contents) - ..() + . += chamber_contents + /obj/item/handheld_chem_dispenser/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg if(isrobot(loc) && cell.charge < cell.maxcharge) @@ -600,7 +633,7 @@ R.cell.charge -= actual cell.charge += actual - update_icon() + update_icon(UPDATE_OVERLAYS) return TRUE /obj/item/handheld_chem_dispenser/attackby(obj/item/W, mob/user, params) @@ -616,7 +649,7 @@ return cell = W to_chat(user, "You install a cell in [src].") - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/handheld_chem_dispenser/screwdriver_act(mob/user, obj/item/I) if(!isrobot(loc) && cell) @@ -624,7 +657,7 @@ cell.loc = get_turf(src) cell = null to_chat(user, "You remove the cell from the [src].") - update_icon() + update_icon(UPDATE_OVERLAYS) return ..() @@ -636,7 +669,7 @@ dispensable_reagents = list("ice", "cream", "cider", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequila", "vermouth", "cognac", "ale", "mead", "synthanol", "jagermeister", "bluecuracao", "sambuka", "schnaps", "sheridan", "iced_beer", "irishcream", "manhattan", "antihol", "synthignon", "bravebull", "goldschlager", "patron", "absinthe", "ethanol", "nothing", - "sake", "bitter", "champagne", "aperol", "alcohol_free_beer") + "sake", "bitter", "champagne", "aperol", "noalco_beer") /obj/item/handheld_chem_dispenser/soda name = "handheld soda fountain" @@ -664,6 +697,7 @@ "ash", "diethylamine") + /obj/item/handheld_chem_dispenser/cooking name = "handheld cooking chemical dispenser" dispensable_reagents = list( @@ -671,3 +705,7 @@ "blackpepper", "ketchup", "herbsmix") + +#undef UPDATE_TYPE_HACK +#undef UPDATE_TYPE_COMPONENTS + diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index 502eca34007..c63bbea8df8 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -44,22 +44,22 @@ if(auto_eject) eject_beaker() + +/obj/machinery/chem_heater/update_icon_state() + icon_state = "mixer[beaker ? "1" : "0"]b" + + + /obj/machinery/chem_heater/proc/eject_beaker(mob/user) if(beaker) beaker.forceMove(get_turf(src)) if(user && Adjacent(user) && !issilicon(user)) user.put_in_hands(beaker, ignore_anim = FALSE) beaker = null - icon_state = "mixer0b" on = FALSE + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) -/obj/machinery/chem_heater/power_change() - if(powered()) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - stat |= NOPOWER /obj/machinery/chem_heater/attackby(obj/item/I, mob/user) if(isrobot(user)) @@ -74,7 +74,7 @@ add_fingerprint(user) beaker = I to_chat(user, "You add the beaker to the machine!") - icon_state = "mixer1b" + update_icon(UPDATE_ICON_STATE) SStgui.update_uis(src) return diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index add481a3d68..20f3c0a70ba 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -68,22 +68,23 @@ else if(A == loaded_pill_bottle) loaded_pill_bottle = null -/obj/machinery/chem_master/update_icon() - overlays.Cut() + +/obj/machinery/chem_master/update_icon_state() icon_state = "mixer[beaker ? "1" : "0"][powered() ? "" : "_nopower"]" + + +/obj/machinery/chem_master/update_overlays() + . = ..() if(powered()) - overlays += "waitlight" + . += "waitlight" /obj/machinery/chem_master/blob_act(obj/structure/blob/B) if(prob(50)) qdel(src) -/obj/machinery/chem_master/power_change() - if(powered()) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - stat |= NOPOWER +/obj/machinery/chem_master/power_change(forced = FALSE) + if(!..()) + return update_icon() /obj/machinery/chem_master/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 26013cb1f57..e530d77cf2f 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -2,7 +2,7 @@ name = "PanD.E.M.I.C 2200" desc = "Used to work with viruses." density = 1 - anchored = 1 + anchored = TRUE icon = 'icons/obj/chemical.dmi' icon_state = "mixer0" circuit = /obj/item/circuitboard/pandemic @@ -19,9 +19,8 @@ update_icon() /obj/machinery/computer/pandemic/set_broken() - icon_state = (beaker ? "mixer1_b" : "mixer0_b") - overlays.Cut() stat |= BROKEN + update_icon() /obj/machinery/computer/pandemic/proc/GetDiseaseByIndex(index) if(beaker?.reagents?.reagent_list.len) @@ -50,17 +49,19 @@ update_icon() playsound(loc, 'sound/machines/ping.ogg', 30, 1) -/obj/machinery/computer/pandemic/update_icon() + +/obj/machinery/computer/pandemic/update_icon_state() if(stat & BROKEN) - icon_state = (beaker ? "mixer1_b" : "mixer0_b") + icon_state = "mixer[beaker ? "1" : "0"]_b" return + icon_state = "mixer[beaker ? "1" : "0"][(powered()) ? "" : "_nopower"]" - icon_state = "mixer[(beaker)?"1":"0"][(powered()) ? "" : "_nopower"]" - if(wait) - overlays.Cut() - else - overlays += "waitlight" +/obj/machinery/computer/pandemic/update_overlays() + . = ..() + if(!(stat & BROKEN) && !wait) + . += "waitlight" + /obj/machinery/computer/pandemic/Topic(href, href_list) if(..()) @@ -211,6 +212,7 @@ P.populatefields() P.updateinfolinks() P.name = "Выпуск вируса «[D.name]»" + P.update_icon() printing = null /obj/machinery/computer/pandemic/attack_hand(mob/user) @@ -339,7 +341,7 @@ updateUsrDialog() icon_state = "mixer1" - else if(istype(I, /obj/item/screwdriver)) + else if(I.tool_behaviour == TOOL_SCREWDRIVER) if(beaker) add_fingerprint(user) beaker.forceMove(get_turf(src)) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index e8acaa151ca..d06d724d91a 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" layer = 2.9 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 100 @@ -131,13 +131,12 @@ /obj/machinery/reagentgrinder/handle_atom_del(atom/A) if(A == beaker) beaker = null - update_icon() + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/reagentgrinder/update_icon_state() + icon_state = "juicer[beaker ? "1" : "0"]" -/obj/machinery/reagentgrinder/update_icon() - if(beaker) - icon_state = "juicer1" - else - icon_state = "juicer0" /obj/machinery/reagentgrinder/crowbar_act(mob/user, obj/item/I) . = TRUE @@ -178,7 +177,7 @@ return FALSE add_fingerprint(user) beaker = I - update_icon() + update_icon(UPDATE_ICON_STATE) updateUsrDialog() return TRUE //no afterattack @@ -319,7 +318,7 @@ return beaker.loc = src.loc beaker = null - update_icon() + update_icon(UPDATE_ICON_STATE) updateUsrDialog() /obj/machinery/reagentgrinder/proc/eject() diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 30d56d3de88..d60fd19d753 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -292,3 +292,10 @@ if(M.healthdoll) M.healthdoll.cached_healthdoll_overlays.Cut() M.updatehealth("fakedeath reagent end") + + +/datum/reagent/proc/taste_amplification(mob/living/user) + . = list() + var/taste_desc = taste_description + var/taste_amount = volume * taste_mult + .[taste_desc] = taste_amount diff --git a/code/modules/reagents/chemistry/reagents/admin.dm b/code/modules/reagents/chemistry/reagents/admin.dm index 531abd930ff..95724270775 100644 --- a/code/modules/reagents/chemistry/reagents/admin.dm +++ b/code/modules/reagents/chemistry/reagents/admin.dm @@ -40,13 +40,14 @@ M.SetParalysis(0) M.SetSilence(0) M.SetHallucinate(0) + M.SetDeaf(0) REMOVE_TRAITS_NOT_IN(M, list(ROUNDSTART_TRAIT)) M.SetDizzy(0) M.SetDrowsy(0) M.SetStuttering(0) M.SetSlur(0) M.SetConfused(0) - M.SetSleeping(0, FALSE) + M.SetSleeping(0) M.SetJitter(0) for(var/thing in M.diseases) var/datum/disease/D = thing diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index b5a97d102cb..a953065bd2e 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -2230,7 +2230,7 @@ /datum/reagent/consumable/ethanol/trans_siberian_express/on_mob_life(mob/living/M) . = ..() - var/datum/language/rus_lang = GLOB.all_languages["Neo-Russkiya"] + var/datum/language/rus_lang = GLOB.all_languages[LANGUAGE_NEO_RUSSIAN] if((rus_lang in M.languages) && !(rus_lang in M.temporary_languages)) if(M.default_language != rus_lang) M.default_language = rus_lang diff --git a/code/modules/reagents/chemistry/reagents/drink_cold.dm b/code/modules/reagents/chemistry/reagents/drink_cold.dm index 09502b52b8b..965277784ea 100644 --- a/code/modules/reagents/chemistry/reagents/drink_cold.dm +++ b/code/modules/reagents/chemistry/reagents/drink_cold.dm @@ -177,3 +177,44 @@ /datum/reagent/consumable/drink/cold/rewriter/on_mob_life(mob/living/M) M.Jitter(10 SECONDS) return ..() + + +/datum/reagent/consumable/drink/cold/zaza + name = "Zaza" + description = "The sharp delicious smell of cherries emanates from the drink." + id = "zaza" + color = "#b10023" // rgb:177, 0, 35 + drink_icon = "zaza" + drink_name = "Zaza" + drink_desc = "A glass filled with cherry drink, for a great Zaza Friday." + taste_description = "delicious shugary water taste" + var/alternate_taste_description = "something messing flavor of this juice... just sugary water taste" + var/healamount = 0.5 + + +/datum/reagent/consumable/drink/cold/zaza/on_mob_life(mob/living/user) + var/update_flags = STATUS_UPDATE_NONE + if(ishuman(user) && prob(40)) + update_flags |= user.adjustBruteLoss(-healamount, FALSE) + update_flags |= user.adjustFireLoss(-healamount, FALSE) + return ..() | update_flags + + +/datum/reagent/consumable/drink/cold/zaza/taste_amplification(mob/living/user) + . = list() + var/taste_desc = ismindshielded(user) ? alternate_taste_description : taste_description + var/taste_amount = volume * taste_mult + .[taste_desc] = taste_amount + + +/datum/reagent/consumable/drink/cold/zaza/fizzy + description = "The sharp delicious smell of cherries emanates from the sparkling drink." + color = "#f30028" // rgb:243, 0, 40 + id = "zazafizzy" + drink_icon = "zaza_fizzy" + drink_desc = "A glass filled with cherry drink, for a great Zaza Friday. Now with bubbles!" + taste_description = "delicious fizzy water taste" + alternate_taste_description = "something messing flavor of this drink... just fizzy water taste" + healamount = 0.25 + + diff --git a/code/modules/reagents/chemistry/reagents/drinks.dm b/code/modules/reagents/chemistry/reagents/drinks.dm index 38fdc391dcd..edb8fe5b8e7 100644 --- a/code/modules/reagents/chemistry/reagents/drinks.dm +++ b/code/modules/reagents/chemistry/reagents/drinks.dm @@ -536,7 +536,7 @@ /datum/reagent/consumable/drink/non_alcoholic_beer name = "Non-alcoholic beer" - id = "alcohol_free_beer" + id = "noalco_beer" description = "The most meaningless thing." drink_icon = "alcohol_free_beer" drink_name = "Non-alcoholic beer" diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm index eed5157a877..a0376503b55 100644 --- a/code/modules/reagents/chemistry/reagents/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -708,6 +708,7 @@ M.emote("laugh") return list(effect, update_flags) + /datum/reagent/rotatium //Rotatium. Fucks up your rotation and is hilarious name = "Rotatium" id = "rotatium" @@ -717,23 +718,26 @@ metabolization_rate = 0.6 * REAGENTS_METABOLISM taste_description = "spinning" + /datum/reagent/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) if(current_cycle >= 20 && current_cycle % 20 == 0) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] var/rotation = min(round(current_cycle / 20), 89) // By this point the player is probably puking and quitting anyway - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() + /datum/reagent/rotatium/on_mob_delete(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) - animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING) + if(M?.hud_used) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(), time = 5, easing = QUAD_EASING) ..() + ////////////////////////////// // laughter // ////////////////////////////// diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index be474044f91..b4eef2c4be7 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -55,6 +55,16 @@ counterlist_normalise(taste_amounts) data = taste_amounts + +/datum/reagent/consumable/nutriment/taste_amplification(mob/living/user) + . = list() + var/list/nutriment_taste_data = data + for(var/nutriment_taste in nutriment_taste_data) + var/ratio = nutriment_taste_data[nutriment_taste] + var/amount = ratio * taste_mult * volume + .[nutriment_taste] = amount + + /datum/reagent/consumable/nutriment/protein // Meat-based protein, digestable by carnivores and omnivores, worthless to herbivores name = "Protein" id = "protein" diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index a7e149d608d..dbbaca3098d 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -716,5 +716,5 @@ /datum/reagent/monkeylanguage/on_mob_life(mob/living/M) if(volume > 4) - M.add_language("Chimpanzee") + M.add_language(LANGUAGE_MONKEY_HUMAN) return ..() diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index 59fc5d732cf..2e148189797 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -209,9 +209,8 @@ if(!S.reagents) S.create_reagents(volume) S.reagents.add_reagent("thermite", volume) - S.thermite = TRUE - S.overlays.Cut() - S.overlays += image('icons/effects/effects.dmi', icon_state = "thermite") + S.melting_olay = mutable_appearance('icons/effects/effects.dmi', icon_state = "thermite") + S.add_overlay(S.melting_olay) if(S.active_hotspot) S.reagents.temperature_reagents(S.active_hotspot.temperature, 10, 300) diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index a65eb53ddd3..2cfa3145972 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -1356,3 +1356,26 @@ if(prob(25)) M.fakevomit(1) return ..() | update_flags + +/datum/reagent/metalic_dust + name = "Metalic dust" + id = "metalicdust" + description = "Metal dust with large pieces of various metals and technical liquids." + reagent_state = SOLID + color = "#353434" + process_flags = ORGANIC | SYNTHETIC + metabolization_rate = 5 + taste_description = span_warning("METAL DUST OH GOD") + +/datum/reagent/metalic_dust/on_mob_life(mob/living/M) + M.emote("scream") + to_chat(M, span_warning("OH SHIT!!!!")) + M.AdjustWeakened(2 SECONDS) + M.EyeBlurry(1 SECONDS) + M.adjustBruteLoss(rand(5, 10)) + if(iscarbon(M)) + var/mob/living/carbon/C = M + for(var/obj/item/organ/internal/organ in C.get_organs_zone(BODY_ZONE_PRECISE_GROIN)) + organ.receive_damage(rand(5, 10)) + + return ..() diff --git a/code/modules/reagents/chemistry/recipes/drinks.dm b/code/modules/reagents/chemistry/recipes/drinks.dm index 53149815ad4..b1729146753 100644 --- a/code/modules/reagents/chemistry/recipes/drinks.dm +++ b/code/modules/reagents/chemistry/recipes/drinks.dm @@ -1475,3 +1475,12 @@ required_reagents = list("trinary" = 1, "codelibre" = 1, "rewriter" = 1, "irishempbomb" = 1, "synthanol" = 1 ) result_amount = 5 mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + + +/datum/chemical_reaction/zaza_fizzy + name = "Fizzy Zaza" + id = "zazafizzy" + result = "zazafizzy" + required_reagents = list("zaza" = 1, "sodawater" = 1) + result_amount = 2 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' diff --git a/code/modules/reagents/chemistry/recipes/food.dm b/code/modules/reagents/chemistry/recipes/food.dm index f559864486e..b30e08272c8 100644 --- a/code/modules/reagents/chemistry/recipes/food.dm +++ b/code/modules/reagents/chemistry/recipes/food.dm @@ -56,6 +56,7 @@ for(var/i = 1, i <= created_volume, i++) new /obj/item/reagent_containers/food/snacks/sliceable/cheesewheel(location) +/* /datum/chemical_reaction/syntiflesh name = "Syntiflesh" id = "syntiflesh" @@ -67,6 +68,7 @@ var/location = get_turf(holder.my_atom) for(var/i = 1, i <= created_volume, i++) new /obj/item/reagent_containers/food/snacks/meat/syntiflesh(location) +*/ /datum/chemical_reaction/hot_ramen name = "Hot Ramen" diff --git a/code/modules/reagents/reagent_containers/applicator.dm b/code/modules/reagents/reagent_containers/applicator.dm index 4e5e6a2671c..dba8e549abc 100644 --- a/code/modules/reagents/reagent_containers/applicator.dm +++ b/code/modules/reagents/reagent_containers/applicator.dm @@ -44,16 +44,15 @@ visible_message("[src] identifies and removes a harmful substance.") update_icon() -/obj/item/reagent_containers/applicator/update_icon() - if(applying) - icon_state = "mender-active" - else - icon_state = "mender" - cut_overlays() + +/obj/item/reagent_containers/applicator/update_icon_state() + icon_state = "mender[applying ? "-active" : ""]" + + +/obj/item/reagent_containers/applicator/update_overlays() + . = ..() if(reagents.total_volume) - var/mutable_appearance/filling = mutable_appearance('icons/goonstation/objects/objects.dmi', "mender-fluid") - filling.color = mix_color_from_reagents(reagents.reagent_list) - add_overlay(filling) + . += mutable_appearance('icons/goonstation/objects/objects.dmi', "mender-fluid", color = mix_color_from_reagents(reagents.reagent_list)) var/reag_pct = round((reagents.total_volume / volume) * 100) var/mutable_appearance/applicator_bar = mutable_appearance('icons/goonstation/objects/objects.dmi', "app_e") switch(reag_pct) @@ -63,7 +62,8 @@ applicator_bar.icon_state = "app_he" if(0) applicator_bar.icon_state = "app_e" - add_overlay(applicator_bar) + . += applicator_bar + /obj/item/reagent_containers/applicator/attack(mob/living/M, mob/user) if(!reagents.total_volume) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 5dc907fbd58..1daf2b9acac 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -13,12 +13,12 @@ volume = 30 /obj/item/reagent_containers/glass/bottle/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/reagent_containers/glass/bottle/update_icon() - overlays.Cut() - underlays.Cut() +/obj/item/reagent_containers/glass/bottle/update_overlays() + . = ..() + underlays.Cut() if(reagents.total_volume) var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") @@ -39,8 +39,8 @@ underlays += filling if(!is_open_container()) - var/image/lid = image(icon, src, "lid_bottle") - overlays += lid + . += "lid_[icon_state]" + /obj/item/reagent_containers/glass/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user) if(!reagents.total_volume) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 1c9162c7280..59b3d19cfdc 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -12,11 +12,14 @@ volume = 5 pass_open_check = TRUE + +/obj/item/reagent_containers/dropper/update_icon_state() + icon_state = "[initial(icon_state)][reagents.total_volume ? "1" : ""]" + + /obj/item/reagent_containers/dropper/on_reagent_change() - if(!reagents.total_volume) - icon_state = "[initial(icon_state)]" - else - icon_state = "[initial(icon_state)]1" + update_icon(UPDATE_ICON_STATE) + /obj/item/reagent_containers/dropper/attack(mob/living/M, mob/living/user, def_zone) return diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index c2dd438a304..dd2db154c12 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -14,6 +14,7 @@ container_type = OPENCONTAINER has_lid = TRUE resistance_flags = ACID_PROOF + blocks_emissive = FALSE var/label_text = "" /obj/item/reagent_containers/glass/New() @@ -25,6 +26,8 @@ if(get_dist(user, src) <= 2 && !is_open_container()) . += "Airtight lid seals it completely." + . += "[src] can hold up to [reagents.maximum_volume] units." + /obj/item/reagent_containers/glass/attack(mob/M, mob/user, def_zone) if(!is_open_container()) return ..() @@ -115,21 +118,28 @@ /obj/item/reagent_containers/glass/beaker name = "beaker" - desc = "A beaker. Can hold up to 50 units." + desc = "A simple glass beaker, nothing special." icon = 'icons/obj/chemical.dmi' icon_state = "beaker" item_state = "beaker" belt_icon = "beaker" materials = list(MAT_GLASS=500) var/obj/item/assembly_holder/assembly = null - var/can_assembly = 1 + var/can_assembly = TRUE + + +/obj/item/reagent_containers/glass/beaker/examine(mob/user) + . = ..() + if(assembly) + . += "There is an [assembly] attached to it, use a screwdriver to remove it." + /obj/item/reagent_containers/glass/beaker/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/reagent_containers/glass/beaker/update_icon() - overlays.Cut() +/obj/item/reagent_containers/glass/beaker/update_overlays() + . = ..() if(reagents.total_volume) var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") @@ -151,14 +161,16 @@ filling.icon_state = "[icon_state]100" filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling + . += filling if(!is_open_container()) - var/image/lid = image(icon, src, "lid_[initial(icon_state)]") - overlays += lid + . += "lid_[initial(icon_state)]" + if(blocks_emissive == FALSE) + . += emissive_blocker(icon, "lid_[initial(icon_state)]") + if(assembly) - overlays += "assembly" - ..() + . += "assembly" + /obj/item/reagent_containers/glass/beaker/verb/remove_assembly() set name = "Remove Assembly" @@ -172,26 +184,29 @@ usr.put_in_hands(assembly, ignore_anim = FALSE) assembly = null qdel(GetComponent(/datum/component/proximity_monitor)) - update_icon() + update_icon(UPDATE_OVERLAYS) else to_chat(usr, "There is no assembly to remove.") + /obj/item/reagent_containers/glass/beaker/proc/heat_beaker() if(reagents) reagents.temperature_reagents(4000) + /obj/item/reagent_containers/glass/beaker/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/assembly_holder) && can_assembly) if(assembly) to_chat(usr, "[src] already has an assembly.") return ..() - assembly = W - user.drop_transfer_item_to_loc(W, src) - if(assembly.has_prox_sensors()) - AddComponent(/datum/component/proximity_monitor) - overlays += "assembly" - else - ..() + if(user.drop_transfer_item_to_loc(W, src)) + if(assembly.has_prox_sensors()) + AddComponent(/datum/component/proximity_monitor) + assembly = W + update_icon(UPDATE_OVERLAYS) + return ..() + return ..() + /obj/item/reagent_containers/glass/beaker/HasProximity(atom/movable/AM) if(assembly) @@ -215,7 +230,7 @@ /obj/item/reagent_containers/glass/beaker/large name = "large beaker" - desc = "A large beaker. Can hold up to 100 units." + desc = "A large glass beaker with twice the capacity of a normal beaker." icon_state = "beakerlarge" belt_icon = "large_beaker" materials = list(MAT_GLASS=2500) @@ -226,7 +241,7 @@ /obj/item/reagent_containers/glass/beaker/vial name = "vial" - desc = "A small glass vial. Can hold up to 25 units." + desc = "A small glass vial, often used by virologists of the 25th century." icon_state = "vial" belt_icon = "vial" materials = list(MAT_GLASS=250) @@ -238,7 +253,7 @@ /obj/item/reagent_containers/glass/beaker/drugs name = "baggie" - desc = "A baggie. Can hold up to 10 units." + desc = "A small plastic baggie, often used by pharmaceutical \"entrepreneurs\"." icon_state = "baggie" amount_per_transfer_from_this = 2 possible_transfer_amounts = null @@ -248,24 +263,25 @@ /obj/item/reagent_containers/glass/beaker/thermite name = "Thermite load" - desc = "A baggie. Can hold up to 20 units." + desc = "A baggie loaded with combustible chemicals." icon_state = "baggie" - amount_per_transfer_from_this = 20 + amount_per_transfer_from_this = 25 possible_transfer_amounts = null - volume = 20 + volume = 25 container_type = OPENCONTAINER can_assembly = 0 - list_reagents = list("thermite" = 20) + list_reagents = list("thermite" = 25) /obj/item/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" - desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." + desc = "A cryostasis beaker that allows for chemical storage without reactions." icon_state = "beakernoreact" materials = list(MAT_METAL=3000) volume = 50 amount_per_transfer_from_this = 10 origin_tech = "materials=2;engineering=3;plasmatech=3" container_type = OPENCONTAINER + blocks_emissive = EMISSIVE_BLOCK_GENERIC /obj/item/reagent_containers/glass/beaker/noreact/New() ..() @@ -273,13 +289,14 @@ /obj/item/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" - desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." + desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete." icon_state = "beakerbluespace" materials = list(MAT_GLASS=3000) volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50,100,300) container_type = OPENCONTAINER + blocks_emissive = EMISSIVE_BLOCK_GENERIC origin_tech = "bluespace=5;materials=4;plasmatech=4" /obj/item/reagent_containers/glass/beaker/cryoxadone @@ -311,14 +328,17 @@ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head slot_flags = SLOT_HEAD resistance_flags = NONE + blocks_emissive = EMISSIVE_BLOCK_GENERIC container_type = OPENCONTAINER var/paintable = TRUE + /obj/item/reagent_containers/glass/bucket/Initialize(mapload) . = ..() if(!color && paintable) color = "#0085E5" - update_icon() //in case bucket's color has been changed in editor or by some deriving buckets + update_icon(UPDATE_OVERLAYS) //in case bucket's color has been changed in editor or by some deriving buckets + /obj/item/reagent_containers/glass/bucket/attackby(obj/D, mob/user, params) . = ..() @@ -326,18 +346,18 @@ var/obj/item/toy/crayon/spraycan/can = D if(!can.capped && Adjacent(can, 1)) color = can.colour - update_icon() + update_icon(UPDATE_OVERLAYS) -/obj/item/reagent_containers/glass/bucket/update_icon() + +/obj/item/reagent_containers/glass/bucket/update_overlays() . = ..() - overlays.Cut() if(color) var/mutable_appearance/bucket_mask = mutable_appearance(icon='icons/obj/janitor.dmi', icon_state = "bucket_mask") - overlays += bucket_mask + . += bucket_mask + + var/mutable_appearance/bucket_hand = mutable_appearance(icon='icons/obj/janitor.dmi', icon_state = "bucket_hand", appearance_flags = RESET_COLOR) + . += bucket_hand - var/mutable_appearance/bucket_hand = mutable_appearance(icon='icons/obj/janitor.dmi', icon_state = "bucket_hand") - bucket_hand.appearance_flags |= RESET_COLOR - overlays += bucket_hand /obj/item/reagent_containers/glass/bucket/wooden name = "wooden bucket" @@ -348,9 +368,10 @@ resistance_flags = FLAMMABLE paintable = FALSE -/obj/item/reagent_containers/glass/bucket/wooden/update_icon() - . = ..() - overlays.Cut() + +/obj/item/reagent_containers/glass/bucket/wooden/update_overlays() + return + /obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot, initial) . = ..() @@ -360,6 +381,7 @@ reagents.reaction(user, REAGENT_TOUCH) reagents.clear_reagents() + /obj/item/reagent_containers/glass/bucket/attackby(obj/D, mob/user, params) if(istype(D, /obj/item/mop)) var/obj/item/mop/m = D diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index fd3a0a9e271..d1c5ca60344 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -269,13 +269,14 @@ return ..() spent = TRUE - update_icon() + update_icon(UPDATE_ICON_STATE) return TRUE -/obj/item/reagent_containers/hypospray/autoinjector/update_icon() - if(spent) - if(icon_state != "[icon_state]0") - icon_state = "[icon_state]0" + +/obj/item/reagent_containers/hypospray/autoinjector/update_icon_state() + var/real_state = replacetext(icon_state, "0", "") // we need to do this since customization is available + icon_state = "[real_state][spent ? "0" : ""]" + /obj/item/reagent_containers/hypospray/autoinjector/examine() . = ..() diff --git a/code/modules/reagents/reagent_containers/iv_bag.dm b/code/modules/reagents/reagent_containers/iv_bag.dm index 798fb060ac1..62c181cc27f 100644 --- a/code/modules/reagents/reagent_containers/iv_bag.dm +++ b/code/modules/reagents/reagent_containers/iv_bag.dm @@ -25,24 +25,24 @@ return ..() /obj/item/reagent_containers/iv_bag/on_reagent_change() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/pickup(mob/user) . = ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/dropped(mob/user, silent = FALSE) ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/attack_self(mob/user) ..() mode = !mode - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/attack_hand() ..() - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/proc/begin_processing(mob/target) injection_target = target @@ -74,13 +74,13 @@ var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) //The amount of reagents we'll transfer to the person reagents.reaction(injection_target, REAGENT_INGEST, fraction) //React the amount we're transfering. reagents.trans_to(injection_target, amount_per_transfer_from_this) - update_icon() + update_icon(UPDATE_OVERLAYS) else // Drawing if(reagents.total_volume < reagents.maximum_volume) injection_target.transfer_blood_to(src, amount_per_transfer_from_this) for(var/datum/reagent/x in injection_target.reagents.reagent_list) // Pull small amounts of reagents from the person while drawing blood injection_target.reagents.trans_to(src, amount_per_transfer_from_this/10) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/reagent_containers/iv_bag/attack(mob/living/M, mob/living/user, def_zone) return @@ -139,24 +139,24 @@ return -/obj/item/reagent_containers/iv_bag/update_icon() - overlays.Cut() - +/obj/item/reagent_containers/iv_bag/update_overlays() + . = ..() if(reagents.total_volume) var/percent = round((reagents.total_volume / volume) * 10) // We round the 1's place off of our percent for easy image processing. var/image/filling = image('icons/goonstation/objects/iv.dmi', src, "[icon_state][percent]") filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling + . += filling if(ismob(loc)) switch(mode) if(IV_DRAW) - overlays += "draw" + . += "draw" if(IV_INJECT) - overlays += "inject" + . += "inject" + /obj/item/reagent_containers/iv_bag/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/pen) || istype(I, /obj/item/flashlight/pen)) + if(is_pen(I) || istype(I, /obj/item/flashlight/pen)) rename_interactive(user, I) // PRE-FILLED IV BAGS BELOW @@ -177,6 +177,7 @@ if(blood_type != null && blood_species != null) name = "[initial(name)] - [blood_type] - [blood_species]" reagents.add_reagent("blood", 200, list("donor"=null,"diseases"=null,"blood_DNA"=null,"blood_type"=blood_type,"blood_species"=blood_species,"resistances"=null,"trace_chem"=null)) + update_icon(UPDATE_OVERLAYS) . = ..() @@ -250,6 +251,8 @@ /obj/item/reagent_containers/iv_bag/bloodsynthetic/oxygenis/Initialize(mapload) if(blood_type != null && blood_species != null) reagents.add_reagent("sbloodoxy", 200, list("donor"=null,"diseases"=null,"blood_DNA"=null,"blood_type"=blood_type,"blood_species"=blood_species,"resistances"=null,"trace_chem"=null)) + update_icon(UPDATE_OVERLAYS) + . = ..() /obj/item/reagent_containers/iv_bag/bloodsynthetic/nitrogenis @@ -259,6 +262,7 @@ /obj/item/reagent_containers/iv_bag/bloodsynthetic/nitrogenis/Initialize(mapload) if(blood_type != null && blood_species != null) reagents.add_reagent("sbloodvox", 200, list("donor"=null,"diseases"=null,"blood_DNA"=null,"blood_type"=blood_type,"blood_species"=blood_species,"resistances"=null,"trace_chem"=null)) + update_icon(UPDATE_OVERLAYS) . = ..() /obj/item/reagent_containers/iv_bag/slime diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index edbe5cf42de..731929f2548 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -205,7 +205,7 @@ -/obj/item/reagent_containers/spray/chemsprayer/attack_self(var/mob/user) +/obj/item/reagent_containers/spray/chemsprayer/attack_self(mob/user) amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10) to_chat(user, "You adjust the output switch. You'll now use [amount_per_transfer_from_this] units per spray.") diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index acaf54f158e..0481068d9c0 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -148,29 +148,35 @@ mode = SYRINGE_DRAW update_icon() -/obj/item/reagent_containers/syringe/update_icon() - cut_overlays() + +/obj/item/reagent_containers/syringe/update_icon_state() var/rounded_vol - if(reagents && reagents.total_volume) + if(reagents?.total_volume) rounded_vol = clamp(round((reagents.total_volume / volume * 15), 5), 1, 15) - var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]") - filling_overlay.icon += mix_color_from_reagents(reagents.reagent_list) - add_overlay(filling_overlay) else rounded_vol = 0 icon_state = "[rounded_vol]" item_state = "syringe_[rounded_vol]" + + +/obj/item/reagent_containers/syringe/update_overlays() + . = ..() + var/rounded_vol + if(reagents && reagents.total_volume) + rounded_vol = clamp(round((reagents.total_volume / volume * 15), 5), 1, 15) + var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]") + filling_overlay.icon += mix_color_from_reagents(reagents.reagent_list) + . += filling_overlay if(ismob(loc)) - var/mob/M = loc var/injoverlay switch(mode) if(SYRINGE_DRAW) injoverlay = "draw" if(SYRINGE_INJECT) injoverlay = "inject" - add_overlay(injoverlay) - M.update_inv_l_hand() - M.update_inv_r_hand() + . += injoverlay + update_equipped_item() + /obj/item/reagent_containers/syringe/antiviral name = "Syringe (spaceacillin)" diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index fbd83bcaeae..474e1f7554e 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "watertank" density = 1 - anchored = 0 + anchored = FALSE pressure_resistance = 2*ONE_ATMOSPHERE container_type = DRAINABLE | AMOUNT_VISIBLE max_integrity = 300 @@ -205,7 +205,7 @@ name = "pepper spray refiller" desc = "Contains condensed capsaicin for use in law \"enforcement.\"" icon_state = "pepper" - anchored = 1 + anchored = TRUE density = 0 reagent_id = "condensedcapsaicin" @@ -214,7 +214,7 @@ desc = "A machine that dispenses liquid to drink." icon = 'icons/obj/machines/vending.dmi' icon_state = "water_cooler" - anchored = 1 + anchored = TRUE tank_volume = 500 reagent_id = "water" var/paper_cups = 25 //Paper cups left from the cooler @@ -281,7 +281,7 @@ name = "virus food dispenser" desc = "A dispenser of low-potency virus mutagenic." icon_state = "virus_food" - anchored = 1 + anchored = TRUE density = 0 reagent_id = "virusfood" @@ -289,14 +289,14 @@ name = "space cleaner refiller" desc = "Refills space cleaner bottles." icon_state = "cleaner" - anchored = 1 + anchored = TRUE density = 0 tank_volume = 5000 reagent_id = "cleaner" /obj/structure/reagent_dispensers/fueltank/chem icon_state = "fuel_chem" - anchored = 1 + anchored = TRUE density = 0 accepts_rig = 0 tank_volume = 1000 diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index a5d2ebcdc65..93f1bae3e2d 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -41,8 +41,7 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) update_move_direction() for(var/I in GLOB.conveyor_switches) var/obj/machinery/conveyor_switch/S = I - if(id == S.id) - S.conveyors += src + S.link_conveyers(src) /obj/machinery/conveyor/Destroy() GLOB.conveyor_belts -= src @@ -96,8 +95,7 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) add_fingerprint(user) user.Move_Pulled(src) -/obj/machinery/conveyor/update_icon() - ..() +/obj/machinery/conveyor/update_icon_state() if(IS_OPERATING) icon_state = "conveyor_started_[clockwise ? "cw" : "ccw"]" if(reversed) @@ -170,10 +168,13 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) dir = turn(dir, -45) clockwise = FALSE -/obj/machinery/conveyor/power_change() - ..() + +/obj/machinery/conveyor/power_change(forced = FALSE) + if(!..()) + return update_icon() + /obj/machinery/conveyor/process() if(!IS_OPERATING) return @@ -213,7 +214,7 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) return var/move_time = 0 - if (slow_factor>1) // yes, 1 is special + if(slow_factor>1) // yes, 1 is special move_time=CEILING(slow_factor, 2) // yes. AM.Move(get_step(loc, forwards), forwards, move_time) @@ -265,6 +266,7 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) var/reversed = TRUE // If we're in neutral, would we go forwards or backwards next? var/slow_factor = 1 // How slow the belts should go. Gets copied into connected belts slow_factor. + /obj/machinery/conveyor_switch/New(newloc, new_id) ..(newloc) GLOB.conveyor_switches += src @@ -272,27 +274,42 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) id = new_id for(var/I in GLOB.conveyor_belts) var/obj/machinery/conveyor/C = I - if(C.id == id) - conveyors += C + link_conveyers(C) + + +/obj/machinery/conveyor_switch/proc/link_conveyers(obj/machinery/conveyor/C) + if(C.id != id) + return + conveyors += C + RegisterSignal(C, COMSIG_PARENT_QDELETING, PROC_REF(unlink_conveyer)) // so it GCs properly + + +/obj/machinery/conveyor_switch/proc/unlink_conveyer(obj/machinery/conveyor/C) + conveyors -= C + /obj/machinery/conveyor_switch/Destroy() GLOB.conveyor_switches -= src return ..() -// update the icon depending on the position -/obj/machinery/conveyor_switch/update_icon() - overlays.Cut() +// update the icon depending on the position +/obj/machinery/conveyor_switch/update_icon_state() if(!position) icon_state = "switch-off" else if(position == DIRECTION_REVERSED) icon_state = "switch-rev" - if(!(stat & NOPOWER)) - overlays += "redlight" else if(position == DIRECTION_FORWARDS) icon_state = "switch-fwd" - if(!(stat & NOPOWER)) - overlays += "greenlight" + + +/obj/machinery/conveyor_switch/update_overlays() + . = ..() + if(position == DIRECTION_REVERSED && !(stat & NOPOWER)) + . += "redlight" + if(position == DIRECTION_FORWARDS && !(stat & NOPOWER)) + . += "greenlight" + /obj/machinery/conveyor_switch/oneway one_way = TRUE @@ -394,8 +411,9 @@ GLOBAL_LIST_INIT(conveyor_switches, list()) return TRUE -/obj/machinery/conveyor_switch/power_change() - ..() +/obj/machinery/conveyor_switch/power_change(forced = FALSE) + if(!..()) + return update_icon() // CONVEYOR CONSTRUCTION STARTS HERE diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 1b3bad78222..1bac343a610 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -6,7 +6,7 @@ desc = "A huge pipe segment used for constructing disposal systems." icon = 'icons/obj/pipes_and_stuff/not_atmos/disposal.dmi' icon_state = "conpipe-s" - anchored = 0 + anchored = FALSE density = 0 pressure_resistance = 5*ONE_ATMOSPHERE level = 2 @@ -69,11 +69,16 @@ // hide called by levelupdate if turf intact status changes // change visibility status and force update of icon -/obj/structure/disposalconstruct/hide(var/intact) - invisibility = (intact && level==1) ? INVISIBILITY_ABSTRACT: 0 // hide if floor is intact +/obj/structure/disposalconstruct/hide(intact) + invisibility = (intact && level == 1) ? INVISIBILITY_MAXIMUM : 0 // hide if floor is intact update() +/obj/structure/disposalconstruct/examine(mob/user) + . = ..() + . += "Alt-Click to rotate it, Alt-Shift-Click to flip it." + + // flip and rotate verbs /obj/structure/disposalconstruct/verb/rotate() set category = "Object" @@ -183,7 +188,7 @@ if(!pipe_check(user)) return if(anchored) - anchored = 0 + anchored = FALSE if(ispipe) level = 2 density = 0 @@ -191,7 +196,7 @@ density = 1 to_chat(user, "You detach the [nicetype] from the underfloor.") else - anchored = 1 + anchored = TRUE if(ispipe) level = 1 // We don't want disposal bins to disappear under the floors density = 0 diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index bc70fb5829c..cd6f2e3e864 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -5,20 +5,22 @@ // Automatically recharges air (unless off), will flush when ready if pre-set // Can hold items and human size things, no other draggables // Toilets are a type of disposal bin for small objects only and work on magic. By magic, I mean torque rotation -#define SEND_PRESSURE 0.05*ONE_ATMOSPHERE +#define SEND_PRESSURE (0.05*ONE_ATMOSPHERE) #define UNSCREWED -1 -#define OFF 0 #define SCREWED 1 +#define OFF 0 #define CHARGING 1 #define CHARGED 2 +/// How frequently disposals can make sounds, to prevent huge sound stacking +#define DISPOSAL_SOUND_COOLDOWN (0.1 SECONDS) /obj/machinery/disposal name = "disposal unit" desc = "A pneumatic waste disposal unit." icon = 'icons/obj/pipes_and_stuff/not_atmos/disposal.dmi' icon_state = "disposal" - anchored = 1 - density = 1 + anchored = TRUE + density = TRUE on_blueprints = TRUE armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) max_integrity = 200 @@ -38,14 +40,6 @@ idle_power_usage = 100 -// create a new disposal -// find the attached trunk (if present) -/obj/machinery/disposal/New() - ..() - trunk_check() - //gas.volume = 1.05 * CELLSTANDARD - update() - /obj/machinery/disposal/proc/trunk_check() var/obj/structure/disposalpipe/trunk/T = locate() in loc if(!T) @@ -59,6 +53,8 @@ //When the disposalsoutlet is forcefully moved. Due to meteorshot (not the recall spell) /obj/machinery/disposal/Moved(atom/OldLoc, Dir) . = ..() + if(!loc) + return eject() var/ptype = istype(src, /obj/machinery/disposal/deliveryChute) ? PIPE_DISPOSALS_CHUTE : PIPE_DISPOSALS_BIN //Check what disposaltype it is var/turf/T = OldLoc @@ -72,15 +68,15 @@ transfer_fingerprints_to(C) C.ptype = ptype C.update() - C.anchored = 0 - C.density = 1 + C.anchored = FALSE + C.density = TRUE if(!QDELING(src)) qdel(src) + /obj/machinery/disposal/Destroy() eject() - if(trunk) - trunk.remove_trunk_links() + trunk?.remove_trunk_links() return ..() /obj/machinery/disposal/singularity_pull(S, current_size) @@ -88,9 +84,9 @@ if(current_size >= STAGE_FIVE) deconstruct() -/obj/machinery/disposal/Initialize() +/obj/machinery/disposal/Initialize(mapload) // this will get a copy of the air turf and take a SEND PRESSURE amount of air from it - ..() + . = ..() var/atom/L = loc var/datum/gas_mixture/env = new env.copy_from(L.return_air()) @@ -98,6 +94,8 @@ air_contents = new air_contents.merge(removed) trunk_check() + update() + //This proc returns TRUE if the item can be picked up and FALSE if it can't. //Set the stop_messages to stop it from printing messages @@ -128,7 +126,7 @@ return TRUE // attack by item places it in to disposal -/obj/machinery/disposal/attackby(var/obj/item/I, var/mob/user, params) +/obj/machinery/disposal/attackby(obj/item/I, mob/user, params) if(stat & BROKEN || !I || !user) return @@ -136,59 +134,57 @@ to_chat(user, "You can't place that item inside the disposal unit.") return - if(istype(I, /obj/item/storage)) - var/obj/item/storage/S = I - if((S.allow_quick_empty || S.allow_quick_gather) && S.contents.len) + if(isstorage(I)) + var/obj/item/storage/storage = I + if((storage.allow_quick_empty || storage.allow_quick_gather) && length(storage.contents)) add_fingerprint(user) - S.hide_from(user) - for(var/obj/item/O in S.contents) - if(!can_be_inserted(O)) + storage.hide_from(user) + for(var/obj/item/item in storage.contents) + if(!can_be_inserted(item)) break - S.remove_from_storage(O, src) - O.add_hiddenprint(user) - if(!S.contents.len) - user.visible_message("[user] empties \the [S] into \the [src].", "You empty \the [S] into \the [src].") + storage.remove_from_storage(item, src) + item.add_hiddenprint(user) + if(!length(storage)) + user.visible_message("[user] empties \the [storage] into \the [src].", "You empty \the [storage] into \the [src].") else - user.visible_message("[user] dumped some items from \the [S] into \the [src].", "You dumped some items \the [S] into \the [src].") - S.update_icon() // For content-sensitive icons + user.visible_message("[user] dumped some items from \the [storage] into \the [src].", "You dumped some items \the [storage] into \the [src].") + storage.update_icon() // For content-sensitive icons update() return - var/obj/item/grab/G = I - if(istype(G)) // handle grabbed mob - if(ismob(G.affecting)) - var/mob/GM = G.affecting - for(var/mob/V in viewers(usr)) - V.show_message("[usr] starts putting [GM.name] into the disposal.", 3) - if(do_after(usr, 20, target = GM)) - add_fingerprint(user) - GM.forceMove(src) - for(var/mob/C in viewers(src)) - C.show_message("[GM.name] has been placed in the [src] by [user].", 3) - qdel(G) - add_attack_logs(usr, GM, "Disposal'ed") - return + var/obj/item/grab/grab = I + if(istype(grab)) // handle grabbed mob + if(grab.affecting && !isliving(grab.affecting)) + return - if(!I) - return + var/mob/living/target = grab.affecting + + for(var/mob/viewer in (viewers(user) - user)) + viewer.show_message("[user] starts putting [target.name] into the disposal.", 3) + + if(!do_mob(user, target , 2 SECONDS)) + return - if(!can_be_inserted(I)) + add_fingerprint(user) + target.forceMove(src) + for(var/mob/viewer in viewers(src)) + viewer.show_message("[target.name] has been placed in the [src] by [user].", 3) + + qdel(grab) + add_attack_logs(user, target, "Disposal'ed") return - if(!user.drop_transfer_item_to_loc(I, src)) + + if(!I || !can_be_inserted(I) || !user.drop_transfer_item_to_loc(I, src)) return add_fingerprint(user) to_chat(user, "You place \the [I] into the [src].") - for(var/mob/M in viewers(src)) - if(M == user) - continue - M.show_message("[user.name] places \the [I] into the [src].", 3) + for(var/mob/viewer in (viewers(src) - user)) + viewer.show_message("[user.name] places \the [I] into the [src].", 3) update() - - /obj/machinery/disposal/screwdriver_act(mob/user, obj/item/I) if(mode > OFF) // It's on return @@ -203,50 +199,61 @@ else if(mode == UNSCREWED) mode = OFF to_chat(user, "You [mode ? "unfasten": "fasten"] the screws around the power connection.") + update() + /obj/machinery/disposal/welder_act(mob/user, obj/item/I) . = TRUE if(mode != UNSCREWED) - return - if(contents.len > 0) + return . + if(length(contents)) to_chat(user, "Eject the items first!") - return + return . if(!I.tool_use_check(user, 0)) - return + return . WELDER_ATTEMPT_FLOOR_SLICE_MESSAGE - if(I.use_tool(src, user, 20, volume = I.tool_volume)) - WELDER_FLOOR_SLICE_SUCCESS_MESSAGE - var/obj/structure/disposalconstruct/C = new (src.loc) - C.ptype = deconstructs_to - C.update() - C.anchored = 1 - C.density = 1 - qdel(src) + if(!I.use_tool(src, user, 2 SECONDS, volume = I.tool_volume)) + return . + + WELDER_FLOOR_SLICE_SUCCESS_MESSAGE + var/obj/structure/disposalconstruct/C = new(loc) + C.ptype = deconstructs_to + C.update() + C.anchored = TRUE + C.density = TRUE + qdel(src) // mouse drop another mob or self // -/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user) - if(!istype(target) || target.buckled || target.has_buckled_mobs() || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai)) +/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user, params) + if(!istype(target) || target.buckled || target.has_buckled_mobs() || !in_range(user, src) || !in_range(user, target) || user.incapacitated() || isAI(user)) return - if(isanimal(user) && target != user) return //animals cannot put mobs other than themselves into disposal - src.add_fingerprint(user) - var/target_loc = target.loc + if(isanimal(user) && target != user) + return //animals cannot put mobs other than themselves into disposal + if(target != user && target.anchored) + return + add_fingerprint(user) + for(var/mob/viewer in viewers(user)) + if(target == user) + viewer.show_message("[user] starts climbing into the disposal.", 3) + else + viewer.show_message("[user] starts stuffing [target.name] into the disposal.", 3) + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/disposal, put_in), target, user) + return TRUE + + +/obj/machinery/disposal/proc/put_in(mob/living/target, mob/living/user) // need this proc to use INVOKE_ASYNC in other proc. You're not recommended to use that one var/msg - for(var/mob/V in viewers(usr)) - if(target == user && !user.stat && !user.IsWeakened() && !user.IsStunned() && !user.IsParalyzed()) - V.show_message("[usr] starts climbing into the disposal.", 3) - if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.IsStunned() && !user.IsParalyzed()) - if(target.anchored) return - V.show_message("[usr] starts stuffing [target.name] into the disposal.", 3) - if(!do_after(usr, 20, target = target)) + var/target_loc = target.loc + if(!do_after(usr, 2 SECONDS, target = target)) return if(QDELETED(src) || target_loc != target.loc) return - if(target == user && !user.stat && !user.IsWeakened() && !user.IsStunned() && !user.IsParalyzed()) // if drop self, then climbed in + if(target == user && !user.incapacitated()) // if drop self, then climbed in // must be awake, not stunned or whatever msg = "[user.name] climbs into [src]." to_chat(user, "You climb into [src].") - else if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.IsStunned() && !user.IsParalyzed()) + else if(target != user && !user.restrained() && !user.incapacitated()) msg = "[user.name] stuffs [target.name] into [src]!" to_chat(user, "You stuff [target.name] into [src]!") if(!iscarbon(user)) @@ -258,19 +265,17 @@ return target.forceMove(src) - for(var/mob/C in viewers(src)) - if(C == user) - continue - C.show_message(msg, 3) + for(var/mob/viewer in (viewers(src) - user)) + viewer.show_message(msg, 3) update() - return + // attempt to move while inside /obj/machinery/disposal/relaymove(mob/user as mob) if(user.stat || src.flushing) return - src.go_out(user) + go_out(user) return // leave the disposal @@ -281,16 +286,17 @@ // ai as human but can't flush /obj/machinery/disposal/attack_ai(mob/user as mob) - src.add_hiddenprint(user) + add_hiddenprint(user) ui_interact(user) /obj/machinery/disposal/attack_ghost(mob/user as mob) ui_interact(user) + // human interact with machine -/obj/machinery/disposal/attack_hand(mob/user as mob) - if(..(user)) - return 1 +/obj/machinery/disposal/attack_hand(mob/user) + if(..()) + return TRUE if(stat & BROKEN) return @@ -305,7 +311,7 @@ else flush = !flush update() - return + /obj/machinery/disposal/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) @@ -338,12 +344,12 @@ if(stat & BROKEN) return - src.add_fingerprint(usr) + add_fingerprint(usr) - if(src.flushing) + if(flushing) return - if(istype(src.loc, /turf)) + if(isturf(loc)) if(action == "pumpOn") mode = CHARGING update() @@ -361,9 +367,9 @@ if(action == "eject") eject() - return TRUE + // eject the contents of the disposal unit /obj/machinery/disposal/proc/eject() for(var/atom/movable/AM in src) @@ -371,32 +377,67 @@ AM.pipe_eject(0) update() + +/obj/machinery/disposal/AltClick(mob/user) + if(!Adjacent(user) || !ishuman(user) || user.incapacitated()) + return ..() + user.visible_message( + "[user] tries to eject the contents of [src] manually.", + "You operate the manual ejection lever on [src]." + ) + if(!do_after(user, 5 SECONDS, target = src)) + return ..() + + user.visible_message( + "[user] ejects the contents of [src].", + "You eject the contents of [src].", + ) + eject() + + // update the icon & overlays to reflect mode & status /obj/machinery/disposal/proc/update() - overlays.Cut() if(stat & BROKEN) - icon_state = "disposal-broken" mode = OFF flush = FALSE + + update_icon() + + +/obj/machinery/disposal/update_icon_state() + if(stat & BROKEN) + icon_state = "disposal-broken" return + icon_state = initial(icon_state) + + +/obj/machinery/disposal/update_overlays() + . = ..() + underlays.Cut() // flush handle if(flush) - overlays += image('icons/obj/pipes_and_stuff/not_atmos/disposal.dmi', "dispover-handle") + . += "dispover-handle" // only handle is shown if no power - if(stat & NOPOWER || mode == -1) + if((stat & (NOPOWER|BROKEN)) || mode == UNSCREWED) return // check for items in disposal - occupied light - if(contents.len > 0) - overlays += image('icons/obj/pipes_and_stuff/not_atmos/disposal.dmi', "dispover-full") + if(length(contents)) + . += "dispover-full" + underlays += emissive_appearance(icon, "dispover-full") + return // charging and ready light - if(mode == CHARGING) - overlays += image('icons/obj/pipes_and_stuff/not_atmos/disposal.dmi', "dispover-charge") - else if(mode == CHARGED) - overlays += image('icons/obj/pipes_and_stuff/not_atmos/disposal.dmi', "dispover-ready") + switch(mode) + if(CHARGING) + . += "dispover-charge" + underlays += emissive_appearance(icon, "dispover-lightmask") + if(CHARGED) + . += "dispover-ready" + underlays += emissive_appearance(icon, "dispover-lightmask") + // timed process // charge the gas reservoir and perform flush if ready @@ -406,16 +447,14 @@ return flush_count++ - if( flush_count >= flush_every_ticks ) - if( contents.len ) - if(mode == CHARGED) - spawn(0) - flush() + if(flush_count >= flush_every_ticks) + if(length(contents) && mode == CHARGED) + INVOKE_ASYNC(src, PROC_REF(flush)) flush_count = 0 - src.updateDialog() + updateDialog() - if(flush && air_contents.return_pressure() >= SEND_PRESSURE ) // flush can happen even without power + if(flush && air_contents.return_pressure() >= SEND_PRESSURE) // flush can happen even without power flush() if(stat & NOPOWER) // won't charge if no power @@ -442,12 +481,11 @@ air_contents.merge(removed) air_update_turf() - // if full enough, switch to ready mode if(air_contents.return_pressure() >= SEND_PRESSURE) mode = CHARGED update() - return + // perform a flush /obj/machinery/disposal/proc/flush() @@ -457,7 +495,7 @@ // travels through the pipes. manage_wrapping(H) sleep(10) - if(last_sound < world.time + 1) + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) last_sound = world.time sleep(5) // wait for animation to finish @@ -470,11 +508,12 @@ if(mode == CHARGED) // if was ready, mode = CHARGING // switch to charging update() - return + /obj/machinery/disposal/proc/flush_animation() flick("[icon_state]-flush", src) + /obj/machinery/disposal/proc/manage_wrapping(obj/structure/disposalholder/H) var/wrap_check = FALSE //Hacky test to get drones to mail themselves through disposals. @@ -485,35 +524,42 @@ for(var/obj/item/smallDelivery/O in src) wrap_check = TRUE if(wrap_check == TRUE) - H.tomail = 1 + H.tomail = TRUE + // called when area power changes -/obj/machinery/disposal/power_change() - ..() // do default setting/reset of stat NOPOWER bit +/obj/machinery/disposal/power_change(forced = FALSE) + if(!..()) + return // do default setting/reset of stat NOPOWER bit update() // update icon - return + if(stat & NOPOWER) + set_light(0) + else + set_light(1, LIGHTING_MINIMUM_POWER) // called when holder is expelled from a disposal // should usually only occur if the pipe network is modified -/obj/machinery/disposal/proc/expel(var/obj/structure/disposalholder/H) +/obj/machinery/disposal/proc/expel(obj/structure/disposalholder/H) var/turf/target - playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) + playsound(src, 'sound/machines/hiss.ogg', 50, 0, FALSE) + last_sound = world.time + if(H) // Somehow, someone managed to flush a window which broke mid-transit and caused the disposal to go in an infinite loop trying to expel null, hopefully this fixes it for(var/atom/movable/AM in H) - target = get_offset_target_turf(src.loc, rand(5)-rand(5), rand(5)-rand(5)) + target = get_offset_target_turf(loc, rand(5)-rand(5), rand(5)-rand(5)) AM.forceMove(loc) AM.pipe_eject(0) - if(!istype(AM, /mob/living/silicon/robot/drone) && !istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z - spawn(1) - if(AM) - AM.throw_at(target, 5, 1) + if(!isdrone(AM) && !istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 5, 1), 0.1 SECONDS, TIMER_DELETE_ME) H.vent_gas(loc) qdel(H) + /obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover,/obj/item) && mover.throwing) var/obj/item/I = mover @@ -527,7 +573,7 @@ else for(var/mob/M in viewers(src)) M.show_message("\the [I] bounces off of \the [src]'s rim!.", 3) - return 0 + return FALSE else return ..(mover, target, height) @@ -543,35 +589,45 @@ /obj/machinery/disposal/force_eject_occupant(mob/target) target.forceMove(get_turf(src)) + /obj/machinery/disposal/deliveryChute name = "Delivery chute" desc = "A chute for big and small packages alike!" - density = 1 + density = TRUE icon_state = "intake" deconstructs_to = PIPE_DISPOSALS_CHUTE var/to_waste = TRUE + /obj/machinery/disposal/deliveryChute/New() ..() - spawn(5) - trunk = locate() in src.loc - if(trunk) - trunk.linked = src // link the pipe trunk to self + addtimer(CALLBACK(src, PROC_REF(update_trunk)), 0.5 SECONDS, TIMER_DELETE_ME) + + +/obj/machinery/disposal/deliveryChute/proc/update_trunk() + trunk = locate() in loc + if(trunk) + trunk.linked = src // link the pipe trunk to self + /obj/machinery/disposal/deliveryChute/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/destTagger)) add_fingerprint(user) to_waste = !to_waste - playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) to_chat(user, "The chute is now set to [to_waste ? "waste" : "cargo"] disposals.") + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) + playsound(src.loc, 'sound/machines/twobeep.ogg', 100, TRUE) + last_sound = world.time return . = ..() + /obj/machinery/disposal/deliveryChute/examine(mob/user) . = ..() . += "The chute is set to [to_waste ? "waste" : "cargo"] disposals." . += "Use a destination tagger to change the disposal destination." + /obj/machinery/disposal/deliveryChute/interact() return @@ -581,7 +637,9 @@ /obj/machinery/disposal/deliveryChute/Bumped(atom/movable/moving_atom) //Go straight into the chute ..() - if(istype(moving_atom, /obj/item/projectile) || istype(moving_atom, /obj/effect)) return + if(istype(moving_atom, /obj/item/projectile) || istype(moving_atom, /obj/effect)) + return + switch(dir) if(NORTH) if(moving_atom.loc.y != src.loc.y+1) return @@ -592,15 +650,13 @@ if(WEST) if(moving_atom.loc.x != src.loc.x-1) return - if(istype(moving_atom, /obj)) - var/obj/O = moving_atom - O.loc = src - else if(istype(moving_atom, /mob)) - var/mob/M = moving_atom - M.loc = src + if(isobj(moving_atom) || isliving(moving_atom)) + moving_atom.loc = src + if(mode != OFF) flush() + /obj/machinery/disposal/deliveryChute/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item/projectile)) return ..() //chutes won't eat bullets @@ -626,7 +682,7 @@ if(!O.sealed || O.sortTag == 0) //unsealed or untagged shipping packages will default to disposals O.sortTag = 1 if(wrap_check == TRUE) - H.tomail = 1 + H.tomail = TRUE if(wrap_check == FALSE && to_waste) H.destinationTag = 1 @@ -637,48 +693,51 @@ /obj/structure/disposalholder invisibility = INVISIBILITY_ABSTRACT - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + resistance_flags = INDESTRUCTIBLE|LAVA_PROOF|FIRE_PROOF|UNACIDABLE|ACID_PROOF var/datum/gas_mixture/gas = null // gas used to flush, will appear at exit point - var/active = 0 // true if the holder is moving, otherwise inactive - dir = 0 + var/active = FALSE // true if the holder is moving, otherwise inactive + dir = NONE var/count = 1000 //*** can travel 1000 steps before going inactive (in case of loops) - var/has_fat_guy = 0 // true if contains a fat person - var/destinationTag = 0 // changes if contains a delivery container - var/tomail = 0 //changes if contains wrapped package - var/hasmob = 0 //If it contains a mob + var/has_fat_guy = FALSE // true if contains a fat person + /// Destination the holder is set to, defaulting to disposals and changes if the contents have a mail/sort tag. + var/destinationTag = 1 + var/tomail = FALSE //changes if contains wrapped package + var/hasmob = FALSE //If it contains a mob + /obj/structure/disposalholder/Destroy() QDEL_NULL(gas) active = 0 return ..() - // initialize a holder from the contents of a disposal unit -/obj/structure/disposalholder/proc/init(var/obj/machinery/disposal/D) + +// initialize a holder from the contents of a disposal unit +/obj/structure/disposalholder/proc/init(obj/machinery/disposal/D) gas = D.air_contents// transfer gas resv. into holder object //Check for any living mobs trigger hasmob. //hasmob effects whether the package goes to cargo or its tagged destination. for(var/mob/living/M in D) - if(M && M.stat != 2 && !isdrone(M) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) - hasmob = 1 + if(M && M.stat != DEAD && !isdrone(M) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) + hasmob = TRUE //Checks 1 contents level deep. This means that players can be sent through disposals... //...but it should require a second person to open the package. (i.e. person inside a wrapped locker) for(var/obj/O in D) if(O.contents) for(var/mob/living/M in O.contents) - if(M && M.stat != 2 && !isdrone(M) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) - hasmob = 1 + if(M && M.stat != DEAD && !isdrone(M) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) + hasmob = TRUE // now everything inside the disposal gets put into the holder // note AM since can contain mobs or objs for(var/atom/movable/AM in D) AM.forceMove(src) SEND_SIGNAL(AM, COMSIG_MOVABLE_DISPOSING, src, D) - if(istype(AM, /mob/living/carbon/human)) + if(ishuman(AM)) var/mob/living/carbon/human/H = AM if(FAT in H.mutations) // is a human and fat? - has_fat_guy = 1 // set flag on holder + has_fat_guy = TRUE // set flag on holder if(istype(AM, /obj/structure/bigDelivery) && !hasmob) var/obj/structure/bigDelivery/T = AM destinationTag = T.sortTag @@ -700,33 +759,27 @@ // start the movement process // argument is the disposal unit the holder started in -/obj/structure/disposalholder/proc/start(var/obj/machinery/disposal/D) +/obj/structure/disposalholder/proc/start(obj/machinery/disposal/D) if(!D.trunk) D.expel(src) // no trunk connected, so expel immediately return forceMove(D.trunk) - active = 1 + active = TRUE dir = DOWN - spawn(1) - move() // spawn off the movement process + addtimer(CALLBACK(src, PROC_REF(move)), 0.1 SECONDS, TIMER_DELETE_ME) - return // movement process, persists while holder is moving through pipes /obj/structure/disposalholder/proc/move() var/obj/structure/disposalpipe/last while(active) - /* if(hasmob && prob(3)) - for(var/mob/living/H in src) - if(!istype(H,/mob/living/silicon/robot/drone)) //Drones use the mailing code to move through the disposal system, - H.take_overall_damage(20, 0, "Blunt Trauma") */ //horribly maim any living creature jumping down disposals. c'est la vie - if(has_fat_guy && prob(2)) // chance of becoming stuck per segment if contains a fat guy - active = 0 + active = FALSE // find the fat guys for(var/mob/living/carbon/human/H in src) - + if(FAT in H.mutations) + to_chat(H, span_userdanger("You suddenly stop in [last], your extra weight jamming you against the walls!")) break sleep(1) // was 1 var/obj/structure/disposalpipe/curr = loc @@ -737,9 +790,7 @@ // if(!(count--)) - active = 0 - return - + active = FALSE // find the turf which should contain the next pipe @@ -747,7 +798,7 @@ return get_step(loc,dir) // find a matching pipe on a turf -/obj/structure/disposalholder/proc/findpipe(var/turf/T) +/obj/structure/disposalholder/proc/findpipe(turf/T) if(!T) return null @@ -760,7 +811,7 @@ // merge two holder objects // used when a a holder meets a stuck holder -/obj/structure/disposalholder/proc/merge(var/obj/structure/disposalholder/other) +/obj/structure/disposalholder/proc/merge(obj/structure/disposalholder/other) for(var/atom/movable/AM in other) AM.forceMove(src) // move everything in other holder to this one if(ismob(AM)) @@ -768,34 +819,34 @@ M.reset_perspective(src) // if a client mob, update eye to follow this holder if(other.has_fat_guy) - has_fat_guy = 1 + has_fat_guy = TRUE qdel(other) // called when player tries to move while in a pipe -/obj/structure/disposalholder/relaymove(mob/user as mob) - if(!istype(user,/mob/living)) +/obj/structure/disposalholder/relaymove(mob/user) + if(!isliving(user)) return var/mob/living/U = user - if(U.stat || U.last_special <= world.time) + if(U.stat || world.time <= U.last_special) return - U.last_special = world.time+100 + U.last_special = world.time + 10 SECONDS - if(src.loc) - for(var/mob/M in hearers(src.loc.loc)) + if(loc) + for(var/mob/M in hearers(loc.loc)) to_chat(M, "CLONG, clong!") - playsound(src.loc, 'sound/effects/clang.ogg', 50, 0, 0) + playsound(loc, 'sound/effects/clang.ogg', 50, FALSE, 0) + // called to vent all gas in holder to a location -/obj/structure/disposalholder/proc/vent_gas(var/atom/location) +/obj/structure/disposalholder/proc/vent_gas(atom/location) if(location) location.assume_air(gas) // vent all gas to turf air_update_turf() - return // Disposal pipes @@ -803,9 +854,8 @@ icon = 'icons/obj/pipes_and_stuff/not_atmos/disposal.dmi' name = "disposal pipe" desc = "An underfloor disposal pipe." - anchored = 1 - density = 0 - + anchored = TRUE + density = FALSE on_blueprints = TRUE level = 1 // underfloor only var/dpdir = 0 // bitmask of pipe directions @@ -816,6 +866,8 @@ damage_deflection = 10 plane = FLOOR_PLANE layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes + /// The last time a sound was played from this + var/last_sound // new pipe, set the icon_state as on map /obj/structure/disposalpipe/Initialize(mapload) @@ -857,7 +909,7 @@ // transfer the holder through this pipe segment // overriden for special behaviour // -/obj/structure/disposalpipe/proc/transfer(var/obj/structure/disposalholder/H) +/obj/structure/disposalpipe/proc/transfer(obj/structure/disposalholder/H) var/nextdir = nextdir(H.dir) H.dir = nextdir var/turf/T = H.nextloc() @@ -871,7 +923,10 @@ H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.forceMove(T) + if(is_blocked_turf(T)) + H.forceMove(loc) + else + H.forceMove(T) return null return P @@ -880,23 +935,21 @@ // update the icon_state to reflect hidden status /obj/structure/disposalpipe/proc/update() var/turf/T = get_turf(src) - if(T.transparent_floor) - update_icon() - return - hide(T.intact && !istype(T, /turf/space)) // space never hides pipes - update_icon() + hide(T.intact && !isspaceturf(T) && !T.transparent_floor) // space never hides pipes + update_icon(UPDATE_ICON_STATE) + // hide called by levelupdate if turf intact status changes // change visibility status and force update of icon -/obj/structure/disposalpipe/hide(var/intact) - invisibility = intact ? INVISIBILITY_ABSTRACT: 0 // hide if floor is intact +/obj/structure/disposalpipe/hide(intact) + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 // hide if floor is intact update_icon() // update actual icon_state depending on visibility // if invisible, append "f" to icon_state to show faded version // this will be revealed if a T-scanner is used // if visible, use regular icon_state -/obj/structure/disposalpipe/update_icon() +/obj/structure/disposalpipe/update_icon_state() if(invisibility) icon_state = "[base_icon_state]f" else @@ -907,7 +960,7 @@ // called when there is a break in the pipe // -/obj/structure/disposalpipe/proc/expel(var/obj/structure/disposalholder/H, var/turf/T, var/direction) +/obj/structure/disposalpipe/proc/expel(obj/structure/disposalholder/H, turf/T, direction) if(!T) return @@ -915,33 +968,38 @@ var/turf/target if(T.density) // dense ouput turf, so stop holder - H.active = 0 + H.active = FALSE H.forceMove(src) return - if(T.intact && istype(T,/turf/simulated/floor)) //intact floor, pop the tile + + if(T.intact && isfloorturf(T)) //intact floor, pop the tile var/turf/simulated/floor/F = T F.remove_tile(null, TRUE, TRUE) + if(direction) // direction is specified - if(istype(T, /turf/space)) // if ended in space, then range is unlimited + if(isspaceturf(T)) // if ended in space, then range is unlimited target = get_edge_target_turf(T, direction) else // otherwise limit to 10 tiles target = get_ranged_target_turf(T, direction, 10) - playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) + playsound(src, 'sound/machines/hiss.ogg', 50, FALSE, 0) + last_sound = world.time + if(H) for(var/atom/movable/AM in H) AM.forceMove(T) AM.pipe_eject(direction) SEND_SIGNAL(AM, COMSIG_MOVABLE_EXIT_DISPOSALS) - spawn(1) - if(AM) - AM.throw_at(target, 100, 1) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 100, 1), 0.1 SECONDS, TIMER_DELETE_ME) H.vent_gas(T) qdel(H) else // no specified direction, so throw in random direction - playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) + playsound(src, 'sound/machines/hiss.ogg', 50, 0, FALSE) + last_sound = world.time if(H) for(var/atom/movable/AM in H) target = get_offset_target_turf(T, rand(5)-rand(5), rand(5)-rand(5)) @@ -949,13 +1007,12 @@ AM.forceMove(T) AM.pipe_eject(0) SEND_SIGNAL(AM, COMSIG_MOVABLE_EXIT_DISPOSALS) - spawn(1) - if(AM) - AM.throw_at(target, 5, 1) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 5, 1), 0.1 SECONDS, TIMER_DELETE_ME) H.vent_gas(T) // all gas vent to turf qdel(H) + // call to break the pipe // will expel any holder inside at the time // then delete the pipe @@ -971,24 +1028,23 @@ var/obj/structure/disposalholder/H = locate() in src if(H) // holder was present - H.active = 0 + H.active = FALSE var/turf/T = src.loc if(T.density) // broken pipe is inside a dense turf (wall) // this is unlikely, but just dump out everything into the turf in case - for(var/atom/movable/AM in H) AM.forceMove(T) - AM.pipe_eject(0) + AM.pipe_eject(NONE) qdel(H) return // otherwise, do normal expel from turf if(H) - expel(H, T, 0) + expel(H, T, NONE) + + QDEL_IN(src, 0.2 SECONDS) // delete pipe after delay to ensure expel proc finished - spawn(2) // delete pipe after 2 ticks to ensure expel proc finished - qdel(src) // pipe affected by explosion /obj/structure/disposalpipe/ex_act(severity) @@ -1014,11 +1070,12 @@ //weldingtool: unfasten and convert to obj/disposalconstruct /obj/structure/disposalpipe/attackby(var/obj/item/I, var/mob/user, params) - add_fingerprint(user) var/turf/T = get_turf(src) if(T.intact || T.transparent_floor) to_chat(user, "You can't interact with something that's under the floor!") return // prevent interaction with T-scanner revealed pipes and pipes under glass + add_fingerprint(user) + /obj/structure/disposalpipe/welder_act(mob/user, obj/item/I) . = TRUE @@ -1096,7 +1153,7 @@ // if coming in from secondary dirs, then next is primary dir // if coming in from primary dir, then next is equal chance of other dirs -/obj/structure/disposalpipe/junction/nextdir(var/fromdir) +/obj/structure/disposalpipe/junction/nextdir(fromdir) var/flipdir = turn(fromdir, 180) if(flipdir != dir) // came from secondary dir return dir // so exit through primary @@ -1129,12 +1186,20 @@ var/negdir = 0 var/sortdir = 0 -/obj/structure/disposalpipe/sortjunction/proc/updatedesc() + +/obj/structure/disposalpipe/sortjunction/update_name(updates = ALL) + . = ..() + name = GLOB.TAGGERLOCATIONS[sortType] + + +/obj/structure/disposalpipe/sortjunction/update_desc(updates = ALL) + . = ..() desc = "An underfloor disposal pipe with a package sorting mechanism." - if(sortType>0) + if(sortType > 0) var/tag = uppertext(GLOB.TAGGERLOCATIONS[sortType]) desc += "\nIt's tagged with [tag]" + /obj/structure/disposalpipe/sortjunction/proc/updatedir() posdir = dir negdir = turn(posdir, 180) @@ -1145,29 +1210,29 @@ icon_state = "pipe-j2s" sortdir = turn(posdir, 90) - dpdir = sortdir | posdir | negdir + dpdir = sortdir|posdir|negdir + /obj/structure/disposalpipe/sortjunction/Initialize(mapload) . = ..() updatedir() - updatedesc() + update_appearance(UPDATE_DESC) update() - return -/obj/structure/disposalpipe/sortjunction/attackby(var/obj/item/I, var/mob/user, params) + +/obj/structure/disposalpipe/sortjunction/attackby(obj/item/I, mob/user, params) if(..()) return if(istype(I, /obj/item/destTagger)) - var/obj/item/destTagger/O = I + var/obj/item/destTagger/tagger = I - if(O.currTag > 0)// Tag set - sortType = O.currTag - name = GLOB.TAGGERLOCATIONS[O.currTag] - playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) - var/tag = uppertext(GLOB.TAGGERLOCATIONS[O.currTag]) - to_chat(user, "Changed filter to [tag]") - updatedesc() + if(tagger.currTag > 0) // Tag set + sortType = tagger.currTag + playsound(loc, 'sound/machines/twobeep.ogg', 100, TRUE) + var/tag = uppertext(GLOB.TAGGERLOCATIONS[tagger.currTag]) + to_chat(user, span_notice("Changed filter to [tag].")) + update_appearance(UPDATE_NAME|UPDATE_DESC) // next direction to move @@ -1175,11 +1240,11 @@ // if coming in from posdir, then flip around and go back to posdir // if coming in from sortdir, go to posdir -/obj/structure/disposalpipe/sortjunction/nextdir(var/fromdir, var/sortTag) +/obj/structure/disposalpipe/sortjunction/nextdir(fromdir, sortTag) //var/flipdir = turn(fromdir, 180) if(fromdir != sortdir) // probably came from the negdir - if(src.sortType == sortTag) //if destination matches filtered type... + if(sortType == sortTag) //if destination matches filtered types... return sortdir // exit through sortdirection else return posdir @@ -1187,7 +1252,7 @@ // so go with the flow to positive direction return posdir -/obj/structure/disposalpipe/sortjunction/transfer(var/obj/structure/disposalholder/H) +/obj/structure/disposalpipe/sortjunction/transfer(obj/structure/disposalholder/H) var/nextdir = nextdir(H.dir, H.destinationTag) H.dir = nextdir var/turf/T = H.nextloc() @@ -1212,9 +1277,9 @@ /obj/structure/disposalpipe/wrapsortjunction desc = "An underfloor disposal pipe which sorts wrapped and unwrapped objects." icon_state = "pipe-j1s" - var/posdir = 0 - var/negdir = 0 - var/sortdir = 0 + var/posdir = NONE + var/negdir = NONE + var/sortdir = NONE /obj/structure/disposalpipe/wrapsortjunction/Initialize(mapload) . = ..() @@ -1229,7 +1294,7 @@ dpdir = sortdir | posdir | negdir update() - return + // next direction to move @@ -1237,7 +1302,7 @@ // if coming in from posdir, then flip around and go back to posdir // if coming in from sortdir, go to posdir -/obj/structure/disposalpipe/wrapsortjunction/nextdir(var/fromdir, var/istomail) +/obj/structure/disposalpipe/wrapsortjunction/nextdir(fromdir, istomail) //var/flipdir = turn(fromdir, 180) if(fromdir != sortdir) // probably came from the negdir if(istomail) //if destination matches filtered type... @@ -1247,7 +1312,7 @@ else // came from sortdir return posdir // so go with the flow to positive direction -/obj/structure/disposalpipe/wrapsortjunction/transfer(var/obj/structure/disposalholder/H) +/obj/structure/disposalpipe/wrapsortjunction/transfer(obj/structure/disposalholder/H) var/nextdir = nextdir(H.dir, H.tomail) H.dir = nextdir var/turf/T = H.nextloc() @@ -1278,9 +1343,8 @@ . = ..() dpdir = dir addtimer(CALLBACK(src, PROC_REF(getlinked)), 0) // This has a delay of 0, but wont actually start until the MC is done - update() - return + /obj/structure/disposalpipe/trunk/Destroy() if(istype(linked, /obj/structure/disposaloutlet)) @@ -1367,23 +1431,22 @@ expel(H, loc, FALSE) // nextdir -/obj/structure/disposalpipe/trunk/nextdir(var/fromdir) +/obj/structure/disposalpipe/trunk/nextdir(fromdir) if(fromdir == DOWN) return dir - else - return 0 + return NONE // a broken pipe /obj/structure/disposalpipe/broken icon_state = "pipe-b" - dpdir = 0 // broken pipes have dpdir=0 so they're not found as 'real' pipes + dpdir = NONE // broken pipes have dpdir=0 so they're not found as 'real' pipes // i.e. will be treated as an empty turf desc = "A broken piece of disposal pipe." /obj/structure/disposalpipe/broken/Initialize(mapload) . = ..() update() - return + /obj/structure/disposalpipe/broken/welder_act(mob/user, obj/item/I) if(I.use_tool(src, user, 0, volume = I.tool_volume)) @@ -1399,12 +1462,15 @@ desc = "An outlet for the pneumatic disposal system." icon = 'icons/obj/pipes_and_stuff/not_atmos/disposal.dmi' icon_state = "outlet" - density = 1 - anchored = 1 - var/active = 0 + density = TRUE + anchored = TRUE + var/active = FALSE var/turf/target // this will be where the output objects are 'thrown' to. var/obj/structure/disposalpipe/trunk/linkedtrunk - var/mode = SCREWED + var/mode = FALSE // Is the maintenance panel open? Different than normal disposal's mode + /// The last time a sound was played + var/last_sound + /obj/structure/disposaloutlet/Initialize(mapload) . = ..() @@ -1422,36 +1488,41 @@ expel(FALSE) return ..() -// expel the contents of the outlet + /obj/structure/disposaloutlet/proc/expel(animation = TRUE) if(animation) flick("outlet-open", src) - playsound(src, 'sound/machines/warning-buzzer.ogg', 50, 0, 0) - sleep(20) //wait until correct animation frame - playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) + var/play_sound = FALSE + if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) + play_sound = TRUE + last_sound = world.time + if(play_sound) + playsound(src, 'sound/machines/warning-buzzer.ogg', 50, 0, FALSE) + //wait until correct animation frame + addtimer(CALLBACK(GLOBAL_PROC, /proc/playsound, src, 'sound/machines/hiss.ogg', 50, FALSE, 0), 2 SECONDS, TIMER_DELETE_ME) for(var/atom/movable/AM in contents) AM.forceMove(loc) AM.pipe_eject(dir) - if(isdrone(AM) || istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z + if(QDELETED(AM)) return - spawn(5) - if(QDELETED(AM)) + if(isliving(AM)) + var/mob/living/mob_to_immobilize = AM + if(isdrone(mob_to_immobilize) || istype(mob_to_immobilize, /mob/living/silicon/robot/syndicate/saboteur)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z return - AM.throw_at(target, 3, 1) + mob_to_immobilize.Immobilize(1 SECONDS) + AM.throw_at(target, 3, 1) + /obj/structure/disposaloutlet/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(mode == SCREWED) - mode = UNSCREWED - else - mode = SCREWED - playsound(src.loc, I.usesound, 50, 1) - to_chat(user, "You [mode == SCREWED ? "attach" : "remove"] the screws around the power connection.") + add_fingerprint(user) + I.play_tool_sound(src) + to_chat(user, span_notice("You [mode == FALSE ? "remove" : "attach"] the screws around the power connection.")) + mode = !mode + return TRUE + /obj/structure/disposaloutlet/welder_act(mob/user, obj/item/I) . = TRUE - if(mode != UNSCREWED) - return if(!I.tool_use_check(user, 0)) return WELDER_ATTEMPT_FLOOR_SLICE_MESSAGE @@ -1465,6 +1536,7 @@ transfer_fingerprints_to(C) qdel(src) + //When the disposalsoutlet is forcefully moved. Due to meteorshot or the recall item spell for instance /obj/structure/disposaloutlet/Moved(atom/OldLoc, Dir) . = ..() @@ -1481,33 +1553,36 @@ transfer_fingerprints_to(C) C.ptype = PIPE_DISPOSALS_OUTLET C.update() - C.anchored = 0 - C.density = 1 + C.anchored = FALSE + C.density = TRUE qdel(src) // called when movable is expelled from a disposal pipe or outlet // by default does nothing, override for special behaviour -/atom/movable/proc/pipe_eject(var/direction) +/atom/movable/proc/pipe_eject(direction) return -/obj/effect/decal/cleanable/blood/gibs/pipe_eject(var/direction) + +/obj/effect/decal/cleanable/blood/gibs/pipe_eject(direction) var/list/dirs if(direction) dirs = list( direction, turn(direction, -45), turn(direction, 45)) else dirs = GLOB.alldirs.Copy() - src.streak(dirs) + streak(dirs) + -/obj/effect/decal/cleanable/blood/gibs/robot/gib/pipe_eject(var/direction) +/obj/effect/decal/cleanable/blood/gibs/robot/gib/pipe_eject(direction) var/list/dirs if(direction) dirs = list( direction, turn(direction, -45), turn(direction, 45)) else dirs = GLOB.alldirs.Copy() - src.streak(dirs) + streak(dirs) + #undef SEND_PRESSURE #undef UNSCREWED @@ -1515,3 +1590,5 @@ #undef SCREWED #undef CHARGING #undef CHARGED +#undef DISPOSAL_SOUND_COOLDOWN + diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 7ba318b9b32..26928420699 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -422,7 +422,7 @@ to_chat(user, "You seal [src], preparing it for delivery.") icon_state = "shippack_sealed" sealed = 1 - update_desc() + update_appearance(UPDATE_DESC) else if(alert("Do you want to tear up the package?",, "Yes", "No") == "Yes") to_chat(user, "You shred [src].") @@ -430,7 +430,7 @@ user.temporarily_remove_item_from_inventory(src) qdel(src) -/obj/item/shippingPackage/update_desc() +/obj/item/shippingPackage/update_desc(updates = ALL) . = ..() desc = "A pre-labeled package for shipping an item to coworkers." if(sortTag) diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index a3bc26e3e2f..f75ec7d3502 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -8,8 +8,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). name = "Circuit Imprinter" desc = "Manufactures circuit boards for the construction of machines." icon_state = "circuit_imprinter" - icon_open = "circuit_imprinter_t" - icon_closed = "circuit_imprinter" + base_icon_state = "circuit_imprinter" container_type = OPENCONTAINER categories = list( @@ -38,8 +37,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). RefreshParts() if(is_taipan(z)) icon_state = "syndie_circuit_imprinter" - icon_open = "syndie_circuit_imprinter_t" - icon_closed = "syndie_circuit_imprinter" + base_icon_state = "syndie_circuit_imprinter" reagents.my_atom = src /obj/machinery/r_n_d/circuit_imprinter/upgraded/New() @@ -53,8 +51,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). RefreshParts() if(is_taipan(z)) icon_state = "syndie_circuit_imprinter" - icon_open = "syndie_circuit_imprinter_t" - icon_closed = "syndie_circuit_imprinter" + base_icon_state = "syndie_circuit_imprinter" reagents.my_atom = src /obj/machinery/r_n_d/circuit_imprinter/RefreshParts() @@ -73,7 +70,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). T = clamp(T, 1, 4) efficiency_coeff = 1 / (2 ** (T - 1)) -/obj/machinery/r_n_d/circuit_imprinter/check_mat(datum/design/being_built, var/M) +/obj/machinery/r_n_d/circuit_imprinter/check_mat(datum/design/being_built, M) var/list/all_materials = being_built.reagents_list + being_built.materials var/A = materials.amount(M) @@ -82,12 +79,12 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return round(A / max(1, (all_materials[M] * efficiency_coeff))) -/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) +/obj/machinery/r_n_d/circuit_imprinter/attackby(obj/item/O, mob/user, params) if(shocked) add_fingerprint(user) if(shock(user,50)) return TRUE - if(default_deconstruction_screwdriver(user, icon_open, icon_closed, O)) + if(default_deconstruction_screwdriver(user, "[base_icon_state]_t", base_icon_state, O)) add_fingerprint(user) if(linked_console) linked_console.linked_imprinter = null @@ -98,7 +95,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return if(panel_open) - if(istype(O, /obj/item/crowbar)) + if(O.tool_behaviour == TOOL_CROWBAR) for(var/obj/I in component_parts) if(istype(I, /obj/item/reagent_containers/glass/beaker)) reagents.trans_to(I, reagents.total_volume) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 930ce67eaf9..5ef3e16b4c4 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -801,6 +801,14 @@ build_path = /obj/item/weaponcrafting/receiver category = list("hacked", "Security") +/datum/design/cylinder + name = "Revolver Cylinder" + id = "icylinder" + build_type = AUTOLATHE + materials = list(MAT_METAL = 6000) + build_path = /obj/item/ammo_box/magazine/internal/cylinder/improvised + category = list("hacked", "Security") + /datum/design/shotgun_slug name = "Shotgun Slug" id = "shotgun_slug" diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index f03d2c09ddb..3e1bdf8f173 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -55,7 +55,7 @@ name = "Monkey cube" id = "mcube" build_type = BIOGENERATOR - materials = list(MAT_BIOMASS = 250) + materials = list(MAT_BIOMASS = 500) build_path = /obj/item/reagent_containers/food/snacks/monkeycube category = list("initial", "Food") diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index d89b94bb254..8a066f7756f 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1877,6 +1877,16 @@ construction_time = 10 SECONDS category = list("Exosuit Paintkits") +/datum/design/paint_ripley_nt + name = "Ripley, Firefighter \"NT Special\"" + id = "p_ripleynt" + build_type = MECHFAB + req_tech = list("combat" = 5, "engineering" = 5, "materials" = 5, "programming" = 5) + build_path = /obj/item/paintkit/ripley_nt + materials = list(MAT_METAL=20000, MAT_PLASMA=2000, MAT_GLASS= 2000) + construction_time = 10 SECONDS + category = list("Exosuit Paintkits") + /datum/design/paint_clarke_orangey name = "Clarke \"Orangey\"" id = "p_orangey" @@ -2007,6 +2017,16 @@ construction_time = 30 SECONDS category = list("Exosuit Paintkits") +/datum/design/paint_durand_nt + name = "Durand \"NT Special\"" + id = "p_durandnt" + build_type = MECHFAB + req_tech = list("combat" = 6, "engineering" = 6, "materials" = 6, "programming" = 6) + build_path = /obj/item/paintkit/durand_nt + materials = list(MAT_METAL=40000, MAT_DIAMOND=4000, MAT_URANIUM= 4000) + construction_time = 30 SECONDS + category = list("Exosuit Paintkits") + /datum/design/paint_durand_soviet name = "Durand \"Dollhouse\"" id = "p_soviet" @@ -2066,3 +2086,13 @@ materials = list(MAT_METAL=50000, MAT_DIAMOND=4000, MAT_BLUESPACE=4000) construction_time = 40 SECONDS category = list("Exosuit Paintkits") + +/datum/design/paint_phazon_nt + name = "Phazon \"NT Special\"" + id = "p_phazonnt" + build_type = MECHFAB + req_tech = list("bluespace" = 7, "engineering" = 7, "materials" = 7, "toxins" = 6) + build_path = /obj/item/paintkit/phazon_nt + materials = list(MAT_METAL=50000, MAT_DIAMOND=4000, MAT_BLUESPACE=4000) + construction_time = 40 SECONDS + category = list("Exosuit Paintkits") diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 267cf064b0c..d13592742fd 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -9,8 +9,7 @@ Note: Must be placed within 3 tiles of the R&D Console name = "Destructive Analyzer" desc = "Изучайте науку, разрушая предметы!" icon_state = "d_analyzer" - icon_open = "d_analyzer_t" - icon_closed = "d_analyzer" + base_icon_state = "d_analyzer" var/decon_mod = 0 /obj/machinery/r_n_d/destructive_analyzer/New() @@ -23,8 +22,7 @@ Note: Must be placed within 3 tiles of the R&D Console RefreshParts() if(is_taipan(z)) icon_state = "syndie_d_analyzer" - icon_open = "syndie_d_analyzer_t" - icon_closed = "syndie_d_analyzer" + base_icon_state = "syndie_d_analyzer" /obj/machinery/r_n_d/destructive_analyzer/upgraded/New() ..() @@ -36,8 +34,7 @@ Note: Must be placed within 3 tiles of the R&D Console RefreshParts() if(is_taipan(z)) icon_state = "syndie_d_analyzer" - icon_open = "syndie_d_analyzer_t" - icon_closed = "syndie_d_analyzer" + base_icon_state = "syndie_d_analyzer" /obj/machinery/r_n_d/destructive_analyzer/RefreshParts() var/T = 0 @@ -46,19 +43,19 @@ Note: Must be placed within 3 tiles of the R&D Console decon_mod = T -/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(var/list/source_list) +/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) for(var/O in temp_list) temp_list[O] = text2num(temp_list[O]) return temp_list -/obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/item/O as obj, var/mob/user as mob, params) +/obj/machinery/r_n_d/destructive_analyzer/attackby(obj/item/O, mob/user, params) if(shocked) add_fingerprint(user) if(shock(user,50)) return TRUE - if(default_deconstruction_screwdriver(user, icon_open, icon_closed, O)) + if(default_deconstruction_screwdriver(user, "[base_icon_state]_t", base_icon_state, O)) add_fingerprint(user) if(linked_console) linked_console.linked_destroy = null @@ -79,7 +76,7 @@ Note: Must be placed within 3 tiles of the R&D Console if(busy) to_chat(user, "[src.name] сейчас занят.") return - if(istype(O, /obj/item) && !loaded_item) + if(isitem(O) && !loaded_item) //Ядра аномалий можно разобрать только при улучшеном автомате. 3x4(femto-manipulator,quad-ultra micro-laser,triphasic scanning module) if(istype(O,/obj/item/assembly/signaler/anomaly) && (decon_mod < 12)) to_chat(user, "[src.name] не может обработать такой сложный предмет!") @@ -95,10 +92,21 @@ Note: Must be placed within 3 tiles of the R&D Console to_chat(user, "[O] прилип к вашей руке и вы не можете поместить его в [src.name]!") return add_fingerprint(user) - busy = 1 + busy = TRUE + flick("[base_icon_state]_la", src) loaded_item = O to_chat(user, "[O.name] установлен в [src.name]!") - flick("[icon_state]_la", src) - spawn(10) - icon_state = "[icon_state]_l" - busy = 0 + addtimer(CALLBACK(src, PROC_REF(reset_processing)), 1 SECONDS) + + +/obj/machinery/r_n_d/destructive_analyzer/proc/reset_processing() + busy = FALSE + update_icon(UPDATE_ICON_STATE) + + +/obj/machinery/r_n_d/destructive_analyzer/update_icon_state() + if(loaded_item) + icon_state = "[base_icon_state]_l" + else + icon_state = base_icon_state + diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index ab51b4b564c..85d83a7f4b0 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -20,9 +20,9 @@ icon = 'icons/obj/machines/heavy_lathe.dmi' icon_state = "h_lathe" density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE - var/recentlyExperimented = 0 + var/recentlyExperimented = FALSE var/mob/trackedIan var/mob/trackedRuntime var/badThingCoeff = 0 @@ -111,6 +111,11 @@ return FALSE return TRUE + +/obj/machinery/r_n_d/experimentor/update_icon_state() + icon_state = "h_lathe[recentlyExperimented ? "_wloop" : ""]" + + /obj/machinery/r_n_d/experimentor/attackby(obj/item/O, mob/user, params) if(shocked) add_fingerprint(user) @@ -126,7 +131,7 @@ if(exchange_parts(user, O)) return - if(panel_open && istype(O, /obj/item/crowbar)) + if(panel_open && O.tool_behaviour == TOOL_CROWBAR) default_deconstruction_crowbar(user, O) return @@ -248,8 +253,8 @@ counter = 1 /obj/machinery/r_n_d/experimentor/proc/experiment(exp,obj/item/exp_on) - recentlyExperimented = 1 - icon_state = "h_lathe_wloop" + recentlyExperimented = TRUE + update_icon(UPDATE_ICON_STATE) var/chosenchem var/criticalReaction = (exp_on.type in critical_items) ? TRUE : FALSE //////////////////////////////////////////////////////////////////////////////////////////////// @@ -534,9 +539,13 @@ use_power(500000) investigate_log("Experimentor has drained power from its APC", INVESTIGATE_EXPERIMENTOR) - spawn(resetTime) - icon_state = "h_lathe" - recentlyExperimented = 0 + addtimer(CALLBACK(src, PROC_REF(reset_machine)), resetTime) + + +/obj/machinery/r_n_d/experimentor/proc/reset_machine() + recentlyExperimented = FALSE + update_icon(UPDATE_ICON_STATE) + /obj/machinery/r_n_d/experimentor/Topic(href, href_list) if(..()) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 378c865cae1..894e1d91ce9 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -49,7 +49,7 @@ GLOBAL_LIST_EMPTY(message_servers) icon_state = "server" name = "Messaging Server" density = 1 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 @@ -74,12 +74,12 @@ GLOBAL_LIST_EMPTY(message_servers) //if(decryptkey == "password") // decryptkey = generateKey() if(active && (stat & (BROKEN|NOPOWER))) - active = 0 + active = FALSE + update_icon(UPDATE_ICON_STATE) return if(prob(3)) playsound(loc, "computer_ambience", 50, 1) - update_icon() - return + /obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "") pda_msgs += new/datum/data_pda_msg(recipient,sender,message) @@ -111,20 +111,19 @@ GLOBAL_LIST_EMPTY(message_servers) playsound(RC.loc, 'sound/machines/twobeep.ogg', 50, 1) RC.atom_say("Message from [sender]") RC.message_log += "Message [sender]: [authmsg]" - RC.set_light(2) -/obj/machinery/message_server/attack_hand(user as mob) +/obj/machinery/message_server/attack_hand(user) // to_chat(user, "There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentComm delays.") if(..()) return TRUE add_fingerprint(user) to_chat(user, "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]") active = !active - update_icon() + update_icon(UPDATE_ICON_STATE) - return -/obj/machinery/message_server/update_icon() + +/obj/machinery/message_server/update_icon_state() if((stat & (BROKEN|NOPOWER))) icon_state = "server-nopower" else if(!active) @@ -132,13 +131,12 @@ GLOBAL_LIST_EMPTY(message_servers) else icon_state = "server-on" - return /obj/machinery/blackbox_recorder icon = 'icons/obj/stationobjs.dmi' icon_state = "blackbox" name = "Blackbox Recorder" density = 1 - anchored = 1.0 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index c07f91c72ce..97e885ec09a 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -11,8 +11,7 @@ Note: Must be placed west/left of and R&D console to function. name = "Protolathe" desc = "Converts raw materials into useful objects." icon_state = "protolathe" - icon_open = "protolathe_t" - icon_closed = "protolathe" + base_icon_state = "protolathe" container_type = OPENCONTAINER categories = list( @@ -44,8 +43,7 @@ Note: Must be placed west/left of and R&D console to function. RefreshParts() if(is_taipan(z)) icon_state = "syndie_protolathe" - icon_open = "syndie_protolathe_t" - icon_closed = "syndie_protolathe" + base_icon_state = "syndie_protolathe" reagents.my_atom = src /obj/machinery/r_n_d/protolathe/upgraded/New() @@ -61,8 +59,7 @@ Note: Must be placed west/left of and R&D console to function. RefreshParts() if(is_taipan(z)) icon_state = "syndie_protolathe" - icon_open = "syndie_protolathe_t" - icon_closed = "syndie_protolathe" + base_icon_state = "syndie_protolathe" reagents.my_atom = src /obj/machinery/r_n_d/protolathe/RefreshParts() @@ -77,7 +74,7 @@ Note: Must be placed west/left of and R&D console to function. T -= M.rating/10 efficiency_coeff = min(max(0, T), 1) -/obj/machinery/r_n_d/protolathe/check_mat(datum/design/being_built, var/M) // now returns how many times the item can be built with the material +/obj/machinery/r_n_d/protolathe/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/A = materials.amount(M) if(!A) A = reagents.get_reagent_amount(M) @@ -86,12 +83,12 @@ Note: Must be placed west/left of and R&D console to function. A = A / max(1, (being_built.materials[M] * efficiency_coeff)) return A -/obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob, params) +/obj/machinery/r_n_d/protolathe/attackby(obj/item/O, mob/user, params) if(shocked) add_fingerprint(user) if(shock(user,50)) return TRUE - if(default_deconstruction_screwdriver(user, icon_open, icon_closed, O)) + if(default_deconstruction_screwdriver(user, "[base_icon_state]_t", base_icon_state, O)) add_fingerprint(user) if(linked_console) linked_console.linked_lathe = null @@ -102,7 +99,7 @@ Note: Must be placed west/left of and R&D console to function. return if(panel_open) - if(istype(O, /obj/item/crowbar)) + if(O.tool_behaviour == TOOL_CROWBAR) for(var/obj/I in component_parts) if(istype(I, /obj/item/reagent_containers/glass/beaker)) reagents.trans_to(I, reagents.total_volume) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 9ac9bf62508..cd37fa6ea90 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -329,8 +329,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, return linked_destroy.busy = TRUE + flick("[linked_destroy.base_icon_state]_process", linked_destroy) add_wait_message("Processing and Updating Database...", DECONSTRUCT_DELAY) - flick("[linked_destroy.icon_closed]_process", linked_destroy) addtimer(CALLBACK(src, PROC_REF(finish_destroyer), temp_tech, user), DECONSTRUCT_DELAY) // Sends salvaged materials to a linked protolathe, if any. @@ -376,12 +376,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_destroy.loaded_item = S else qdel(S) - linked_destroy.icon_state = linked_destroy.icon_closed else if(!(I in linked_destroy.component_parts)) qdel(I) - linked_destroy.icon_state = linked_destroy.icon_closed + linked_destroy.loaded_item = null linked_destroy.busy = FALSE + linked_destroy.update_icon(UPDATE_ICON_STATE) use_power(DECONSTRUCT_POWER) menu = MENU_MAIN submenu = SUBMENU_MAIN @@ -436,10 +436,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(is_lathe) add_wait_message("Constructing Prototype. Please Wait...", time_to_construct) - flick("[machine.icon_state]_n", machine) + flick("[machine.base_icon_state]_n", machine) else add_wait_message("Imprinting Circuit. Please Wait...", time_to_construct) - flick("[machine.icon_state]_ani", machine) + flick("[machine.base_icon_state]_ani", machine) machine.busy = TRUE use_power(power) @@ -611,7 +611,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, else if(linked_destroy.loaded_item) linked_destroy.loaded_item.forceMove(linked_destroy.loc) linked_destroy.loaded_item = null - linked_destroy.icon_state = "[linked_destroy.icon_closed]" + linked_destroy.update_icon(UPDATE_ICON_STATE) menu = MENU_DESTROY if("maxresearch") diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index aa5491ed23c..fb55ab2ec3a 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -7,7 +7,7 @@ var/icon_open = null var/icon_closed = null density = 1 - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE var/busy = 0 var/hacked = 0 @@ -133,9 +133,8 @@ var/obj/item/stack/S = type_inserted stack_name = initial(S.name) use_power(min(1000, (amount_inserted / 100))) - overlays += "[initial(name)]_[stack_name]" - sleep(10) - overlays -= "[initial(name)]_[stack_name]" + flick_overlay_view(image(icon, src,"[initial(name)]_[stack_name]", layer + 0.01), 1 SECONDS) + /obj/machinery/r_n_d/proc/check_mat(datum/design/being_built, var/M) return 0 // number of copies of design beign_built you can make with material M diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 6a789ffa579..b04518564cb 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -2,8 +2,7 @@ name = "R&D Server" icon = 'icons/obj/machines/research.dmi' icon_state = "server" - icon_open = "server_o" - icon_closed = "server" + base_icon_state = "server" var/datum/research/files var/health = 100 var/list/id_with_upload = list() //List of R&D consoles with upload to server access. @@ -29,8 +28,7 @@ syndicate = 1 req_access = list(ACCESS_SYNDICATE_RESEARCH_DIRECTOR) icon_state = "syndie_server" - icon_open = "syndie_server_o" - icon_closed = "syndie_server" + base_icon_state = "syndie_server" component_parts = list() component_parts += new /obj/item/circuitboard/rdserver(null) component_parts += new /obj/item/stock_parts/scanning_module(null) @@ -152,16 +150,16 @@ add_fingerprint(user) shock(user,50) - if(istype(O, /obj/item/screwdriver)) + if(O.tool_behaviour == TOOL_SCREWDRIVER) add_fingerprint(user) - default_deconstruction_screwdriver(user, icon_open, icon_closed, O) + default_deconstruction_screwdriver(user, "[base_icon_state]_o", base_icon_state, O) return 1 if(exchange_parts(user, O)) return 1 if(panel_open) - if(istype(O, /obj/item/crowbar)) + if(O.tool_behaviour == TOOL_CROWBAR) griefProtection() default_deconstruction_crowbar(user, O) return 1 diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index cc925d8ad77..7544f8727ba 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -3,25 +3,38 @@ visible_icon = 1 icon = 'icons/obj/abductor.dmi' icon_state = "camera_target" + ai_detector_visible = FALSE // The Xenobio Console does not trigger the AI Detector + /// Area that the xenobio camera eye is allowed to travel var/allowed_area = null -/mob/camera/aiEye/remote/xenobio/New(loc) +/mob/camera/aiEye/remote/xenobio/Initialize(mapload) + . = ..() var/area/A = get_area(loc) allowed_area = A.name - ..() /mob/camera/aiEye/remote/xenobio/setLoc(t) var/area/new_area = get_area(t) - if(new_area && new_area.name == allowed_area || new_area && new_area.xenobiology_compatible) - return ..() - else + if(!new_area) + return + if(new_area.name != allowed_area && !new_area.xenobiology_compatible) return + return ..() + +#define MAX_SLIME_IN_CONSOLE 5 +/* + * # Slime Management Console + * + * Camera overview console for xenobiology, handles slime management and xenobio actions +*/ /obj/machinery/computer/camera_advanced/xenobio name = "slime management console" desc = "A computer used for remotely handling slimes." networks = list("SS13") circuit = /obj/item/circuitboard/xenobiology + icon_screen = "slime_comp" + icon_keyboard = "rd_key" + var/datum/action/innate/slime_place/slime_place_action = new var/datum/action/innate/slime_pick_up/slime_up_action = new var/datum/action/innate/feed_slime/feed_slime_action = new @@ -31,20 +44,21 @@ var/datum/action/innate/hotkey_help/hotkey_help = new var/list/stored_slimes = list() - var/max_slimes = 5 var/monkeys = 0 var/obj/item/slimepotion/slime/current_potion var/obj/machinery/monkey_recycler/connected_recycler - icon_screen = "slime_comp" - icon_keyboard = "rd_key" +/obj/machinery/computer/camera_advanced/xenobio/Initialize() + . = ..() + if(!connected_recycler) + locate_recycler() -/obj/machinery/computer/camera_advanced/xenobio/New() - ..() - for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers) - if(get_area(recycler.loc) == get_area(loc)) +/obj/machinery/computer/camera_advanced/xenobio/proc/locate_recycler() + for(var/obj/machinery/monkey_recycler/recycler as anything in GLOB.monkey_recyclers) + if(get_area(recycler) == get_area(loc)) connected_recycler = recycler - connected_recycler.connected += src + connected_recycler.connected |= src + break /obj/machinery/computer/camera_advanced/xenobio/Destroy() QDEL_NULL(current_potion) @@ -67,7 +81,7 @@ /obj/machinery/computer/camera_advanced/xenobio/CreateEye() eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) eyeobj.origin = src - eyeobj.visible_icon = 1 + eyeobj.visible_icon = TRUE eyeobj.acceleration = FALSE eyeobj.icon = 'icons/obj/abductor.dmi' eyeobj.icon_state = "camera_target" @@ -118,10 +132,7 @@ RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, PROC_REF(XenoMonkeyClickCtrl)) if(!connected_recycler) - for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers) - if(get_area(recycler.loc) == get_area(loc)) - connected_recycler = recycler - connected_recycler.connected += src + locate_recycler() /obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL) @@ -132,6 +143,33 @@ UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL) ..() +/obj/machinery/computer/camera_advanced/xenobio/proc/insert_potion(obj/item/slimepotion/slime/potion) + clear_potion() + potion.forceMove(src) + current_potion = potion + RegisterSignal(current_potion, COMSIG_PARENT_QDELETING, PROC_REF(clear_potion)) + +/obj/machinery/computer/camera_advanced/xenobio/proc/clear_potion() + if(!QDELETED(current_potion)) + current_potion.forceMove(drop_location()) + UnregisterSignal(current_potion, COMSIG_PARENT_QDELETING) + current_potion = null + +/obj/machinery/computer/camera_advanced/xenobio/proc/capture_slime(mob/living/simple_animal/slime/slime) + slime.visible_message("[slime] vanishes in a flash of light!") + slime.forceMove(src) + stored_slimes += slime + RegisterSignal(slime, COMSIG_PARENT_QDELETING, PROC_REF(clear_slime)) + +/obj/machinery/computer/camera_advanced/xenobio/proc/release_slime(mob/living/simple_animal/slime/slime, release_spot) + slime.visible_message("[slime] warps in!") + clear_slime(slime) + slime.forceMove(release_spot) + +/obj/machinery/computer/camera_advanced/xenobio/proc/clear_slime(mob/living/simple_animal/slime/slime) + UnregisterSignal(slime, COMSIG_PARENT_QDELETING) + stored_slimes -= slime + /obj/machinery/computer/camera_advanced/xenobio/attack_hand(mob/user) if(!ishuman(user)) //AIs using it might be weird return @@ -145,17 +183,14 @@ to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.") qdel(O) return - else if(istype(O, /obj/item/slimepotion/slime)) - var/replaced = FALSE - if(user.drop_transfer_item_to_loc(O, src)) - add_fingerprint(user) - if(!QDELETED(current_potion)) - current_potion.forceMove(drop_location()) - replaced = TRUE - current_potion = O - to_chat(user, "You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].") + if(istype(O, /obj/item/slimepotion/slime)) + if(!user.drop_transfer_item_to_loc(O, src)) + return + add_fingerprint(user) + to_chat(user, span_notice("You load [O] in the console's potion slot[current_potion ? ", replacing the one that was there before" : ""].")) + insert_potion(O, user) return - else if(istype(O, /obj/item/storage/bag/bio) || istype(O, /obj/item/storage/box/monkeycubes)) + if(istype(O, /obj/item/storage/bag/bio) || istype(O, /obj/item/storage/box/monkeycubes)) var/obj/item/storage/P = O var/loaded = 0 for(var/obj/item/reagent_containers/food/snacks/monkeycube/MC in P.contents) @@ -213,14 +248,12 @@ if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - if(X.stored_slimes.len >= X.max_slimes) + if(length(X.stored_slimes) >= MAX_SLIME_IN_CONSOLE) break if(!S.ckey) if(S.buckled) S.Feedstop(silent = TRUE) - S.visible_message("[S] vanishes in a flash of light!") - S.forceMove(X) - X.stored_slimes += S + X.capture_slime(S) else to_chat(owner, "Target is not near a camera. Cannot proceed.") @@ -301,7 +334,7 @@ var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control var/obj/machinery/computer/camera_advanced/xenobio/X = target - if(QDELETED(X.current_potion)) + if(!X.current_potion) to_chat(owner, "No potion loaded.") return @@ -378,7 +411,7 @@ var/mob/camera/aiEye/remote/xenobio/E = C.remote_control var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin var/area/mobarea = get_area(S.loc) - if(QDELETED(X.current_potion)) + if(!X.current_potion) to_chat(C, "No potion loaded.") return if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) @@ -394,7 +427,7 @@ var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin var/area/mobarea = get_area(S.loc) if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) - if(X.stored_slimes.len >= X.max_slimes) + if(length(X.stored_slimes) >= MAX_SLIME_IN_CONSOLE) to_chat(C, "Slime storage is full.") return if(S.ckey) @@ -402,9 +435,7 @@ return if(S.buckled) S.Feedstop(silent = TRUE) - S.visible_message("[S] vanishes in a flash of light!") - S.forceMove(X) - X.stored_slimes += S + X.capture_slime(S) //Place slimes /obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/T) @@ -426,6 +457,9 @@ if(!GLOB.cameranet.checkTurfVis(T)) to_chat(user, "Target is not near a camera. Cannot proceed.") return + if(LAZYLEN(SSmobs.cubemonkeys) >= CONFIG_GET(number/cubemonkey_cap)) + to_chat(user, "Bluespace harmonics prevent the spawning of more than [CONFIG_GET(number/cubemonkey_cap)] monkeys on the station at one time!") + return var/mob/living/C = user var/mob/camera/aiEye/remote/xenobio/E = C.remote_control var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin @@ -435,7 +469,8 @@ if(X.monkeys >= 1) var/mob/living/carbon/human/lesser/monkey/food = new /mob/living/carbon/human/lesser/monkey(T) food.LAssailant = C - X.monkeys -- + SSmobs.cubemonkeys += food + X.monkeys-- X.monkeys = round(X.monkeys, 0.1) to_chat(user, "[X] now has [X.monkeys] monkeys left.") @@ -450,7 +485,7 @@ var/area/mobarea = get_area(M.loc) var/obj/machinery/monkey_recycler/recycler = X.connected_recycler if(!recycler) - to_chat(C, "There is no connected monkey recycler. Use a multitool to link one.") + to_chat(C, "There is no connected monkey recycler. Use a multitool to link one.") return if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) if(issmall(M) && M.stat) @@ -458,3 +493,6 @@ recycler.use_power(500) X.monkeys = round(X.monkeys + recycler.cube_production/recycler.required_grind, 0.1) qdel(M) + + +#undef MAX_SLIME_IN_CONSOLE diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 6f30df3b131..1dd037c1146 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -514,19 +514,19 @@ qdel(src) -/obj/item/slimepotion/speed/MouseDrop(atom/over) +/obj/item/slimepotion/speed/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(istype(over, /obj/screen)) + if(istype(over_object, /obj/screen)) return FALSE - if(over == user || loc != user || user.incapacitated() || !ishuman(user)) + if(over_object == user || loc != user || user.incapacitated() || !ishuman(user)) return FALSE - afterattack(over, user, TRUE, drop = TRUE) + afterattack(over_object, user, TRUE, drop = TRUE) return TRUE @@ -581,20 +581,19 @@ qdel(src) -/obj/item/slimepotion/clothing/MouseDrop(atom/over) +/obj/item/slimepotion/clothing/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() if(!.) return FALSE var/mob/user = usr - if(istype(over, /obj/screen)) + if(istype(over_object, /obj/screen)) return FALSE - if(over == user || loc != user || user.incapacitated() || !ishuman(user)) + if(over_object == user || loc != user || user.incapacitated() || !ishuman(user)) return FALSE - afterattack(over, user, TRUE) - return TRUE + afterattack(over_object, user, TRUE) /obj/item/slimepotion/clothing/fireproof @@ -751,7 +750,7 @@ return C.armor.melee < 100 || C.armor.bullet < 100 /obj/effect/timestop - anchored = 1 + anchored = TRUE name = "chronofield" desc = "ZA WARUDO" icon = 'icons/effects/160x160.dmi' @@ -783,7 +782,7 @@ if(M in immune) continue M.notransform = 1 - M.anchored = 1 + M.anchored = TRUE if(istype(M, /mob/living/simple_animal/hostile)) var/mob/living/simple_animal/hostile/H = M H.AIStatus = AI_OFF @@ -811,7 +810,7 @@ /obj/effect/timestop/proc/unfreeze_mob(mob/living/M) M.notransform = 0 - M.anchored = 0 + M.anchored = FALSE if(istype(M, /mob/living/simple_animal/hostile)) var/mob/living/simple_animal/hostile/H = M H.AIStatus = initial(H.AIStatus) diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index 33d2550f6fd..b0a9979cf68 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -35,7 +35,7 @@ rt_assignment = "Emergency Response Team Leader" rt_job = "Emergency Response Team Leader" rt_mob_job = "ERT Commander" - special_message = "За обычных условий вы подчиняетесь старшим по рангу офицерам Защиты Активов. \n Впрочем, на время проведения операции вы подчиняетесь Офицеру Специальных Операций. \n Исключениями являются случаи, когда его приказания прямо противоречат интересам Отдела Защиты Активов или приказаниям членов ОЗА в более высоком звании, чем вы. \n Вы имеете абсолютную власть в рамках вашего отряда, и практически абсолютную в рамках зоны проведения операции. Пресекайте прямое неподчинение, но не забывайте прислушиваться к мнению специалистов." + special_message = "В обычных условий вы подчиняетесь старшим по рангу офицерам Защиты Активов. \n Впрочем, на время проведения операции вы подчиняетесь Офицеру Специальных Операций. \n Исключениями являются случаи, когда его приказания прямо противоречат интересам Отдела Защиты Активов или приказаниям членов ОЗА в более высоком звании, чем вы. \n Вы имеете абсолютную власть в рамках вашего отряда, и практически абсолютную в рамках зоны проведения операции. Пресекайте прямое неподчинение, но не забывайте прислушиваться к мнению специалистов." exp_type = EXP_TYPE_COMMAND uniform = /obj/item/clothing/under/rank/centcom_officer/sensor @@ -66,7 +66,7 @@ "Max" = "Мастер-сержант") backpack_contents = list( /obj/item/restraints/handcuffs = 1, - /obj/item/storage/lockbox/mindshield = 1, + /obj/item/storage/lockbox/mindshield/ert = 1, /obj/item/flashlight/seclite = 1 ) @@ -79,7 +79,7 @@ glasses = /obj/item/clothing/glasses/sunglasses mask = /obj/item/clothing/mask/gas/sechailer/swat suit_store = /obj/item/gun/energy/gun/pdw9/ert - belt = /obj/item/gun/projectile/automatic/pistol/sp8t + belt = /obj/item/gun/projectile/automatic/pistol/sp8/sp8t hours_dif = 250 ranks = list("Min" = "Мастер-сержант", @@ -90,7 +90,7 @@ /obj/item/camera_bug/ert = 1, /obj/item/door_remote/omni = 1, /obj/item/restraints/handcuffs = 1, - /obj/item/storage/lockbox/mindshield = 1 + /obj/item/storage/lockbox/mindshield/ert = 1 ) cybernetic_implants = list( @@ -112,7 +112,7 @@ glasses = /obj/item/clothing/glasses/night mask = /obj/item/clothing/mask/gas/sechailer/swat suit_store = /obj/item/gun/energy/gun/pdw9/ert - belt = /obj/item/gun/projectile/automatic/pistol/sp8t + belt = /obj/item/gun/projectile/automatic/pistol/sp8/sp8t hours_dif = 300 ranks = list("Min" = "Лейтенант", @@ -121,12 +121,13 @@ backpack_contents = list( /obj/item/ammo_box/magazine/sp8 = 4, /obj/item/restraints/handcuffs = 1, - /obj/item/storage/lockbox/mindshield = 1, + /obj/item/storage/lockbox/mindshield/ert = 1, /obj/item/camera_bug/ert = 1, /obj/item/door_remote/omni = 1, ) cybernetic_implants = list( + /obj/item/organ/internal/cyberimp/eyes/thermals/empproof, /obj/item/organ/internal/cyberimp/chest/nutriment_old/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, @@ -146,7 +147,7 @@ rt_mob_job = "ERT Security" uniform = /obj/item/clothing/under/rank/security/sensor back = /obj/item/storage/backpack/ert/security - belt = /obj/item/storage/belt/security/response_team + belt = /obj/item/storage/belt/security/sec pda = /obj/item/pda/heads/ert/security id = /obj/item/card/id/ert/security exp_type = EXP_TYPE_SECURITY @@ -184,7 +185,7 @@ "Max" = "Специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 3, /obj/item/storage/box/handcuffs = 1, /obj/item/grenade/flashbang = 2, @@ -209,7 +210,7 @@ shoes = /obj/item/clothing/shoes/magboots/advance gloves = /obj/item/clothing/gloves/combat suit = /obj/item/clothing/suit/space/hardsuit/ert/gamma/security - belt = /obj/item/storage/belt/security/response_team_gamma + belt = /obj/item/storage/belt/military/assault/gammaert/full suit_store = /obj/item/gun/energy/immolator/multi/sibyl glasses = /obj/item/clothing/glasses/night mask = /obj/item/clothing/mask/gas/sechailer/swat @@ -222,7 +223,7 @@ "Max" = "Старший специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 3, /obj/item/storage/box/handcuffs = 1, /obj/item/storage/box/flashbangs = 1, @@ -232,6 +233,7 @@ ) cybernetic_implants = list( + /obj/item/organ/internal/cyberimp/eyes/thermals/empproof, /obj/item/organ/internal/cyberimp/chest/nutriment_old/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, @@ -300,7 +302,7 @@ "Max" = "Специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/rcd/preloaded = 1, /obj/item/rcd_ammo = 3, @@ -336,7 +338,7 @@ "Max" = "Старший специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/rcd/combat = 1, /obj/item/rcd_ammo/large = 3, @@ -418,7 +420,7 @@ "Max" = "Специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/storage/firstaid/ertm = 1, /obj/item/storage/box/autoinjectors = 1, @@ -460,7 +462,7 @@ "Max" = "Старший специалист") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/storage/firstaid/ertm = 1, /obj/item/bodyanalyzer/advanced = 1, @@ -495,14 +497,15 @@ l_ear = /obj/item/radio/headset/ert/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses mask = /obj/item/clothing/mask/gas/sechailer/swat - belt = /obj/item/storage/belt/security/response_team + belt = /obj/item/storage/belt/security/sec id = /obj/item/card/id/centcom pda = /obj/item/pda/centcom special_message = "Вы подчиняетесь непосредственно назначенному корпорацией командиру. \n Хоть вы и можете возражать ему, прямое подчинение крайне нежелательно. Исключениями являются случаи, когда ваш командир открыто действует против интересов НТ, или случаи, когда это требуется согласно приказаниям членов вашего Ордена с высшим саном. \n В случае его отсутствия или недееспособности, вам стоит прислушиваться к мнению члена отряда с самым высоким званием." backpack_contents = list( /obj/item/storage/box/zipties = 1, - /obj/item/flashlight/seclite = 1 + /obj/item/flashlight/seclite = 1, + /obj/item/reagent_containers/food/drinks/bottle/holywater = 1 ) /datum/outfit/job/centcom/response_team/paranormal/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) @@ -538,8 +541,9 @@ "Max" = "Инквизитор") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, + /obj/item/reagent_containers/food/drinks/bottle/holywater = 1 ) @@ -569,8 +573,9 @@ "Max" = "Инквизитор") backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, + /obj/item/reagent_containers/food/drinks/bottle/holywater = 1 ) cybernetic_implants = list( @@ -633,7 +638,7 @@ mask = /obj/item/clothing/mask/gas/sechailer backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, ) @@ -656,7 +661,7 @@ r_pocket = /obj/item/scythe/tele backpack_contents = list( - /obj/item/gun/projectile/automatic/pistol/sp8t = 1, + /obj/item/gun/projectile/automatic/pistol/sp8/sp8t = 1, /obj/item/ammo_box/magazine/sp8 = 2, /obj/item/grenade/chem_grenade/antiweed = 2, /obj/item/storage/box/lights/mixed = 1, diff --git a/code/modules/ruins/lavalandruin_code/fountain_hall.dm b/code/modules/ruins/lavalandruin_code/fountain_hall.dm index 4f4dfa5c10b..484e0d2c3fd 100644 --- a/code/modules/ruins/lavalandruin_code/fountain_hall.dm +++ b/code/modules/ruins/lavalandruin_code/fountain_hall.dm @@ -41,9 +41,10 @@ to_chat(user, "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.") user.reagents.add_reagent("godblood", 20) update_icon() - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), time_between_uses) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_ICON_STATE), time_between_uses) -/obj/structure/healingfountain/update_icon() + +/obj/structure/healingfountain/update_icon_state() if(last_process + time_between_uses > world.time) icon_state = "fountain" else diff --git a/code/modules/ruins/lavalandruin_code/necropolis_lavalend.dm b/code/modules/ruins/lavalandruin_code/necropolis_lavalend.dm index 3b4c0de09ba..bc7918a0332 100644 --- a/code/modules/ruins/lavalandruin_code/necropolis_lavalend.dm +++ b/code/modules/ruins/lavalandruin_code/necropolis_lavalend.dm @@ -86,7 +86,7 @@ flick("necrclosing", src) playsound(src, 'sound/effects/stonedoor_openclose.ogg', 30, 1) -/obj/machinery/door/poddoor/impassable/necropolisdoor/update_icon() +/obj/machinery/door/poddoor/impassable/necropolisdoor/update_icon_state() if(density) icon_state = "necr" else @@ -150,7 +150,7 @@ flick("blocked_passage", src) playsound(src, 'sound/effects/stonedoor_openclose.ogg', 30, 1) -/obj/machinery/door/poddoor/impassable/necropolisdoor/multi_tile/four_tile_hor/update_icon() +/obj/machinery/door/poddoor/impassable/necropolisdoor/multi_tile/four_tile_hor/update_icon_state() if(density) icon_state = "blocked_passage" else diff --git a/code/modules/ruins/syndicate_space_base.dm b/code/modules/ruins/syndicate_space_base.dm index 1da15dd1097..a1455f56d7e 100644 --- a/code/modules/ruins/syndicate_space_base.dm +++ b/code/modules/ruins/syndicate_space_base.dm @@ -1,8 +1,8 @@ /obj/item/paper/syndicate/code_words name = "Code Words" -/obj/item/paper/syndicate/code_words/New() - ..() +/obj/item/paper/syndicate/code_words/Initialize(mapload) + . = ..() var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") var/responses = jointext(GLOB.syndicate_code_response, ", ") @@ -11,7 +11,8 @@ info += "Кодовые ответы: [responses]
    \n" info += "Используйте слова при общении с потенциальными агентами. В тоже время будьте осторожны, ибо кто угодно может оказаться потенциальным врагом." info_links = info - overlays += "paper_words" + update_icon() + // Space Base Spawners. Исспользуется переделанная копия спавнеров лавалендовских. /obj/effect/mob_spawn/human/space_base_syndicate @@ -22,9 +23,9 @@ id_job = "Syndicate Scientist" icon = 'icons/obj/machines/cryogenic2.dmi' icon_state = "cryo_s" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Эксперементируйте со смертельными химикатами, растениями, генами и вирусами. Наслаждайтесь спокойной жизнью зная, что ваша работа так или иначе насолит НТ в будущем!" - flavour_text = "Вы агент синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования на сколько можете и постарайтесь не высовываться. \ + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Экспериментируйте со смертельными химикатами, растениями, генами и вирусами. Наслаждайтесь спокойной жизнью, зная, что ваша работа так или иначе насолит НТ в будущем!" + flavour_text = "Вы — агент Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования насколько можете и постарайтесь не высовываться. \ Вам дали ясно понять, что синдикат заставит вас очень сильно пожалеть если вы разочаруете их!" outfit = /datum/outfit/space_base_syndicate assignedrole = TAIPAN_SCIENTIST @@ -108,9 +109,9 @@ name = "Syndicate Medic sleeper" mob_name = "Syndicate Medic" id_job = "Syndicate Medic" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Проводите медицинские опыты сомнительного содержания. Вылечивайте своих коллег, которые опять поссорились с генералом Синди, или оживляйте неудачных космических путников, для допросов или боргизации. Даже Синдикату нужны врачи!" - flavour_text = "Вы агент синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования на сколько можете и постарайтесь не высовываться. \ + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Проводите медицинские опыты сомнительного содержания. Вылечивайте своих коллег, которые опять поссорились с генералом Синди, или оживляйте неудачливых космических путников, для допросов или киборгизации. Даже Синдикату нужны врачи!" + flavour_text = "Вы — агент Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования насколько можете и постарайтесь не высовываться. \ Вам дали ясно понять, что синдикат заставит вас очень сильно пожалеть если вы разочаруете их!" outfit = /datum/outfit/space_base_syndicate/medic assignedrole = TAIPAN_MEDIC @@ -142,9 +143,9 @@ name = "Syndicate Botanist sleeper" mob_name = "Syndicate Botanist" id_job = "Syndicate Botanist" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Выращивайте сомнительные растения. Помогите повару накормить экипаж, а учёным создать опаснейшие растения! Наслаждайтесь силой природы в руках Синдиката!" - flavour_text = "Вы агент синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования на сколько можете и постарайтесь не высовываться. \ + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Выращивайте сомнительные растения. Помогите повару накормить экипаж, а учёным — создать опаснейшие растения! Наслаждайтесь силой природы в руках Синдиката!" + flavour_text = "Вы — агент Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования насколько можете и постарайтесь не высовываться. \ Вам дали ясно понять, что синдикат заставит вас очень сильно пожалеть если вы разочаруете их!" outfit = /datum/outfit/space_base_syndicate/botanist assignedrole = TAIPAN_BOTANIST @@ -169,9 +170,9 @@ name = "Syndicate Cargo Technician sleeper" mob_name = "Syndicate Cargo Technician" id_job = "Syndicate Cargo Technician" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Даже синдикату нужны рабочие руки, приносите людям их посылки, заказывайте и продавайте, наслаждайтесь простой работой среди всех этих учёных. Здесь всё равно платят в разы лучше!" - flavour_text = "Вы Грузчик синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Работайте с грузами, заказывайте всё что может потребоваться станции или вам и зарабатывайте реальные деньги, а не виртуальные очки!" + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Даже Синдикату нужны рабочие руки, приносите людям их посылки, заказывайте и продавайте, наслаждайтесь простой работой среди всех этих учёных. Здесь всё равно платят в разы лучше!" + flavour_text = "Вы — грузчик Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Работайте с грузами, заказывайте всё, что может потребоваться станции или вам и зарабатывайте реальные деньги, а не виртуальные очки!" outfit = /datum/outfit/space_base_syndicate/cargotech assignedrole = TAIPAN_CARGO min_hours = 10 @@ -190,9 +191,9 @@ name = "Syndicate Chef Sleeper" mob_name = "Syndicate Chef" id_job = "Syndicate Chef" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Даже синдикату нужны рабочие руки! У вас в распоряжении свой бар, кухня и ботаника. Накормите этих голодных учёных или помогите им создать последнее блюдо для ваших врагов. Здесь всё равно платят в разы лучше!" - flavour_text = "Вы Повар синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Готовьте еду и напитки экипажу и постарайтесь не высовываться!" + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Даже Синдикату нужны рабочие руки! У вас в распоряжении свой бар, кухня и ботаника. Накормите этих голодных учёных или помогите им создать последнее блюдо для ваших врагов. Здесь всё равно платят в разы лучше!" + flavour_text = "Вы — повар Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Готовьте еду и напитки экипажу и постарайтесь не высовываться!" outfit = /datum/outfit/space_base_syndicate/chef assignedrole = TAIPAN_CHEF min_hours = 10 @@ -217,9 +218,9 @@ name = "Syndicate Atmos Engineer Sleeper" mob_name = "Syndicate Atmos Engineer" id_job = "Syndicate Atmos Engineer" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Там где есть космическая станция, есть и двигатели с трубами которым нужно своё техобслуживание. Обеспечьте станцию энергией, чините повреждения после неудачных опытов учёных и отдыхайте в баре пока снова что-нибудь не взорвут. " - flavour_text = "Вы Инженер атмосферник синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Запустите двигатель, убедитесь, что на станцию подаётся достаточно электричества и воздуха, а так же чините отделы которые неприменно сломают." + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Там, где есть космическая станция, есть и двигатели с трубами, которым нужно своё техобслуживание. Обеспечьте станцию энергией, чините повреждения после неудачных опытов учёных и отдыхайте в баре, пока снова что-нибудь не взорвут. " + flavour_text = "Вы — инженер-атмосферник Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Запустите двигатель, убедитесь, что на станцию подаётся достаточно электричества и воздуха, а также чините отделы, которые непременно сломают." outfit = /datum/outfit/space_base_syndicate/engineer assignedrole = TAIPAN_ENGINEER min_hours = 10 @@ -238,9 +239,9 @@ name = "Syndicate Comms Officer sleeper" mob_name = "Syndicate Comms Officer" id_job = "Syndicate Comms Officer" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Проверяйте камеры и коммуникации, руководите станцией в случае ЧП, старайтесь помогать любым агентам синдиката на станции при этом сохраняя свою базу секретом от НТ. Вы являетесь единственным агентом с доступом в хранилище и оружейную." - flavour_text = "Вы Офицер синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Наблюдайте за станцией НТ, руководите вверенной вам базой и постарайтесь не высовываться. \ + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Проверяйте камеры и коммуникации, руководите станцией в случае ЧП, старайтесь помогать любым агентам Синдиката на станции, при этом сохраняя свою базу в секрете от НТ. Вы являетесь единственным агентом с доступом в хранилище и оружейную." + flavour_text = "Вы — офицер Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Наблюдайте за станцией НТ, руководите вверенной вам базой и постарайтесь не высовываться. \ Синдикат ясно дал вам понять, что не стоит подводить их доверие. Не разочаруйте их!" outfit = /datum/outfit/space_base_syndicate/comms assignedrole = TAIPAN_COMMS @@ -265,9 +266,9 @@ name = "Syndicate Research Director sleeper" mob_name = "Syndicate Research Director" id_job = "Syndicate Research Director" - important_info = "Не мешайте другим оперативникам синдиката (Таким как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и её сохранность является для вас высшим приоритетом!" - description = "Следите за тем чтобы учёные занимались исследованиями и не подорвали всю станцию, предоставьте синдикату результаты своих исследований через карго и помните, смерть Нанотрейзен!" - flavour_text = "Вы Директор Исследований синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания Нанотрэйзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования на сколько можете и постарайтесь не высовываться. \ + important_info = "Не мешайте другим оперативникам Синдиката (таким, как предатели или ядерные оперативники). Вы можете работать вместе или против не связанных с Синдикатом антагонистов в индивидуальном порядке. Не покидайте свою базу без разрешения администрации! Ваша база, её секретность и сохранность является для вас высшим приоритетом!" + description = "Следите за тем, чтобы учёные занимались исследованиями и не подорвали всю станцию, предоставьте Синдикату результаты своих исследований через карго и помните: смерть НаноТрейзен!" + flavour_text = "Вы Директор Исследований Синдиката, работающий на сверхсекретной научно-наблюдательной станции Тайпан, занимающейся созданием биооружия и взаимодействием с чёрным рынком. К несчастью, ваш самый главный враг, компания НаноТрейзен, имеет собственную массивную научную базу в вашем секторе. Продолжайте свои исследования насколько сможете и постарайтесь не высовываться. \ Вам дали ясно понять, что синдикат заставит вас очень сильно пожалеть если вы разочаруете их!" outfit = /datum/outfit/space_base_syndicate/rd assignedrole = TAIPAN_RD diff --git a/code/modules/ruins/ussp_base.dm b/code/modules/ruins/ussp_base.dm index 1dfc8878033..c1ff55bb4cb 100644 --- a/code/modules/ruins/ussp_base.dm +++ b/code/modules/ruins/ussp_base.dm @@ -61,8 +61,8 @@ return H.rename_character(null, "[pick("Полковник", "Генерал майор", "Генерал лейтенант", "Генерал полковник")] [H.real_name]") - H.add_language("Neo-Russkiya") - H.set_default_language(GLOB.all_languages["Neo-Russkiya"]) + H.add_language(LANGUAGE_NEO_RUSSIAN) + H.set_default_language(GLOB.all_languages[LANGUAGE_NEO_RUSSIAN]) var/obj/item/card/id/I = H.wear_id if(istype(I)) H.sec_hud_set_ID() @@ -124,9 +124,9 @@ return H.rename_character(null, "[pick("Старший сержант", "Старшина", "Прапорщик", "Старший прапорщик")] [H.real_name]") - H.add_language("Neo-Russkiya") - H.remove_language("Galactic Common") - H.set_default_language(GLOB.all_languages["Neo-Russkiya"]) + H.add_language(LANGUAGE_NEO_RUSSIAN) + H.remove_language(LANGUAGE_GALACTIC_COMMON) + H.set_default_language(GLOB.all_languages[LANGUAGE_NEO_RUSSIAN]) var/obj/item/card/id/I = H.wear_id if(istype(I)) H.sec_hud_set_ID() @@ -189,9 +189,9 @@ return H.rename_character(null, "[pick("Сержант", "Старший сержант", "Младший лейтенант")] [H.real_name]") - H.add_language("Neo-Russkiya") - H.remove_language("Galactic Common") - H.set_default_language(GLOB.all_languages["Neo-Russkiya"]) + H.add_language(LANGUAGE_NEO_RUSSIAN) + H.remove_language(LANGUAGE_GALACTIC_COMMON) + H.set_default_language(GLOB.all_languages[LANGUAGE_NEO_RUSSIAN]) var/obj/item/card/id/I = H.wear_id if(istype(I)) H.sec_hud_set_ID() @@ -241,9 +241,9 @@ return H.rename_character(null, "[pick("Прапорщик", "Старший прапорщик", "Младший лейтенант", "Лейтенант")] [H.real_name]") - H.add_language("Neo-Russkiya") - H.remove_language("Galactic Common") - H.set_default_language(GLOB.all_languages["Neo-Russkiya"]) + H.add_language(LANGUAGE_NEO_RUSSIAN) + H.remove_language(LANGUAGE_GALACTIC_COMMON) + H.set_default_language(GLOB.all_languages[LANGUAGE_NEO_RUSSIAN]) var/obj/item/card/id/I = H.wear_id if(istype(I)) H.sec_hud_set_ID() diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index c401d24fe5d..8af80c16e7f 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -8,7 +8,6 @@ var/event var/swiping = FALSE // on swiping screen? var/list/ert_chosen = list() - var/confirmed = FALSE // This variable is set by the device that confirms the request. var/confirm_delay = 5 SECONDS // time allowed for a second person to confirm a swipe. var/busy = FALSE // Busy when waiting for authentication or an event request has been sent from this device. var/obj/machinery/keycard_auth/event_source @@ -16,7 +15,7 @@ var/mob/event_confirmed_by var/ert_reason - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 @@ -29,7 +28,7 @@ to_chat(user, "The station AI is not to interact with these devices.") return -/obj/machinery/keycard_auth/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/machinery/keycard_auth/attackby(obj/item/W, mob/user, params) if(stat & (NOPOWER|BROKEN)) to_chat(user, "This device is not powered.") return @@ -39,15 +38,14 @@ if(active) //This is not the device that made the initial request. It is the device confirming the request. if(event_source) - event_source.confirmed = TRUE - event_source.event_confirmed_by = usr + event_source.event_confirmed_by = user SStgui.update_uis(event_source) SStgui.update_uis(src) else if(swiping) if(event == "Emergency Response Team" && !ert_reason) to_chat(user, "Supply a reason for calling the ERT first!") return - event_triggered_by = usr + event_triggered_by = user SStgui.update_uis(src) broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices else @@ -56,12 +54,26 @@ return return ..() -/obj/machinery/keycard_auth/power_change() - if(powered(ENVIRON)) - stat &= ~NOPOWER - icon_state = "auth_off" + +/obj/machinery/keycard_auth/update_icon_state() + if(event_triggered_by || event_source) + icon_state = "auth_on" else - stat |= NOPOWER + icon_state = "auth_off" + + +/obj/machinery/keycard_auth/update_overlays() + . = ..() + underlays.Cut() + + if(event_triggered_by || event_source) + underlays += emissive_appearance(icon, "auth_lightmask") + + +/obj/machinery/keycard_auth/power_change(forced = FALSE) + if(!..()) + return + update_icon() /obj/machinery/keycard_auth/attack_ghost(mob/user) ui_interact(user) @@ -119,43 +131,45 @@ active = FALSE event = null swiping = FALSE - confirmed = FALSE event_source = null - icon_state = "auth_off" event_triggered_by = null event_confirmed_by = null + set_light(0) + update_icon() + /obj/machinery/keycard_auth/proc/broadcast_request() - icon_state = "auth_on" + update_icon() + set_light(1, LIGHTING_MINIMUM_POWER) for(var/obj/machinery/keycard_auth/KA in GLOB.machines) - if(KA == src) continue - KA.reset() - spawn() - KA.receive_request(src) - - sleep(confirm_delay) - if(confirmed) - confirmed = FALSE - trigger_event(event) - add_game_logs("[key_name_log(event_triggered_by)] triggered and [key_name_log(event_confirmed_by)] confirmed event [event]", event_triggered_by) - message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1) + if(KA == src) + continue + KA.receive_request(src) + + addtimer(CALLBACK(src, PROC_REF(reset)), confirm_delay) + + +/obj/machinery/keycard_auth/proc/confirm_and_trigger() + trigger_event(event) + add_game_logs("[key_name_log(event_triggered_by)] triggered and [key_name_log(event_confirmed_by)] confirmed event [event]", event_triggered_by) + message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1) reset() + /obj/machinery/keycard_auth/proc/receive_request(var/obj/machinery/keycard_auth/source) if(stat & (BROKEN|NOPOWER)) return + reset() + + set_light(1, LIGHTING_MINIMUM_POWER) event_source = source busy = TRUE active = TRUE SStgui.update_uis(src) - icon_state = "auth_on" + update_icon() - sleep(confirm_delay) + addtimer(CALLBACK(src, PROC_REF(reset)), confirm_delay) - event_source = null - icon_state = "auth_off" - active = FALSE - busy = FALSE /obj/machinery/keycard_auth/proc/trigger_event() switch(event) @@ -182,13 +196,11 @@ if(check_rights(R_EVENT, 0, C.mob)) fullmin_count++ if(fullmin_count) + addtimer(CALLBACK(src, PROC_REF(remind_admins), ert_reason, event_triggered_by), 5 MINUTES) GLOB.ert_request_answered = TRUE ERT_Announce(ert_reason , event_triggered_by, 0) ert_reason = null SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("ert", "called")) - spawn(3000) - if(!GLOB.ert_request_answered) - ERT_Announce(ert_reason , event_triggered_by, 1) else var/list/excludemodes = list(/datum/game_mode/nuclear, /datum/game_mode/blob) if(SSticker.mode.type in excludemodes) @@ -199,6 +211,14 @@ return trigger_armed_response_team(new /datum/response_team/amber) // No admins? No problem. Automatically send a code amber ERT. + +/obj/machinery/keycard_auth/proc/remind_admins(old_reason, event_triggered_by) + if(GLOB.ert_request_answered) + GLOB.ert_request_answered = FALSE // For ERT requests that may come later + return + ERT_Announce(old_reason, event_triggered_by, repeat_warning = TRUE) + + /obj/machinery/keycard_auth/proc/is_ert_blocked() return SSticker.mode && SSticker.mode.ert_disabled @@ -210,7 +230,7 @@ GLOBAL_VAR_INIT(station_all_access, 0) for(var/area/maintenance/A in GLOB.all_areas) // Why are these global lists? AAAAAAAAAAAAAA for(var/obj/machinery/door/airlock/D in A.machinery_cache) D.emergency = 1 - D.update_icon(0) + D.update_icon() GLOB.minor_announcement.Announce("Ограничения на доступ к техническим и внешним шл+юзам были сняты.") GLOB.maint_all_access = 1 SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "enabled")) @@ -219,7 +239,7 @@ GLOBAL_VAR_INIT(station_all_access, 0) for(var/area/maintenance/A in GLOB.all_areas) for(var/obj/machinery/door/airlock/D in A.machinery_cache) D.emergency = 0 - D.update_icon(0) + D.update_icon() GLOB.minor_announcement.Announce("Ограничения на доступ к техническим и внешним шл+юзам были возобновлены.") GLOB.maint_all_access = 0 SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "disabled")) @@ -228,7 +248,7 @@ GLOBAL_VAR_INIT(station_all_access, 0) for(var/obj/machinery/door/airlock/D in GLOB.airlocks) if(is_station_level(D.z)) D.emergency = 1 - D.update_icon(0) + D.update_icon() GLOB.minor_announcement.Announce("Ограничения на доступ ко всем шл+юзам станции были сняты в связи с происходящим кризисом. Статьи о незаконном проникновении по-прежнему действуют, если командование не заявит об обратном.") GLOB.station_all_access = 1 SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency station access", "enabled")) @@ -237,7 +257,7 @@ GLOBAL_VAR_INIT(station_all_access, 0) for(var/obj/machinery/door/airlock/D in GLOB.airlocks) if(is_station_level(D.z)) D.emergency = 0 - D.update_icon(0) + D.update_icon() GLOB.minor_announcement.Announce("Ограничения на доступ ко всем шл+юзам станции были вновь возобновлены. Если вы застряли, обратитесь за помощью к ИИ станции, или к коллегам.") GLOB.station_all_access = 0 SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency station access", "disabled")) diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 1abcb2be9dc..c72e523c649 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -10,20 +10,9 @@ GLOBAL_VAR_INIT(security_level, 0) GLOBAL_DATUM_INIT(security_announcement_up, /datum/announcement/priority/security, new(do_log = 0, do_newscast = 0, new_sound = sound('sound/misc/notice1.ogg'))) GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/security, new(do_log = 0, do_newscast = 0)) -/proc/set_security_level(var/level) - switch(level) - if("green") - level = SEC_LEVEL_GREEN - if("blue") - level = SEC_LEVEL_BLUE - if("red") - level = SEC_LEVEL_RED - if("gamma") - level = SEC_LEVEL_GAMMA - if("epsilon") - level = SEC_LEVEL_EPSILON - if("delta") - level = SEC_LEVEL_DELTA + +/proc/set_security_level(level) + level = istext(level) ? seclevel2num(level) : level //Will not be announced if you try to set to the same level as it already is if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level) @@ -36,13 +25,11 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur GLOB.security_announcement_down.Announce("Все угрозы для станции устранены. Все оружие должно быть в кобуре, и законы о конфиденциальности вновь полностью соблюдаются.","ВНИМАНИЕ! Уровень угрозы понижен до ЗЕЛЁНОГО.") GLOB.security_level = SEC_LEVEL_GREEN unset_stationwide_emergency_lighting() - post_status("alert", "outline") - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_green") - FA.update_icon() + if(SSshuttle.emergency.timer) + post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) + else + post_status(STATUS_DISPLAY_TIME) + update_station_firealarms() if(SEC_LEVEL_BLUE) if(GLOB.security_level < SEC_LEVEL_BLUE) @@ -51,13 +38,9 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur GLOB.security_announcement_down.Announce("Непосредственная угроза миновала. Служба безопасности может больше не держать оружие в полной боевой готовности, но может по-прежнему держать его на виду. Выборочные обыски запрещены.","ВНИМАНИЕ! Уровень угрозы понижен до СИНЕГО") GLOB.security_level = SEC_LEVEL_BLUE - post_status("alert", "default") + post_status(STATUS_DISPLAY_ALERT, "default") unset_stationwide_emergency_lighting() - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_blue") - FA.update_icon() + update_station_firealarms() if(SEC_LEVEL_RED) if(GLOB.security_level < SEC_LEVEL_RED) @@ -71,13 +54,8 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur R.locked = 0 R.update_icon() - post_status("alert", "redalert") - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_red") - FA.update_icon() + post_status(STATUS_DISPLAY_ALERT, "redalert") + update_station_firealarms() if(SEC_LEVEL_GAMMA) GLOB.security_announcement_up.Announce("Центральным Командованием был установлен Код Гамма. Станция находится под угрозой полного уничтожения. Службе безопасности следует получить полное вооружение и приготовиться к ведению боевых действий с враждебными элементами на борту станции. Гражданский персонал обязан немедленно обратиться к Главам отделов для получения дальнейших указаний.", "Внимание! Код ГАММА!", sound('sound/effects/new_siren.ogg')) @@ -89,13 +67,8 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur R.locked = 0 R.update_icon() - post_status("alert", "gammaalert") - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_gamma") - FA.update_icon() + post_status(STATUS_DISPLAY_ALERT, "gammaalert") + update_station_firealarms() if(SEC_LEVEL_EPSILON) for(var/mob/M in GLOB.player_list) @@ -112,14 +85,9 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur GLOB.security_announcement_up.Announce("Механизм самоуничтожения станции задействован. Все члены экипажа обязан подчиняться всем указаниям, данными Главами отделов. Любые нарушения этих приказов наказуемы уничтожением на месте. Это не учебная тревога.","ВНИМАНИЕ! КОД ДЕЛЬТА!", new_sound = sound('sound/effects/deltaalarm.ogg')) GLOB.security_level = SEC_LEVEL_DELTA - post_status("alert", "deltaalert") - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_delta") - FA.update_icon() + post_status(STATUS_DISPLAY_ALERT, "deltaalert") set_stationwide_emergency_lighting() + update_station_firealarms() SSblackbox.record_feedback("tally", "security_level_changes", 1, level) return @@ -129,8 +97,14 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur if(GLOB.sibsys_automode && !isnull(GLOB.sybsis_registry)) for(var/obj/item/sibyl_system_mod/mod in GLOB.sybsis_registry) mod.sync_limit() - else - return + + +/proc/update_station_firealarms() + for(var/obj/machinery/firealarm/alarm as anything in GLOB.firealarms) + if(is_station_contact(alarm.z)) + alarm.update_icon() + alarm.update_fire_light() + /proc/get_security_level() switch(GLOB.security_level) @@ -147,7 +121,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur if(SEC_LEVEL_DELTA) return "delta" -/proc/num2seclevel(var/num) +/proc/num2seclevel(num) switch(num) if(SEC_LEVEL_GREEN) return "green" @@ -162,8 +136,8 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur if(SEC_LEVEL_DELTA) return "delta" -/proc/seclevel2num(var/seclevel) - switch( lowertext(seclevel) ) +/proc/seclevel2num(seclevel) + switch(lowertext(seclevel)) if("green") return SEC_LEVEL_GREEN if("blue") @@ -293,22 +267,16 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur /proc/epsilon_process() GLOB.security_announcement_up.Announce("Центральным командованием был установлен код ЭПСИЛОН. Все контракты расторгнуты.","ВНИМАНИЕ! КОД ЭПСИЛОН", new_sound = sound('sound/effects/epsilon.ogg')) GLOB.security_level = SEC_LEVEL_EPSILON - post_status("alert", "epsilonalert") + post_status(STATUS_DISPLAY_ALERT, "epsilonalert") for(var/area/A as anything in GLOB.all_areas) if(!is_station_level(A.z)) continue - for(var/L in A.lights_cache) - var/obj/machinery/light/light = L + for(var/obj/machinery/light/light as anything in A.lights_cache) if(light.status) continue light.fire_mode = TRUE light.update() - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_contact(FA.z)) - FA.overlays.Cut() - FA.overlays += image('icons/obj/machines/monitors.dmi', "overlay_epsilon") - FA.update_icon() + update_station_firealarms() GLOB.PDA_Manifest = list(\ "heads" = list(),\ "pro" = list(),\ diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index f18815403b0..b19fa04f2ae 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -334,14 +334,20 @@ icon_state = "dorm_available" density = 0 -/obj/machinery/computer/shuttle/pod/update_icon() - return + +/obj/machinery/computer/shuttle/pod/update_icon_state() + icon_state = "dorm_[emagged ? "emag" : "available"]" + + +/obj/machinery/computer/shuttle/pod/update_overlays() + . = list() + /obj/machinery/computer/shuttle/pod/emag_act(mob/user) if(user) to_chat(user, " Access requirements overridden. The pod may now be launched manually at any time.") - admin_controlled = 0 - icon_state = "dorm_emag" + admin_controlled = FALSE + update_icon(UPDATE_ICON_STATE) /obj/docking_port/stationary/random name = "escape pod" diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 2cfe4af85b6..4ca3506ee92 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -299,6 +299,7 @@ visible_icon = FALSE use_static = FALSE simulated = FALSE + ai_detector_visible = FALSE // The Shuttle Docker does not trigger the AI Detector var/list/placement_images = list() var/list/placed_images = list() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 8ba53824fc9..8ad1bb68b9c 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -10,7 +10,7 @@ icon_state = "pinonfar" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - anchored = 1 + anchored = TRUE var/id dir = NORTH //this should point -away- from the dockingport door, ie towards the ship diff --git a/code/modules/shuttle/shuttle_manipulator.dm b/code/modules/shuttle/shuttle_manipulator.dm index 8ba798e3bf9..3df1e4c8af6 100644 --- a/code/modules/shuttle/shuttle_manipulator.dm +++ b/code/modules/shuttle/shuttle_manipulator.dm @@ -25,18 +25,14 @@ var/list/templates = list() var/list/shuttle_data = list() -/obj/machinery/shuttle_manipulator/New() +/obj/machinery/shuttle_manipulator/Initialize(mapload) . = ..() - update_icon() - -/obj/machinery/shuttle_manipulator/update_icon() - overlays.Cut() - var/image/hologram_projection = image(icon, "hologram_on") - hologram_projection.pixel_y = 22 - var/image/hologram_ship = image(icon, "hologram_whiteship") - hologram_ship.pixel_y = 27 - overlays += hologram_projection - overlays += hologram_ship + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/shuttle_manipulator/update_overlays() + . = ..() + . += image(icon, icon_state = "hologram_on", pixel_y = 22) + . += image(icon, icon_state = "hologram_whiteship", pixel_y = 27) /obj/machinery/shuttle_manipulator/attack_ghost(user as mob) attack_hand(user) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 34e4dd77998..459dabe861c 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -341,12 +341,12 @@ if(istype(Crate, /obj/structure/closet/crate)) var/obj/structure/closet/crate/CR = Crate CR.manifest = slip - CR.update_icon() + CR.update_icon(UPDATE_OVERLAYS) CR.announce_beacons = object.announce_beacons.Copy() if(istype(Crate, /obj/structure/largecrate)) var/obj/structure/largecrate/LC = Crate LC.manifest = slip - LC.update_icon() + LC.update_icon(UPDATE_OVERLAYS) return Crate @@ -388,7 +388,6 @@ return TRUE add_fingerprint(user) - post_signal("supply") ui_interact(user) return @@ -433,6 +432,7 @@ data["canapprove"] = (SSshuttle.supply.getDockedId() == "supply_away") && !(SSshuttle.supply.mode != SHUTTLE_IDLE) && !is_public data["points"] = round(SSshuttle.points) + data["credits"] = SSshuttle.cargo_money_account.money data["moving"] = SSshuttle.supply.mode != SHUTTLE_IDLE data["at_station"] = SSshuttle.supply.getDockedId() == "supply_home" @@ -449,7 +449,7 @@ var/datum/supply_packs/pack = SSshuttle.supply_packs[set_name] var/has_sale = pack.cost < initial(pack.cost) if((pack.hidden && hacked) || (pack.contraband && can_order_contraband) || (pack.special && pack.special_enabled) || (!pack.contraband && !pack.hidden && !pack.special)) - packs_list.Add(list(list("name" = pack.name, "cost" = pack.cost, "ref" = "[pack.UID()]", "contents" = pack.ui_manifest, "cat" = pack.group, "has_sale" = has_sale))) + packs_list.Add(list(list("name" = pack.name, "cost" = pack.cost, "creditsCost" = pack.credits_cost, "ref" = "[pack.UID()]", "contents" = pack.ui_manifest, "cat" = pack.group, "has_sale" = has_sale))) data["supply_packs"] = packs_list @@ -495,7 +495,6 @@ SSshuttle.toggleShuttle("supply", "supply_home", "supply_away", 1) investigate_log("[key_name_log(usr)] has sent the supply shuttle away. Remaining points: [SSshuttle.points]. Shuttle contents: [SSshuttle.sold_atoms]", INVESTIGATE_CARGO) else if(!SSshuttle.supply.request(SSshuttle.getDock("supply_home"))) - post_signal("supply") if(LAZYLEN(SSshuttle.shoppinglist) && prob(10)) var/datum/supply_order/O = new /datum/supply_order() O.ordernum = SSshuttle.ordernum @@ -568,6 +567,8 @@ else if(P.can_approve(usr)) SSshuttle.requestlist.Cut(i,i+1) SSshuttle.points -= P.cost + if(P.credits_cost) + SSshuttle.cargo_money_account.money -= P.credits_cost SSshuttle.shoppinglist += O P.times_ordered += 1 investigate_log("[key_name_log(usr)] has authorized an order for [P.name]. Remaining points: [SSshuttle.points].", INVESTIGATE_CARGO) @@ -598,16 +599,3 @@ ccmsg_browser.set_content(SSshuttle.centcom_message) ccmsg_browser.open() -/obj/machinery/computer/supplycomp/proc/post_signal(command) - var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) - - if(!frequency) return - - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - - frequency.post_signal(src, status_signal) - - diff --git a/code/modules/spacepods/construction.dm b/code/modules/spacepods/construction.dm index cc408ccbd9b..098565e7c2b 100644 --- a/code/modules/spacepods/construction.dm +++ b/code/modules/spacepods/construction.dm @@ -2,7 +2,7 @@ density = 1 opacity = 0 - anchored = 1 + anchored = TRUE layer = 3.9 icon = 'icons/goonstation/48x48/pod_construction.dmi' diff --git a/code/modules/spacepods/lock_buster.dm b/code/modules/spacepods/lock_buster.dm index 8a83315ce3d..57ff9030524 100644 --- a/code/modules/spacepods/lock_buster.dm +++ b/code/modules/spacepods/lock_buster.dm @@ -3,12 +3,15 @@ desc = "Destroys a podlock in mere seconds once applied. Waranty void if used." icon = 'icons/obj/device.dmi' icon_state = "lock_buster_off" - var/on = 0 + var/on = FALSE -/obj/item/lock_buster/attack_self(mob/user as mob) + +/obj/item/lock_buster/update_icon_state() + icon_state = "lock_buster_[on ? "on" : "off"]" + + +/obj/item/lock_buster/attack_self(mob/user = usr) on = !on - if(on) - icon_state = "lock_buster_on" - else - icon_state = "lock_buster_off" - to_chat(usr, "You turn the [src] [on ? "on" : "off"].") + update_icon(UPDATE_ICON_STATE) + to_chat(user, span_notice("You turn the [src] [on ? "on" : "off"].")) + diff --git a/code/modules/spacepods/parts.dm b/code/modules/spacepods/parts.dm index ec1d8665023..edafdd18ebe 100644 --- a/code/modules/spacepods/parts.dm +++ b/code/modules/spacepods/parts.dm @@ -13,7 +13,7 @@ icon_state = "" flags = CONDUCT density = 0 - anchored = 0 + anchored = FALSE var/link_to = null var/link_angle = 0 @@ -74,7 +74,7 @@ pod.loc = F.loc qdel(F) playsound(get_turf(src), O.usesound, 50, 1) - if(istype(O, /obj/item/wrench)) + if(O.tool_behaviour == TOOL_WRENCH) to_chat(user, "You [!anchored ? "secure \the [src] in place." : "remove the securing bolts."]") anchored = !anchored density = anchored diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index cd1eaef4c68..4f3a77e2aee 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -18,7 +18,7 @@ density = 1 //Dense. To raise the heat. opacity = 0 - anchored = 1 + anchored = TRUE resistance_flags = ACID_PROOF layer = 3.9 @@ -726,7 +726,7 @@ playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) return 1 -/obj/spacepod/MouseDrop_T(atom/A, mob/user) +/obj/spacepod/MouseDrop_T(atom/A, mob/user, params) if(user == pilot || (user in passengers)) return @@ -1075,19 +1075,19 @@ switch(direction) if(NORTH) if(inertia_dir == SOUTH) - inertia_dir = 0 + inertia_dir = NONE moveship = 0 if(SOUTH) if(inertia_dir == NORTH) - inertia_dir = 0 + inertia_dir = NONE moveship = 0 if(EAST) if(inertia_dir == WEST) - inertia_dir = 0 + inertia_dir = NONE moveship = 0 if(WEST) if(inertia_dir == EAST) - inertia_dir = 0 + inertia_dir = NONE moveship = 0 if(moveship) Move(get_step(src, direction), direction) diff --git a/code/modules/station_goals/bfl.dm b/code/modules/station_goals/bfl.dm index 88ed4b4144b..ac71d483ad0 100644 --- a/code/modules/station_goals/bfl.dm +++ b/code/modules/station_goals/bfl.dm @@ -168,9 +168,10 @@ receiver.mining = TRUE return TRUE + /obj/machinery/power/bfl_emitter/proc/emitter_activate() state = TRUE - icon_state = "Emitter_On" + update_icon(UPDATE_ICON_STATE) var/turf/location = get_step(src, NORTH) location.ex_act(1) working_sound() @@ -190,7 +191,7 @@ /obj/machinery/power/bfl_emitter/proc/emitter_deactivate() state = FALSE - icon_state = "Emitter_Off" + update_icon(UPDATE_ICON_STATE) if(receiver) receiver.mining = FALSE if(receiver.lens?.state) @@ -200,12 +201,19 @@ qdel(laser) laser = null + /obj/machinery/power/bfl_emitter/proc/working_sound() set waitfor = FALSE while(state) playsound(src, 'sound/BFL/emitter.ogg', 100, TRUE) sleep(25) + +/obj/machinery/power/bfl_emitter/update_icon_state() + icon_state = "Emitter_[state ? "On" : "Off"]" + + + //code stolen from bluespace_tap, including comment below. He was right about the new datum //code stolen from dna vault, inculding comment below. Taking bets on that datum being made ever. //TODO: Replace this,bsa and gravgen with some big machinery datum @@ -273,7 +281,7 @@ ///Used for storing last icon update for receiver lights on borders of receiver var/last_light_state_number = 0 -/obj/machinery/bfl_receiver/attack_hand(mob/user as mob) +/obj/machinery/bfl_receiver/attack_hand(mob/user) if(..()) return TRUE var/response @@ -299,7 +307,7 @@ var/turf/location = get_turf(src) internal.empty_storage(location) ore_count = 0 - icon_change() + update_state() /obj/machinery/bfl_receiver/crowbar_act(mob/user, obj/item/I) @@ -312,17 +320,19 @@ receiver_activate() ///This proc handles light updating on borders of BFL receiver. -/obj/machinery/bfl_receiver/proc/icon_change() +/obj/machinery/bfl_receiver/proc/update_state() var/light_state = clamp(length(internal.contents), 0, 20) if(last_light_state_number == light_state) return - receiver_light.icon_state = "Receiver_Light_[light_state]" + receiver_light.light_amount = light_state last_light_state_number = light_state + receiver_light.update_icon(UPDATE_ICON_STATE) + /obj/machinery/bfl_receiver/process() - if (!(mining && state)) + if(!(mining && state)) return - if (ore_count >= internal.storage_slots * 50) + if(ore_count >= internal.storage_slots * 50) return switch(ore_type) if(PLASMA) @@ -332,7 +342,7 @@ internal.handle_item_insertion(new /obj/item/stack/ore/glass, TRUE) ore_count += 1 - icon_change() + update_state() /obj/machinery/bfl_receiver/Initialize() . = ..() @@ -352,13 +362,17 @@ ore_type = NOTHING /obj/machinery/bfl_receiver/Destroy() - overlays.Cut() qdel(receiver_light) return ..() + +/obj/machinery/bfl_receiver/update_icon_state() + icon_state = "Receiver_[state ? "On" : "Off"]" + + /obj/machinery/bfl_receiver/proc/receiver_activate() state = TRUE - icon_state = "Receiver_On" + update_icon(UPDATE_ICON_STATE) var/turf/T = get_turf(src) T.ChangeTurf(/turf/simulated/floor/chasm/straight_down/lava_land_surface) @@ -366,7 +380,7 @@ var/turf/turf_under = get_step(src, SOUTH) var/turf/T = get_turf(src) state = FALSE - icon_state = "Receiver_Off" + update_icon(UPDATE_ICON_STATE) T.ChangeTurf(turf_under.type) /obj/machinery/bfl_receiver/Crossed(atom/movable/AM, oldloc) @@ -386,11 +400,19 @@ layer = LOW_ITEM_LAYER flags = INDESTRUCTIBLE anchored = TRUE + var/light_amount = 0 + /atom/movable/bfl_receiver_light/Initialize(mapload) . = ..() pixel_x = -32 pixel_y = -32 + + +/atom/movable/bfl_receiver_light/update_icon_state() + icon_state = "Receiver_Light_[light_amount]" + + //////// //Lens// //////// @@ -406,7 +428,7 @@ var/step_count = 0 var/state = FALSE -/obj/machinery/bfl_lens/update_icon() +/obj/machinery/bfl_lens/update_icon_state() if(state) icon_state = "Lens_On" else if(anchored) @@ -414,25 +436,33 @@ else icon_state = "Lens_Pull" + +/obj/machinery/bfl_lens/update_overlays() + . = ..() + if(state) + . += image('icons/obj/machines/BFL_Mission/Laser.dmi', icon_state = "Laser_Blue", pixel_y = 64, layer = GASFIRE_LAYER) + + /obj/machinery/bfl_lens/proc/activate_lens() state = TRUE update_icon() - overlays += image('icons/obj/machines/BFL_Mission/Laser.dmi', icon_state = "Laser_Blue", pixel_y = 64, layer = GASFIRE_LAYER) set_light(8) working_sound() + /obj/machinery/bfl_lens/proc/deactivate_lens() - overlays.Cut() state = FALSE update_icon() set_light(0) + /obj/machinery/bfl_lens/proc/working_sound() set waitfor = FALSE while(state) playsound(src, 'sound/BFL/receiver.ogg', 100, TRUE) sleep(25) + /obj/machinery/bfl_lens/wrench_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = 0)) @@ -449,10 +479,10 @@ pixel_x = -32 pixel_y = -32 + /obj/machinery/bfl_lens/Destroy() visible_message("Lens shatters in a million pieces") playsound(src, "shatter", 70, 1) - overlays.Cut() return ..() diff --git a/code/modules/station_goals/brs/brs_portable_scanner.dm b/code/modules/station_goals/brs/brs_portable_scanner.dm index 60a4edc4586..9ee1e005b9b 100644 --- a/code/modules/station_goals/brs/brs_portable_scanner.dm +++ b/code/modules/station_goals/brs/brs_portable_scanner.dm @@ -130,21 +130,15 @@ cause = "[src] was working too long within critical range of a rift." ) -/obj/machinery/brs_portable_scanner/update_icon() - overlays.Cut() - set_light(0) + +/obj/machinery/brs_portable_scanner/update_icon_state() var/prefix = initial(icon_state) if(stat & BROKEN) icon_state = "[prefix]-broken" return - - if(panel_open) - overlays += image(icon, "[prefix]-panel") - if(!anchored) icon_state = prefix return - if((scanning_status == SCAN_OFF) || (stat & NOPOWER)) icon_state ="[prefix]-anchored" return @@ -153,14 +147,28 @@ return if(scanning_status == SCAN_NORMAL) icon_state = "[prefix]-act" - set_light(l_range = 1, l_power = 1, l_color = COLOR_BLUE_LIGHT) return if(scanning_status == SCAN_CRITICAL) icon_state = "[prefix]-act-critical" + + +/obj/machinery/brs_portable_scanner/update_overlays() + . = ..() + if(panel_open) + . += image(icon, "[initial(icon_state)]-panel") + + +/obj/machinery/brs_portable_scanner/proc/brs_light_update() + if(scanning_status == SCAN_NORMAL) + set_light(l_range = 1, l_power = 1, l_color = COLOR_BLUE_LIGHT) + return + if(scanning_status == SCAN_CRITICAL) set_light(l_range = 1, l_power = 1, l_color = COLOR_RED_LIGHT) return + set_light(0) + -/obj/machinery/brs_portable_scanner/power_change() +/obj/machinery/brs_portable_scanner/power_change(forced = FALSE) ..() if(stat & NOPOWER) SStgui.close_uis(src) @@ -169,12 +177,14 @@ else if(scanning_status != SCAN_OFF) playsound(loc, activation_sound, 100) - update_icon() + update_icon(UPDATE_ICON_STATE) + brs_light_update() /obj/machinery/brs_portable_scanner/obj_break() ..() SStgui.close_uis(src) - update_icon() + update_icon(UPDATE_ICON_STATE) + brs_light_update() /obj/machinery/brs_portable_scanner/screwdriver_act(mob/living/user, obj/item/I) . = TRUE @@ -189,7 +199,8 @@ return default_deconstruction_screwdriver(user, icon_state, icon_state, I) - update_icon() + update_icon(UPDATE_OVERLAYS) + brs_light_update() if(panel_open) SStgui.close_uis(src) @@ -216,7 +227,8 @@ scanning_status = SCAN_OFF default_unfasten_wrench(user, I, 4 SECONDS) - update_icon() + update_icon(UPDATE_ICON_STATE) + brs_light_update() if(!anchored) SStgui.close_uis(src) @@ -228,7 +240,7 @@ continue if(scanner.anchored) anchored = FALSE - update_icon() + update_icon(UPDATE_ICON_STATE) return // Update density @@ -244,7 +256,7 @@ // Reset status if the scanner was turned on before the failure. turn_on() else - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/brs_portable_scanner/emag_act(mob/user) if(!emagged) @@ -342,7 +354,8 @@ // Set timer to kaboom failure_time = world.time + time_for_failure - update_icon() + update_icon(UPDATE_ICON_STATE) + brs_light_update() /obj/machinery/brs_portable_scanner/proc/toggle() switching = TRUE diff --git a/code/modules/station_goals/brs/brs_reward.dm b/code/modules/station_goals/brs/brs_reward.dm index 819a5118965..e5e4a010c62 100644 --- a/code/modules/station_goals/brs/brs_reward.dm +++ b/code/modules/station_goals/brs/brs_reward.dm @@ -4,7 +4,7 @@ origin_tech = "bluespace=9;magnets=8" icon_state = "docs_part" -/obj/item/paper/researchnotes_brs/update_icon() +/obj/item/paper/researchnotes_brs/update_icon_state() return /obj/structure/toilet/bluespace @@ -14,13 +14,18 @@ var/teleport_sound = 'sound/magic/lightning_chargeup.ogg' var/teleport_sound_cooldown = FALSE -/obj/structure/toilet/bluespace/update_icon() + +/obj/structure/toilet/bluespace/update_icon_state() . = ..() icon_state = "bluespace_toilet[open][cistern]" - overlays.Cut() + + +/obj/structure/toilet/bluespace/update_overlays() + . = ..() if(open) overlays += image(icon, "bluespace_toilet_singularity") + /obj/structure/toilet/bluespace/attack_hand(mob/living/user) . = ..() if(open) @@ -47,8 +52,8 @@ /obj/structure/toilet/bluespace/nt icon_state = "bluespace_toilet00-NT" -/obj/structure/toilet/bluespace/nt/update_icon() - . = ..() +/obj/structure/toilet/bluespace/nt/update_icon_state() + ..() icon_state = "bluespace_toilet[open][cistern]-NT" /obj/effect/spawner/lootdrop/bluespace_rift diff --git a/code/modules/station_goals/brs/brs_server.dm b/code/modules/station_goals/brs/brs_server.dm index 4385ef8c9c6..a80053b8212 100644 --- a/code/modules/station_goals/brs/brs_server.dm +++ b/code/modules/station_goals/brs/brs_server.dm @@ -85,7 +85,8 @@ probe_cooldown_end_time = world.time + probe_cooldown_time new_component_parts() - update_icon() + update_icon(UPDATE_ICON_STATE) + create_light() /obj/machinery/brs_server/Destroy() GLOB.bluespace_rifts_server_list.Remove(src) @@ -144,31 +145,48 @@ // Return index of the last element return length(data) -/obj/machinery/brs_server/update_icon() + +/obj/machinery/brs_server/update_icon_state() var/prefix = initial(icon_state) - overlays.Cut() + if(stat & (BROKEN)) + icon_state = "[prefix]-broken" + return + if(stat & (NOPOWER)) + icon_state = prefix + return + if(emagged) + icon_state = "[prefix]-on-emagged" + return + + icon_state = "[prefix]-on" + + +/obj/machinery/brs_server/update_overlays() + . = ..() if(panel_open) - overlays += image(icon, "[initial(icon_state)]-panel") + . += image(icon, "[initial(icon_state)]-panel") + +/obj/machinery/brs_server/proc/create_light() if(stat & (BROKEN)) - icon_state = "[prefix]-broken" set_light(0) return if(stat & (NOPOWER)) - icon_state = prefix set_light(0) return if(emagged) - icon_state = "[prefix]-on-emagged" set_light(l_range = 1, l_power = 1, l_color = COLOR_RED_LIGHT) return - icon_state = "[prefix]-on" set_light(l_range = 1, l_power = 1, l_color = COLOR_BLUE_LIGHT) -/obj/machinery/brs_server/power_change() - ..() - update_icon() + +/obj/machinery/brs_server/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) + create_light() + /obj/machinery/brs_server/wrench_act(mob/living/user, obj/item/I) . = TRUE @@ -177,7 +195,7 @@ /obj/machinery/brs_server/screwdriver_act(mob/living/user, obj/item/I) . = TRUE default_deconstruction_screwdriver(user, icon_state, icon_state, I) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/brs_server/crowbar_act(mob/living/user, obj/item/I) if((!panel_open) || (flags & NODECONSTRUCT)) @@ -219,7 +237,8 @@ points_per_probe = points_per_probe_emagged probe_success_chance = probe_success_chance_emagged playsound(loc, 'sound/effects/sparks4.ogg', 60, TRUE) - update_icon() + update_icon(UPDATE_ICON_STATE) + create_light() if(user) to_chat(user, span_warning("@?%!№@Протоколы безопасности сканнера перезаписаны@?%!№@")) diff --git a/code/modules/station_goals/brs/brs_stationary_scanner.dm b/code/modules/station_goals/brs/brs_stationary_scanner.dm index 12df8bcb918..17ec5c0f082 100644 --- a/code/modules/station_goals/brs/brs_stationary_scanner.dm +++ b/code/modules/station_goals/brs/brs_stationary_scanner.dm @@ -85,7 +85,7 @@ GLOB.poi_list |= src new_component_parts() connect_to_network() - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/brs_stationary_scanner/Destroy() GLOB.bluespace_rifts_scanner_list.Remove(src) @@ -162,24 +162,28 @@ cause = "[src] was working too long within critical range of a rift." ) -/obj/machinery/power/brs_stationary_scanner/update_icon() +/obj/machinery/power/brs_stationary_scanner/update_icon_state() var/prefix = initial(icon_state) - overlays.Cut() - if(panel_open) - overlays += image(icon, "[prefix]-panel") - - if (stat & BROKEN) + if(stat & BROKEN) icon_state = "[prefix]-broken" return - if ((scanning_status == SCAN_OFF) || (!cable_powered)) + if((scanning_status == SCAN_OFF) || (!cable_powered)) icon_state = prefix return + icon_state = "[prefix]-act" -/obj/machinery/power/brs_stationary_scanner/power_change() - // It shouldn't react to the apc - ..() + +/obj/machinery/brs_stationary_scanner/update_overlays() + . = ..() + if(panel_open) + . += image(icon, "[initial(icon_state)]-panel") + + +/obj/machinery/power/brs_stationary_scanner/power_change(forced = FALSE) + return + /obj/machinery/power/brs_stationary_scanner/proc/on_power_change() if(!cable_powered) @@ -189,11 +193,11 @@ else if(scanning_status != SCAN_OFF) playsound(loc, activation_sound, 100) - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/brs_stationary_scanner/obj_break() ..() - update_icon() + update_icon(UPDATE_ICON_STATE) SStgui.close_uis(src) /obj/machinery/power/brs_stationary_scanner/screwdriver_act(mob/living/user, obj/item/I) @@ -208,7 +212,7 @@ return default_deconstruction_screwdriver(user, icon_state, icon_state, I) - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/machinery/power/brs_stationary_scanner/crowbar_act(mob/living/user, obj/item/I) . = TRUE @@ -234,7 +238,7 @@ // Reset if the scanner was turned on before the failure. turn_on() else - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/brs_stationary_scanner/emag_act(mob/user) if(!emagged) @@ -315,7 +319,7 @@ // Our state just changed to critical // Set timer to kaboom failure_time = world.time + time_for_failure - update_icon() + update_icon(UPDATE_ICON_STATE) /obj/machinery/power/brs_stationary_scanner/proc/toggle() switching = TRUE diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 95f96c26a58..a7c631bced9 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -31,7 +31,7 @@ /obj/machinery/bsa icon = 'icons/obj/engines_and_power/particle_accelerator3.dmi' density = 1 - anchored = 1 + anchored = TRUE /obj/machinery/bsa/back name = "Bluespace Artillery Generator" @@ -44,7 +44,7 @@ var/obj/item/multitool/M = W M.buffer = src to_chat(user, "You store linkage information in [W]'s buffer.") - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) default_unfasten_wrench(user, W, 10) return TRUE @@ -62,7 +62,7 @@ var/obj/item/multitool/M = W M.buffer = src to_chat(user, "You store linkage information in [W]'s buffer.") - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) default_unfasten_wrench(user, W, 10) return TRUE @@ -89,7 +89,7 @@ front = M.buffer M.buffer = null to_chat(user, "You link [src] with [front].") - else if(istype(W, /obj/item/wrench)) + else if(W.tool_behaviour == TOOL_WRENCH) add_fingerprint(user) default_unfasten_wrench(user, W, 10) return TRUE @@ -295,9 +295,9 @@ /obj/machinery/computer/bsa_control/process() ..() - update_icon() + update_icon(UPDATE_ICON_STATE) -/obj/machinery/computer/bsa_control/update_icon() +/obj/machinery/computer/bsa_control/update_icon_state() if(stat & BROKEN) icon_state = icon_state_broken else if(stat & NOPOWER) diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index da3020e486b..1e47816c83a 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -134,7 +134,7 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/l /obj/structure/filler name = "big machinery part" density = 1 - anchored = 1 + anchored = TRUE invisibility = INVISIBILITY_ABSTRACT var/obj/machinery/parent @@ -151,7 +151,7 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/l icon = 'icons/obj/machines/dna_vault.dmi' icon_state = "vault" density = 1 - anchored = 1 + anchored = TRUE idle_power_usage = 5000 pixel_x = -32 pixel_y = -64 @@ -192,19 +192,16 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/l ..() -/obj/machinery/dna_vault/update_icon() - ..() +/obj/machinery/dna_vault/update_icon_state() if(stat & NOPOWER) icon_state = "vaultoff" return icon_state = "vault" -/obj/machinery/dna_vault/power_change() - if(powered(power_channel)) - stat &= ~NOPOWER - else - stat |= NOPOWER - update_icon() +/obj/machinery/dna_vault/power_change(forced = FALSE) + if(!..()) + return + update_icon(UPDATE_ICON_STATE) /obj/machinery/dna_vault/Destroy() diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index 35d0aca8532..dc312ca1374 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -132,18 +132,18 @@ active = !active if(active) animate(src, pixel_y = 2, time = 10, loop = -1) - anchored = 1 + anchored = TRUE else animate(src, pixel_y = 0, time = 10) - anchored = 0 - update_icon() + anchored = FALSE + update_icon(UPDATE_ICON_STATE) return TRUE -/obj/machinery/satellite/update_icon() +/obj/machinery/satellite/update_icon_state() icon_state = active ? "sat_active" : "sat_inactive" /obj/machinery/satellite/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/multitool)) + if(I.tool_behaviour == TOOL_MULTITOOL) add_fingerprint(user) to_chat(user, "// NTSAT-[id] // Режим : [active ? "ОСНОВНОЙ" : "ОЖИДАНИЕ"] //[emagged ? "ОТЛАДКА //" : ""]") else diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 6bc908c2204..1b1d65f5a98 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -78,6 +78,9 @@ origin_tech = "materials=5;programming=4;biotech=4;magnets=4" aug_message = "You see prey everywhere you look..." +/obj/item/organ/internal/cyberimp/eyes/thermals/empproof/emp_act(severity) + return + // HUD implants /obj/item/organ/internal/cyberimp/eyes/hud name = "HUD implant" @@ -85,7 +88,7 @@ slot = INTERNAL_ORGAN_EYE_HUD_DEVICE var/HUDType = 0 /// A list of extension kinds added to the examine text. Things like medical or security records. - var/list/examine_extensions = null + var/examine_extensions = 0 /obj/item/organ/internal/cyberimp/eyes/hud/insert(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) . = ..() @@ -107,7 +110,7 @@ origin_tech = "materials=4;programming=4;biotech=4" aug_message = "You suddenly see health bars floating above people's heads..." HUDType = DATA_HUD_MEDICAL_ADVANCED - examine_extensions = list(EXAMINE_HUD_MEDICAL) + examine_extensions = EXAMINE_HUD_MEDICAL /obj/item/organ/internal/cyberimp/eyes/hud/diagnostic name = "Diagnostic HUD implant" @@ -126,7 +129,7 @@ origin_tech = "materials=4;programming=4;biotech=3;combat=3" aug_message = "Job indicator icons pop up in your vision. That is not a certified surgeon..." HUDType = DATA_HUD_SECURITY_ADVANCED - examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE) + examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE // Welding shield implant /obj/item/organ/internal/cyberimp/eyes/shield diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm index 4a8df60e841..34f9c200c29 100644 --- a/code/modules/surgery/organs/autoimplanter.dm +++ b/code/modules/surgery/organs/autoimplanter.dm @@ -15,6 +15,10 @@ if(!storedorgan) to_chat(user, "[src] currently has no implant stored.") return FALSE + var/mob/living/carbon/human/patient = user + if(!patient.bodyparts_by_name[check_zone(storedorgan.parent_organ_zone)]) + to_chat(user, span_warning("Missing limb!")) + return FALSE storedorgan.insert(user)//insert stored organ into the user user.visible_message("[user] presses a button on [src], and you hear a short mechanical noise.", "You feel a sharp sting as [src] plunges into your body.") playsound(get_turf(user), usesound, 50, 1) @@ -31,7 +35,7 @@ I.forceMove(src) storedorgan = I to_chat(user, "You insert the [I] into [src].") - else if(istype(I, /obj/item/screwdriver)) + else if(I.tool_behaviour == TOOL_SCREWDRIVER) if(!storedorgan) to_chat(user, "There's no implant in [src] for you to remove.") else @@ -51,7 +55,7 @@ qdel(src) /obj/item/autoimplanter/oneuse/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) storedorgan.forceMove(get_turf(user)) storedorgan = null to_chat(user, "You remove the [storedorgan] from [src].") diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 9399e1d36ad..005ac0c47cf 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -8,7 +8,7 @@ dead_icon = "heart-off" var/icon_base = "heart" -/obj/item/organ/internal/heart/update_icon() +/obj/item/organ/internal/heart/update_icon_state() if(beating) icon_state = "[icon_base]-on" else diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index fd751e1d553..aac29ff4e4c 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -347,7 +347,7 @@ if(updating_health) organ_owner?.updatehealth("limb receive damage") - return update_icon() + return update_state() /obj/item/organ/external/proc/heal_damage(brute, burn, internal = FALSE, robo_repair = FALSE, updating_health = TRUE) @@ -364,7 +364,7 @@ if(updating_health) owner.updatehealth("limb heal damage") - return update_icon() + return update_state() /obj/item/organ/external/emp_act(severity) @@ -420,7 +420,7 @@ This function completely restores a damaged organ to perfect condition. if(owner) owner.updatehealth("limb rejuvenate") - update_icon() + update_state() if(!owner) START_PROCESSING(SSobj, src) diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index 3820587dfb1..5df3ab55241 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -131,14 +131,15 @@ GLOBAL_LIST_EMPTY(limb_icon_cache) add_overlay(head_accessory_s) if(f_style) - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(facial_hair_style.do_colouration) - facial_s.Blend(facial_colour, ICON_ADD) - add_overlay(facial_s) + if(!ismachineperson(owner) || (ismachineperson(owner) && ((owner.head && (owner.head.flags & BLOCKFACIALHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKFACIALHAIR))))) + var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(facial_hair_style.do_colouration) + facial_s.Blend(facial_colour, ICON_ADD) + add_overlay(facial_s) if(h_style) if(!ismachineperson(owner) || (ismachineperson(owner) && ((owner.head && (owner.head.flags & BLOCKHEADHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHEADHAIR))))) @@ -189,10 +190,9 @@ GLOBAL_LIST_EMPTY(limb_icon_cache) // new damage icon system // adjusted to set damage_state to brute/burn code only (without r_name0 as before) -/obj/item/organ/external/update_icon() +/obj/item/organ/external/proc/update_state() var/n_is = damage_state_text() if(n_is != damage_state) damage_state = n_is - owner?.UpdateDamageIcon() return TRUE return FALSE diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index e56e1805f4b..f7f79630138 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -148,7 +148,7 @@ icon_state = "nymph" parent_organ_zone = BODY_ZONE_PRECISE_GROIN -/obj/item/organ/internal/heart/diona/update_icon() +/obj/item/organ/internal/heart/diona/update_icon_state() return /obj/item/organ/internal/eyes/diona diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm index 5b3e0dccd2d..513c6048ac0 100644 --- a/code/modules/surgery/organs/subtypes/grey.dm +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -15,10 +15,10 @@ /obj/item/organ/internal/brain/grey/insert(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) . = ..() - M.add_language("Psionic Communication") + M.add_language(LANGUAGE_GREY) /obj/item/organ/internal/brain/grey/remove(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) - M.remove_language("Psionic Communication") + M.remove_language(LANGUAGE_GREY) . = ..() /obj/item/organ/internal/eyes/grey diff --git a/code/modules/surgery/organs/subtypes/slime.dm b/code/modules/surgery/organs/subtypes/slime.dm index 19eccc1bdb9..04f86b4afd2 100644 --- a/code/modules/surgery/organs/subtypes/slime.dm +++ b/code/modules/surgery/organs/subtypes/slime.dm @@ -6,7 +6,7 @@ desc = "This is a slime's osmotic pressure regulator, it appears to be some kind of biological pump that uses osmotic pressure to regulate water flow. It seems to work similar to a heart." dead_icon = null -/obj/item/organ/internal/heart/slime/update_icon() +/obj/item/organ/internal/heart/slime/update_icon_state() return /obj/item/organ/internal/lungs/slime diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm index e1311ed00da..0e4a2218995 100644 --- a/code/modules/surgery/organs/subtypes/xenos.dm +++ b/code/modules/surgery/organs/subtypes/xenos.dm @@ -184,19 +184,19 @@ /obj/item/organ/internal/xenos/hivenode/insert(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) . = ..() M.faction |= "alien" - M.add_language("Hivemind") - M.add_language("Xenomorph") + M.add_language(LANGUAGE_XENOS) + M.add_language(LANGUAGE_HIVE_XENOS) /obj/item/organ/internal/xenos/hivenode/remove(mob/living/carbon/M, special = ORGAN_MANIPULATION_DEFAULT) M.faction -= "alien" - M.remove_language("Hivemind") - M.remove_language("Xenomorph") + M.remove_language(LANGUAGE_XENOS) + M.remove_language(LANGUAGE_HIVE_XENOS) . = ..() /obj/item/organ/internal/xenos/neurotoxin - name = "xeno neurotoxin gland" + name = "large xeno neurotoxin gland" icon_state = "neurotox" parent_organ_zone = BODY_ZONE_HEAD slot = INTERNAL_ORGAN_NEUROTOXIN_GLAND @@ -204,6 +204,7 @@ alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin) /obj/item/organ/internal/xenos/neurotoxin/sentinel + name = "medium xeno neurotoxin gland" alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin/sentinel) /obj/item/organ/internal/xenos/resinspinner diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index cf1530b24fb..fe74a36e94a 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -35,23 +35,23 @@ GLOBAL_LIST_EMPTY(GPS_list) GLOB.poi_list.Add(src) if(name == initial(name)) name = "global positioning system ([gpstag])" - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/gps/Destroy() GLOB.GPS_list.Remove(src) GLOB.poi_list.Remove(src) return ..() -/obj/item/gps/update_icon() - cut_overlays() +/obj/item/gps/update_overlays() + . = ..() if(emped) - add_overlay("emp") + . += "emp" else if(tracking) - add_overlay("working") + . += "working" /obj/item/gps/emp_act(severity) emped = TRUE - update_icon() + update_icon(UPDATE_OVERLAYS) addtimer(CALLBACK(src, PROC_REF(reboot)), EMP_DISABLE_TIME) /obj/item/gps/AltClick(mob/living/user) @@ -67,7 +67,7 @@ GLOBAL_LIST_EMPTY(GPS_list) return tracking = !tracking - update_icon() + update_icon(UPDATE_OVERLAYS) if(tracking) to_chat(user, "[src] is now tracking, and visible to other GPS devices.") else @@ -120,7 +120,7 @@ GLOBAL_LIST_EMPTY(GPS_list) ui_interact(user) -/obj/item/gps/MouseDrop(atom/over) +/obj/item/gps/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() var/mob/user = usr @@ -163,7 +163,7 @@ GLOBAL_LIST_EMPTY(GPS_list) */ /obj/item/gps/proc/reboot() emped = FALSE - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/gps/science icon_state = "gps-s" @@ -179,6 +179,12 @@ GLOBAL_LIST_EMPTY(GPS_list) desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life." tracking = FALSE +/obj/item/gps/security + icon_state = "gps-r" + gpstag = "SEC0" + desc = "A positioning system helpful for monitoring prisoners that are implanted with a tracking implant." + local = TRUE + /obj/item/gps/cyborg icon_state = "gps-b" gpstag = "BORG0" @@ -201,7 +207,7 @@ GLOBAL_LIST_EMPTY(GPS_list) local = TRUE gpstag = "Eerie Signal" desc = "Report to a coder immediately." - invisibility = INVISIBILITY_MAXIMUM + invisibility = INVISIBILITY_ABSTRACT /obj/item/gps/internal/mining icon_state = "gps-m" diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index af73f65de87..5d1723df672 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -4,7 +4,7 @@ desc = "A bluespace telepad used for teleporting objects to and from a location." icon = 'icons/obj/telescience.dmi' icon_state = "pad-idle" - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 200 active_power_usage = 5000 diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm index fd4a5904fd1..d1a86817085 100644 --- a/code/modules/vehicle/ambulance.dm +++ b/code/modules/vehicle/ambulance.dm @@ -112,13 +112,15 @@ . = ..() . += "Drag [src]'s sprite over the ambulance to (de)attach it." -/obj/structure/bed/amb_trolley/MouseDrop(obj/over_object as obj) - ..() - if(istype(over_object, /obj/vehicle/ambulance)) - var/obj/vehicle/ambulance/amb = over_object - if(amb.bed) - amb.bed = null - to_chat(usr, "You unhook the bed to the ambulance.") - else - amb.bed = src - to_chat(usr, "You hook the bed to the ambulance.") +/obj/structure/bed/amb_trolley/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) + . = ..() + if(!. || !istype(over_object, /obj/vehicle/ambulance)) + return FALSE + + var/obj/vehicle/ambulance/amb = over_object + if(amb.bed) + amb.bed = null + to_chat(usr, "You unhook the bed to the ambulance.") + else + amb.bed = src + to_chat(usr, "You hook the bed to the ambulance.") diff --git a/code/modules/vehicle/janicart.dm b/code/modules/vehicle/janicart.dm index b0b28c7f4d7..3e61fc16851 100644 --- a/code/modules/vehicle/janicart.dm +++ b/code/modules/vehicle/janicart.dm @@ -55,7 +55,7 @@ I.forceMove(src) to_chat(user, "") trash_bag = I - update_icon() + update_icon(UPDATE_OVERLAYS) else if(istype(I, /obj/item/janiupgrade)) if(floorbuffer) to_chat(user, "[src] already has an upgrade installed! Use a screwdriver to remove it.") @@ -63,18 +63,20 @@ floorbuffer = TRUE qdel(I) to_chat(user,"You upgrade [src] with [I].") - update_icon() + update_icon(UPDATE_OVERLAYS) else if(trash_bag && (!is_key(I) || is_key(inserted_key))) // don't put a key in the trash when we need it trash_bag.attackby(I, user) else return ..() -/obj/vehicle/janicart/update_icon() - cut_overlays() + +/obj/vehicle/janicart/update_overlays() + . = ..() if(trash_bag) - add_overlay("cart_garbage") + . += "cart_garbage" if(floorbuffer) - add_overlay("cart_buffer") + . += "cart_buffer" + /obj/vehicle/janicart/attack_hand(mob/user) if(..()) @@ -83,7 +85,7 @@ trash_bag.forceMove_turf() user.put_in_hands(trash_bag, ignore_anim = FALSE) trash_bag = null - update_icon() + update_icon(UPDATE_OVERLAYS) /obj/item/key/janitor desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." diff --git a/code/modules/vehicle/vehicle.dm b/code/modules/vehicle/vehicle.dm index c035cd89244..93eb2b441f9 100644 --- a/code/modules/vehicle/vehicle.dm +++ b/code/modules/vehicle/vehicle.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/vehicles/vehicles.dmi' icon_state = "scooter" density = 1 - anchored = 0 + anchored = FALSE can_buckle = TRUE buckle_lying = FALSE max_integrity = 300 @@ -113,10 +113,6 @@ buckled_mob.pixel_y = generic_pixel_y -/obj/vehicle/update_icon() - return - - /obj/item/key name = "key" desc = "A small grey key." diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index e64d877ec4a..fc1daabda54 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -9,7 +9,7 @@ ## This value must be set to the version of the paradise schema in use. ## If this value does not match, the SQL database will not be loaded and an error will be generated. ## Roundstart will be delayed. -DB_VERSION 31 +DB_VERSION 33 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css index 6f5272afe53..1fc0d8ec93e 100644 --- a/goon/browserassets/css/browserOutput-dark.css +++ b/goon/browserassets/css/browserOutput-dark.css @@ -21,6 +21,7 @@ body { scrollbar-face-color:#1A1A1A; scrollbar-track-color:#171717; scrollbar-highlight-color:#171717; + scrollbar-arrow-color: #a4bad6; } h1, h2, h3, h4, h5, h6 {color: #06f; font-family: Georgia, Verdana, sans-serif;} @@ -266,7 +267,7 @@ em {font-style: normal;font-weight: bold;} .ooc {font-weight: bold;} .looc {color: #6699CC;} .adminobserverooc {color: #0099cc;font-weight: bold;} -.adminooc {color: #b82e00;font-weight: bold;} +.adminooc {color: #a0320e;font-weight: bold;} .adminobserver {color: #996600;font-weight: bold;} .admin {color: #386aff;font-weight: bold;} .adminsay {color: #9611D4;font-weight: bold;} @@ -292,7 +293,7 @@ em {font-style: normal;font-weight: bold;} .event_gamma {color: #d46549;} .dsquadradio {color: #998599;} .resteamradio {color: #18BC46;} -.airadio {color: #ff5ed7;} +.airadio {color: #de4fbb;} .centradio {color: #2681a5;} .secradio {color: #CF0000;} /* .engradio {color: #FEAC20;} */ @@ -300,7 +301,7 @@ em {font-style: normal;font-weight: bold;} .sciradio {color: #c68cfa;} .supradio {color: #9F8545;} .srvradio {color: #bbd164;} -.proradio {color: #b84f92;} +/* .proradio {color: #b84f92;} */ .admin_channel {color: #fcba03;} .all_admin_ping {color: #12A5F4; font-weight: bold; font-size: 120%; text-align: center;} .mentor_channel {color: #775BFF;font-weight: bold;} @@ -314,8 +315,8 @@ h1.alert, h2.alert {color: #a4bad6;} .emote {font-style: italic;} .selecteddna {color: #a4bad6; background-color: #001B1B} -.attack {color: #ff0000;} -.moderate {color: #CC0000;} +.attack {color: #be2020;} +.moderate {color: #a91b1b;} .disarm {color: #990000;} .passive {color: #660000;} @@ -328,26 +329,35 @@ h1.alert, h2.alert {color: #a4bad6;} .info {color: #9ab0ff;} .notice {color: #6685f5;} .boldnotice {color: #6685f5;font-weight: bold;} -.suicide {color: #ff5050;font-style: italic;} +.suicide {color: #d33838;font-style: italic;} .green {color: #03bb39;} .pr_announce {color: #c51e1e;font-weight: bold;} .boldannounce {color: #c51e1e;font-weight: bold;} .greenannounce {color: #059223;font-weight: bold;} -.alien {color: #543354;} -.noticealien {color: #00c000;} -.alertalien {color: #00c000; font-weight: bold;} -.terrorspider {color: #822382;} +.alien {color: #923492;} +.noticealien {color: #00a000;} +.alertalien {color: #00a000; font-weight: bold;} +.terrorspider {color: #7d0284;} .dantalion {color: #1a7d5b;} .sinister {color: #800080;font-weight: bold;font-style: italic;} /* /vg/ */ -.blob {color: #006221;font-weight: bold;font-style: italic;} -.confirm {color: #00af3b;} +.blob {color: #006221;font-weight: bold;font-style: italic;} +.blobteslium_paste {color: #512e89;font-weight: bold;font-style: italic;} +.blobradioactive_gel {color: #2476f0;font-weight: bold;font-style: italic;} +.blobb_sorium {color: #808000;font-weight: bold;font-style: italic;} +.blobcryogenic_liquid {color: #8BA6E9;font-weight: bold;font-style: italic;} +.blobkinetic {color: #FFA500;font-weight: bold;font-style: italic;} +.bloblexorin_jelly {color: #00FFC5;font-weight: bold;font-style: italic;} +.blobenvenomed_filaments {color: #9ACD32;font-weight: bold;font-style: italic;} +.blobboiling_oil {color: #B68D00;font-weight: bold;font-style: italic;} +.blobripping_tendrils {color: #7F0000;font-weight: bold;font-style: italic;} +.confirm {color: #00af3b;} .rose {color: #ff5050;} .sans {font-family: 'Comic Sans MS', cursive, sans-serif;} .wingdings {font-family: Wingdings, Webdings;} .robot {font-family: 'PxPlus IBM MDA'; font-size: 1.15em;} -.ancient {color: #008B8B;font-style: italic;} +.ancient {color: #008B8B;font-style: italic;} .newscaster {color: #CC0000;} .mod {color: #735638;font-weight: bold;} .modooc {color: #184880;font-weight: bold;} diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index 0a4be213cdc..897423cb6cb 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -334,7 +334,16 @@ h1.alert, h2.alert {color: #000000;} .sinister {color: #800080; font-weight: bold; font-style: italic;} /* /vg/ */ -.blob {color: #006221; font-weight: bold; font-style: italic;} +.blob {color: #006221;font-weight: bold;font-style: italic;} +.blobteslium_paste {color: #412968;font-weight: bold;font-style: italic;} +.blobradioactive_gel {color: #2476f0;font-weight: bold;font-style: italic;} +.blobb_sorium {color: #808000;font-weight: bold;font-style: italic;} +.blobcryogenic_liquid {color: #8BA6E9;font-weight: bold;font-style: italic;} +.blobkinetic {color: #FFA500;font-weight: bold;font-style: italic;} +.bloblexorin_jelly {color: #00FFC5;font-weight: bold;font-style: italic;} +.blobenvenomed_filaments {color: #9ACD32;font-weight: bold;font-style: italic;} +.blobboiling_oil {color: #B68D00;font-weight: bold;font-style: italic;} +.blobripping_tendrils {color: #7F0000;font-weight: bold;font-style: italic;} .confirm {color: #00af3b;} .rose {color: #ff5050;} .sans {font-family: 'Comic Sans MS', cursive, sans-serif;} diff --git a/html/browser/bootstrap.min.css b/html/browser/bootstrap.min.css new file mode 100644 index 00000000000..840cf2b504f --- /dev/null +++ b/html/browser/bootstrap.min.css @@ -0,0 +1,2131 @@ +/*! + * Bootstrap v4.6.2 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Copyright 2011-2022 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px} +*,::after,::before{box-sizing:border-box} +html{line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent} +article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block} +[tabindex="-1"]:focus:not(:focus-visible){outline:0!important} +hr{box-sizing:content-box;height:0;overflow:visible} +h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem} +p{margin-top:0;margin-bottom:1rem} +abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none} +address{margin-bottom:1rem;font-style:normal;line-height:inherit} +dl,ol,ul{margin-top:0;margin-bottom:1rem} +ol ol,ol ul,ul ol,ul ul{margin-bottom:0} +dt{font-weight:700} +dd{margin-bottom:.5rem;margin-left:0} +blockquote{margin:0 0 1rem} +b,strong{font-weight:bolder} +small{font-size:80%} +sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline} +sub{bottom:-.25em} +sup{top:-.5em} +a{color:#007bff;text-decoration:none;background-color:transparent} +a:hover{color:#0056b3;text-decoration:underline} +a:not([href]):not([class]){color:inherit;text-decoration:none} +a:not([href]):not([class]):hover{color:inherit;text-decoration:none} +code,kbd,pre,samp{font-size:1em} +pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar} +figure{margin:0 0 1rem} +img{vertical-align:middle;border-style:none} +svg{overflow:hidden;vertical-align:middle} +table{border-collapse:collapse} +caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom} +th{text-align:inherit;text-align:-webkit-match-parent} +label{display:inline-block;margin-bottom:.5rem} +button{border-radius:0} +button:focus:not(:focus-visible){outline:0} +button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit} +button,input{overflow:visible} +button,select{text-transform:none} +[role=button]{cursor:pointer} +select{word-wrap:normal} +[type=button],[type=reset],[type=submit],button{-webkit-appearance:button} +[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer} +[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none} +input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0} +textarea{overflow:auto;resize:vertical} +fieldset{min-width:0;padding:0;margin:0;border:0} +legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5em;line-height:inherit;color:inherit;white-space:normal} +progress{vertical-align:baseline} +[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto} +[type=search]{outline-offset:-2px;-webkit-appearance:none} +[type=search]::-webkit-search-decoration{-webkit-appearance:none} +::-webkit-file-upload-button{font:inherit;-webkit-appearance:button} +output{display:inline-block} +summary{display:list-item;cursor:pointer} +template{display:none} +[hidden]{display:none!important} +.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2} +.h1,h1{font-size:2.5em} +.h2,h2{font-size:2em} +.h3,h3{font-size:1.75em} +.h4,h4{font-size:1.5em} +.h5,h5{font-size:1.25em} +.h6,h6{font-size:1em} +.lead{font-size:1.25em;font-weight:300} +.display-1{font-size:6em;font-weight:300;line-height:1.2} +.display-2{font-size:5.5em;font-weight:300;line-height:1.2} +.display-3{font-size:4.5em;font-weight:300;line-height:1.2} +.display-4{font-size:3.5em;font-weight:300;line-height:1.2} +hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)} +.small,small{font-size:.875em;font-weight:400} +.mark,mark{padding:.2em;background-color:#fcf8e3} +.list-unstyled{padding-left:0;list-style:none} +.list-inline{padding-left:0;list-style:none} +.list-inline-item{display:inline-block} +.list-inline-item:not(:last-child){margin-right:.5rem} +.initialism{font-size:90%;text-transform:uppercase} +.blockquote{margin-bottom:1rem;font-size:1.25em} +.blockquote-footer{display:block;font-size:.875em;color:#6c757d} +.blockquote-footer::before{content:"\2014\00A0"} +.img-fluid{max-width:100%;height:auto} +.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto} +.figure{display:inline-block} +.figure-img{margin-bottom:.5rem;line-height:1} +.figure-caption{font-size:90%;color:#6c757d} +code{font-size:87.5%;color:#e83e8c;word-wrap:break-word} +a>code{color:inherit} +kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem} +kbd kbd{padding:0;font-size:100%;font-weight:700} +pre{display:block;font-size:87.5%;color:#212529} +pre code{font-size:inherit;color:inherit;word-break:normal} +.pre-scrollable{max-height:340px;overflow-y:scroll} +.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto} +@media (min-width:576px){.container,.container-sm{max-width:540px} +} +@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px} +} +@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px} +} +@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px} +} +.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px} +.no-gutters{margin-right:0;margin-left:0} +.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0} +.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px} +.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%} +.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%} +.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%} +.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%} +.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%} +.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%} +.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%} +.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%} +.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%} +.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%} +.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.order-first{-ms-flex-order:-1;order:-1} +.order-last{-ms-flex-order:13;order:13} +.order-0{-ms-flex-order:0;order:0} +.order-1{-ms-flex-order:1;order:1} +.order-2{-ms-flex-order:2;order:2} +.order-3{-ms-flex-order:3;order:3} +.order-4{-ms-flex-order:4;order:4} +.order-5{-ms-flex-order:5;order:5} +.order-6{-ms-flex-order:6;order:6} +.order-7{-ms-flex-order:7;order:7} +.order-8{-ms-flex-order:8;order:8} +.order-9{-ms-flex-order:9;order:9} +.order-10{-ms-flex-order:10;order:10} +.order-11{-ms-flex-order:11;order:11} +.order-12{-ms-flex-order:12;order:12} +.offset-1{margin-left:8.333333%} +.offset-2{margin-left:16.666667%} +.offset-3{margin-left:25%} +.offset-4{margin-left:33.333333%} +.offset-5{margin-left:41.666667%} +.offset-6{margin-left:50%} +.offset-7{margin-left:58.333333%} +.offset-8{margin-left:66.666667%} +.offset-9{margin-left:75%} +.offset-10{margin-left:83.333333%} +.offset-11{margin-left:91.666667%} +@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%} +.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%} +.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%} +.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%} +.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%} +.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%} +.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%} +.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%} +.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%} +.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%} +.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.order-sm-first{-ms-flex-order:-1;order:-1} +.order-sm-last{-ms-flex-order:13;order:13} +.order-sm-0{-ms-flex-order:0;order:0} +.order-sm-1{-ms-flex-order:1;order:1} +.order-sm-2{-ms-flex-order:2;order:2} +.order-sm-3{-ms-flex-order:3;order:3} +.order-sm-4{-ms-flex-order:4;order:4} +.order-sm-5{-ms-flex-order:5;order:5} +.order-sm-6{-ms-flex-order:6;order:6} +.order-sm-7{-ms-flex-order:7;order:7} +.order-sm-8{-ms-flex-order:8;order:8} +.order-sm-9{-ms-flex-order:9;order:9} +.order-sm-10{-ms-flex-order:10;order:10} +.order-sm-11{-ms-flex-order:11;order:11} +.order-sm-12{-ms-flex-order:12;order:12} +.offset-sm-0{margin-left:0} +.offset-sm-1{margin-left:8.333333%} +.offset-sm-2{margin-left:16.666667%} +.offset-sm-3{margin-left:25%} +.offset-sm-4{margin-left:33.333333%} +.offset-sm-5{margin-left:41.666667%} +.offset-sm-6{margin-left:50%} +.offset-sm-7{margin-left:58.333333%} +.offset-sm-8{margin-left:66.666667%} +.offset-sm-9{margin-left:75%} +.offset-sm-10{margin-left:83.333333%} +.offset-sm-11{margin-left:91.666667%} +} +@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%} +.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%} +.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%} +.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%} +.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%} +.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%} +.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%} +.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%} +.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%} +.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%} +.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.order-md-first{-ms-flex-order:-1;order:-1} +.order-md-last{-ms-flex-order:13;order:13} +.order-md-0{-ms-flex-order:0;order:0} +.order-md-1{-ms-flex-order:1;order:1} +.order-md-2{-ms-flex-order:2;order:2} +.order-md-3{-ms-flex-order:3;order:3} +.order-md-4{-ms-flex-order:4;order:4} +.order-md-5{-ms-flex-order:5;order:5} +.order-md-6{-ms-flex-order:6;order:6} +.order-md-7{-ms-flex-order:7;order:7} +.order-md-8{-ms-flex-order:8;order:8} +.order-md-9{-ms-flex-order:9;order:9} +.order-md-10{-ms-flex-order:10;order:10} +.order-md-11{-ms-flex-order:11;order:11} +.order-md-12{-ms-flex-order:12;order:12} +.offset-md-0{margin-left:0} +.offset-md-1{margin-left:8.333333%} +.offset-md-2{margin-left:16.666667%} +.offset-md-3{margin-left:25%} +.offset-md-4{margin-left:33.333333%} +.offset-md-5{margin-left:41.666667%} +.offset-md-6{margin-left:50%} +.offset-md-7{margin-left:58.333333%} +.offset-md-8{margin-left:66.666667%} +.offset-md-9{margin-left:75%} +.offset-md-10{margin-left:83.333333%} +.offset-md-11{margin-left:91.666667%} +} +@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%} +.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%} +.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%} +.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%} +.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%} +.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%} +.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%} +.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%} +.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%} +.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%} +.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.order-lg-first{-ms-flex-order:-1;order:-1} +.order-lg-last{-ms-flex-order:13;order:13} +.order-lg-0{-ms-flex-order:0;order:0} +.order-lg-1{-ms-flex-order:1;order:1} +.order-lg-2{-ms-flex-order:2;order:2} +.order-lg-3{-ms-flex-order:3;order:3} +.order-lg-4{-ms-flex-order:4;order:4} +.order-lg-5{-ms-flex-order:5;order:5} +.order-lg-6{-ms-flex-order:6;order:6} +.order-lg-7{-ms-flex-order:7;order:7} +.order-lg-8{-ms-flex-order:8;order:8} +.order-lg-9{-ms-flex-order:9;order:9} +.order-lg-10{-ms-flex-order:10;order:10} +.order-lg-11{-ms-flex-order:11;order:11} +.order-lg-12{-ms-flex-order:12;order:12} +.offset-lg-0{margin-left:0} +.offset-lg-1{margin-left:8.333333%} +.offset-lg-2{margin-left:16.666667%} +.offset-lg-3{margin-left:25%} +.offset-lg-4{margin-left:33.333333%} +.offset-lg-5{margin-left:41.666667%} +.offset-lg-6{margin-left:50%} +.offset-lg-7{margin-left:58.333333%} +.offset-lg-8{margin-left:66.666667%} +.offset-lg-9{margin-left:75%} +.offset-lg-10{margin-left:83.333333%} +.offset-lg-11{margin-left:91.666667%} +} +@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%} +.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%} +.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%} +.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%} +.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%} +.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%} +.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%} +.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%} +.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%} +.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%} +.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%} +.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%} +.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%} +.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%} +.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%} +.order-xl-first{-ms-flex-order:-1;order:-1} +.order-xl-last{-ms-flex-order:13;order:13} +.order-xl-0{-ms-flex-order:0;order:0} +.order-xl-1{-ms-flex-order:1;order:1} +.order-xl-2{-ms-flex-order:2;order:2} +.order-xl-3{-ms-flex-order:3;order:3} +.order-xl-4{-ms-flex-order:4;order:4} +.order-xl-5{-ms-flex-order:5;order:5} +.order-xl-6{-ms-flex-order:6;order:6} +.order-xl-7{-ms-flex-order:7;order:7} +.order-xl-8{-ms-flex-order:8;order:8} +.order-xl-9{-ms-flex-order:9;order:9} +.order-xl-10{-ms-flex-order:10;order:10} +.order-xl-11{-ms-flex-order:11;order:11} +.order-xl-12{-ms-flex-order:12;order:12} +.offset-xl-0{margin-left:0} +.offset-xl-1{margin-left:8.333333%} +.offset-xl-2{margin-left:16.666667%} +.offset-xl-3{margin-left:25%} +.offset-xl-4{margin-left:33.333333%} +.offset-xl-5{margin-left:41.666667%} +.offset-xl-6{margin-left:50%} +.offset-xl-7{margin-left:58.333333%} +.offset-xl-8{margin-left:66.666667%} +.offset-xl-9{margin-left:75%} +.offset-xl-10{margin-left:83.333333%} +.offset-xl-11{margin-left:91.666667%} +} +.table{width:100%;margin-bottom:1rem;color:#212529} +.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6} +.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6} +.table tbody+tbody{border-top:2px solid #dee2e6} +.table-sm td,.table-sm th{padding:.3rem} +.table-bordered{border:1px solid #dee2e6} +.table-bordered td,.table-bordered th{border:1px solid #dee2e6} +.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px} +.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0} +.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)} +.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)} +.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff} +.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff} +.table-hover .table-primary:hover{background-color:#9fcdff} +.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff} +.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db} +.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb} +.table-hover .table-secondary:hover{background-color:#c8cbcf} +.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf} +.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb} +.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e} +.table-hover .table-success:hover{background-color:#b1dfbb} +.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb} +.table-info,.table-info>td,.table-info>th{background-color:#bee5eb} +.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda} +.table-hover .table-info:hover{background-color:#abdde5} +.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5} +.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba} +.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e} +.table-hover .table-warning:hover{background-color:#ffe8a1} +.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1} +.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb} +.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e} +.table-hover .table-danger:hover{background-color:#f1b0b7} +.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7} +.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe} +.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc} +.table-hover .table-light:hover{background-color:#ececf6} +.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6} +.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca} +.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c} +.table-hover .table-dark:hover{background-color:#b9bbbe} +.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe} +.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)} +.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)} +.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)} +.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55} +.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6} +.table-dark{color:#fff;background-color:#343a40} +.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55} +.table-dark.table-bordered{border:0} +.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)} +.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)} +@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch} +.table-responsive-sm>.table-bordered{border:0} +} +@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch} +.table-responsive-md>.table-bordered{border:0} +} +@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch} +.table-responsive-lg>.table-bordered{border:0} +} +@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch} +.table-responsive-xl>.table-bordered{border:0} +} +.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch} +.table-responsive>.table-bordered{border:0} +.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1em;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out} +@media (prefers-reduced-motion:reduce){.form-control{transition:none} +} +.form-control::-ms-expand{background-color:transparent;border:0} +.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1} +.form-control::-moz-placeholder{color:#6c757d;opacity:1} +.form-control:-ms-input-placeholder{color:#6c757d;opacity:1} +.form-control::-ms-input-placeholder{color:#6c757d;opacity:1} +.form-control::placeholder{color:#6c757d;opacity:1} +.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1} +input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none} +select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057} +select.form-control:focus::-ms-value{color:#495057;background-color:#fff} +.form-control-file,.form-control-range{display:block;width:100%} +.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5} +.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25em;line-height:1.5} +.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875em;line-height:1.5} +.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1em;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0} +.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0} +.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875em;line-height:1.5;border-radius:.2rem} +.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25em;line-height:1.5;border-radius:.3rem} +select.form-control[multiple],select.form-control[size]{height:auto} +textarea.form-control{height:auto} +.form-group{margin-bottom:1rem} +.form-text{display:block;margin-top:.25rem} +.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px} +.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px} +.form-check{position:relative;display:block;padding-left:1.25rem} +.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem} +.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d} +.form-check-label{margin-bottom:0} +.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem} +.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0} +.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745} +.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875em;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem} +.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px} +.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block} +.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)} +.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)} +.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem!important;background-position:right 1.5rem center} +.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)} +.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat} +.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)} +.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745} +.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block} +.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745} +.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745} +.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57} +.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)} +.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745} +.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745} +.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)} +.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545} +.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875em;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem} +.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px} +.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block} +.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)} +.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)} +.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem!important;background-position:right 1.5rem center} +.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)} +.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat} +.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)} +.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545} +.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block} +.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545} +.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545} +.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d} +.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)} +.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545} +.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545} +.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)} +.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center} +.form-inline .form-check{width:100%} +@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0} +.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0} +.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle} +.form-inline .form-control-plaintext{display:inline-block} +.form-inline .custom-select,.form-inline .input-group{width:auto} +.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0} +.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0} +.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center} +.form-inline .custom-control-label{margin-bottom:0} +} +.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1em;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out} +@media (prefers-reduced-motion:reduce){.btn{transition:none} +} +.btn:hover{color:#212529;text-decoration:none} +.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.btn.disabled,.btn:disabled{opacity:.65} +.btn:not(:disabled):not(.disabled){cursor:pointer} +a.btn.disabled,fieldset:disabled a.btn{pointer-events:none} +.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff} +.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc} +.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)} +.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff} +.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf} +.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)} +.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d} +.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62} +.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)} +.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d} +.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b} +.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)} +.btn-success{color:#fff;background-color:#28a745;border-color:#28a745} +.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34} +.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)} +.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745} +.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430} +.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)} +.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8} +.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b} +.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)} +.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8} +.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f} +.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)} +.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107} +.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00} +.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)} +.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107} +.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500} +.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)} +.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545} +.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130} +.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)} +.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545} +.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d} +.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)} +.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa} +.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5} +.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)} +.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa} +.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df} +.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)} +.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40} +.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124} +.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)} +.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40} +.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d} +.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)} +.btn-outline-primary{color:#007bff;border-color:#007bff} +.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff} +.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)} +.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent} +.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff} +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)} +.btn-outline-secondary{color:#6c757d;border-color:#6c757d} +.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d} +.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)} +.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent} +.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d} +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)} +.btn-outline-success{color:#28a745;border-color:#28a745} +.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745} +.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)} +.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent} +.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745} +.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)} +.btn-outline-info{color:#17a2b8;border-color:#17a2b8} +.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8} +.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)} +.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent} +.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8} +.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)} +.btn-outline-warning{color:#ffc107;border-color:#ffc107} +.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107} +.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)} +.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent} +.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107} +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)} +.btn-outline-danger{color:#dc3545;border-color:#dc3545} +.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545} +.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)} +.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent} +.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545} +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)} +.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa} +.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa} +.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)} +.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent} +.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa} +.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)} +.btn-outline-dark{color:#343a40;border-color:#343a40} +.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40} +.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)} +.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent} +.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40} +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)} +.btn-link{font-weight:400;color:#007bff;text-decoration:none} +.btn-link:hover{color:#0056b3;text-decoration:underline} +.btn-link.focus,.btn-link:focus{text-decoration:underline} +.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none} +.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25em;line-height:1.5;border-radius:.3rem} +.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875em;line-height:1.5;border-radius:.2rem} +.btn-block{display:block;width:100%} +.btn-block+.btn-block{margin-top:.5rem} +input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%} +.fade{transition:opacity .15s linear} +@media (prefers-reduced-motion:reduce){.fade{transition:none} +} +.fade:not(.show){opacity:0} +.collapse:not(.show){display:none} +.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease} +@media (prefers-reduced-motion:reduce){.collapsing{transition:none} +} +.collapsing.width{width:0;height:auto;transition:width .35s ease} +@media (prefers-reduced-motion:reduce){.collapsing.width{transition:none} +} +.dropdown,.dropleft,.dropright,.dropup{position:relative} +.dropdown-toggle{white-space:nowrap} +.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent} +.dropdown-toggle:empty::after{margin-left:0} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1em;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem} +.dropdown-menu-left{right:auto;left:0} +.dropdown-menu-right{right:0;left:auto} +@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0} +.dropdown-menu-sm-right{right:0;left:auto} +} +@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0} +.dropdown-menu-md-right{right:0;left:auto} +} +@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0} +.dropdown-menu-lg-right{right:0;left:auto} +} +@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0} +.dropdown-menu-xl-right{right:0;left:auto} +} +.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem} +.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent} +.dropup .dropdown-toggle:empty::after{margin-left:0} +.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem} +.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid} +.dropright .dropdown-toggle:empty::after{margin-left:0} +.dropright .dropdown-toggle::after{vertical-align:0} +.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem} +.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""} +.dropleft .dropdown-toggle::after{display:none} +.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent} +.dropleft .dropdown-toggle:empty::after{margin-left:0} +.dropleft .dropdown-toggle::before{vertical-align:0} +.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto} +.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef} +.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0} +.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef} +.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff} +.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent} +.dropdown-menu.show{display:block} +.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875em;color:#6c757d;white-space:nowrap} +.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529} +.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle} +.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto} +.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1} +.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1} +.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start} +.btn-toolbar .input-group{width:auto} +.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px} +.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0} +.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0} +.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem} +.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0} +.dropleft .dropdown-toggle-split::before{margin-right:0} +.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem} +.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem} +.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center} +.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%} +.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px} +.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0} +.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0} +.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0} +.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none} +.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%} +.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0} +.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px} +.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3} +.input-group>.custom-file .custom-file-input:focus{z-index:4} +.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0} +.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center} +.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0} +.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0} +.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0} +.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0} +.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex} +.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2} +.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3} +.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px} +.input-group-prepend{margin-right:-1px} +.input-group-append{margin-left:-1px} +.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1em;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem} +.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0} +.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)} +.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25em;line-height:1.5;border-radius:.3rem} +.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)} +.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875em;line-height:1.5;border-radius:.2rem} +.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem} +.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0} +.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0} +.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact} +.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem} +.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0} +.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff} +.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff} +.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff} +.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d} +.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef} +.custom-control-label{position:relative;margin-bottom:0;vertical-align:top} +.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:1px solid #adb5bd} +.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat} +.custom-checkbox .custom-control-label::before{border-radius:.25rem} +.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")} +.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff} +.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")} +.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)} +.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)} +.custom-radio .custom-control-label::before{border-radius:50%} +.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")} +.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)} +.custom-switch{padding-left:2.25rem} +.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem} +.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out} +@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none} +} +.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)} +.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)} +.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1em;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none} +.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.custom-select:focus::-ms-value{color:#495057;background-color:#fff} +.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none} +.custom-select:disabled{color:#6c757d;background-color:#e9ecef} +.custom-select::-ms-expand{display:none} +.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057} +.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem} +.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem} +.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0} +.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0} +.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef} +.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"} +.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)} +.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem} +.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0} +.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none} +.custom-range:focus{outline:0} +.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)} +.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)} +.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)} +.custom-range::-moz-focus-outer{border:0} +.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none} +@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none} +} +.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff} +.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem} +.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none} +@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none} +} +.custom-range::-moz-range-thumb:active{background-color:#b3d7ff} +.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem} +.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none} +@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none} +} +.custom-range::-ms-thumb:active{background-color:#b3d7ff} +.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem} +.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem} +.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem} +.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd} +.custom-range:disabled::-webkit-slider-runnable-track{cursor:default} +.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd} +.custom-range:disabled::-moz-range-track{cursor:default} +.custom-range:disabled::-ms-thumb{background-color:#adb5bd} +.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out} +@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none} +} +.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none} +.nav-link{display:block;padding:.5rem 1rem} +.nav-link:focus,.nav-link:hover{text-decoration:none} +.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default} +.nav-tabs{border-bottom:1px solid #dee2e6} +.nav-tabs .nav-link{margin-bottom:-1px;background-color:transparent;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem} +.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:#e9ecef #e9ecef #dee2e6} +.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent} +.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff} +.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0} +.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem} +.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff} +.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center} +.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center} +.tab-content>.tab-pane{display:none} +.tab-content>.active{display:block} +.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem} +.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between} +.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25em;line-height:inherit;white-space:nowrap} +.navbar-brand:focus,.navbar-brand:hover{text-decoration:none} +.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none} +.navbar-nav .nav-link{padding-right:0;padding-left:0} +.navbar-nav .dropdown-menu{position:static;float:none} +.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem} +.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center} +.navbar-toggler{padding:.25rem .75rem;font-size:1.25em;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem} +.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none} +.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat} +.navbar-nav-scroll{max-height:75vh;overflow-y:auto} +@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0} +} +@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start} +.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row} +.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute} +.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem} +.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap} +.navbar-expand-sm .navbar-nav-scroll{overflow:visible} +.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto} +.navbar-expand-sm .navbar-toggler{display:none} +} +@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0} +} +@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start} +.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row} +.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute} +.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem} +.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap} +.navbar-expand-md .navbar-nav-scroll{overflow:visible} +.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto} +.navbar-expand-md .navbar-toggler{display:none} +} +@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0} +} +@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start} +.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row} +.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute} +.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem} +.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap} +.navbar-expand-lg .navbar-nav-scroll{overflow:visible} +.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto} +.navbar-expand-lg .navbar-toggler{display:none} +} +@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0} +} +@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start} +.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row} +.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute} +.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem} +.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap} +.navbar-expand-xl .navbar-nav-scroll{overflow:visible} +.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto} +.navbar-expand-xl .navbar-toggler{display:none} +} +.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start} +.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0} +.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row} +.navbar-expand .navbar-nav .dropdown-menu{position:absolute} +.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem} +.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap} +.navbar-expand .navbar-nav-scroll{overflow:visible} +.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto} +.navbar-expand .navbar-toggler{display:none} +.navbar-light .navbar-brand{color:rgba(0,0,0,.9)} +.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)} +.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)} +.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)} +.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)} +.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)} +.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)} +.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")} +.navbar-light .navbar-text{color:rgba(0,0,0,.5)} +.navbar-light .navbar-text a{color:rgba(0,0,0,.9)} +.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)} +.navbar-dark .navbar-brand{color:#fff} +.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff} +.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)} +.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)} +.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)} +.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff} +.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)} +.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")} +.navbar-dark .navbar-text{color:rgba(255,255,255,.5)} +.navbar-dark .navbar-text a{color:#fff} +.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff} +.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem} +.card>hr{margin-right:0;margin-left:0} +.card>.list-group{border-top:inherit;border-bottom:inherit} +.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)} +.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)} +.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0} +.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem} +.card-title{margin-bottom:.75rem} +.card-subtitle{margin-top:-.375rem;margin-bottom:0} +.card-text:last-child{margin-bottom:0} +.card-link:hover{text-decoration:none} +.card-link+.card-link{margin-left:1.25rem} +.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)} +.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0} +.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)} +.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)} +.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0} +.card-header-pills{margin-right:-.625rem;margin-left:-.625rem} +.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)} +.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%} +.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)} +.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)} +.card-deck .card{margin-bottom:15px} +@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px} +.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px} +} +.card-group>.card{margin-bottom:15px} +@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap} +.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0} +.card-group>.card+.card{margin-left:0;border-left:0} +.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0} +.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0} +.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0} +.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0} +.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0} +.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0} +} +.card-columns .card{margin-bottom:.75rem} +@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1} +.card-columns .card{display:inline-block;width:100%} +} +.accordion{overflow-anchor:none} +.accordion>.card{overflow:hidden} +.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0} +.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0} +.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px} +.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem} +.breadcrumb-item+.breadcrumb-item{padding-left:.5rem} +.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"} +.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline} +.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none} +.breadcrumb-item.active{color:#6c757d} +.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem} +.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6} +.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6} +.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)} +.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem} +.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem} +.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff} +.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6} +.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25em;line-height:1.5} +.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem} +.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem} +.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875em;line-height:1.5} +.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem} +.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem} +.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out} +@media (prefers-reduced-motion:reduce){.badge{transition:none} +} +a.badge:focus,a.badge:hover{text-decoration:none} +.badge:empty{display:none} +.btn .badge{position:relative;top:-1px} +.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem} +.badge-primary{color:#fff;background-color:#007bff} +a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc} +a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)} +.badge-secondary{color:#fff;background-color:#6c757d} +a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62} +a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)} +.badge-success{color:#fff;background-color:#28a745} +a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34} +a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)} +.badge-info{color:#fff;background-color:#17a2b8} +a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b} +a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)} +.badge-warning{color:#212529;background-color:#ffc107} +a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00} +a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)} +.badge-danger{color:#fff;background-color:#dc3545} +a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130} +a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)} +.badge-light{color:#212529;background-color:#f8f9fa} +a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5} +a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)} +.badge-dark{color:#fff;background-color:#343a40} +a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124} +a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)} +.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem} +@media (min-width:576px){.jumbotron{padding:4rem 2rem} +} +.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0} +.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem} +.alert-heading{color:inherit} +.alert-link{font-weight:700} +.alert-dismissible{padding-right:4rem} +.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit} +.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff} +.alert-primary hr{border-top-color:#9fcdff} +.alert-primary .alert-link{color:#002752} +.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db} +.alert-secondary hr{border-top-color:#c8cbcf} +.alert-secondary .alert-link{color:#202326} +.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb} +.alert-success hr{border-top-color:#b1dfbb} +.alert-success .alert-link{color:#0b2e13} +.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb} +.alert-info hr{border-top-color:#abdde5} +.alert-info .alert-link{color:#062c33} +.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba} +.alert-warning hr{border-top-color:#ffe8a1} +.alert-warning .alert-link{color:#533f03} +.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb} +.alert-danger hr{border-top-color:#f1b0b7} +.alert-danger .alert-link{color:#491217} +.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe} +.alert-light hr{border-top-color:#ececf6} +.alert-light .alert-link{color:#686868} +.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca} +.alert-dark hr{border-top-color:#b9bbbe} +.alert-dark .alert-link{color:#040505} +@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0} +to{background-position:0 0} +} +@keyframes progress-bar-stripes{from{background-position:1rem 0} +to{background-position:0 0} +} +.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75em;background-color:#e9ecef;border-radius:.25rem} +.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease} +@media (prefers-reduced-motion:reduce){.progress-bar{transition:none} +} +.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem} +.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes} +@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none} +} +.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start} +.media-body{-ms-flex:1;flex:1} +.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem} +.list-group-item-action{width:100%;color:#495057;text-align:inherit} +.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa} +.list-group-item-action:active{color:#212529;background-color:#e9ecef} +.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)} +.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit} +.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit} +.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff} +.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff} +.list-group-item+.list-group-item{border-top-width:0} +.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px} +.list-group-horizontal{-ms-flex-direction:row;flex-direction:row} +.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0} +.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0} +.list-group-horizontal>.list-group-item.active{margin-top:0} +.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0} +.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px} +@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row} +.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0} +.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0} +.list-group-horizontal-sm>.list-group-item.active{margin-top:0} +.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0} +.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px} +} +@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row} +.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0} +.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0} +.list-group-horizontal-md>.list-group-item.active{margin-top:0} +.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0} +.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px} +} +@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row} +.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0} +.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0} +.list-group-horizontal-lg>.list-group-item.active{margin-top:0} +.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0} +.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px} +} +@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row} +.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0} +.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0} +.list-group-horizontal-xl>.list-group-item.active{margin-top:0} +.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0} +.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px} +} +.list-group-flush{border-radius:0} +.list-group-flush>.list-group-item{border-width:0 0 1px} +.list-group-flush>.list-group-item:last-child{border-bottom-width:0} +.list-group-item-primary{color:#004085;background-color:#b8daff} +.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff} +.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085} +.list-group-item-secondary{color:#383d41;background-color:#d6d8db} +.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf} +.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41} +.list-group-item-success{color:#155724;background-color:#c3e6cb} +.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb} +.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724} +.list-group-item-info{color:#0c5460;background-color:#bee5eb} +.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5} +.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460} +.list-group-item-warning{color:#856404;background-color:#ffeeba} +.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1} +.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404} +.list-group-item-danger{color:#721c24;background-color:#f5c6cb} +.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7} +.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24} +.list-group-item-light{color:#818182;background-color:#fdfdfe} +.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6} +.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182} +.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca} +.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe} +.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21} +.close{float:right;font-size:1.5em;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5} +.close:hover{color:#000;text-decoration:none} +.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75} +button.close{padding:0;background-color:transparent;border:0} +a.close.disabled{pointer-events:none} +.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875em;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem} +.toast:not(:last-child){margin-bottom:.75rem} +.toast.showing{opacity:1} +.toast.show{display:block;opacity:1} +.toast.hide{display:none} +.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)} +.toast-body{padding:.75rem} +.modal-open{overflow:hidden} +.modal-open .modal{overflow-x:hidden;overflow-y:auto} +.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0} +.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none} +.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)} +@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none} +} +.modal.show .modal-dialog{-webkit-transform:none;transform:none} +.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)} +.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)} +.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden} +.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0} +.modal-dialog-scrollable .modal-body{overflow-y:auto} +.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)} +.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""} +.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%} +.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none} +.modal-dialog-centered.modal-dialog-scrollable::before{content:none} +.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0} +.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000} +.modal-backdrop.fade{opacity:0} +.modal-backdrop.show{opacity:.5} +.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)} +.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto} +.modal-title{margin-bottom:0;line-height:1.5} +.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem} +.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)} +.modal-footer>*{margin:.25rem} +.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll} +@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto} +.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)} +.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)} +.modal-dialog-centered{min-height:calc(100% - 3.5rem)} +.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content} +.modal-sm{max-width:300px} +} +@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px} +} +@media (min-width:1200px){.modal-xl{max-width:1140px} +} +.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875em;word-wrap:break-word;opacity:0} +.tooltip.show{opacity:.9} +.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem} +.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid} +.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0} +.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0} +.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000} +.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem} +.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem} +.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000} +.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0} +.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0} +.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000} +.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem} +.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem} +.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000} +.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem} +.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875em;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem} +.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem} +.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid} +.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem} +.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)} +.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)} +.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff} +.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem} +.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0} +.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)} +.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff} +.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem} +.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)} +.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)} +.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff} +.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7} +.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem} +.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0} +.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)} +.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff} +.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1em;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)} +.popover-header:empty{display:none} +.popover-body{padding:.5rem .75rem;color:#212529} +.carousel{position:relative} +.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y} +.carousel-inner{position:relative;width:100%;overflow:hidden} +.carousel-inner::after{display:block;clear:both;content:""} +.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out} +@media (prefers-reduced-motion:reduce){.carousel-item{transition:none} +} +.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block} +.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)} +.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)} +.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none} +.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1} +.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s} +@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none} +} +.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease} +@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none} +} +.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9} +.carousel-control-prev{left:0} +.carousel-control-next{right:0} +.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat} +.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")} +.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")} +.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none} +.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease} +@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none} +} +.carousel-indicators .active{opacity:1} +.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center} +@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)} +} +@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)} +} +.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentcolor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border} +.spinner-border-sm{width:1rem;height:1rem;border-width:.2em} +@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)} +50%{opacity:1;-webkit-transform:none;transform:none} +} +@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)} +50%{opacity:1;-webkit-transform:none;transform:none} +} +.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentcolor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow} +.spinner-grow-sm{width:1rem;height:1rem} +@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s} +} +.align-baseline{vertical-align:baseline!important} +.align-top{vertical-align:top!important} +.align-middle{vertical-align:middle!important} +.align-bottom{vertical-align:bottom!important} +.align-text-bottom{vertical-align:text-bottom!important} +.align-text-top{vertical-align:text-top!important} +.bg-primary{background-color:#007bff!important} +a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important} +.bg-secondary{background-color:#6c757d!important} +a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important} +.bg-success{background-color:#28a745!important} +a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important} +.bg-info{background-color:#17a2b8!important} +a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important} +.bg-warning{background-color:#ffc107!important} +a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important} +.bg-danger{background-color:#dc3545!important} +a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important} +.bg-light{background-color:#f8f9fa!important} +a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important} +.bg-dark{background-color:#343a40!important} +a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important} +.bg-white{background-color:#fff!important} +.bg-transparent{background-color:transparent!important} +.border{border:1px solid #dee2e6!important} +.border-top{border-top:1px solid #dee2e6!important} +.border-right{border-right:1px solid #dee2e6!important} +.border-bottom{border-bottom:1px solid #dee2e6!important} +.border-left{border-left:1px solid #dee2e6!important} +.border-0{border:0!important} +.border-top-0{border-top:0!important} +.border-right-0{border-right:0!important} +.border-bottom-0{border-bottom:0!important} +.border-left-0{border-left:0!important} +.border-primary{border-color:#007bff!important} +.border-secondary{border-color:#6c757d!important} +.border-success{border-color:#28a745!important} +.border-info{border-color:#17a2b8!important} +.border-warning{border-color:#ffc107!important} +.border-danger{border-color:#dc3545!important} +.border-light{border-color:#f8f9fa!important} +.border-dark{border-color:#343a40!important} +.border-white{border-color:#fff!important} +.rounded-sm{border-radius:.2rem!important} +.rounded{border-radius:.25rem!important} +.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important} +.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important} +.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important} +.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important} +.rounded-lg{border-radius:.3rem!important} +.rounded-circle{border-radius:50%!important} +.rounded-pill{border-radius:50rem!important} +.rounded-0{border-radius:0!important} +.clearfix::after{display:block;clear:both;content:""} +.d-none{display:none!important} +.d-inline{display:inline!important} +.d-inline-block{display:inline-block!important} +.d-block{display:block!important} +.d-table{display:table!important} +.d-table-row{display:table-row!important} +.d-table-cell{display:table-cell!important} +.d-flex{display:-ms-flexbox!important;display:flex!important} +.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +@media (min-width:576px){.d-sm-none{display:none!important} +.d-sm-inline{display:inline!important} +.d-sm-inline-block{display:inline-block!important} +.d-sm-block{display:block!important} +.d-sm-table{display:table!important} +.d-sm-table-row{display:table-row!important} +.d-sm-table-cell{display:table-cell!important} +.d-sm-flex{display:-ms-flexbox!important;display:flex!important} +.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +} +@media (min-width:768px){.d-md-none{display:none!important} +.d-md-inline{display:inline!important} +.d-md-inline-block{display:inline-block!important} +.d-md-block{display:block!important} +.d-md-table{display:table!important} +.d-md-table-row{display:table-row!important} +.d-md-table-cell{display:table-cell!important} +.d-md-flex{display:-ms-flexbox!important;display:flex!important} +.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +} +@media (min-width:992px){.d-lg-none{display:none!important} +.d-lg-inline{display:inline!important} +.d-lg-inline-block{display:inline-block!important} +.d-lg-block{display:block!important} +.d-lg-table{display:table!important} +.d-lg-table-row{display:table-row!important} +.d-lg-table-cell{display:table-cell!important} +.d-lg-flex{display:-ms-flexbox!important;display:flex!important} +.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +} +@media (min-width:1200px){.d-xl-none{display:none!important} +.d-xl-inline{display:inline!important} +.d-xl-inline-block{display:inline-block!important} +.d-xl-block{display:block!important} +.d-xl-table{display:table!important} +.d-xl-table-row{display:table-row!important} +.d-xl-table-cell{display:table-cell!important} +.d-xl-flex{display:-ms-flexbox!important;display:flex!important} +.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +} +@media print{.d-print-none{display:none!important} +.d-print-inline{display:inline!important} +.d-print-inline-block{display:inline-block!important} +.d-print-block{display:block!important} +.d-print-table{display:table!important} +.d-print-table-row{display:table-row!important} +.d-print-table-cell{display:table-cell!important} +.d-print-flex{display:-ms-flexbox!important;display:flex!important} +.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important} +} +.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden} +.embed-responsive::before{display:block;content:""} +.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0} +.embed-responsive-21by9::before{padding-top:42.857143%} +.embed-responsive-16by9::before{padding-top:56.25%} +.embed-responsive-4by3::before{padding-top:75%} +.embed-responsive-1by1::before{padding-top:100%} +.flex-row{-ms-flex-direction:row!important;flex-direction:row!important} +.flex-column{-ms-flex-direction:column!important;flex-direction:column!important} +.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important} +.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important} +.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important} +.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important} +.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important} +.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important} +.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important} +.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important} +.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important} +.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important} +.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important} +.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important} +.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important} +.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important} +.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important} +.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important} +.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important} +.align-items-center{-ms-flex-align:center!important;align-items:center!important} +.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important} +.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important} +.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important} +.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important} +.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important} +.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important} +.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important} +.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important} +.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important} +.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important} +.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important} +.align-self-center{-ms-flex-item-align:center!important;align-self:center!important} +.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important} +.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important} +@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important} +.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important} +.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important} +.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important} +.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important} +.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important} +.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important} +.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important} +.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important} +.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important} +.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important} +.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important} +.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important} +.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important} +.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important} +.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important} +.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important} +.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important} +.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important} +.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important} +.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important} +.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important} +.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important} +.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important} +.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important} +.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important} +.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important} +.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important} +.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important} +.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important} +.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important} +.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important} +.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important} +.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important} +} +@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important} +.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important} +.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important} +.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important} +.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important} +.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important} +.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important} +.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important} +.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important} +.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important} +.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important} +.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important} +.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important} +.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important} +.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important} +.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important} +.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important} +.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important} +.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important} +.align-items-md-center{-ms-flex-align:center!important;align-items:center!important} +.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important} +.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important} +.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important} +.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important} +.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important} +.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important} +.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important} +.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important} +.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important} +.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important} +.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important} +.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important} +.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important} +.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important} +} +@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important} +.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important} +.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important} +.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important} +.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important} +.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important} +.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important} +.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important} +.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important} +.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important} +.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important} +.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important} +.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important} +.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important} +.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important} +.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important} +.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important} +.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important} +.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important} +.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important} +.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important} +.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important} +.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important} +.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important} +.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important} +.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important} +.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important} +.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important} +.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important} +.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important} +.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important} +.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important} +.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important} +.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important} +} +@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important} +.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important} +.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important} +.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important} +.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important} +.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important} +.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important} +.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important} +.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important} +.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important} +.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important} +.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important} +.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important} +.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important} +.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important} +.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important} +.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important} +.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important} +.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important} +.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important} +.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important} +.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important} +.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important} +.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important} +.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important} +.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important} +.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important} +.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important} +.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important} +.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important} +.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important} +.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important} +.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important} +.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important} +} +.float-left{float:left!important} +.float-right{float:right!important} +.float-none{float:none!important} +@media (min-width:576px){.float-sm-left{float:left!important} +.float-sm-right{float:right!important} +.float-sm-none{float:none!important} +} +@media (min-width:768px){.float-md-left{float:left!important} +.float-md-right{float:right!important} +.float-md-none{float:none!important} +} +@media (min-width:992px){.float-lg-left{float:left!important} +.float-lg-right{float:right!important} +.float-lg-none{float:none!important} +} +@media (min-width:1200px){.float-xl-left{float:left!important} +.float-xl-right{float:right!important} +.float-xl-none{float:none!important} +} +.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important} +.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important} +.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important} +.overflow-auto{overflow:auto!important} +.overflow-hidden{overflow:hidden!important} +.position-static{position:static!important} +.position-relative{position:relative!important} +.position-absolute{position:absolute!important} +.position-fixed{position:fixed!important} +.position-sticky{position:-webkit-sticky!important;position:sticky!important} +.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030} +.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030} +@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020} +} +.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} +.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal} +.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important} +.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important} +.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important} +.shadow-none{box-shadow:none!important} +.w-25{width:25%!important} +.w-50{width:50%!important} +.w-75{width:75%!important} +.w-100{width:100%!important} +.w-auto{width:auto!important} +.h-25{height:25%!important} +.h-50{height:50%!important} +.h-75{height:75%!important} +.h-100{height:100%!important} +.h-auto{height:auto!important} +.mw-100{max-width:100%!important} +.mh-100{max-height:100%!important} +.min-vw-100{min-width:100vw!important} +.min-vh-100{min-height:100vh!important} +.vw-100{width:100vw!important} +.vh-100{height:100vh!important} +.m-0{margin:0!important} +.mt-0,.my-0{margin-top:0!important} +.mr-0,.mx-0{margin-right:0!important} +.mb-0,.my-0{margin-bottom:0!important} +.ml-0,.mx-0{margin-left:0!important} +.m-1{margin:.25rem!important} +.mt-1,.my-1{margin-top:.25rem!important} +.mr-1,.mx-1{margin-right:.25rem!important} +.mb-1,.my-1{margin-bottom:.25rem!important} +.ml-1,.mx-1{margin-left:.25rem!important} +.m-2{margin:.5rem!important} +.mt-2,.my-2{margin-top:.5rem!important} +.mr-2,.mx-2{margin-right:.5rem!important} +.mb-2,.my-2{margin-bottom:.5rem!important} +.ml-2,.mx-2{margin-left:.5rem!important} +.m-3{margin:1rem!important} +.mt-3,.my-3{margin-top:1rem!important} +.mr-3,.mx-3{margin-right:1rem!important} +.mb-3,.my-3{margin-bottom:1rem!important} +.ml-3,.mx-3{margin-left:1rem!important} +.m-4{margin:1.5rem!important} +.mt-4,.my-4{margin-top:1.5rem!important} +.mr-4,.mx-4{margin-right:1.5rem!important} +.mb-4,.my-4{margin-bottom:1.5rem!important} +.ml-4,.mx-4{margin-left:1.5rem!important} +.m-5{margin:3rem!important} +.mt-5,.my-5{margin-top:3rem!important} +.mr-5,.mx-5{margin-right:3rem!important} +.mb-5,.my-5{margin-bottom:3rem!important} +.ml-5,.mx-5{margin-left:3rem!important} +.p-0{padding:0!important} +.pt-0,.py-0{padding-top:0!important} +.pr-0,.px-0{padding-right:0!important} +.pb-0,.py-0{padding-bottom:0!important} +.pl-0,.px-0{padding-left:0!important} +.p-1{padding:.25rem!important} +.pt-1,.py-1{padding-top:.25rem!important} +.pr-1,.px-1{padding-right:.25rem!important} +.pb-1,.py-1{padding-bottom:.25rem!important} +.pl-1,.px-1{padding-left:.25rem!important} +.p-2{padding:.5rem!important} +.pt-2,.py-2{padding-top:.5rem!important} +.pr-2,.px-2{padding-right:.5rem!important} +.pb-2,.py-2{padding-bottom:.5rem!important} +.pl-2,.px-2{padding-left:.5rem!important} +.p-3{padding:1rem!important} +.pt-3,.py-3{padding-top:1rem!important} +.pr-3,.px-3{padding-right:1rem!important} +.pb-3,.py-3{padding-bottom:1rem!important} +.pl-3,.px-3{padding-left:1rem!important} +.p-4{padding:1.5rem!important} +.pt-4,.py-4{padding-top:1.5rem!important} +.pr-4,.px-4{padding-right:1.5rem!important} +.pb-4,.py-4{padding-bottom:1.5rem!important} +.pl-4,.px-4{padding-left:1.5rem!important} +.p-5{padding:3rem!important} +.pt-5,.py-5{padding-top:3rem!important} +.pr-5,.px-5{padding-right:3rem!important} +.pb-5,.py-5{padding-bottom:3rem!important} +.pl-5,.px-5{padding-left:3rem!important} +.m-n1{margin:-.25rem!important} +.mt-n1,.my-n1{margin-top:-.25rem!important} +.mr-n1,.mx-n1{margin-right:-.25rem!important} +.mb-n1,.my-n1{margin-bottom:-.25rem!important} +.ml-n1,.mx-n1{margin-left:-.25rem!important} +.m-n2{margin:-.5rem!important} +.mt-n2,.my-n2{margin-top:-.5rem!important} +.mr-n2,.mx-n2{margin-right:-.5rem!important} +.mb-n2,.my-n2{margin-bottom:-.5rem!important} +.ml-n2,.mx-n2{margin-left:-.5rem!important} +.m-n3{margin:-1rem!important} +.mt-n3,.my-n3{margin-top:-1rem!important} +.mr-n3,.mx-n3{margin-right:-1rem!important} +.mb-n3,.my-n3{margin-bottom:-1rem!important} +.ml-n3,.mx-n3{margin-left:-1rem!important} +.m-n4{margin:-1.5rem!important} +.mt-n4,.my-n4{margin-top:-1.5rem!important} +.mr-n4,.mx-n4{margin-right:-1.5rem!important} +.mb-n4,.my-n4{margin-bottom:-1.5rem!important} +.ml-n4,.mx-n4{margin-left:-1.5rem!important} +.m-n5{margin:-3rem!important} +.mt-n5,.my-n5{margin-top:-3rem!important} +.mr-n5,.mx-n5{margin-right:-3rem!important} +.mb-n5,.my-n5{margin-bottom:-3rem!important} +.ml-n5,.mx-n5{margin-left:-3rem!important} +.m-auto{margin:auto!important} +.mt-auto,.my-auto{margin-top:auto!important} +.mr-auto,.mx-auto{margin-right:auto!important} +.mb-auto,.my-auto{margin-bottom:auto!important} +.ml-auto,.mx-auto{margin-left:auto!important} +@media (min-width:576px){.m-sm-0{margin:0!important} +.mt-sm-0,.my-sm-0{margin-top:0!important} +.mr-sm-0,.mx-sm-0{margin-right:0!important} +.mb-sm-0,.my-sm-0{margin-bottom:0!important} +.ml-sm-0,.mx-sm-0{margin-left:0!important} +.m-sm-1{margin:.25rem!important} +.mt-sm-1,.my-sm-1{margin-top:.25rem!important} +.mr-sm-1,.mx-sm-1{margin-right:.25rem!important} +.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important} +.ml-sm-1,.mx-sm-1{margin-left:.25rem!important} +.m-sm-2{margin:.5rem!important} +.mt-sm-2,.my-sm-2{margin-top:.5rem!important} +.mr-sm-2,.mx-sm-2{margin-right:.5rem!important} +.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important} +.ml-sm-2,.mx-sm-2{margin-left:.5rem!important} +.m-sm-3{margin:1rem!important} +.mt-sm-3,.my-sm-3{margin-top:1rem!important} +.mr-sm-3,.mx-sm-3{margin-right:1rem!important} +.mb-sm-3,.my-sm-3{margin-bottom:1rem!important} +.ml-sm-3,.mx-sm-3{margin-left:1rem!important} +.m-sm-4{margin:1.5rem!important} +.mt-sm-4,.my-sm-4{margin-top:1.5rem!important} +.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important} +.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important} +.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important} +.m-sm-5{margin:3rem!important} +.mt-sm-5,.my-sm-5{margin-top:3rem!important} +.mr-sm-5,.mx-sm-5{margin-right:3rem!important} +.mb-sm-5,.my-sm-5{margin-bottom:3rem!important} +.ml-sm-5,.mx-sm-5{margin-left:3rem!important} +.p-sm-0{padding:0!important} +.pt-sm-0,.py-sm-0{padding-top:0!important} +.pr-sm-0,.px-sm-0{padding-right:0!important} +.pb-sm-0,.py-sm-0{padding-bottom:0!important} +.pl-sm-0,.px-sm-0{padding-left:0!important} +.p-sm-1{padding:.25rem!important} +.pt-sm-1,.py-sm-1{padding-top:.25rem!important} +.pr-sm-1,.px-sm-1{padding-right:.25rem!important} +.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important} +.pl-sm-1,.px-sm-1{padding-left:.25rem!important} +.p-sm-2{padding:.5rem!important} +.pt-sm-2,.py-sm-2{padding-top:.5rem!important} +.pr-sm-2,.px-sm-2{padding-right:.5rem!important} +.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important} +.pl-sm-2,.px-sm-2{padding-left:.5rem!important} +.p-sm-3{padding:1rem!important} +.pt-sm-3,.py-sm-3{padding-top:1rem!important} +.pr-sm-3,.px-sm-3{padding-right:1rem!important} +.pb-sm-3,.py-sm-3{padding-bottom:1rem!important} +.pl-sm-3,.px-sm-3{padding-left:1rem!important} +.p-sm-4{padding:1.5rem!important} +.pt-sm-4,.py-sm-4{padding-top:1.5rem!important} +.pr-sm-4,.px-sm-4{padding-right:1.5rem!important} +.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important} +.pl-sm-4,.px-sm-4{padding-left:1.5rem!important} +.p-sm-5{padding:3rem!important} +.pt-sm-5,.py-sm-5{padding-top:3rem!important} +.pr-sm-5,.px-sm-5{padding-right:3rem!important} +.pb-sm-5,.py-sm-5{padding-bottom:3rem!important} +.pl-sm-5,.px-sm-5{padding-left:3rem!important} +.m-sm-n1{margin:-.25rem!important} +.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important} +.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important} +.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important} +.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important} +.m-sm-n2{margin:-.5rem!important} +.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important} +.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important} +.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important} +.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important} +.m-sm-n3{margin:-1rem!important} +.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important} +.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important} +.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important} +.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important} +.m-sm-n4{margin:-1.5rem!important} +.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important} +.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important} +.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important} +.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important} +.m-sm-n5{margin:-3rem!important} +.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important} +.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important} +.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important} +.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important} +.m-sm-auto{margin:auto!important} +.mt-sm-auto,.my-sm-auto{margin-top:auto!important} +.mr-sm-auto,.mx-sm-auto{margin-right:auto!important} +.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important} +.ml-sm-auto,.mx-sm-auto{margin-left:auto!important} +} +@media (min-width:768px){.m-md-0{margin:0!important} +.mt-md-0,.my-md-0{margin-top:0!important} +.mr-md-0,.mx-md-0{margin-right:0!important} +.mb-md-0,.my-md-0{margin-bottom:0!important} +.ml-md-0,.mx-md-0{margin-left:0!important} +.m-md-1{margin:.25rem!important} +.mt-md-1,.my-md-1{margin-top:.25rem!important} +.mr-md-1,.mx-md-1{margin-right:.25rem!important} +.mb-md-1,.my-md-1{margin-bottom:.25rem!important} +.ml-md-1,.mx-md-1{margin-left:.25rem!important} +.m-md-2{margin:.5rem!important} +.mt-md-2,.my-md-2{margin-top:.5rem!important} +.mr-md-2,.mx-md-2{margin-right:.5rem!important} +.mb-md-2,.my-md-2{margin-bottom:.5rem!important} +.ml-md-2,.mx-md-2{margin-left:.5rem!important} +.m-md-3{margin:1rem!important} +.mt-md-3,.my-md-3{margin-top:1rem!important} +.mr-md-3,.mx-md-3{margin-right:1rem!important} +.mb-md-3,.my-md-3{margin-bottom:1rem!important} +.ml-md-3,.mx-md-3{margin-left:1rem!important} +.m-md-4{margin:1.5rem!important} +.mt-md-4,.my-md-4{margin-top:1.5rem!important} +.mr-md-4,.mx-md-4{margin-right:1.5rem!important} +.mb-md-4,.my-md-4{margin-bottom:1.5rem!important} +.ml-md-4,.mx-md-4{margin-left:1.5rem!important} +.m-md-5{margin:3rem!important} +.mt-md-5,.my-md-5{margin-top:3rem!important} +.mr-md-5,.mx-md-5{margin-right:3rem!important} +.mb-md-5,.my-md-5{margin-bottom:3rem!important} +.ml-md-5,.mx-md-5{margin-left:3rem!important} +.p-md-0{padding:0!important} +.pt-md-0,.py-md-0{padding-top:0!important} +.pr-md-0,.px-md-0{padding-right:0!important} +.pb-md-0,.py-md-0{padding-bottom:0!important} +.pl-md-0,.px-md-0{padding-left:0!important} +.p-md-1{padding:.25rem!important} +.pt-md-1,.py-md-1{padding-top:.25rem!important} +.pr-md-1,.px-md-1{padding-right:.25rem!important} +.pb-md-1,.py-md-1{padding-bottom:.25rem!important} +.pl-md-1,.px-md-1{padding-left:.25rem!important} +.p-md-2{padding:.5rem!important} +.pt-md-2,.py-md-2{padding-top:.5rem!important} +.pr-md-2,.px-md-2{padding-right:.5rem!important} +.pb-md-2,.py-md-2{padding-bottom:.5rem!important} +.pl-md-2,.px-md-2{padding-left:.5rem!important} +.p-md-3{padding:1rem!important} +.pt-md-3,.py-md-3{padding-top:1rem!important} +.pr-md-3,.px-md-3{padding-right:1rem!important} +.pb-md-3,.py-md-3{padding-bottom:1rem!important} +.pl-md-3,.px-md-3{padding-left:1rem!important} +.p-md-4{padding:1.5rem!important} +.pt-md-4,.py-md-4{padding-top:1.5rem!important} +.pr-md-4,.px-md-4{padding-right:1.5rem!important} +.pb-md-4,.py-md-4{padding-bottom:1.5rem!important} +.pl-md-4,.px-md-4{padding-left:1.5rem!important} +.p-md-5{padding:3rem!important} +.pt-md-5,.py-md-5{padding-top:3rem!important} +.pr-md-5,.px-md-5{padding-right:3rem!important} +.pb-md-5,.py-md-5{padding-bottom:3rem!important} +.pl-md-5,.px-md-5{padding-left:3rem!important} +.m-md-n1{margin:-.25rem!important} +.mt-md-n1,.my-md-n1{margin-top:-.25rem!important} +.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important} +.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important} +.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important} +.m-md-n2{margin:-.5rem!important} +.mt-md-n2,.my-md-n2{margin-top:-.5rem!important} +.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important} +.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important} +.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important} +.m-md-n3{margin:-1rem!important} +.mt-md-n3,.my-md-n3{margin-top:-1rem!important} +.mr-md-n3,.mx-md-n3{margin-right:-1rem!important} +.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important} +.ml-md-n3,.mx-md-n3{margin-left:-1rem!important} +.m-md-n4{margin:-1.5rem!important} +.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important} +.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important} +.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important} +.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important} +.m-md-n5{margin:-3rem!important} +.mt-md-n5,.my-md-n5{margin-top:-3rem!important} +.mr-md-n5,.mx-md-n5{margin-right:-3rem!important} +.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important} +.ml-md-n5,.mx-md-n5{margin-left:-3rem!important} +.m-md-auto{margin:auto!important} +.mt-md-auto,.my-md-auto{margin-top:auto!important} +.mr-md-auto,.mx-md-auto{margin-right:auto!important} +.mb-md-auto,.my-md-auto{margin-bottom:auto!important} +.ml-md-auto,.mx-md-auto{margin-left:auto!important} +} +@media (min-width:992px){.m-lg-0{margin:0!important} +.mt-lg-0,.my-lg-0{margin-top:0!important} +.mr-lg-0,.mx-lg-0{margin-right:0!important} +.mb-lg-0,.my-lg-0{margin-bottom:0!important} +.ml-lg-0,.mx-lg-0{margin-left:0!important} +.m-lg-1{margin:.25rem!important} +.mt-lg-1,.my-lg-1{margin-top:.25rem!important} +.mr-lg-1,.mx-lg-1{margin-right:.25rem!important} +.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important} +.ml-lg-1,.mx-lg-1{margin-left:.25rem!important} +.m-lg-2{margin:.5rem!important} +.mt-lg-2,.my-lg-2{margin-top:.5rem!important} +.mr-lg-2,.mx-lg-2{margin-right:.5rem!important} +.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important} +.ml-lg-2,.mx-lg-2{margin-left:.5rem!important} +.m-lg-3{margin:1rem!important} +.mt-lg-3,.my-lg-3{margin-top:1rem!important} +.mr-lg-3,.mx-lg-3{margin-right:1rem!important} +.mb-lg-3,.my-lg-3{margin-bottom:1rem!important} +.ml-lg-3,.mx-lg-3{margin-left:1rem!important} +.m-lg-4{margin:1.5rem!important} +.mt-lg-4,.my-lg-4{margin-top:1.5rem!important} +.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important} +.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important} +.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important} +.m-lg-5{margin:3rem!important} +.mt-lg-5,.my-lg-5{margin-top:3rem!important} +.mr-lg-5,.mx-lg-5{margin-right:3rem!important} +.mb-lg-5,.my-lg-5{margin-bottom:3rem!important} +.ml-lg-5,.mx-lg-5{margin-left:3rem!important} +.p-lg-0{padding:0!important} +.pt-lg-0,.py-lg-0{padding-top:0!important} +.pr-lg-0,.px-lg-0{padding-right:0!important} +.pb-lg-0,.py-lg-0{padding-bottom:0!important} +.pl-lg-0,.px-lg-0{padding-left:0!important} +.p-lg-1{padding:.25rem!important} +.pt-lg-1,.py-lg-1{padding-top:.25rem!important} +.pr-lg-1,.px-lg-1{padding-right:.25rem!important} +.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important} +.pl-lg-1,.px-lg-1{padding-left:.25rem!important} +.p-lg-2{padding:.5rem!important} +.pt-lg-2,.py-lg-2{padding-top:.5rem!important} +.pr-lg-2,.px-lg-2{padding-right:.5rem!important} +.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important} +.pl-lg-2,.px-lg-2{padding-left:.5rem!important} +.p-lg-3{padding:1rem!important} +.pt-lg-3,.py-lg-3{padding-top:1rem!important} +.pr-lg-3,.px-lg-3{padding-right:1rem!important} +.pb-lg-3,.py-lg-3{padding-bottom:1rem!important} +.pl-lg-3,.px-lg-3{padding-left:1rem!important} +.p-lg-4{padding:1.5rem!important} +.pt-lg-4,.py-lg-4{padding-top:1.5rem!important} +.pr-lg-4,.px-lg-4{padding-right:1.5rem!important} +.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important} +.pl-lg-4,.px-lg-4{padding-left:1.5rem!important} +.p-lg-5{padding:3rem!important} +.pt-lg-5,.py-lg-5{padding-top:3rem!important} +.pr-lg-5,.px-lg-5{padding-right:3rem!important} +.pb-lg-5,.py-lg-5{padding-bottom:3rem!important} +.pl-lg-5,.px-lg-5{padding-left:3rem!important} +.m-lg-n1{margin:-.25rem!important} +.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important} +.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important} +.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important} +.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important} +.m-lg-n2{margin:-.5rem!important} +.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important} +.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important} +.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important} +.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important} +.m-lg-n3{margin:-1rem!important} +.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important} +.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important} +.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important} +.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important} +.m-lg-n4{margin:-1.5rem!important} +.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important} +.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important} +.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important} +.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important} +.m-lg-n5{margin:-3rem!important} +.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important} +.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important} +.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important} +.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important} +.m-lg-auto{margin:auto!important} +.mt-lg-auto,.my-lg-auto{margin-top:auto!important} +.mr-lg-auto,.mx-lg-auto{margin-right:auto!important} +.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important} +.ml-lg-auto,.mx-lg-auto{margin-left:auto!important} +} +@media (min-width:1200px){.m-xl-0{margin:0!important} +.mt-xl-0,.my-xl-0{margin-top:0!important} +.mr-xl-0,.mx-xl-0{margin-right:0!important} +.mb-xl-0,.my-xl-0{margin-bottom:0!important} +.ml-xl-0,.mx-xl-0{margin-left:0!important} +.m-xl-1{margin:.25rem!important} +.mt-xl-1,.my-xl-1{margin-top:.25rem!important} +.mr-xl-1,.mx-xl-1{margin-right:.25rem!important} +.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important} +.ml-xl-1,.mx-xl-1{margin-left:.25rem!important} +.m-xl-2{margin:.5rem!important} +.mt-xl-2,.my-xl-2{margin-top:.5rem!important} +.mr-xl-2,.mx-xl-2{margin-right:.5rem!important} +.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important} +.ml-xl-2,.mx-xl-2{margin-left:.5rem!important} +.m-xl-3{margin:1rem!important} +.mt-xl-3,.my-xl-3{margin-top:1rem!important} +.mr-xl-3,.mx-xl-3{margin-right:1rem!important} +.mb-xl-3,.my-xl-3{margin-bottom:1rem!important} +.ml-xl-3,.mx-xl-3{margin-left:1rem!important} +.m-xl-4{margin:1.5rem!important} +.mt-xl-4,.my-xl-4{margin-top:1.5rem!important} +.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important} +.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important} +.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important} +.m-xl-5{margin:3rem!important} +.mt-xl-5,.my-xl-5{margin-top:3rem!important} +.mr-xl-5,.mx-xl-5{margin-right:3rem!important} +.mb-xl-5,.my-xl-5{margin-bottom:3rem!important} +.ml-xl-5,.mx-xl-5{margin-left:3rem!important} +.p-xl-0{padding:0!important} +.pt-xl-0,.py-xl-0{padding-top:0!important} +.pr-xl-0,.px-xl-0{padding-right:0!important} +.pb-xl-0,.py-xl-0{padding-bottom:0!important} +.pl-xl-0,.px-xl-0{padding-left:0!important} +.p-xl-1{padding:.25rem!important} +.pt-xl-1,.py-xl-1{padding-top:.25rem!important} +.pr-xl-1,.px-xl-1{padding-right:.25rem!important} +.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important} +.pl-xl-1,.px-xl-1{padding-left:.25rem!important} +.p-xl-2{padding:.5rem!important} +.pt-xl-2,.py-xl-2{padding-top:.5rem!important} +.pr-xl-2,.px-xl-2{padding-right:.5rem!important} +.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important} +.pl-xl-2,.px-xl-2{padding-left:.5rem!important} +.p-xl-3{padding:1rem!important} +.pt-xl-3,.py-xl-3{padding-top:1rem!important} +.pr-xl-3,.px-xl-3{padding-right:1rem!important} +.pb-xl-3,.py-xl-3{padding-bottom:1rem!important} +.pl-xl-3,.px-xl-3{padding-left:1rem!important} +.p-xl-4{padding:1.5rem!important} +.pt-xl-4,.py-xl-4{padding-top:1.5rem!important} +.pr-xl-4,.px-xl-4{padding-right:1.5rem!important} +.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important} +.pl-xl-4,.px-xl-4{padding-left:1.5rem!important} +.p-xl-5{padding:3rem!important} +.pt-xl-5,.py-xl-5{padding-top:3rem!important} +.pr-xl-5,.px-xl-5{padding-right:3rem!important} +.pb-xl-5,.py-xl-5{padding-bottom:3rem!important} +.pl-xl-5,.px-xl-5{padding-left:3rem!important} +.m-xl-n1{margin:-.25rem!important} +.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important} +.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important} +.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important} +.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important} +.m-xl-n2{margin:-.5rem!important} +.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important} +.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important} +.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important} +.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important} +.m-xl-n3{margin:-1rem!important} +.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important} +.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important} +.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important} +.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important} +.m-xl-n4{margin:-1.5rem!important} +.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important} +.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important} +.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important} +.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important} +.m-xl-n5{margin:-3rem!important} +.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important} +.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important} +.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important} +.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important} +.m-xl-auto{margin:auto!important} +.mt-xl-auto,.my-xl-auto{margin-top:auto!important} +.mr-xl-auto,.mx-xl-auto{margin-right:auto!important} +.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important} +.ml-xl-auto,.mx-xl-auto{margin-left:auto!important} +} +.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)} +.text-justify{text-align:justify!important} +.text-wrap{white-space:normal!important} +.text-nowrap{white-space:nowrap!important} +.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.text-left{text-align:left!important} +.text-right{text-align:right!important} +.text-center{text-align:center!important} +@media (min-width:576px){.text-sm-left{text-align:left!important} +.text-sm-right{text-align:right!important} +.text-sm-center{text-align:center!important} +} +@media (min-width:768px){.text-md-left{text-align:left!important} +.text-md-right{text-align:right!important} +.text-md-center{text-align:center!important} +} +@media (min-width:992px){.text-lg-left{text-align:left!important} +.text-lg-right{text-align:right!important} +.text-lg-center{text-align:center!important} +} +@media (min-width:1200px){.text-xl-left{text-align:left!important} +.text-xl-right{text-align:right!important} +.text-xl-center{text-align:center!important} +} +.text-lowercase{text-transform:lowercase!important} +.text-uppercase{text-transform:uppercase!important} +.text-capitalize{text-transform:capitalize!important} +.font-weight-light{font-weight:300!important} +.font-weight-lighter{font-weight:lighter!important} +.font-weight-normal{font-weight:400!important} +.font-weight-bold{font-weight:700!important} +.font-weight-bolder{font-weight:bolder!important} +.font-italic{font-style:italic!important} +.text-white{color:#fff!important} +.text-primary{color:#007bff!important} +a.text-primary:focus,a.text-primary:hover{color:#0056b3!important} +.text-secondary{color:#6c757d!important} +a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important} +.text-success{color:#28a745!important} +a.text-success:focus,a.text-success:hover{color:#19692c!important} +.text-info{color:#17a2b8!important} +a.text-info:focus,a.text-info:hover{color:#0f6674!important} +.text-warning{color:#ffc107!important} +a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important} +.text-danger{color:#dc3545!important} +a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important} +.text-light{color:#f8f9fa!important} +a.text-light:focus,a.text-light:hover{color:#cbd3da!important} +.text-dark{color:#343a40!important} +a.text-dark:focus,a.text-dark:hover{color:#121416!important} +.text-body{color:#212529!important} +.text-muted{color:#6c757d!important} +.text-black-50{color:rgba(0,0,0,.5)!important} +.text-white-50{color:rgba(255,255,255,.5)!important} +.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} +.text-decoration-none{text-decoration:none!important} +.text-break{word-break:break-word!important;word-wrap:break-word!important} +.text-reset{color:inherit!important} +.visible{visibility:visible!important} +.invisible{visibility:hidden!important} +@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important} +a:not(.btn){text-decoration:underline} +abbr[title]::after{content:" (" attr(title) ")"} +pre{white-space:pre-wrap!important} +blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid} +img,tr{page-break-inside:avoid} +h2,h3,p{orphans:3;widows:3} +h2,h3{page-break-after:avoid} +@page{size:a3} +body{min-width:992px!important} +.container{min-width:992px!important} +.navbar{display:none} +.badge{border:1px solid #000} +.table{border-collapse:collapse!important} +.table td,.table th{background-color:#fff!important} +.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important} +.table-dark{color:inherit} +.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6} +.table .thead-dark th{color:inherit;border-color:#dee2e6} +} + +/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/html/changelogs/archive/2024-02.yml b/html/changelogs/archive/2024-02.yml index dbfb52ce256..b2ad5be032c 100644 --- a/html/changelogs/archive/2024-02.yml +++ b/html/changelogs/archive/2024-02.yml @@ -115,3 +115,196 @@ - add: Remove Mr.Cheng Technique from melee thunderdome (#4359) github-actions[bot]: - server: Automatic NanoMap Update (#4372) +'2024-02-11': + ArtemDerp: + - bugfix: reconstruction of the disposal pipe system (#4375) +'2024-02-12': + ArtemDerp: + - bugfix: added missed sprites for sec bundles (#4268) + - bugfix: fixed overlap of wall objects (#4398) + - add: security drip update (#4371) + - add: Updated Wizard Clothing (#4252) + - add: laser gun reskin (#4278) + - add: new species meat (#4259) + BeebBeebBoob: + - refactor: Define bitflags (#4181) + Daeberdir: + - bugfix: correct view range calculating and examine corrections. (#4400) + - add: Zaza drink. (#4318) + Darkest08: + - imageadd: added sst hardsuit skins (#4120) + Den109G: + - add: Added adds a popup window with suggested version (#4386) + Etrnlmelancholy: + - tweak: ipc and pai wire sprite update (#4391) + Renascitur: + - add: Hierophant Talisman from hardmode Hierophant (#4314) + Rerik007: + - bugfix: fix null.len runtime (#4388) + - bugfix: mecha cargomodule for lockermech broken (#4396) + - bugfix: fix runtime to_chat called with invalid message (#4387) + SAAD: + - tweak: Remove extra atmos different turfes and useless dirs and tags (#4394) + Vladisvell: + - bugfix: Removed incorrect winsets for dark and light themes (#4392) + Zwei: + - refactor: Icon Updates Rework Part2 (#4170) + - bugfix: Paper Fix (#4407) + - add: Added Adidas Uniform (#4381) + github-actions[bot]: + - server: Automatic NanoMap Update (#4399) + xTrogwaRx: + - bugfix: show panel virology fridge after screw act (#4321) + - qol: keybinds for tail and wings (#4320) +'2024-02-13': + ArtemDerp: + - bugfix: correct naming for tasers locker (#4415) + - bugfix: fixed missed cheks for sec scarf and googles (#4409) + BeebBeebBoob: + - bugfix: inflatable barrier box could fit anything (#4408) + Daeberdir: + - bugfix: outfit inhand items disappearing. (#4401) + Valtor: + - qol: Borer QoL update (#4343) + Zwei: + - bugfix: Laser Weapons In Hands Fix (#4410) + - bugfix: ChemDispenser Overlays Fix (#4418) + github-actions[bot]: + - server: Automatic NanoMap Update (#4412) +'2024-02-14': + ArtemDerp: + - bugfix: security gas mask removed extra cover flags (#4426) + - add: new meat steak recipes (#4425) + - add: removed meatwheat mutation and syntiflesh reaction (#4417) + - add: new meat pie recipes (#4416) + BeebBeebBoob: + - refactor: Update CONTRIBUTING.md (#4402) + Daeberdir: + - tweak: progressbar for examining and possibility to examine items in storages. + (#4427) + ROdenFL: + - bugfix: pain hunter late game fix (#4424) + Rerik007: + - bugfix: glands names was the same (#4421) + - qol: bindable action buttons (#4420) + Zwei: + - bugfix: Inflatable Door Vision Fix (#4429) + - bugfix: Falsewall Opacity Fix (#4431) + - bugfix: Multicolored Pen Overlay Fix (#4430) + - bugfix: Taperecorder Fix (#4419) + - tweak: Vision And Emotes Fixes (#4233) +'2024-02-15': + ArtemDerp: + - add: Resprited Stoks (#4322) +'2024-02-16': + Den109G: + - bugfix: Construction bag from cloth craft (#4433) + Etrnlmelancholy: + - tweak: seccie webbing to sectech (#4437) +'2024-02-17': + ARZUMATA: + - bugfix: airlock electronics null fix (#4397) + ArtemDerp: + - bugfix: humans have human meat (#4457) + Aziz Chynaliev: + - server: auto review requests for maps + Mindfri: + - add: NT Mecha PaintKit (#4438) + NightDawnFox: + - refactor: moving almost all tool checks to "tool_behaviour" (#4434) + - add: frosty breath effect in low-temperature rooms (#3385) + Pavel Lysenko: + - spellcheck: Исправлены опечатки и мелкие ошибки в описаниях ролей Тайпана (#2310) + ROdenFL: + - experiment: dark theme, colors, font-awesome, blob update (#4354) + WolfLox: + - tweak: lots of small, varied and not too noticeable changes ERT loadout (#4154) + Zwei: + - bugfix: Welding Mask Overlays (#4448) + mrWhiteFox365: + - unknown: Kerberos R&D Cafeteria (#4285) + xTrogwaRx: + - qol: Recolor "Set Occupation Preferences" menu (#4428) +'2024-02-18': + ArtemDerp: + - bugfix: fixed glasses over mask layer position (#4449) + Aziz Chynaliev: + - server: ensure security via CODEOWNERS file + - server: check user permission on deploy action + - server: fix action permission checks + BeebBeebBoob: + - tweak: Change locator on GPS-sec in implant-tracking boxes. (#4454) + - bugfix: runtime machinery.ui_act null.tool_behaviour (#4461) + Daeberdir: + - bugfix: alphabet sorting for chem dispensers on spawn. (#4453) + - bugfix: silicon PDA UI working properly. (#4445) + - bugfix: '`update_equipped_item()` correct updating clothing sprites. (#4456)' + Den109G: + - bugfix: adds area to AI's cams (#4452) + LiquidPotroh: + - tweak: Amomaly extract cooldown & cost (#4447) + - bugfix: invincibility machinepersons to neurotoxin spit (#4225) + ROdenFL: + - bugfix: darkmode runtime (#4455) + - balance: pulse demon only shitspawn and mage pet (#4440) + - unknown: NULL crate (#4422) + - add: exploit records for uplink and pick darkness for ghosts (#3909) + Rerik007: + - add: alt-click on the damage zone will be equivalent to clicking on itself (#4384) + - bugfix: flashbangs can permanently break your hearing (#4439) + - bugfix: t-ray scanner can make you invisible (#4414) + - bugfix: base pai can toggle apc (#4459) + SAAD: + - refactor: Transit tubes (#4443) + Vladisvell: + - bugfix: bootstrap.min.css CRLF -> LF (#4463) + - add: New Thunderdome items (#4460) + Zwei: + - bugfix: Matchbox Icons Fix (#4441) + - bugfix: Barrel Icon State Fix (#4451) + - tweak: Tables Flip Hotkey Change (#4423) + github-actions[bot]: + - server: Automatic NanoMap Update (#4458) +'2024-02-20': + Daeberdir: + - bugfix: Autopsy scanner can scan different "Unknown" bodies. (#4442) + Den109G: + - bugfix: Standardization and action desc fix (#4470) + LiquidPotroh: + - bugfix: holster examine (#4467) + - bugfix: Vampire position after bestia transform resets normally (#4468) + Rerik007: + - tweak: cargo few orders and change access for cargo quest console (#4472) + - refactor: move defib code to component (#4406) + Valtor: + - bugfix: autoimplanter missing limb (#4466) + Vladisvell: + - bugfix: Fixed Chef's and Machinery errors (#4462) + - add: Added book flag tracking and view flagged books does not crash server (#4191) + Zwei: + - refactor: Icon Updates Rework Part3 (#4221) + github-actions[bot]: + - server: Automatic NanoMap Update (#4469) +'2024-02-21': + Daeberdir: + - bugfix: examine through the camera console. (#4476) + - add: makeshift MOD-revolver. (#4131) + - bugfix: multipulling. (#4205) + - refactor: two-character keys for languages. (#4215) + LiquidPotroh: + - add: Lavaland Apprentice (#4413) + Rafnik02: + - tweak: Oldstation update (#4346) + Rerik007: + - bugfix: xenobioconsole can make monkeys out of the limit. (#4473) +'2024-02-22': + BeebBeebBoob: + - bugfix: fax discord (#4483) + Daeberdir: + - bugfix: arrival shuttle zone. (#4484) + Valtor: + - bugfix: autoimplanter v2 (#4485) +'2024-02-24': + Vladisvell: + - balance: added scalable antags from alive players count for paradise_antag game + mode (#4450) diff --git a/html/font-awesome/css/all.min.css b/html/font-awesome/css/all.min.css index e7cdfffe751..12b385404d7 100644 --- a/html/font-awesome/css/all.min.css +++ b/html/font-awesome/css/all.min.css @@ -1,5 +1,5 @@ /*! - * Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ -.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff) format("woff")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff) format("woff")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(fa-brands-400.eot);src:url(fa-brands-400.eot?#iefix) format("embedded-opentype"),url(fa-brands-400.woff2) format("woff2"),url(fa-brands-400.woff) format("woff"),url(fa-brands-400.ttf) format("truetype"),url(fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff2) format("woff2"),url(fa-regular-400.woff) format("woff"),url(fa-regular-400.ttf) format("truetype"),url(fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff2) format("woff2"),url(fa-solid-900.woff) format("woff"),url(fa-solid-900.ttf) format("truetype"),url(fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} diff --git a/html/font-awesome/css/v4-shims.min.css b/html/font-awesome/css/v4-shims.min.css index 5f3fdc598c8..21a0708aafa 100644 --- a/html/font-awesome/css/v4-shims.min.css +++ b/html/font-awesome/css/v4-shims.min.css @@ -1,5 +1,5 @@ /*! - * Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ -.fa.fa-glass:before{content:"\f000"}.fa.fa-meetup{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-star-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-file-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-pencil:before{content:"\f303"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-share-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart:before{content:"\f080"}.fa.fa-bar-chart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart-o:before{content:"\f080"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-lemon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-scissors:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-google-plus,.fa.fa-google-plus-square,.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f3fd"}.fa.fa-comment-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard,.fa.fa-paste{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paste:before{content:"\f328"}.fa.fa-lightbulb-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f381"}.fa.fa-cloud-upload:before{content:"\f382"}.fa.fa-bell-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f089"}.fa.fa-star-half-empty{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f089"}.fa.fa-star-half-full{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f089"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before{content:"\f127"}.fa.fa-shield:before{content:"\f3ed"}.fa.fa-calendar-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ticket:before{content:"\f3ff"}.fa.fa-minus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\f155"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\f156"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f15e"}.fa.fa-sort-amount-asc:before{content:"\f160"}.fa.fa-sort-amount-desc:before{content:"\f161"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f163"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-play,.fa.fa-youtube-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\f195"}.fa.fa-plus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-google,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle,.fa.fa-yahoo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-spoon:before{content:"\f2e5"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-cab:before{content:"\f1ba"}.fa.fa-envelope-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-deviantart,.fa.fa-soundcloud{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-life-bouy,.fa.fa-life-ring{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-bouy:before{content:"\f1cd"}.fa.fa-life-buoy{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-buoy:before{content:"\f1cd"}.fa.fa-life-saver{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-saver:before{content:"\f1cd"}.fa.fa-support{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-sliders:before{content:"\f1de"}.fa.fa-futbol-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-angellist,.fa.fa-ioxhost,.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-meanpath{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-meanpath:before{content:"\f2b4"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before{content:"\f224"}.fa.fa-facebook-official{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-clone,.fa.fa-hourglass-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-chrome,.fa.fa-creative-commons,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-internet-explorer,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square,.fa.fa-opera,.fa.fa-safari,.fa.fa-tripadvisor,.fa.fa-wikipedia-w{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat,.fa.fa-snapchat-ghost,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-viadeo,.fa.fa-viadeo-square,.fa.fa-yoast{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-spotify,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 5 Brands";font-weight:400} \ No newline at end of file +.fa.fa-glass:before{content:"\f000"}.fa.fa-meetup{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-star-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-file-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-pencil:before{content:"\f303"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-share-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart:before{content:"\f080"}.fa.fa-bar-chart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart-o:before{content:"\f080"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-lemon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-scissors:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-google-plus,.fa.fa-google-plus-square,.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f3fd"}.fa.fa-comment-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard,.fa.fa-paste{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paste:before{content:"\f328"}.fa.fa-lightbulb-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f381"}.fa.fa-cloud-upload:before{content:"\f382"}.fa.fa-bell-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f089"}.fa.fa-star-half-empty{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f089"}.fa.fa-star-half-full{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f089"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before{content:"\f127"}.fa.fa-shield:before{content:"\f3ed"}.fa.fa-calendar-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ticket:before{content:"\f3ff"}.fa.fa-minus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\f155"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\f156"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f160"}.fa.fa-sort-amount-desc:before{content:"\f884"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-play,.fa.fa-youtube-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\f195"}.fa.fa-plus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-google,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle,.fa.fa-yahoo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-spoon:before{content:"\f2e5"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-envelope-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-life-bouy,.fa.fa-life-ring{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-bouy:before{content:"\f1cd"}.fa.fa-life-buoy{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-buoy:before{content:"\f1cd"}.fa.fa-life-saver{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-saver:before{content:"\f1cd"}.fa.fa-support{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-sliders:before{content:"\f1de"}.fa.fa-futbol-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-angellist,.fa.fa-ioxhost,.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-meanpath{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-meanpath:before{content:"\f2b4"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before{content:"\f224"}.fa.fa-facebook-official{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-clone,.fa.fa-hourglass-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-chrome,.fa.fa-creative-commons,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-internet-explorer,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square,.fa.fa-opera,.fa.fa-safari,.fa.fa-tripadvisor,.fa.fa-wikipedia-w{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat,.fa.fa-snapchat-ghost,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-viadeo,.fa.fa-viadeo-square,.fa.fa-yoast{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cab:before{content:"\f1ba"} \ No newline at end of file diff --git a/html/font-awesome/webfonts/fa-regular-400.eot b/html/font-awesome/webfonts/fa-regular-400.eot index d62be2fad88..a4e598936b3 100644 Binary files a/html/font-awesome/webfonts/fa-regular-400.eot and b/html/font-awesome/webfonts/fa-regular-400.eot differ diff --git a/html/font-awesome/webfonts/fa-regular-400.woff b/html/font-awesome/webfonts/fa-regular-400.woff index 43b1a9ae49d..ad077c6bec7 100644 Binary files a/html/font-awesome/webfonts/fa-regular-400.woff and b/html/font-awesome/webfonts/fa-regular-400.woff differ diff --git a/html/font-awesome/webfonts/fa-solid-900.eot b/html/font-awesome/webfonts/fa-solid-900.eot index c77baa8d46a..e99417197e4 100644 Binary files a/html/font-awesome/webfonts/fa-solid-900.eot and b/html/font-awesome/webfonts/fa-solid-900.eot differ diff --git a/html/font-awesome/webfonts/fa-solid-900.woff b/html/font-awesome/webfonts/fa-solid-900.woff index 77c1786227f..23ee663443a 100644 Binary files a/html/font-awesome/webfonts/fa-solid-900.woff and b/html/font-awesome/webfonts/fa-solid-900.woff differ diff --git a/icons/_nanomaps/Cyberiad_nanomap_z1.png b/icons/_nanomaps/Cyberiad_nanomap_z1.png index 5ce736d1576..50530b372ed 100644 Binary files a/icons/_nanomaps/Cyberiad_nanomap_z1.png and b/icons/_nanomaps/Cyberiad_nanomap_z1.png differ diff --git a/icons/_nanomaps/Delta_nanomap_z1.png b/icons/_nanomaps/Delta_nanomap_z1.png index c5f78375087..524961ff272 100644 Binary files a/icons/_nanomaps/Delta_nanomap_z1.png and b/icons/_nanomaps/Delta_nanomap_z1.png differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 4fd3beb4153..37295319bb3 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi index b11a2ac75fd..8c837b0e546 100644 Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi index d0439308691..f654295e8f3 100644 Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi index d64644b0d50..b554c709f92 100644 Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi index 1a63f700907..a54246cc501 100644 Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 62d862d5092..c2c47492f6b 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/species/drask/eyes.dmi b/icons/mob/clothing/species/drask/eyes.dmi index 7fbe4aced2f..355f5e2cf51 100644 Binary files a/icons/mob/clothing/species/drask/eyes.dmi and b/icons/mob/clothing/species/drask/eyes.dmi differ diff --git a/icons/mob/clothing/species/drask/head.dmi b/icons/mob/clothing/species/drask/head.dmi index ed7fcb3538b..6d02bb20fe6 100644 Binary files a/icons/mob/clothing/species/drask/head.dmi and b/icons/mob/clothing/species/drask/head.dmi differ diff --git a/icons/mob/clothing/species/drask/helmet.dmi b/icons/mob/clothing/species/drask/helmet.dmi index 0ab58369a0f..b0c49b3c419 100644 Binary files a/icons/mob/clothing/species/drask/helmet.dmi and b/icons/mob/clothing/species/drask/helmet.dmi differ diff --git a/icons/mob/clothing/species/drask/mask.dmi b/icons/mob/clothing/species/drask/mask.dmi index 807cec3cdea..db26ee4b53f 100644 Binary files a/icons/mob/clothing/species/drask/mask.dmi and b/icons/mob/clothing/species/drask/mask.dmi differ diff --git a/icons/mob/clothing/species/drask/suit.dmi b/icons/mob/clothing/species/drask/suit.dmi index 83b1cbc29d6..4f725b4ecf8 100644 Binary files a/icons/mob/clothing/species/drask/suit.dmi and b/icons/mob/clothing/species/drask/suit.dmi differ diff --git a/icons/mob/clothing/species/drask/uniform.dmi b/icons/mob/clothing/species/drask/uniform.dmi index d1bfb3f3aa0..123d948dd41 100644 Binary files a/icons/mob/clothing/species/drask/uniform.dmi and b/icons/mob/clothing/species/drask/uniform.dmi differ diff --git a/icons/mob/clothing/species/grey/eyes.dmi b/icons/mob/clothing/species/grey/eyes.dmi index acff6dee4b9..8d1ae19391c 100644 Binary files a/icons/mob/clothing/species/grey/eyes.dmi and b/icons/mob/clothing/species/grey/eyes.dmi differ diff --git a/icons/mob/clothing/species/grey/helmet.dmi b/icons/mob/clothing/species/grey/helmet.dmi index 4f8bfc79a7b..5c0010c30c9 100644 Binary files a/icons/mob/clothing/species/grey/helmet.dmi and b/icons/mob/clothing/species/grey/helmet.dmi differ diff --git a/icons/mob/clothing/species/grey/mask.dmi b/icons/mob/clothing/species/grey/mask.dmi index d85ea5dce21..82c9d36ff3b 100644 Binary files a/icons/mob/clothing/species/grey/mask.dmi and b/icons/mob/clothing/species/grey/mask.dmi differ diff --git a/icons/mob/clothing/species/grey/uniform.dmi b/icons/mob/clothing/species/grey/uniform.dmi index fe0f46b4b71..41ebec1c8a1 100644 Binary files a/icons/mob/clothing/species/grey/uniform.dmi and b/icons/mob/clothing/species/grey/uniform.dmi differ diff --git a/icons/mob/clothing/species/monkey/eyes.dmi b/icons/mob/clothing/species/monkey/eyes.dmi index b430e2e5020..7e0e44e270f 100644 Binary files a/icons/mob/clothing/species/monkey/eyes.dmi and b/icons/mob/clothing/species/monkey/eyes.dmi differ diff --git a/icons/mob/clothing/species/monkey/head.dmi b/icons/mob/clothing/species/monkey/head.dmi index 055216eaed9..95c06af67bc 100644 Binary files a/icons/mob/clothing/species/monkey/head.dmi and b/icons/mob/clothing/species/monkey/head.dmi differ diff --git a/icons/mob/clothing/species/monkey/mask.dmi b/icons/mob/clothing/species/monkey/mask.dmi index bbc13fc65d7..c37c41b35a1 100644 Binary files a/icons/mob/clothing/species/monkey/mask.dmi and b/icons/mob/clothing/species/monkey/mask.dmi differ diff --git a/icons/mob/clothing/species/monkey/uniform.dmi b/icons/mob/clothing/species/monkey/uniform.dmi index aa7ffea3268..cb8e3d0dd85 100644 Binary files a/icons/mob/clothing/species/monkey/uniform.dmi and b/icons/mob/clothing/species/monkey/uniform.dmi differ diff --git a/icons/mob/clothing/species/plasmaman/mask.dmi b/icons/mob/clothing/species/plasmaman/mask.dmi index 374c4c25aa6..0d28762d032 100644 Binary files a/icons/mob/clothing/species/plasmaman/mask.dmi and b/icons/mob/clothing/species/plasmaman/mask.dmi differ diff --git a/icons/mob/clothing/species/tajaran/head.dmi b/icons/mob/clothing/species/tajaran/head.dmi index b9e3090c037..8fb90a451d2 100644 Binary files a/icons/mob/clothing/species/tajaran/head.dmi and b/icons/mob/clothing/species/tajaran/head.dmi differ diff --git a/icons/mob/clothing/species/tajaran/helmet.dmi b/icons/mob/clothing/species/tajaran/helmet.dmi index 48521b0bfda..7340c8c9db1 100644 Binary files a/icons/mob/clothing/species/tajaran/helmet.dmi and b/icons/mob/clothing/species/tajaran/helmet.dmi differ diff --git a/icons/mob/clothing/species/tajaran/mask.dmi b/icons/mob/clothing/species/tajaran/mask.dmi index a433e44f240..90b55d2fb79 100644 Binary files a/icons/mob/clothing/species/tajaran/mask.dmi and b/icons/mob/clothing/species/tajaran/mask.dmi differ diff --git a/icons/mob/clothing/species/tajaran/suit.dmi b/icons/mob/clothing/species/tajaran/suit.dmi index 6bbc8c52e0e..05cb40b48f5 100644 Binary files a/icons/mob/clothing/species/tajaran/suit.dmi and b/icons/mob/clothing/species/tajaran/suit.dmi differ diff --git a/icons/mob/clothing/species/unathi/head.dmi b/icons/mob/clothing/species/unathi/head.dmi index 3c7a9aee3c3..bc7498ef90f 100644 Binary files a/icons/mob/clothing/species/unathi/head.dmi and b/icons/mob/clothing/species/unathi/head.dmi differ diff --git a/icons/mob/clothing/species/unathi/helmet.dmi b/icons/mob/clothing/species/unathi/helmet.dmi index 8ddf7d08395..13ffdaab528 100644 Binary files a/icons/mob/clothing/species/unathi/helmet.dmi and b/icons/mob/clothing/species/unathi/helmet.dmi differ diff --git a/icons/mob/clothing/species/unathi/mask.dmi b/icons/mob/clothing/species/unathi/mask.dmi index f76cae2d357..9802caa3ac1 100644 Binary files a/icons/mob/clothing/species/unathi/mask.dmi and b/icons/mob/clothing/species/unathi/mask.dmi differ diff --git a/icons/mob/clothing/species/unathi/suit.dmi b/icons/mob/clothing/species/unathi/suit.dmi index 9c34852f8ce..edecf31cba7 100644 Binary files a/icons/mob/clothing/species/unathi/suit.dmi and b/icons/mob/clothing/species/unathi/suit.dmi differ diff --git a/icons/mob/clothing/species/unathi/uniform.dmi b/icons/mob/clothing/species/unathi/uniform.dmi index d3a3d2639ad..7756dbf128a 100644 Binary files a/icons/mob/clothing/species/unathi/uniform.dmi and b/icons/mob/clothing/species/unathi/uniform.dmi differ diff --git a/icons/mob/clothing/species/vox/eyes.dmi b/icons/mob/clothing/species/vox/eyes.dmi index d39ec8fadae..482199a45f4 100644 Binary files a/icons/mob/clothing/species/vox/eyes.dmi and b/icons/mob/clothing/species/vox/eyes.dmi differ diff --git a/icons/mob/clothing/species/vox/head.dmi b/icons/mob/clothing/species/vox/head.dmi index 0300c275c49..53e1be9486b 100644 Binary files a/icons/mob/clothing/species/vox/head.dmi and b/icons/mob/clothing/species/vox/head.dmi differ diff --git a/icons/mob/clothing/species/vox/helmet.dmi b/icons/mob/clothing/species/vox/helmet.dmi index 321a41a2cc5..c34f0f63950 100644 Binary files a/icons/mob/clothing/species/vox/helmet.dmi and b/icons/mob/clothing/species/vox/helmet.dmi differ diff --git a/icons/mob/clothing/species/vox/mask.dmi b/icons/mob/clothing/species/vox/mask.dmi index a23a8637fbe..173b80e41df 100644 Binary files a/icons/mob/clothing/species/vox/mask.dmi and b/icons/mob/clothing/species/vox/mask.dmi differ diff --git a/icons/mob/clothing/species/vox/suit.dmi b/icons/mob/clothing/species/vox/suit.dmi index 441cbf306d0..76a40146137 100644 Binary files a/icons/mob/clothing/species/vox/suit.dmi and b/icons/mob/clothing/species/vox/suit.dmi differ diff --git a/icons/mob/clothing/species/vox/uniform.dmi b/icons/mob/clothing/species/vox/uniform.dmi index 463de38f524..911a291a18b 100644 Binary files a/icons/mob/clothing/species/vox/uniform.dmi and b/icons/mob/clothing/species/vox/uniform.dmi differ diff --git a/icons/mob/clothing/species/vulpkanin/head.dmi b/icons/mob/clothing/species/vulpkanin/head.dmi index 7273ff2892f..0296d04a8e4 100644 Binary files a/icons/mob/clothing/species/vulpkanin/head.dmi and b/icons/mob/clothing/species/vulpkanin/head.dmi differ diff --git a/icons/mob/clothing/species/vulpkanin/helmet.dmi b/icons/mob/clothing/species/vulpkanin/helmet.dmi index 23fd7e15162..14113ae663e 100644 Binary files a/icons/mob/clothing/species/vulpkanin/helmet.dmi and b/icons/mob/clothing/species/vulpkanin/helmet.dmi differ diff --git a/icons/mob/clothing/species/vulpkanin/mask.dmi b/icons/mob/clothing/species/vulpkanin/mask.dmi index 83c3999a622..802d3b337a5 100644 Binary files a/icons/mob/clothing/species/vulpkanin/mask.dmi and b/icons/mob/clothing/species/vulpkanin/mask.dmi differ diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi index d307193378e..539a5a9a6c8 100644 Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ diff --git a/icons/mob/clothing/ties.dmi b/icons/mob/clothing/ties.dmi index 671083841eb..62ac2879d78 100644 Binary files a/icons/mob/clothing/ties.dmi and b/icons/mob/clothing/ties.dmi differ diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi index 7861962369d..f748c37e23f 100644 Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ diff --git a/icons/mob/human_races/monkeys/r_stok.dmi b/icons/mob/human_races/monkeys/r_stok.dmi index 69c6c3538d6..d844e1d2439 100644 Binary files a/icons/mob/human_races/monkeys/r_stok.dmi and b/icons/mob/human_races/monkeys/r_stok.dmi differ diff --git a/icons/mob/human_races/monkeys/r_stok_old.dmi b/icons/mob/human_races/monkeys/r_stok_old.dmi new file mode 100644 index 00000000000..69c6c3538d6 Binary files /dev/null and b/icons/mob/human_races/monkeys/r_stok_old.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index f03dc3a3c93..969efe2a696 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index 6c31d017974..1fcce3b1128 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index b233633759c..882cc2a15d8 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index 8c24a10827d..e2b4eda57af 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 71186ba1370..73edd66b4c3 100755 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 481a0213806..a2e82d6bd2e 100755 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 438b8e20018..7017d61798b 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/candle.dmi b/icons/obj/candle.dmi index eac8464b282..cf79a083197 100644 Binary files a/icons/obj/candle.dmi and b/icons/obj/candle.dmi differ diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi index cf27889017c..4d790c73929 100644 Binary files a/icons/obj/chairs.dmi and b/icons/obj/chairs.dmi differ diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi index 686c80ddbed..5aa7095a37b 100644 Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 0564edd3a27..b2ee708721d 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 62e8ecf7ac1..4d8bd11d56e 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 3d7a16a75aa..1aed2bdf3c1 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 774e3bd2e6a..8682da10e4a 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/ties_overlay.dmi b/icons/obj/clothing/ties_overlay.dmi index 91cd0410475..67271752f82 100644 Binary files a/icons/obj/clothing/ties_overlay.dmi and b/icons/obj/clothing/ties_overlay.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 4a75fab1b09..6675b289799 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index a99b07743d7..284415e32b2 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 4673770391d..f6287575a15 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/doors/airlocks/abductor/overlays.dmi b/icons/obj/doors/airlocks/abductor/overlays.dmi index 6bc8aae620f..8456deec518 100644 Binary files a/icons/obj/doors/airlocks/abductor/overlays.dmi and b/icons/obj/doors/airlocks/abductor/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/centcom/overlays.dmi b/icons/obj/doors/airlocks/centcom/overlays.dmi index 7ec3486053f..28a8dca2fec 100644 Binary files a/icons/obj/doors/airlocks/centcom/overlays.dmi and b/icons/obj/doors/airlocks/centcom/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/clockwork/overlays.dmi b/icons/obj/doors/airlocks/clockwork/overlays.dmi index c78fa88e812..30baed8d11e 100644 Binary files a/icons/obj/doors/airlocks/clockwork/overlays.dmi and b/icons/obj/doors/airlocks/clockwork/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi b/icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi index 19920538d9d..3b30c6c8643 100644 Binary files a/icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi and b/icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/runed/hell-overlays.dmi b/icons/obj/doors/airlocks/cult/runed/hell-overlays.dmi index a1b9596b5b5..5fdf93bac2f 100644 Binary files a/icons/obj/doors/airlocks/cult/runed/hell-overlays.dmi and b/icons/obj/doors/airlocks/cult/runed/hell-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/runed/reaper-overlays.dmi b/icons/obj/doors/airlocks/cult/runed/reaper-overlays.dmi index 429e0c92697..ec6c33f775c 100644 Binary files a/icons/obj/doors/airlocks/cult/runed/reaper-overlays.dmi and b/icons/obj/doors/airlocks/cult/runed/reaper-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi b/icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi index 5fb77f2676c..9b2e14096ed 100644 Binary files a/icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi and b/icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/unruned/hell-overlays.dmi b/icons/obj/doors/airlocks/cult/unruned/hell-overlays.dmi index 2bbc8e386d5..7ca6f82658a 100644 Binary files a/icons/obj/doors/airlocks/cult/unruned/hell-overlays.dmi and b/icons/obj/doors/airlocks/cult/unruned/hell-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/cult/unruned/reaper-overlays.dmi b/icons/obj/doors/airlocks/cult/unruned/reaper-overlays.dmi index 241f0794f2e..7d2f8411744 100644 Binary files a/icons/obj/doors/airlocks/cult/unruned/reaper-overlays.dmi and b/icons/obj/doors/airlocks/cult/unruned/reaper-overlays.dmi differ diff --git a/icons/obj/doors/airlocks/external/overlays.dmi b/icons/obj/doors/airlocks/external/overlays.dmi index 1dde58ab5af..b2fc550e55c 100644 Binary files a/icons/obj/doors/airlocks/external/overlays.dmi and b/icons/obj/doors/airlocks/external/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/glass_large/overlays.dmi b/icons/obj/doors/airlocks/glass_large/overlays.dmi index dccaca00255..eec7e845951 100644 Binary files a/icons/obj/doors/airlocks/glass_large/overlays.dmi and b/icons/obj/doors/airlocks/glass_large/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/hatch/overlays.dmi b/icons/obj/doors/airlocks/hatch/overlays.dmi index affcbbf2ce4..d625042ff9a 100644 Binary files a/icons/obj/doors/airlocks/hatch/overlays.dmi and b/icons/obj/doors/airlocks/hatch/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/highsec/overlays.dmi b/icons/obj/doors/airlocks/highsec/overlays.dmi index 2a6868c34b9..c56285b96fe 100644 Binary files a/icons/obj/doors/airlocks/highsec/overlays.dmi and b/icons/obj/doors/airlocks/highsec/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/shuttle/overlays.dmi b/icons/obj/doors/airlocks/shuttle/overlays.dmi index b2bb2cfa04a..5372b7b4bb6 100644 Binary files a/icons/obj/doors/airlocks/shuttle/overlays.dmi and b/icons/obj/doors/airlocks/shuttle/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/station/overlays.dmi b/icons/obj/doors/airlocks/station/overlays.dmi index ec1a418dab1..8e337ef4eed 100644 Binary files a/icons/obj/doors/airlocks/station/overlays.dmi and b/icons/obj/doors/airlocks/station/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/station2/overlays.dmi b/icons/obj/doors/airlocks/station2/overlays.dmi index 4cb389cbf2d..b24033f8f05 100644 Binary files a/icons/obj/doors/airlocks/station2/overlays.dmi and b/icons/obj/doors/airlocks/station2/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/survival/survival_overlays.dmi b/icons/obj/doors/airlocks/survival/survival_overlays.dmi index f8e62144cd8..08c6df521d6 100644 Binary files a/icons/obj/doors/airlocks/survival/survival_overlays.dmi and b/icons/obj/doors/airlocks/survival/survival_overlays.dmi differ diff --git a/icons/obj/doors/airlocks/syndicate/overlays.dmi b/icons/obj/doors/airlocks/syndicate/overlays.dmi index 343a75f1363..197ce0458f0 100644 Binary files a/icons/obj/doors/airlocks/syndicate/overlays.dmi and b/icons/obj/doors/airlocks/syndicate/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/vault/overlays.dmi b/icons/obj/doors/airlocks/vault/overlays.dmi index f18346acf68..413e88239fa 100644 Binary files a/icons/obj/doors/airlocks/vault/overlays.dmi and b/icons/obj/doors/airlocks/vault/overlays.dmi differ diff --git a/icons/obj/doors/doorfire.dmi b/icons/obj/doors/doorfire.dmi index 94ec8b967fb..a20b20a1d90 100644 Binary files a/icons/obj/doors/doorfire.dmi and b/icons/obj/doors/doorfire.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 189df1f4852..f1c80e3c584 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/engines_and_power/power.dmi b/icons/obj/engines_and_power/power.dmi index 69ed1d29db8..4e22f28d467 100644 Binary files a/icons/obj/engines_and_power/power.dmi and b/icons/obj/engines_and_power/power.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 1917b2ce215..a3b3ada8e00 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/guncabinet.dmi b/icons/obj/guncabinet.dmi index 977a03e63b7..4ef6077b690 100644 Binary files a/icons/obj/guncabinet.dmi and b/icons/obj/guncabinet.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index 10809b14177..be50ea56c49 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/improvised.dmi b/icons/obj/improvised.dmi index 216112a97f4..79044095cb8 100644 Binary files a/icons/obj/improvised.dmi and b/icons/obj/improvised.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 41ac5232d52..ce029b72ac6 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi index c90fe002a7a..178610b7424 100644 Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 58bb9c7e12e..7a090bf49a4 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index 01274806dec..eaa9c366fc2 100644 Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ diff --git a/icons/obj/machines/computer.dmi b/icons/obj/machines/computer.dmi index 2ee9802b91b..79202db1365 100644 Binary files a/icons/obj/machines/computer.dmi and b/icons/obj/machines/computer.dmi differ diff --git a/icons/obj/machines/cryogenics.dmi b/icons/obj/machines/cryogenics.dmi index 74ecc17ffb0..010a42de8c9 100644 Binary files a/icons/obj/machines/cryogenics.dmi and b/icons/obj/machines/cryogenics.dmi differ diff --git a/icons/obj/machines/monitors.dmi b/icons/obj/machines/monitors.dmi index 21a0853678c..3b0a02531a9 100644 Binary files a/icons/obj/machines/monitors.dmi and b/icons/obj/machines/monitors.dmi differ diff --git a/icons/obj/machines/terminals.dmi b/icons/obj/machines/terminals.dmi index c47cd86e6d3..8e1e612bc93 100644 Binary files a/icons/obj/machines/terminals.dmi and b/icons/obj/machines/terminals.dmi differ diff --git a/icons/obj/machines/vending.dmi b/icons/obj/machines/vending.dmi index 34a31642bc3..c8458237862 100644 Binary files a/icons/obj/machines/vending.dmi and b/icons/obj/machines/vending.dmi differ diff --git a/icons/obj/mecha/lockermech.dmi b/icons/obj/mecha/lockermech.dmi index ac7688d5ce4..ea99827ee41 100644 Binary files a/icons/obj/mecha/lockermech.dmi and b/icons/obj/mecha/lockermech.dmi differ diff --git a/icons/obj/mecha/mecha.dmi b/icons/obj/mecha/mecha.dmi index 582b559b043..1eff9ee63d0 100644 Binary files a/icons/obj/mecha/mecha.dmi and b/icons/obj/mecha/mecha.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 4b6e186348d..ce6fb34a070 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/paintkit.dmi b/icons/obj/paintkit.dmi index 8f7e2048e2f..3b24583010d 100644 Binary files a/icons/obj/paintkit.dmi and b/icons/obj/paintkit.dmi differ diff --git a/icons/obj/pipes_and_stuff/not_atmos/disposal.dmi b/icons/obj/pipes_and_stuff/not_atmos/disposal.dmi index 18d97345686..38906f334fa 100644 Binary files a/icons/obj/pipes_and_stuff/not_atmos/disposal.dmi and b/icons/obj/pipes_and_stuff/not_atmos/disposal.dmi differ diff --git a/icons/obj/pipes_and_stuff/not_atmos/transit_tube.dmi b/icons/obj/pipes_and_stuff/not_atmos/transit_tube.dmi index bdb1608a313..aca65d502fd 100644 Binary files a/icons/obj/pipes_and_stuff/not_atmos/transit_tube.dmi and b/icons/obj/pipes_and_stuff/not_atmos/transit_tube.dmi differ diff --git a/icons/obj/pipes_and_stuff/not_atmos/transit_tube_pod.dmi b/icons/obj/pipes_and_stuff/not_atmos/transit_tube_pod.dmi index 86070b8ce59..a0bdb36ec22 100644 Binary files a/icons/obj/pipes_and_stuff/not_atmos/transit_tube_pod.dmi and b/icons/obj/pipes_and_stuff/not_atmos/transit_tube_pod.dmi differ diff --git a/icons/obj/pipes_and_stuff/not_atmos/transit_tube_station.dmi b/icons/obj/pipes_and_stuff/not_atmos/transit_tube_station.dmi index 6f59f5e0084..348f6d29561 100644 Binary files a/icons/obj/pipes_and_stuff/not_atmos/transit_tube_station.dmi and b/icons/obj/pipes_and_stuff/not_atmos/transit_tube_station.dmi differ diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi index 728e109587b..5e0abf22d74 100644 Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 4158ae4087b..8904316e1e4 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/icons/obj/status_display.dmi b/icons/obj/status_display.dmi index 81ccc415de1..69919eeccd5 100644 Binary files a/icons/obj/status_display.dmi and b/icons/obj/status_display.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index f21a36b69c0..32136d7295c 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/telescience.dmi b/icons/obj/telescience.dmi index bfbd41bc081..81471202dc2 100644 Binary files a/icons/obj/telescience.dmi and b/icons/obj/telescience.dmi differ diff --git a/icons/obj/walllocker.dmi b/icons/obj/walllocker.dmi index 8495e00ff83..1b133f04ad3 100644 Binary files a/icons/obj/walllocker.dmi and b/icons/obj/walllocker.dmi differ diff --git a/icons/obj/weapons/ammo.dmi b/icons/obj/weapons/ammo.dmi index f544ae394ce..b25e7166813 100644 Binary files a/icons/obj/weapons/ammo.dmi and b/icons/obj/weapons/ammo.dmi differ diff --git a/icons/obj/weapons/energy.dmi b/icons/obj/weapons/energy.dmi index 10b9725b96f..e198fb60ac3 100644 Binary files a/icons/obj/weapons/energy.dmi and b/icons/obj/weapons/energy.dmi differ diff --git a/icons/obj/weapons/projectile.dmi b/icons/obj/weapons/projectile.dmi index 72887c007d2..7c3256f3f5a 100644 Binary files a/icons/obj/weapons/projectile.dmi and b/icons/obj/weapons/projectile.dmi differ diff --git a/icons/testing/greyscale_error.dmi b/icons/testing/greyscale_error.dmi new file mode 100644 index 00000000000..6c781a70ad1 Binary files /dev/null and b/icons/testing/greyscale_error.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 2a99ddbb4c2..421506da67e 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 4d4e6e833ca..dde8b2cf92c 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -191,44 +191,42 @@ window "outputwindow" elem "outputwindow" type = MAIN pos = 0,0 - size = 640x500 + size = 637x480 anchor1 = 0,0 anchor2 = 100,100 is-pane = true elem "input" type = INPUT - pos = 0,480 - size = 539x18 + pos = 3,456 + size = 467x20 anchor1 = 0,100 anchor2 = 100,100 background-color = #d3b5b5 is-default = true - border = sunken + border = line saved-params = "command" elem "saybutton" type = BUTTON - pos = 541,480 - size = 48x16 + pos = 474,456 + size = 80x20 anchor1 = 100,100 anchor2 = -1,-1 - background-color = #d4d4d4 text = "Say" command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" macrobutton.is-checked=false:input.command=\"\"saybutton.is-checked=true?mebutton.is-checked=false\"" button-type = pushbox elem "mebutton" type = BUTTON - pos = 590,480 - size = 48x16 + pos = 553,456 + size = 80x20 anchor1 = 100,100 anchor2 = -1,-1 - background-color = #d4d4d4 text = "Me" command = ".winset \"mebutton.is-checked=true ? input.command=\"!me \\\"\" : input.command=\"\"mebutton.is-checked=true ? saybutton.is-checked=false\"\"mebutton.is-checked=true ? oocbutton.is-checked=false\"" button-type = pushbox elem "browseroutput" type = BROWSER pos = 0,0 - size = 638x479 + size = 633x452 anchor1 = 0,0 anchor2 = 100,100 background-color = #ffffff diff --git a/paradise.dme b/paradise.dme index d63f58a97c5..608461bd0e6 100644 --- a/paradise.dme +++ b/paradise.dme @@ -44,6 +44,7 @@ #include "code\__DEFINES\crafting.dm" #include "code\__DEFINES\criminal_status.dm" #include "code\__DEFINES\cult.dm" +#include "code\__DEFINES\directions.dm" #include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\dmjit.dm" #include "code\__DEFINES\dna.dm" @@ -273,6 +274,7 @@ #include "code\controllers\subsystem\debugview.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\fires.dm" +#include "code\controllers\subsystem\game_events.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\ghost_spawns.dm" #include "code\controllers\subsystem\http.dm" @@ -326,6 +328,7 @@ #include "code\controllers\subsystem\processing\obj.dm" #include "code\controllers\subsystem\processing\processing.dm" #include "code\controllers\subsystem\processing\projectiles.dm" +#include "code\controllers\subsystem\processing\transittube.dm" #include "code\controllers\subsystem\tickets\mentor_tickets.dm" #include "code\controllers\subsystem\tickets\tickets.dm" #include "code\datums\action.dm" @@ -393,6 +396,7 @@ #include "code\datums\components\caltrop.dm" #include "code\datums\components\contsruction_regenerate.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\defibrillator.dm" #include "code\datums\components\ducttape.dm" #include "code\datums\components\edit_complainer.dm" #include "code\datums\components\emissive_blocker.dm" @@ -588,6 +592,10 @@ #include "code\datums\spells\alien_spells\regurgitate.dm" #include "code\datums\spells\alien_spells\transfer_plasma.dm" #include "code\datums\spells\alien_spells\whisper.dm" +#include "code\datums\spells\lavaland_spells\conjure_skulls.dm" +#include "code\datums\spells\lavaland_spells\goliath_dash.dm" +#include "code\datums\spells\lavaland_spells\goliath_tentacles.dm" +#include "code\datums\spells\lavaland_spells\watchers_look.dm" #include "code\datums\status_effects\buffs.dm" #include "code\datums\status_effects\debuffs.dm" #include "code\datums\status_effects\gas.dm" @@ -1754,7 +1762,6 @@ #include "code\modules\clothing\suits\labcoat.dm" #include "code\modules\clothing\suits\miscellaneous.dm" #include "code\modules\clothing\suits\storage.dm" -#include "code\modules\clothing\suits\toggles.dm" #include "code\modules\clothing\suits\utility.dm" #include "code\modules\clothing\suits\wiz_robe.dm" #include "code\modules\clothing\under\color.dm" diff --git a/sound/weapons/gunshots/improvrev_shot.ogg b/sound/weapons/gunshots/1rev257.ogg similarity index 100% rename from sound/weapons/gunshots/improvrev_shot.ogg rename to sound/weapons/gunshots/1rev257.ogg diff --git a/sound/weapons/gunshots/1rev257S.ogg b/sound/weapons/gunshots/1rev257S.ogg new file mode 100644 index 00000000000..6ef45fc1d2e Binary files /dev/null and b/sound/weapons/gunshots/1rev257S.ogg differ diff --git a/sound/weapons/jammed.ogg b/sound/weapons/jammed.ogg new file mode 100644 index 00000000000..69324f2bb5b Binary files /dev/null and b/sound/weapons/jammed.ogg differ diff --git a/tgui/packages/tgui/interfaces/CargoConsole.js b/tgui/packages/tgui/interfaces/CargoConsole.js index 8e95b3a0722..bd7a2e5fbd9 100644 --- a/tgui/packages/tgui/interfaces/CargoConsole.js +++ b/tgui/packages/tgui/interfaces/CargoConsole.js @@ -67,6 +67,7 @@ const StatusPane = (_properties, context) => { const { is_public, points, + credits, timeleft, moving, at_station, @@ -98,6 +99,9 @@ const StatusPane = (_properties, context) => { {points} + + {credits} + {statusText} @@ -181,7 +185,7 @@ const CataloguePane = (_properties, context) => { {cratesToShow.map(c => ( - {c.name} ({c.cost} Points) + {c.name} {c.cost ? c.cost+" Points" : ""} {c.creditsCost ? c.creditsCost+" Credits" : ""}