diff --git a/README.md b/README.md index 2a1ffe65ec..0ecf4c5b01 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,28 @@ ## Citadel Station 13 Based and maintained from /tg/station. -[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/pretty-risque.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](http://forthebadge.com) +[![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) +[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") -[![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) - -[![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) - -[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") +[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/pretty-risque.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](http://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) **Upstream Information** -**Website:** https://tgstation13.org -**Code:** https://github.com/tgstation/tgstation -**Wiki** https://tgstation13.org/wiki/Main_Page -**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus). - +* **Website:** +* **Code:** +* **Wiki:** +* **Codedocs:** +* **/tg/station Discord:** +* **Coderbus Discord:** +* ~~**IRC:** ~~ (dead) + **Citadel Station Information** -**Website:** http://citadel-station.net -**Forums:** http://citadel-station.net/forum -**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8 -**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13 -**Discord:** [Here](https://discord.gg/E6SQuhz) +* **Website:** +* **Code:** +* **Wiki:** +* **Forums:** +* **Ban Appeals:** +* **Discord:** ## DOWNLOADING @@ -162,13 +164,12 @@ All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 a See LICENSE and GPLv3.txt for more details. +The TGS3 API is licensed as a subproject under the MIT license. + +See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license. + tgui clientside is licensed as a subproject under the MIT license. Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1 tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). -The TGS3 API is licensed as a subproject under the MIT license. -See tgui/LICENSE.md for the MIT license. -See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. -See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license. - -All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. +All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](https://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm new file mode 100644 index 0000000000..f590af752b --- /dev/null +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm @@ -0,0 +1,1721 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface) +"ac" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/unpowered/elephant_graveyard) +"ad" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/structure/closet/crate/grave/lead_researcher, +/obj/effect/decal/cleanable/blood/gibs/old, +/obj/effect/mob_spawn/human/skeleton, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ae" = ( +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"af" = ( +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ag" = ( +/obj/effect/decal/cleanable/vomit, +/obj/item/shovel, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ah" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ai" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aj" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/item/paper/fluff/ruins/elephant_graveyard/final_message, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ak" = ( +/turf/open/floor/plating/asteroid/basalt/wasteland{ + icon_state = "wasteland_dug" + }, +/area/ruin/unpowered/elephant_graveyard) +"al" = ( +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"am" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"an" = ( +/obj/item/reagent_containers/food/snacks/deadmouse, +/obj/item/assembly/mousetrap, +/turf/open/floor/plating/asteroid/basalt/wasteland{ + icon_state = "wasteland_dug" + }, +/area/ruin/unpowered/elephant_graveyard) +"ao" = ( +/obj/structure/statue/bone/skull/half, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ap" = ( +/obj/structure/statue/bone/skull/half{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aq" = ( +/obj/item/reagent_containers/glass/bottle/frostoil{ + desc = "A small bottle. Contains cold sauce. There's a label on here: APPLY ON SEVERE BURNS."; + volume = 10 + }, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ar" = ( +/obj/structure/flora/rock, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"as" = ( +/obj/structure/flora/rock, +/obj/item/pickaxe{ + layer = 2.5; + pixel_x = -8; + pixel_y = 5 + }, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"at" = ( +/turf/closed/mineral/strong/wasteland, +/area/lavaland/surface) +"au" = ( +/obj/structure/table, +/obj/item/t_scanner/adv_mining_scanner/lesser, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"av" = ( +/obj/structure/barricade/wooden/crude, +/obj/structure/barricade/wooden, +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aw" = ( +/obj/structure/table, +/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/rnd_notes, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ax" = ( +/obj/structure/statue/bone/rib{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ay" = ( +/obj/structure/statue/bone/rib, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"az" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/pen, +/obj/item/pen, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aA" = ( +/turf/closed/wall, +/area/ruin/unpowered/elephant_graveyard) +"aB" = ( +/obj/item/chair, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aC" = ( +/obj/effect/decal/remains/human, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aD" = ( +/obj/structure/table, +/obj/item/reagent_containers/glass/bottle/plasma{ + volume = 25 + }, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aE" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aF" = ( +/obj/structure/table, +/obj/machinery/power/floodlight, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aG" = ( +/obj/structure/table, +/obj/effect/spawner/lootdrop/glowstick, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aH" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/powered/graveyard_shuttle) +"aI" = ( +/obj/effect/spawner/structure/window/shuttle, +/obj/structure/grille, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/graveyard_shuttle) +"aJ" = ( +/obj/structure/table, +/obj/item/clipboard, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aK" = ( +/obj/item/cigbutt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aL" = ( +/obj/structure/table, +/obj/item/paper_bin, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aM" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/black, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aN" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/ruin/powered/graveyard_shuttle) +"aO" = ( +/obj/effect/decal/cleanable/glass, +/obj/machinery/computer, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"aP" = ( +/obj/structure/bed, +/obj/item/flashlight/lantern, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aQ" = ( +/obj/machinery/power/floodlight, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aR" = ( +/obj/structure/table, +/obj/item/taperecorder, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aS" = ( +/obj/structure/table, +/obj/item/tape/random, +/obj/item/tape/random, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aT" = ( +/obj/structure/closet/crate/bin, +/obj/item/trash/candle, +/obj/item/trash/can, +/obj/item/trash/can, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/cigbutt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aU" = ( +/obj/structure/bed, +/obj/item/bedsheet/brown, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aV" = ( +/obj/structure/bed, +/obj/item/bedsheet/brown, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aW" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/item/clothing/mask/gas/explorer/folded, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"aX" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"aY" = ( +/obj/structure/sign/warning/nosmoking/circle, +/turf/closed/wall, +/area/ruin/unpowered/elephant_graveyard) +"aZ" = ( +/obj/item/organ/brain, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ba" = ( +/obj/structure/headpike/bone, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bb" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bc" = ( +/obj/structure/sign/poster/ripped, +/turf/closed/wall, +/area/ruin/unpowered/elephant_graveyard) +"bd" = ( +/obj/item/organ/heart, +/obj/item/organ/eyes, +/obj/item/organ/ears, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"be" = ( +/obj/item/organ/lungs, +/obj/item/organ/liver, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bf" = ( +/turf/closed/mineral/strong/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bg" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered/graveyard_shuttle) +"bh" = ( +/obj/effect/decal/cleanable/oil, +/obj/structure/chair/office/light, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bi" = ( +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/circuit/off, +/area/ruin/powered/graveyard_shuttle) +"bj" = ( +/obj/structure/barricade/wooden, +/obj/structure/mineral_door/wood, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bk" = ( +/obj/item/kitchen/knife/combat/bone, +/obj/item/organ/tongue, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bl" = ( +/obj/effect/decal/cleanable/shreds, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bm" = ( +/obj/structure/closet/wardrobe/curator, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bn" = ( +/obj/structure/sink/oil_well, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bo" = ( +/obj/item/stack/medical/gauze/improvised, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bp" = ( +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bq" = ( +/obj/machinery/iv_drip, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"br" = ( +/obj/structure/sign/warning/nosmoking/circle, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered/graveyard_shuttle) +"bs" = ( +/obj/structure/fence/door, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bt" = ( +/obj/structure/table, +/turf/closed/mineral/strong/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bu" = ( +/obj/structure/bed, +/obj/item/trash/pistachios, +/obj/item/trash/chips, +/obj/item/bedsheet/brown, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bv" = ( +/obj/effect/decal/remains/human, +/obj/item/clothing/under/misc/overalls, +/obj/item/clothing/mask/bandana/green, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bw" = ( +/obj/structure/rack, +/obj/item/shovel, +/obj/item/wrench, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bx" = ( +/obj/item/reagent_containers/food/snacks/deadmouse, +/obj/item/assembly/mousetrap, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"by" = ( +/obj/structure/closet/emcloset, +/obj/item/light/bulb, +/obj/effect/turf_decal/box/white, +/turf/open/floor/mineral/titanium/purple, +/area/ruin/powered/graveyard_shuttle) +"bz" = ( +/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/mutiny, +/obj/item/cigbutt, +/obj/item/cigbutt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bA" = ( +/obj/machinery/suit_storage_unit/mining/eva, +/obj/effect/turf_decal/box/white, +/turf/open/floor/mineral/titanium/purple, +/area/ruin/powered/graveyard_shuttle) +"bB" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bC" = ( +/obj/structure/barricade/sandbags, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bD" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/elephant_graveyard) +"bE" = ( +/obj/structure/shuttle/engine/heater, +/obj/structure/window{ + dir = 1 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/mineral/titanium/purple, +/area/ruin/powered/graveyard_shuttle) +"bF" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/elephant_graveyard) +"bG" = ( +/obj/effect/decal/remains/human, +/obj/item/tank/internals/emergency_oxygen/empty, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bH" = ( +/obj/item/paper/fluff/ruins/elephant_graveyard, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface) +"bI" = ( +/obj/structure/shuttle/engine/propulsion, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/graveyard_shuttle) +"bJ" = ( +/obj/structure/sign/warning/xeno_mining, +/turf/closed/wall, +/area/ruin/unpowered/elephant_graveyard) +"bK" = ( +/obj/structure/sign/warning/explosives, +/turf/closed/wall, +/area/ruin/unpowered/elephant_graveyard) +"bL" = ( +/obj/effect/decal/cleanable/blood/gibs/old, +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bM" = ( +/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker, +/obj/structure/closet/crate/grave, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bN" = ( +/obj/structure/sign/warning/securearea, +/obj/structure/sign/warning/securearea, +/turf/closed/mineral/strong/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bO" = ( +/obj/item/paper/fluff/ruins/elephant_graveyard, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bP" = ( +/obj/structure/barricade/wooden/crude, +/obj/item/paper/fluff/ruins/elephant_graveyard, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/elephant_graveyard) +"bQ" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/effect/decal/cleanable/cobweb, +/obj/item/paper/fluff/ruins/elephant_graveyard/hypothesis, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bR" = ( +/obj/effect/decal/cleanable/generic, +/obj/item/cigbutt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bS" = ( +/obj/effect/decal/cleanable/oil/slippery, +/obj/machinery/rnd/destructive_analyzer, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bT" = ( +/obj/structure/barricade/wooden, +/obj/item/paper/fluff/ruins/elephant_graveyard, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bU" = ( +/obj/item/light/bulb/broken, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bV" = ( +/obj/effect/decal/cleanable/dirt, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/unpowered/elephant_graveyard) +"bW" = ( +/obj/effect/decal/cleanable/glass, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/door/airlock/shuttle{ + name = "archaeology shuttle airlock" + }, +/turf/open/floor/mineral/titanium/purple, +/area/ruin/powered/graveyard_shuttle) +"bX" = ( +/obj/effect/decal/remains/human, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/clothing/head/fedora/curator, +/obj/item/clothing/suit/curator, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"bY" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/cigbutt, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"bZ" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface) +"ca" = ( +/obj/structure/table, +/obj/item/storage/firstaid/o2, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cb" = ( +/obj/machinery/power/port_gen/pacman, +/obj/effect/mapping_helpers/network_builder/power_cable, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cc" = ( +/obj/effect/decal/remains/human, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/shreds, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cd" = ( +/obj/item/trash/can, +/obj/structure/bedsheetbin/empty, +/obj/structure/table, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ce" = ( +/obj/structure/stone_tile/slab/cracked, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cf" = ( +/obj/structure/bed, +/obj/item/wirecutters, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cg" = ( +/obj/structure/stone_tile/center/cracked, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ch" = ( +/obj/effect/decal/remains/human, +/obj/item/restraints/handcuffs/cable/zipties/used, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ci" = ( +/obj/structure/stone_tile/surrounding_tile, +/turf/open/floor/plating/asteroid/basalt/wasteland{ + icon_state = "wasteland_dug" + }, +/area/ruin/unpowered/elephant_graveyard) +"cj" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ck" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cl" = ( +/obj/structure/closet/crate/grave, +/obj/effect/mob_spawn/human/skeleton, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cm" = ( +/obj/structure/table/optable, +/obj/item/storage/backpack/explorer, +/obj/item/reagent_containers/food/drinks/soda_cans/cola, +/obj/item/restraints/handcuffs/cable/zipties/used, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"cn" = ( +/obj/structure/stone_tile/cracked, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"co" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/structure/stone_tile/cracked, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cq" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cr" = ( +/obj/structure/bonfire/prelit, +/obj/effect/decal/cleanable/ash, +/obj/item/organ/tail/lizard, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/stone_tile/slab/cracked, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cs" = ( +/obj/structure/ore_box, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"ct" = ( +/obj/structure/stone_tile, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cu" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cv" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/titanium/white, +/area/ruin/powered/graveyard_shuttle) +"cw" = ( +/obj/structure/closet/crate/grave, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mob_spawn/human/skeleton, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) +"cx" = ( +/obj/item/light/bulb/broken, +/obj/effect/turf_decal/caution/stand_clear/white, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/titanium/purple, +/area/ruin/powered/graveyard_shuttle) +"cz" = ( +/obj/structure/stone_tile, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/asteroid/basalt/wasteland, +/area/ruin/unpowered/elephant_graveyard) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +at +ab +ab +ab +ac +ac +ac +ac +bf +ac +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +bf +bf +bf +bf +bf +ac +ac +ac +ac +bf +bf +bf +ac +ac +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +ab +ab +bf +bf +aT +bR +bf +bf +bf +ac +bf +bf +bf +bf +bf +bf +bf +ac +ac +ab +ab +aa +aa +aa +aa +aa +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +bf +bf +bf +bz +aK +bY +ae +bf +bf +bf +cs +aE +bJ +bf +bf +bf +ac +ac +ac +ab +ab +ab +aa +aa +aa +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +aa +ab +ab +bf +bf +bf +bf +aA +bc +aA +aY +ae +bv +ae +cl +ae +ae +aC +bs +bO +ae +ae +ac +ac +ac +ac +ab +ab +ab +aa +aa +aa +"} +(7,1,1) = {" +aa +aa +aa +aa +ab +bf +bf +bf +aq +al +al +al +aQ +ae +ae +ak +ae +ae +ae +ae +bK +bf +bf +bf +ae +ac +ac +ac +ac +ac +ac +ab +ab +aa +aa +"} +(8,1,1) = {" +aa +aa +ab +ab +ab +bf +bf +al +al +ar +ae +ae +ae +ar +aZ +ae +ba +ae +ba +ae +ae +ae +ae +bf +ae +ac +ac +ac +ac +ac +ac +ac +ab +ab +aa +"} +(9,1,1) = {" +aa +ab +ab +bf +bf +bf +al +al +ak +ae +aE +ae +ae +ae +ba +ae +af +ae +ae +ae +ba +ae +ak +bf +ae +ae +ac +ac +ac +ac +ac +ac +ac +ac +aa +"} +(10,1,1) = {" +ab +ab +bf +bf +bf +al +am +ae +ae +ae +ae +cl +ae +ae +ae +co +bd +bk +ae +ae +ae +ae +aE +bf +bf +ae +ae +ac +ac +ac +ac +bG +bM +ac +ac +"} +(11,1,1) = {" +at +bf +bf +bf +bf +al +ae +ae +ao +ae +ax +ax +ax +ax +ae +ae +be +cr +ae +cz +ae +ae +bn +cw +bf +bf +bB +ac +ac +ac +ac +bL +ae +ae +ac +"} +(12,1,1) = {" +at +bf +bf +bf +bf +al +cl +ae +ae +ae +ae +ci +cj +ce +ae +cj +ae +cq +ae +ae +cu +ae +ae +ae +bf +bf +bC +ac +ac +ac +ac +ac +ac +bD +ac +"} +(13,1,1) = {" +bf +ad +ae +bf +cl +al +ae +ae +ae +ae +cg +ae +ak +ak +cn +ae +cq +ae +ct +ar +ae +cl +ae +ae +bf +bf +ae +ac +ac +ac +ac +ac +ac +ae +ac +"} +(14,1,1) = {" +bf +aj +ae +bf +ae +al +aE +ae +ap +ae +ay +ay +ay +ay +ae +ae +ak +ae +ae +bn +ae +ae +aE +aQ +bf +cl +bB +ae +ac +ac +ac +ac +ac +ae +ac +"} +(15,1,1) = {" +bf +ai +ag +bf +an +al +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +cw +ae +ae +ae +ae +ae +al +bf +ac +ae +ae +bB +ac +ac +ac +ac +bD +ac +"} +(16,1,1) = {" +bf +ai +bf +bf +bf +al +al +al +ae +ae +aE +ae +ar +ae +ba +ae +ae +ae +ae +ae +ba +ae +ae +al +bf +ac +ac +ae +ae +bB +ac +ac +ac +bB +bP +"} +(17,1,1) = {" +bf +ae +af +bf +bf +aE +bf +al +as +au +az +aG +aM +aR +ae +ae +ba +ae +ba +ae +ae +aE +cl +al +bf +bf +ac +ac +ae +bD +ac +ac +ac +bF +bT +"} +(18,1,1) = {" +at +bf +ah +bf +bf +af +bf +ae +ae +aw +aB +ae +ae +aS +ae +ae +aE +ae +ae +ae +ae +ae +ae +al +cb +bf +ac +ac +ac +ae +bB +bB +bF +bB +bP +"} +(19,1,1) = {" +ab +bf +af +av +af +ae +bf +ae +bt +aD +ch +ae +ae +ca +ae +al +al +al +al +al +al +al +al +bx +bf +bf +ac +ac +ac +ac +bF +bB +bV +ac +ac +"} +(20,1,1) = {" +aa +at +bf +bf +bf +bf +bf +bj +bf +aF +aJ +aL +al +al +al +bw +bf +ac +bm +ae +bn +bf +bf +bf +bf +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +"} +(21,1,1) = {" +aa +aa +ab +ac +ac +bf +aU +aE +bf +bf +bf +bf +ck +aX +ae +bf +bf +bf +bf +bf +bf +bf +bf +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +"} +(22,1,1) = {" +aa +aa +ab +ab +ac +bf +aU +ae +bl +cd +bf +bf +bf +bN +ae +bf +bf +bf +bf +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +bZ +bZ +"} +(23,1,1) = {" +aa +aa +aa +ab +ab +bf +aV +bl +aE +bu +bf +bf +bf +bf +bb +bf +bf +bf +bf +ab +ab +ab +ab +ab +ab +ab +ab +bZ +bZ +bZ +bH +bZ +bZ +bZ +ab +"} +(24,1,1) = {" +aa +aa +aa +aa +ab +at +aP +bo +cc +cf +bf +aH +aH +bg +bW +bg +aH +aH +aH +bH +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +ab +ab +ab +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +at +bf +bf +bf +bf +aH +aN +bQ +bh +cv +bU +by +aH +aH +bI +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +bZ +ab +ab +ab +ab +ab +ab +"} +(26,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +aI +aO +bX +bi +bp +bi +cx +bE +aH +bI +bZ +bZ +bZ +bZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +"} +(27,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +aH +aN +aW +cm +bq +bS +bA +aH +aH +bI +bZ +bZ +bZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +aH +aH +aH +br +aH +aH +aH +aH +bZ +bZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +"} diff --git a/_maps/RandomRuins/SpaceRuins/spacediner.dmm b/_maps/RandomRuins/SpaceRuins/spacediner.dmm new file mode 100644 index 0000000000..21670da9e4 --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/spacediner.dmm @@ -0,0 +1,2918 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"ac" = ( +/obj/machinery/door/airlock/external/glass{ + name = "Shuttle Dock" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ad" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ae" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"af" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"ag" = ( +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"ah" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/external/glass{ + name = "Shuttle Dock" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ai" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 1 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aj" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ak" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"al" = ( +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"am" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/power/solar, +/turf/open/floor/plasteel/solarpanel, +/area/ruin/space/diner/solars) +"an" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"ao" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ap" = ( +/obj/structure/sign/poster/official/pda_ad600{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aq" = ( +/obj/structure/sign/poster/official/nanotrasen_logo{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ar" = ( +/obj/structure/sign/poster/official/cohiba_robusto_ad{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"as" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"at" = ( +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/power/solar, +/turf/open/floor/plasteel/solarpanel, +/area/ruin/space/diner/solars) +"au" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"av" = ( +/turf/open/floor/plating/airless, +/area/ruin/space/diner) +"aw" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/ruin/space/diner) +"ax" = ( +/turf/closed/wall/r_wall, +/area/ruin/space/diner) +"ay" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/airalarm/all_access{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"az" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/coffee, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aA" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/ruin/space/diner/interior) +"aB" = ( +/obj/structure/reagent_dispensers/beerkeg, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aC" = ( +/obj/structure/table/reinforced, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aD" = ( +/obj/structure/kitchenspike, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aE" = ( +/obj/structure/closet/crate, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aF" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/closet/crate/freezer, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aG" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aH" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aI" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aJ" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aK" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aL" = ( +/turf/open/floor/engine/airless, +/area/ruin/space/diner) +"aM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"aN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/cola/red, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aP" = ( +/obj/machinery/atmospherics/components/unary/tank/air{ + dir = 1 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aQ" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 10 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aR" = ( +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/ruin/space/diner/interior) +"aS" = ( +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aT" = ( +/obj/structure/cable, +/obj/machinery/power/solar, +/turf/open/floor/plasteel/solarpanel, +/area/ruin/space/diner/solars) +"aU" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/template_noop, +/area/ruin/space/diner/solars) +"aV" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Fore Docking Area" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aW" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Fore Docking Area" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"aX" = ( +/obj/machinery/vending/boozeomat/pubby_maint, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"aY" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"aZ" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"ba" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bb" = ( +/obj/machinery/gibber, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bc" = ( +/turf/closed/wall/r_wall/rust, +/area/ruin/space/diner/interior) +"bd" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Fore Pod Bay" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor/closed, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"be" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel/stairs/old, +/area/ruin/space/diner/interior) +"bf" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"bg" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"bh" = ( +/obj/machinery/light/small/broken, +/turf/open/floor/engine/airless, +/area/ruin/space/diner) +"bi" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/reagent_dispensers/fueltank, +/obj/machinery/button{ + pixel_y = -24 + }, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"bj" = ( +/obj/effect/spawner/structure/window/hollow/reinforced, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bk" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bl" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/chem_dispenser/drinks/beer, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bm" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/chem_dispenser/drinks, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/dinnerware, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bo" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = null; + req_access_txt = "200" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bp" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/kitchen/rollingpin, +/obj/item/reagent_containers/food/condiment/rice{ + pixel_x = -8; + pixel_y = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/processor, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"br" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bs" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/grill, +/obj/machinery/light/small/broken{ + icon_state = "bulb-broken"; + dir = 1 + }, +/obj/machinery/power/apc/highcap/five_k{ + name = "Space Diner APC"; + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bu" = ( +/obj/machinery/deepfryer, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bv" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bw" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"bx" = ( +/obj/structure/toilet/secret/low_loot{ + icon_state = "toilet00"; + dir = 4 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/window/eastright, +/turf/open/floor/mineral/titanium/white, +/area/ruin/space/diner/interior) +"by" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/poster/contraband/rebels_unite{ + pixel_y = 32 + }, +/obj/item/reagent_containers/food/urinalcake, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bz" = ( +/obj/structure/urinal{ + pixel_y = 28 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bA" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/closet/crate/bin, +/obj/machinery/airalarm/all_access{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bB" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 8 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bC" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bD" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 4 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bG" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bI" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/grunge/abandoned{ + name = "Staff Entrance" + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/manifold/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 10 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bM" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/secure_closet/freezer/meat{ + req_access_txt = "200" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bO" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"bP" = ( +/obj/structure/toilet/secret/low_loot{ + icon_state = "toilet00"; + dir = 4 + }, +/obj/structure/window/reinforced/spawner/north, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/window/eastright, +/turf/open/floor/mineral/titanium/white, +/area/ruin/space/diner/interior) +"bQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 6 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/sign/poster/official/cleanliness{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bT" = ( +/obj/structure/rack, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"bU" = ( +/obj/structure/table, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"bV" = ( +/obj/structure/table, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"bW" = ( +/obj/structure/table, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/item/storage/toolbox/electrical, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"bX" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 1 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"bY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"bZ" = ( +/obj/machinery/icecream_vat, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/airalarm/all_access{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ca" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + icon_state = "manifold-2"; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cb" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cc" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 10 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cd" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave{ + pixel_y = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ce" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/mirror{ + icon_state = "mirror_broke"; + pixel_x = 24 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cg" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"ch" = ( +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"ci" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cj" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"ck" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cl" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"cm" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/structure/table/wood/bar, +/obj/effect/decal/cleanable/dirt, +/obj/item/reagent_containers/food/snacks/stewedsoymeat, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cn" = ( +/obj/structure/table/wood/bar, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"co" = ( +/obj/structure/table/wood/bar, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/item/trash/plate, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cp" = ( +/obj/structure/table/wood/bar, +/obj/effect/decal/cleanable/dirt, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cq" = ( +/obj/structure/table/wood/bar, +/obj/effect/decal/cleanable/dirt, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = 4; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cr" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/structure/frame, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cs" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table/wood/bar, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ct" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/table/wood/bar, +/obj/structure/window/reinforced/spawner, +/obj/structure/window/reinforced/spawner/west, +/obj/machinery/dish_drive, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cu" = ( +/obj/structure/sign/barsign, +/turf/closed/wall/r_wall, +/area/ruin/space/diner/interior) +"cv" = ( +/obj/machinery/door/airlock/grunge/abandoned{ + name = "Restrooms" + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cw" = ( +/obj/machinery/airalarm/all_access{ + dir = 1; + icon_state = "alarm0"; + pixel_x = 0; + pixel_y = -24 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/airalarm/all_access{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cy" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cz" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/obj/item/beacon, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cA" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cB" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Teleporter Room" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"cC" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cD" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cE" = ( +/obj/structure/chair/stool/bar, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cF" = ( +/obj/structure/chair/stool/bar, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cG" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cH" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cI" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/computer/slot_machine, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cJ" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cK" = ( +/obj/structure/table/wood, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cL" = ( +/obj/structure/table/wood, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/trash/plate, +/obj/item/kitchen/fork, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cM" = ( +/obj/machinery/light/broken{ + icon_state = "tube-broken"; + dir = 1 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/chair, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"cN" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cO" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/sign/departments/restroom{ + pixel_y = 32 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cP" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/computer/arcade{ + icon_state = "arcade"; + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cQ" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"cS" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 1 + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"cT" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/bin, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/poster/official/report_crimes{ + pixel_y = 32 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cW" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Diner" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cX" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cY" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"cZ" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 5 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"da" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"db" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/general/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dc" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dd" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + icon_state = "pipe11-2"; + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"de" = ( +/obj/machinery/door/airlock/external{ + name = "Mining Shuttle Dock" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"df" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dg" = ( +/obj/machinery/door/airlock/external/glass, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dh" = ( +/obj/machinery/teleport/hub, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"di" = ( +/obj/machinery/light/small/broken, +/obj/machinery/teleport/station, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"dj" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/computer/teleporter{ + icon_state = "computer"; + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/plasteel/dark, +/area/ruin/space/diner/interior) +"dk" = ( +/obj/structure/lattice/catwalk, +/turf/template_noop, +/area/space/nearstation) +"dm" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end, +/obj/structure/cable, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dn" = ( +/obj/machinery/light/small, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"do" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Diner" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dp" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dq" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dr" = ( +/obj/structure/sign/mining{ + pixel_x = 32 + }, +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/rag, +/obj/item/kitchen/fork, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"ds" = ( +/obj/structure/cable, +/obj/machinery/power/solar_control{ + icon_state = "computer"; + dir = 4 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dt" = ( +/obj/structure/sign/poster/ripped{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dv" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 4 + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dy" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/light/broken{ + icon_state = "tube-broken"; + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dz" = ( +/obj/structure/chair, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/chair, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dB" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dC" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/chair{ + icon_state = "chair_toppled"; + dir = 1 + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dD" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/food/snacks/sushi_rice, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dE" = ( +/obj/machinery/light/small/broken{ + icon_state = "bulb-broken"; + dir = 1 + }, +/turf/open/floor/engine/airless, +/area/ruin/space/diner) +"dF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/button{ + pixel_y = 24 + }, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"dG" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/vending/cola/blue, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dH" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/trash/plate, +/obj/item/reagent_containers/food/condiment/pack/ketchup{ + pixel_x = -4 + }, +/obj/item/reagent_containers/food/condiment/pack/mustard{ + pixel_x = 4 + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dI" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/item/trash/plate, +/obj/item/reagent_containers/food/snacks/hotdog, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dJ" = ( +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dK" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dL" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/trash/plate{ + pixel_y = -2 + }, +/obj/item/reagent_containers/food/snacks/burger/mcguffin, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dM" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/jukebox, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dN" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/kitchen/fork, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dO" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/trash/plate, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dP" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dQ" = ( +/obj/machinery/light, +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/food/drinks/bottle/vodka, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dR" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/reagent_containers/food/drinks/coffee, +/turf/open/floor/carpet, +/area/ruin/space/diner/interior) +"dS" = ( +/obj/item/storage/wallet/random, +/turf/open/floor/engine/airless, +/area/ruin/space/diner) +"dT" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"dU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Aft Pod Bay" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor/closed, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"dV" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/directional{ + icon_state = "hrwindow_spawner_directional"; + dir = 10 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dW" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dX" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 4 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dY" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 8 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"dZ" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/directional{ + icon_state = "hrwindow_spawner_directional"; + dir = 6 + }, +/turf/open/floor/plating, +/area/ruin/space/diner/interior) +"ea" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/template_noop, +/area/space/nearstation) +"eb" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Aft Docking Area" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor/closed, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ec" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/public/glass{ + name = "Aft Docking Area" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor/closed, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel, +/area/ruin/space/diner/interior) +"ed" = ( +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"ee" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"ef" = ( +/obj/machinery/light/small/broken{ + icon_state = "bulb-broken"; + dir = 1 + }, +/obj/machinery/vending/snack, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"eg" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + icon_state = "hrwindow_spawner_end"; + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/ruin/space/diner) +"eh" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/turf/open/floor/plating/airless, +/area/ruin/space/diner) +"ei" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/airless, +/area/ruin/space/diner) +"ej" = ( +/obj/structure/girder/reinforced, +/turf/open/floor/plating/airless, +/area/ruin/space/diner) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +af +af +af +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +af +dk +dk +dk +af +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(7,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +af +av +ax +af +dk +dk +dk +af +ej +aa +aa +aa +aa +aa +aa +aa +aa +"} +(8,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +av +aL +aL +ag +ag +ag +dg +ag +ag +ag +af +aa +aa +aa +aa +aa +aa +aa +"} +(9,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +af +aL +aL +aL +aL +bB +bT +cg +ch +ch +dh +bB +av +af +aa +aa +aa +aa +aa +aa +"} +(10,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +av +aL +aL +aL +bh +bC +bU +ch +cy +ch +di +bC +dE +aL +af +aa +aa +aa +aa +aa +"} +(11,1,1) = {" +aa +aa +aa +aa +aa +af +aa +aw +aL +aL +aL +aL +bD +bV +ci +cz +ci +dj +dv +aL +dS +av +af +aa +aa +aa +aa +"} +(12,1,1) = {" +aa +aa +aa +aa +af +af +af +ax +aM +aM +aM +bi +ag +bW +ch +cA +ch +cw +ag +dF +dT +av +af +aa +aa +aa +aa +"} +(13,1,1) = {" +aa +aa +aa +ag +ai +an +ag +ag +ag +ag +bd +bj +ag +bX +cj +cB +cS +dm +ag +bj +dU +ag +ax +ax +ej +aa +aa +"} +(14,1,1) = {" +aa +aa +aa +ag +aj +aj +aj +ay +aj +aV +aj +aj +bE +aj +aj +cC +cT +aj +cx +aj +aj +eb +ed +ed +av +aa +aa +"} +(15,1,1) = {" +aa +aa +aa +ag +ak +ao +au +au +aN +aW +au +au +bF +bY +bY +cD +cU +au +dx +au +aN +ec +ee +eh +ed +af +aa +"} +(16,1,1) = {" +aa +ab +ab +ab +al +al +ag +az +aO +ag +ag +bc +bG +aj +ck +aj +bL +dn +ag +ag +ag +ag +ef +ei +af +aa +aa +"} +(17,1,1) = {" +aa +ac +ad +ah +al +ap +ag +ag +ag +ag +ae +ag +bH +ag +ag +ag +cV +aj +ag +af +af +ax +eg +av +aa +aa +aa +"} +(18,1,1) = {" +aa +ab +ab +ab +al +al +ag +aA +aP +aX +ag +ag +bI +ag +cl +ag +cW +do +ag +af +af +aa +aa +af +aa +aa +aa +"} +(19,1,1) = {" +aa +aa +af +ab +al +aq +ag +aB +aQ +aY +be +bk +bJ +ag +ag +ag +cX +cH +ag +ai +dV +aa +aa +af +aa +aa +aa +"} +(20,1,1) = {" +aa +ab +ab +ab +al +al +ag +aC +aR +aZ +ag +bl +bH +bZ +cm +cE +cX +cH +dy +dG +dW +aa +aa +af +aa +aa +aa +"} +(21,1,1) = {" +aa +ac +ad +ah +al +ar +ag +aD +aS +ba +ag +bm +bH +aj +cn +cF +cX +cH +dz +dH +dX +af +af +af +aa +aa +aa +"} +(22,1,1) = {" +aa +ab +ab +ab +al +as +ag +aE +aS +ba +bc +bn +bK +ca +co +cF +cY +dp +dA +dI +bw +ea +ea +ea +aa +aa +aa +"} +(23,1,1) = {" +aa +aa +aa +ag +ak +al +ag +aF +aS +bb +bc +bo +bL +cb +cp +cF +cX +cH +dq +dJ +ag +af +af +af +aa +aa +aa +"} +(24,1,1) = {" +aa +aa +aa +ag +ai +an +ag +ag +ag +bc +ag +bp +bL +cb +cq +cF +cX +cH +dz +dK +dY +aa +aa +af +aa +aa +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +af +af +af +aa +ag +bq +bL +cc +cr +cG +cZ +cH +dz +dL +dW +aa +aa +aa +aa +aa +aa +"} +(26,1,1) = {" +aa +aa +aa +af +am +at +at +aG +aT +af +ag +br +bL +aj +cs +cH +da +cH +dq +dq +dW +aa +af +aa +aa +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +aa +aa +aa +af +aH +af +aa +ag +bs +bL +aj +ct +cH +da +cH +dq +dM +dW +aa +aa +aa +aa +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +af +am +at +at +aI +aT +af +ag +bt +bM +aj +cu +cI +da +cH +dz +dN +dW +aa +aa +aa +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +af +aH +af +aa +bc +bu +bL +aj +ag +cJ +da +cH +dz +dO +dW +aa +aa +aa +af +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +af +am +at +at +aI +aT +af +ag +bv +bN +cd +ag +cK +db +cH +dq +dq +dW +aa +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +af +aH +af +af +bf +bw +bO +bw +bw +cL +dc +cH +dz +dP +dX +aa +aa +af +aa +aa +aa +"} +(32,1,1) = {" +aa +aa +aa +aa +af +am +at +aJ +aU +aU +bg +bx +bP +bP +bc +cM +da +cH +dz +dQ +ag +af +af +af +aa +aa +aa +"} +(33,1,1) = {" +aa +aa +aa +aa +aa +aa +af +aH +af +af +bc +by +bQ +ce +cv +cN +dd +dp +dB +dB +bw +ea +ea +aa +aa +aa +aa +"} +(34,1,1) = {" +aa +aa +aa +aa +aa +af +am +aK +aT +af +ag +bz +bR +bL +ag +cO +cX +dq +dC +dq +dY +af +af +aa +aa +aa +aa +"} +(35,1,1) = {" +aa +aa +aa +aa +aa +aa +af +af +af +aa +ag +bA +bS +cf +ag +cP +cX +dr +dD +dR +dW +aa +aa +aa +aa +aa +aa +"} +(36,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ag +ag +ag +ag +ag +bc +de +ag +ag +ai +dZ +aa +aa +aa +aa +aa +aa +"} +(37,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +ag +aS +df +ds +ag +aa +aa +aa +aa +aa +aa +aa +aa +"} +(38,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +ag +cQ +aS +dt +ag +af +af +aa +aa +aa +aa +aa +aa +"} +(39,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +af +ag +dg +dg +ag +ag +aa +aa +aa +aa +aa +aa +aa +aa +"} +(40,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index b26fa5ee7a..4c6aeb2a9d 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -3993,8 +3993,6 @@ }, /obj/structure/closet/wardrobe/white, /obj/item/clothing/under/suit/waiter, -/obj/item/clothing/under/suit/waiter, -/obj/item/clothing/under/suit/waiter, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ahD" = ( @@ -4139,11 +4137,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/mixed, /obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/dress/skirt/purple, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, /obj/structure/sign/poster/official/fashion{ pixel_x = -32 }, @@ -4674,13 +4667,13 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "aiB" = ( -/obj/machinery/vending/kink, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/structure/sign/poster/official/fashion{ pixel_y = 32 }, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aiC" = ( @@ -10716,21 +10709,7 @@ /obj/structure/closet{ name = "Holodeck Outfits" }, -/obj/item/clothing/under/trek/Q, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/medsci/next, -/obj/item/clothing/under/trek/medsci/next, -/obj/item/clothing/under/trek/medsci/next, /obj/item/clothing/under/misc/blue_camo, -/obj/item/clothing/under/misc/blue_camo, -/obj/item/clothing/under/costume/gladiator, -/obj/item/clothing/under/costume/gladiator, /obj/machinery/firealarm{ dir = 4; pixel_x = -24 @@ -18286,7 +18265,6 @@ /obj/structure/closet/wardrobe/white, /obj/item/clothing/suit/ghost_sheet, /obj/item/clothing/suit/ghost_sheet, -/obj/item/clothing/suit/ghost_sheet, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQP" = ( @@ -18314,10 +18292,10 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQV" = ( -/obj/machinery/vending/autodrobe, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/vending/clothing, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQW" = ( @@ -18331,7 +18309,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/vending/games, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQY" = ( @@ -18814,9 +18792,6 @@ name = "Station Intercom (General)"; pixel_x = -27 }, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/russobluecamohat, /obj/item/clothing/head/russobluecamohat, /turf/open/floor/plasteel, /area/crew_quarters/locker) @@ -19300,7 +19275,6 @@ dir = 8 }, /obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/costume/kilt, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTy" = ( @@ -19818,11 +19792,6 @@ department = "Locker Room"; pixel_x = -32 }, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/color/grey, -/obj/item/clothing/under/color/grey, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aUW" = ( @@ -20433,13 +20402,6 @@ "aWn" = ( /obj/structure/closet/wardrobe/black, /obj/item/clothing/shoes/jackboots, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/head/beret/black, /obj/item/clothing/head/beret/black, /turf/open/floor/plasteel, /area/crew_quarters/locker) @@ -21788,12 +21750,10 @@ dir = 4; pixel_x = 11 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, /obj/structure/mirror{ pixel_x = 28 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "aZp" = ( @@ -21866,6 +21826,7 @@ /area/crew_quarters/toilet/locker) "aZw" = ( /obj/effect/landmark/blobstart, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "aZx" = ( @@ -22224,6 +22185,7 @@ c_tag = "Locker Room Toilets"; dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "bax" = ( @@ -22358,13 +22320,6 @@ /area/maintenance/port) "baO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, -/obj/structure/mirror{ - pixel_x = 28 - }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "baP" = ( @@ -22550,9 +22505,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "bbs" = ( @@ -22919,9 +22872,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bct" = ( -/obj/structure/chair/wood/wings, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "bcu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/maintenance{ @@ -23398,9 +23350,12 @@ /turf/open/floor/carpet, /area/bridge/meeting_room) "bdJ" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/door/airlock{ + id_tag = "LockerShitter3"; + name = "Unit 3" + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "bdK" = ( /obj/machinery/holopad, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -23417,6 +23372,7 @@ dir = 8 }, /obj/structure/bedsheetbin/color, +/obj/structure/table, /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/locker) "bdN" = ( @@ -23966,13 +23922,6 @@ }, /turf/closed/wall, /area/maintenance/disposal) -"bfa" = ( -/obj/structure/closet/crate, -/obj/item/stack/sheet/mineral/wood/fifty{ - amount = 20 - }, -/turf/open/floor/plating, -/area/maintenance/port) "bfb" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -24448,14 +24397,12 @@ /turf/open/floor/plating, /area/maintenance/port) "bgr" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plating, -/area/maintenance/port) -"bgs" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/structure/table/wood/fancy/purple, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/door/airlock{ + id_tag = "LockerShitter4"; + name = "Unit 4" + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "bgt" = ( /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, @@ -25070,7 +25017,7 @@ dir = 4 }, /turf/closed/wall, -/area/maintenance/port) +/area/crew_quarters/toilet/locker) "bhR" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -29216,14 +29163,7 @@ /turf/open/floor/plating, /area/maintenance/starboard) "brz" = ( -/obj/structure/table, -/obj/item/pen, -/obj/machinery/camera{ - c_tag = "Experimentor Lab"; - network = list("ss13","rd") - }, -/obj/item/hand_labeler, -/obj/item/stack/packageWrap, +/obj/machinery/rnd/bepis, /turf/open/floor/plasteel/white/side, /area/science/explab) "brA" = ( @@ -29240,11 +29180,14 @@ "brC" = ( /obj/structure/table, /obj/item/folder/white, -/obj/item/folder/white, /obj/machinery/airalarm{ pixel_y = 23 }, /obj/item/radio/off, +/obj/machinery/camera{ + c_tag = "Experimentor Lab"; + network = list("ss13","rd") + }, /turf/open/floor/plasteel/white/side, /area/science/explab) "brD" = ( @@ -38177,7 +38120,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/chem_dispenser, +/obj/machinery/chem_dispenser/apothecary, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bLV" = ( @@ -47896,8 +47839,6 @@ "clO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/grey, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, /obj/machinery/camera{ c_tag = "Dorms East - Holodeck"; dir = 4 @@ -51959,24 +51900,15 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "cBn" = ( -/obj/structure/closet, -/obj/item/stack/tile/carpet/royalblue{ - amount = 24 +/obj/structure/sink{ + dir = 4; + pixel_x = 11 }, -/obj/item/stack/tile/carpet/green{ - amount = 24 +/obj/structure/mirror{ + pixel_x = 28 }, -/obj/item/stack/tile/carpet/purple{ - amount = 24 - }, -/obj/item/stack/tile/carpet/orange{ - amount = 24 - }, -/obj/item/stack/tile/wood{ - amount = 24 - }, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "cBo" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/wood, @@ -52446,6 +52378,19 @@ /obj/structure/closet/boxinggloves, /turf/open/floor/plasteel, /area/crew_quarters/fitness) +"cFG" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/mirror{ + pixel_x = 28 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "cGz" = ( /obj/structure/table/wood, /obj/item/instrument/violin, @@ -52834,10 +52779,6 @@ }, /turf/open/floor/plasteel/airless/solarpanel, /area/solar/starboard/aft) -"cMS" = ( -/obj/item/chair/wood, -/turf/open/floor/plating, -/area/maintenance/port) "cNa" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -53899,14 +53840,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/security/execution/transfer) -"epC" = ( -/obj/machinery/door/airlock{ - desc = "To keep the station within regulations, space IKEA requires one storage cupboard for their Nanotrasen partnership to continue."; - id_tag = "MaintDorm1"; - name = "Furniture Storage" - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) "epD" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/machinery/light{ @@ -54630,10 +54563,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"gfr" = ( -/obj/structure/bed, -/turf/open/floor/plating, -/area/maintenance/port) "gfC" = ( /obj/effect/turf_decal/tile/red, /obj/structure/chair{ @@ -54887,17 +54816,28 @@ /area/crew_quarters/fitness) "gQX" = ( /obj/machinery/button/door{ - desc = "Alright, GAMER! Want to take your PWRGAME addiction to the MAX? Just smash this button with your chubby chetto encrusted hands an- oh, you broke the switch. Good job, idiot."; - id = "RIPFUN"; - name = "Powerful Gamer Toggle"; + id = "LockerShitter4"; + name = "Door Bolt Control"; normaldoorcontrol = 1; - pixel_x = -24; - pixel_y = 7; + pixel_x = 14; + pixel_y = 38; specialfunctions = 4 }, -/obj/structure/table_frame/wood, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/structure/toilet/secret/low_loot{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/obj/structure/mirror{ + pixel_y = 32 + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "gRZ" = ( /obj/structure/bookcase{ name = "Forbidden Knowledge" @@ -54975,16 +54915,6 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/crew_quarters/fitness) -"hew" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/port) "hgG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/structure/extinguisher_cabinet{ @@ -55022,10 +54952,6 @@ }, /turf/closed/wall, /area/crew_quarters/dorms) -"hnl" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/port) "hnU" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -55120,15 +55046,12 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "hPs" = ( -/obj/structure/fireplace{ - pixel_y = -6 - }, /obj/machinery/airalarm{ dir = 8; pixel_x = 23 }, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "hPP" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -55336,13 +55259,6 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel, /area/hallway/primary/starboard) -"iwB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/maintenance/port) "izg" = ( /obj/item/cigbutt/cigarbutt, /turf/open/floor/plating, @@ -55584,9 +55500,7 @@ }, /area/maintenance/bar) "jrE" = ( -/obj/structure/sign/poster/official/random{ - pixel_x = 32 - }, +/obj/item/beacon, /turf/open/floor/plasteel/white, /area/science/circuit) "jtj" = ( @@ -56260,10 +56174,6 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"kQO" = ( -/obj/structure/reagent_dispensers/keg/semen, -/turf/open/floor/plating, -/area/maintenance/bar) "kSb" = ( /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, @@ -56395,7 +56305,7 @@ }, /area/maintenance/bar) "lsk" = ( -/obj/machinery/vending/autodrobe, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ltK" = ( @@ -57327,17 +57237,29 @@ /turf/open/floor/plasteel, /area/security/prison) "omY" = ( -/obj/item/flashlight/lamp/green{ - pixel_x = -2; - pixel_y = 15 +/obj/machinery/button/door{ + id = "LockerShitter3"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 14; + pixel_y = 38; + specialfunctions = 4 }, -/obj/structure/dresser{ - desc = "There's plenty of clothes here to change into! It has a surprising amount of variety, too."; - name = "Dresser"; - pixel_y = 7 +/obj/structure/toilet/secret/low_loot{ + dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/obj/structure/mirror{ + pixel_y = 32 + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "oqj" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -57557,12 +57479,7 @@ "oZl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/pjs, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/under/costume/maid, /obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/accessory/maidapron, /obj/machinery/light{ dir = 8 }, @@ -57659,7 +57576,6 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "pqs" = ( -/obj/machinery/vending/clothing, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -58155,11 +58071,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/vending/kink, /obj/machinery/light{ dir = 4; light_color = "#e8eaff" }, +/obj/machinery/vending/games, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "rgL" = ( @@ -58261,11 +58177,6 @@ dir = 4 }, /obj/structure/closet/wardrobe/black, -/obj/item/clothing/under/dress/skirt, -/obj/item/clothing/head/beret/black, -/obj/item/clothing/head/beret/black, -/obj/item/clothing/under/custom/trendy_fit, -/obj/item/clothing/under/custom/trendy_fit, /obj/item/clothing/under/dress/sundress, /turf/open/floor/plasteel, /area/crew_quarters/fitness) @@ -58964,11 +58875,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) -"txm" = ( -/obj/structure/table/wood/fancy/royalblue, -/obj/item/crowbar/red, -/turf/open/floor/plating, -/area/maintenance/port) "tyX" = ( /obj/structure/cable{ icon_state = "4-8" @@ -60263,6 +60169,12 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"wTk" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "wUg" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -77199,10 +77111,10 @@ aXQ aXQ aXQ aXQ -aPz -aPz -epC -aPz +aXQ +aXQ +aXQ +aXQ bhQ bjj bkF @@ -77456,9 +77368,9 @@ aXQ aZt aXQ ycd -aPz +aXQ omY -cMS +aXQ gQX bhQ bjj @@ -77713,12 +77625,12 @@ aXQ aZv aXQ bbL -aPz +aXQ bdJ -txm +aXQ bgr -iwB -hew +bhQ +bjj bkF aaa aaa @@ -77970,10 +77882,10 @@ aWy aYe bbq aZw -aPz +wTk +bct +bct bct -bfa -gfr bhQ bjk bkE @@ -78227,11 +78139,11 @@ aXp baO aZo baw -aPz +cFG hPs cBn -bgs -hnl +bct +bhQ bjk bkF aaa @@ -78484,10 +78396,10 @@ aXQ aXQ aXQ aXQ -aPz -aPz -aPz -aPz +aXQ +aXQ +aXQ +aXQ bhQ bjk aPz @@ -82641,7 +82553,7 @@ mrR dKP odx rBq -kQO +evR bCq bUs bLv diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index f90edc9178..6247f4a185 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -72017,6 +72017,10 @@ }, /turf/open/space/basic, /area/space/nearstation) +"mBP" = ( +/obj/machinery/rnd/bepis, +/turf/open/floor/plasteel/white, +/area/science/circuit) "mEa" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/visible, /obj/machinery/meter, @@ -93372,7 +93376,7 @@ aTE bTG aVF cGs -aVF +mBP caw caA cHk diff --git a/_maps/map_files/CogStation/FOLDER.txt b/_maps/map_files/CogStation/FOLDER.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 86397c5751..000ddf0665 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -97848,17 +97848,17 @@ /obj/structure/sign/poster/official/science{ pixel_x = -32 }, +/obj/item/clothing/mask/gas, /turf/open/floor/plasteel, /area/science/explab) "djC" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/rnd/bepis, /turf/open/floor/plasteel, /area/science/explab) "djD" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/light{ dir = 1 }, @@ -97869,7 +97869,6 @@ /turf/open/floor/plasteel, /area/science/explab) "djE" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -98853,34 +98852,20 @@ /obj/machinery/newscaster{ pixel_x = -32 }, -/obj/item/crowbar, -/obj/item/wrench, -/obj/item/clothing/mask/gas, /obj/effect/turf_decal/bot, +/obj/item/storage/bag/money, /turf/open/floor/plasteel, /area/science/explab) "dlp" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 - }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, +/obj/structure/chair/office/light{ + dir = 8 + }, /turf/open/floor/plasteel/white, /area/science/explab) "dlq" = ( -/obj/machinery/atmospherics/components/trinary/filter{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/science/explab) -"dlr" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, @@ -124888,10 +124873,6 @@ }, /turf/open/floor/plasteel/airless/solarpanel, /area/solar/port/aft) -"egC" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/chapel/office) "egD" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 @@ -125125,7 +125106,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/chem_dispenser, +/obj/machinery/chem_dispenser/apothecary, /turf/open/floor/plasteel/dark, /area/medical/medbay/central) "eMD" = ( @@ -156768,7 +156749,7 @@ cOM dgs cMY djE -dlr +dlq dmE dow dqm @@ -162468,7 +162449,7 @@ edT eeC efp egd -egC +efg aaa aad aaa @@ -162725,7 +162706,7 @@ edU eeD efq ege -egC +efg aaa aad aaa @@ -162982,7 +162963,7 @@ edV eeE efr ege -egC +efg aad ajr aaa diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index bfea5f9289..6603821c82 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -3806,8 +3806,6 @@ }, /obj/structure/closet/wardrobe/white, /obj/item/clothing/under/suit/waiter, -/obj/item/clothing/under/suit/waiter, -/obj/item/clothing/under/suit/waiter, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ahD" = ( @@ -3952,11 +3950,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/mixed, /obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/dress/skirt/purple, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, /obj/structure/sign/poster/official/fashion{ pixel_x = -32 }, @@ -4487,13 +4480,13 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "aiB" = ( -/obj/machinery/vending/kink, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/structure/sign/poster/official/fashion{ pixel_y = 32 }, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aiC" = ( @@ -10746,21 +10739,7 @@ /obj/structure/closet{ name = "Holodeck Outfits" }, -/obj/item/clothing/under/trek/Q, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/command/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/engsec/next, -/obj/item/clothing/under/trek/medsci/next, -/obj/item/clothing/under/trek/medsci/next, -/obj/item/clothing/under/trek/medsci/next, /obj/item/clothing/under/misc/blue_camo, -/obj/item/clothing/under/misc/blue_camo, -/obj/item/clothing/under/costume/gladiator, -/obj/item/clothing/under/costume/gladiator, /obj/machinery/firealarm{ dir = 4; pixel_x = -24 @@ -18449,7 +18428,6 @@ /obj/structure/closet/wardrobe/white, /obj/item/clothing/suit/ghost_sheet, /obj/item/clothing/suit/ghost_sheet, -/obj/item/clothing/suit/ghost_sheet, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQP" = ( @@ -18477,10 +18455,10 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQV" = ( -/obj/machinery/vending/autodrobe, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/vending/clothing, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQW" = ( @@ -18494,7 +18472,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/vending/games, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQY" = ( @@ -18977,9 +18955,6 @@ name = "Station Intercom (General)"; pixel_x = -27 }, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/beret, -/obj/item/clothing/head/russobluecamohat, /obj/item/clothing/head/russobluecamohat, /turf/open/floor/plasteel, /area/crew_quarters/locker) @@ -19463,7 +19438,6 @@ dir = 8 }, /obj/item/clothing/under/costume/kilt, -/obj/item/clothing/under/costume/kilt, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTy" = ( @@ -19982,13 +19956,8 @@ department = "Locker Room"; pixel_x = -32 }, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/color/grey, -/obj/item/clothing/under/color/grey, /turf/open/floor/plasteel, -/area/crew_quarters/locker) +/area/space) "aUW" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp/green, @@ -20597,13 +20566,6 @@ "aWn" = ( /obj/structure/closet/wardrobe/black, /obj/item/clothing/shoes/jackboots, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/head/beret/black, /obj/item/clothing/head/beret/black, /turf/open/floor/plasteel, /area/crew_quarters/locker) @@ -21947,19 +21909,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/security/vacantoffice) -"aZo" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/structure/mirror{ - pixel_x = 28 - }, -/turf/open/floor/plasteel/freezer, -/area/crew_quarters/toilet/locker) "aZp" = ( /obj/structure/rack, /obj/item/electronics/apc, @@ -22030,6 +21979,7 @@ /area/crew_quarters/toilet/locker) "aZw" = ( /obj/effect/landmark/blobstart, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "aZx" = ( @@ -22388,6 +22338,7 @@ c_tag = "Locker Room Toilets"; dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "bax" = ( @@ -22714,9 +22665,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet/locker) "bbs" = ( @@ -23083,9 +23032,11 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bct" = ( -/obj/structure/chair/wood/wings, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "bcu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/maintenance{ @@ -23562,9 +23513,12 @@ /turf/open/floor/carpet, /area/bridge/meeting_room) "bdJ" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/door/airlock{ + id_tag = "LockerShitter3"; + name = "Unit 3" + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "bdK" = ( /obj/machinery/holopad, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -24131,12 +24085,8 @@ /turf/closed/wall, /area/maintenance/disposal) "bfa" = ( -/obj/structure/closet/crate, -/obj/item/stack/sheet/mineral/wood/fifty{ - amount = 20 - }, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "bfb" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -24611,14 +24561,12 @@ /turf/open/floor/plating, /area/maintenance/port) "bgr" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plating, -/area/maintenance/port) -"bgs" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/structure/table/wood/fancy/purple, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/door/airlock{ + id_tag = "LockerShitter4"; + name = "Unit 4" + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "bgt" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/structure/reagent_dispensers/watertank, @@ -25235,7 +25183,7 @@ dir = 4 }, /turf/closed/wall, -/area/maintenance/port) +/area/crew_quarters/toilet/locker) "bhR" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -29367,14 +29315,7 @@ /turf/open/floor/plating, /area/maintenance/starboard) "brz" = ( -/obj/structure/table, -/obj/item/pen, -/obj/machinery/camera{ - c_tag = "Experimentor Lab"; - network = list("ss13","rd") - }, -/obj/item/hand_labeler, -/obj/item/stack/packageWrap, +/obj/machinery/rnd/bepis, /turf/open/floor/plasteel/white/side, /area/science/explab) "brA" = ( @@ -29396,6 +29337,10 @@ pixel_y = 23 }, /obj/item/radio/off, +/obj/machinery/camera{ + c_tag = "Experimentor Lab"; + network = list("ss13","rd") + }, /turf/open/floor/plasteel/white/side, /area/science/explab) "brD" = ( @@ -38320,7 +38265,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/chem_dispenser, +/obj/machinery/chem_dispenser/apothecary, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bLV" = ( @@ -41718,7 +41663,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/dark/visible{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, /turf/open/floor/plasteel/white/corner, @@ -44852,7 +44797,7 @@ /area/engine/engineering) "ccy" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/atmospherics/pipe/simple/dark/visible{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, /turf/open/floor/plasteel, @@ -45205,7 +45150,7 @@ "cdB" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/dark/visible{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, /turf/open/floor/plating, @@ -48338,8 +48283,6 @@ "clO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/grey, -/obj/item/clothing/under/misc/assistantformal, -/obj/item/clothing/under/misc/assistantformal, /obj/machinery/camera{ c_tag = "Dorms East - Holodeck"; dir = 4 @@ -52200,24 +52143,15 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "cBn" = ( -/obj/structure/closet, -/obj/item/stack/tile/carpet/royalblue{ - amount = 24 +/obj/structure/sink{ + dir = 4; + pixel_x = 11 }, -/obj/item/stack/tile/carpet/green{ - amount = 24 +/obj/structure/mirror{ + pixel_x = 28 }, -/obj/item/stack/tile/carpet/purple{ - amount = 24 - }, -/obj/item/stack/tile/carpet/orange{ - amount = 24 - }, -/obj/item/stack/tile/wood{ - amount = 24 - }, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "cBo" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/wood, @@ -53005,10 +52939,6 @@ }, /turf/open/floor/plating/asteroid/snow/ice/icemoon/solarpanel, /area/icemoon/surface/outdoors) -"cMS" = ( -/obj/item/chair/wood, -/turf/open/floor/plating, -/area/maintenance/port) "cNa" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -54124,6 +54054,13 @@ }, /turf/open/floor/wood, /area/crew_quarters/bar) +"emX" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/plating/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors) "ene" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -54141,14 +54078,6 @@ }, /turf/open/floor/engine, /area/engine/engineering) -"epC" = ( -/obj/machinery/door/airlock{ - desc = "To keep the station within regulations, space IKEA requires one storage cupboard for their Nanotrasen partnership to continue."; - id_tag = "MaintDorm1"; - name = "Furniture Storage" - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) "epD" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/machinery/light{ @@ -55014,10 +54943,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"gfr" = ( -/obj/structure/bed, -/turf/open/floor/plating, -/area/maintenance/port) "gfC" = ( /obj/effect/turf_decal/tile/red, /obj/structure/chair{ @@ -55317,17 +55242,28 @@ /area/crew_quarters/fitness) "gQX" = ( /obj/machinery/button/door{ - desc = "Alright, GAMER! Want to take your PWRGAME addiction to the MAX? Just smash this button with your chubby chetto encrusted hands an- oh, you broke the switch. Good job, idiot."; - id = "RIPFUN"; - name = "Powerful Gamer Toggle"; + id = "LockerShitter4"; + name = "Door Bolt Control"; normaldoorcontrol = 1; - pixel_x = -24; - pixel_y = 7; + pixel_x = 14; + pixel_y = 38; specialfunctions = 4 }, -/obj/structure/table_frame/wood, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/structure/toilet/secret/low_loot{ + dir = 4 + }, +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/obj/structure/mirror{ + pixel_y = 32 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "gRZ" = ( /obj/structure/bookcase{ name = "Forbidden Knowledge" @@ -55397,16 +55333,6 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/crew_quarters/fitness) -"hew" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/port) "hgO" = ( /obj/structure/table, /obj/item/storage/pill_bottle/dice{ @@ -55453,10 +55379,6 @@ }, /turf/closed/wall, /area/crew_quarters/dorms) -"hnl" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/port) "hnU" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -55604,15 +55526,15 @@ /turf/open/floor/engine, /area/engine/engineering) "hPs" = ( -/obj/structure/fireplace{ - pixel_y = -6 - }, /obj/machinery/airalarm{ dir = 8; pixel_x = 23 }, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "hPP" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -55830,13 +55752,6 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel, /area/hallway/primary/starboard) -"iwB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/maintenance/port) "izg" = ( /obj/item/cigbutt/cigarbutt, /turf/open/floor/plating, @@ -55865,6 +55780,12 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/pool) +"iBR" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 6 + }, +/turf/open/floor/plating/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors) "iEJ" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod One" @@ -56609,6 +56530,12 @@ /obj/structure/window, /turf/open/floor/wood, /area/crew_quarters/bar) +"krn" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 9 + }, +/turf/open/floor/plating/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors) "ksp" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/closed/wall, @@ -56859,10 +56786,6 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"kQO" = ( -/obj/structure/reagent_dispensers/keg/semen, -/turf/open/floor/plating, -/area/maintenance/bar) "kSb" = ( /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, @@ -56907,6 +56830,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"kYy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "kZE" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -57041,7 +56968,7 @@ /turf/open/floor/engine, /area/engine/engineering) "lsk" = ( -/obj/machinery/vending/autodrobe, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ltK" = ( @@ -57462,6 +57389,13 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"mAU" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/plating/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors) "mCy" = ( /obj/machinery/space_heater{ anchored = 1 @@ -58081,17 +58015,26 @@ /turf/open/floor/plasteel, /area/security/prison) "omY" = ( -/obj/item/flashlight/lamp/green{ - pixel_x = -2; - pixel_y = 15 +/obj/machinery/button/door{ + id = "LockerShitter4"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 14; + pixel_y = 38; + specialfunctions = 4 }, -/obj/structure/dresser{ - desc = "There's plenty of clothes here to change into! It has a surprising amount of variety, too."; - name = "Dresser"; - pixel_y = 7 +/obj/structure/toilet/secret/low_loot{ + dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/crew_quarters/toilet/locker) "oqj" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58399,12 +58342,7 @@ "oZl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/pjs, -/obj/item/clothing/under/costume/maid, -/obj/item/clothing/under/costume/maid, /obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/under/rank/civilian/janitor/maid, -/obj/item/clothing/accessory/maidapron, -/obj/item/clothing/accessory/maidapron, /obj/machinery/light{ dir = 8 }, @@ -58525,7 +58463,6 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "pqs" = ( -/obj/machinery/vending/clothing, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -59046,18 +58983,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/engine/engineering) -"rca" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/obj/structure/closet/secure_closet/atmospherics, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/plasteel/dark/corner{ - dir = 1 - }, -/area/engine/atmos) "rcD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59101,11 +59026,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/vending/kink, /obj/machinery/light{ dir = 4; light_color = "#e8eaff" }, +/obj/machinery/vending/games, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "rfW" = ( @@ -59228,11 +59153,6 @@ dir = 4 }, /obj/structure/closet/wardrobe/black, -/obj/item/clothing/under/dress/skirt, -/obj/item/clothing/head/beret/black, -/obj/item/clothing/head/beret/black, -/obj/item/clothing/under/custom/trendy_fit, -/obj/item/clothing/under/custom/trendy_fit, /obj/item/clothing/under/dress/sundress, /turf/open/floor/plasteel, /area/crew_quarters/fitness) @@ -60176,11 +60096,6 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) -"txm" = ( -/obj/structure/table/wood/fancy/royalblue, -/obj/item/crowbar/red, -/turf/open/floor/plating, -/area/maintenance/port) "tyX" = ( /obj/structure/cable{ icon_state = "4-8" @@ -61008,6 +60923,10 @@ }, /turf/open/floor/wood, /area/maintenance/bar) +"vke" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/toilet/locker) "vmQ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 @@ -78702,10 +78621,10 @@ aXQ aXQ aXQ aXQ -aPz -aPz -epC -aPz +aXQ +aXQ +aXQ +aXQ bhQ bjj bkF @@ -78959,9 +78878,9 @@ aXQ aZt aXQ ycd -aPz +aXQ omY -cMS +aXQ gQX bhQ bjj @@ -79216,12 +79135,12 @@ aXQ aZv aXQ bbL -aPz +aXQ bdJ -txm +aXQ bgr -iwB -hew +bhQ +bjj bkF ayF ayF @@ -79473,10 +79392,10 @@ aWy aYe bbq aZw -aPz +kYy bct bfa -gfr +bfa bhQ bjk bkE @@ -79727,14 +79646,14 @@ aSV aUo aUX aXp +vke baO -aZo baw -aPz +baO hPs cBn -bgs -hnl +bfa +bhQ bjk bkF ayF @@ -79987,10 +79906,10 @@ aXQ aXQ aXQ aXQ -aPz -aPz -aPz -aPz +aXQ +aXQ +aXQ +aXQ bhQ bjk aPz @@ -84144,7 +84063,7 @@ mrR dKP odx rBq -kQO +evR bCq bUs bLv @@ -93127,7 +93046,7 @@ bOX bQm bRv bRs -rca +glY bTP bVX bWQ @@ -93384,7 +93303,7 @@ bOW bQl bRu bRs -rca +glY bUI bVR bWQ @@ -97747,14 +97666,14 @@ bFJ bvd bKH bzs -avm -ayF -avm -ayF -avB -ayF -avm -ayF +iBR +avx +mAU +avx +emX +avx +mAU +krn avB awd awe diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 84da15075b..2dcb78d188 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -30477,9 +30477,8 @@ dir = 4 }, /obj/machinery/light{ - dir = 4 + dir = 1 }, -/obj/machinery/computer/nanite_cloud_controller, /turf/open/floor/plasteel/dark, /area/science/research) "aXx" = ( @@ -30591,7 +30590,8 @@ name = "science camera"; network = list("ss13","rd") }, -/obj/machinery/computer/nanite_chamber_control, +/obj/structure/table/reinforced, +/obj/item/storage/bag/money, /turf/open/floor/plasteel/dark, /area/science/research) "aXG" = ( @@ -31259,8 +31259,6 @@ dir = 1 }, /obj/structure/table/reinforced, -/obj/item/nanite_scanner, -/obj/item/nanite_remote, /turf/open/floor/plasteel/dark, /area/science/research) "aYO" = ( @@ -35120,7 +35118,6 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/obj/machinery/nanite_program_hub, /turf/open/floor/plasteel/dark, /area/science/research) "beE" = ( @@ -85141,7 +85138,7 @@ dir = 8 }, /obj/effect/turf_decal/bot, -/obj/machinery/nanite_chamber, +/obj/machinery/rnd/bepis, /turf/open/floor/plasteel/dark, /area/science/research) "kSc" = ( @@ -85408,14 +85405,6 @@ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, /area/hallway/secondary/entry) -"sfp" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/nanite_programmer, -/turf/open/floor/plasteel/dark, -/area/science/research) "swG" = ( /obj/item/reagent_containers/food/drinks/drinkingglass{ pixel_x = 4; @@ -123520,7 +123509,7 @@ aZv aXw kRh aXI -sfp +aXI beD bbj aNF diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 45f0721cc0..262572aaea 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -23470,9 +23470,7 @@ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/closet/l3closet/scientist{ - pixel_x = -2 - }, +/obj/structure/closet/l3closet/scientist, /turf/open/floor/plasteel/white, /area/science/explab) "aQI" = ( @@ -38260,12 +38258,10 @@ /turf/open/floor/plasteel/white, /area/medical/chemistry) "btD" = ( -/obj/machinery/chem_dispenser{ - layer = 2.7 - }, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, +/obj/machinery/chem_dispenser/apothecary, /turf/open/floor/plasteel/white, /area/medical/chemistry) "btE" = ( @@ -81493,6 +81489,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"sZf" = ( +/obj/machinery/rnd/bepis, +/turf/open/floor/engine, +/area/science/explab) "tbT" = ( /obj/machinery/power/emitter/anchored{ dir = 1; @@ -113779,7 +113779,7 @@ aFb aFO aGD aHo -aGD +aHp aDr aaA aaA @@ -114035,7 +114035,7 @@ aEj aFc aFO aGD -aHp +aGD aGD aDr apk @@ -114548,9 +114548,9 @@ aJP aKA aFe aDr -aGD aHq aGD +sZf aDr aJI aKB diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 9f7e39af54..f71ef42135 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -56943,21 +56943,12 @@ }, /area/science/research) "ciS" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/mob/living/simple_animal/pet/dog/pug{ - desc = "It's Pugley IV, the research department's lovable pug clone. Hopefully nothing happens to this one - fourth time lucky!"; - name = "Pugley IV"; - real_name = "Pugley IV" - }, +/obj/machinery/rnd/bepis, /turf/open/floor/engine, /area/science/explab) "ciT" = ( /obj/item/beacon, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/engine, /area/science/explab) "ciU" = ( @@ -59556,6 +59547,11 @@ /obj/structure/chair/office/light{ dir = 4 }, +/mob/living/simple_animal/pet/dog/pug{ + desc = "It's Pugley IV, the research department's lovable pug clone. Hopefully nothing happens to this one - fourth time lucky!"; + name = "Pugley IV"; + real_name = "Pugley IV" + }, /turf/open/floor/plasteel/white, /area/science/explab) "com" = ( @@ -63927,9 +63923,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/machinery/chem_dispenser{ - layer = 2.7 - }, +/obj/machinery/chem_dispenser/apothecary, /turf/open/floor/plasteel/white, /area/medical/medbay/aft) "cwp" = ( diff --git a/_maps/shuttles/emergency_gorilla.dmm b/_maps/shuttles/emergency_gorilla.dmm index 0c75cd8b7e..cc2e67ee3e 100644 --- a/_maps/shuttles/emergency_gorilla.dmm +++ b/_maps/shuttles/emergency_gorilla.dmm @@ -326,10 +326,6 @@ /mob/living/simple_animal/hostile/gorilla, /turf/open/floor/plasteel/shuttle, /area/shuttle/escape) -"bn" = ( -/obj/structure/reagent_dispensers/keg/semen, -/turf/open/floor/plating, -/area/shuttle/escape) "bo" = ( /obj/structure/closet/crate/freezer/surplus_limbs, /turf/open/floor/plasteel/shuttle, @@ -539,7 +535,7 @@ aD fV Pi bm -bn +ax bs bu "} @@ -610,7 +606,7 @@ aX aD fV bi -bn +ax bl fV ab diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 82dc87e465..07f24fd8a3 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -101,8 +101,5 @@ #define TOGGLES_CITADEL 0 -//component stuff -#define COMSIG_VORE_TOGGLED "voremode_toggled" // totally not copypasta - //belly sound pref things #define NORMIE_HEARCHECK 4 diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 6ef8b07ddd..6e9383326e 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -29,38 +29,27 @@ #define EFFECT_DROWSY "drowsy" #define EFFECT_JITTER "jitter" -// /mob/living/combat_flags -#define CAN_TOGGLE_COMBAT_MODE(mob) FORCE_BOOLEAN((mob.stat == CONSCIOUS) && !(mob.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) - -/// Default combat flags for those affected by ((stamina combat)) +/// Default combat flags for those affected by sprinting (combat mode has been made into its own component) #define COMBAT_FLAGS_DEFAULT NONE -/// Default combat flags for everyone else (so literally everyone but humans) -#define COMBAT_FLAGS_STAMSYSTEM_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED | COMBAT_FLAG_COMBAT_FORCED) -/// Default combat flags for those only affected by sprint (so just silicons) -#define COMBAT_FLAGS_STAMEXEMPT_YESSPRINT (COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_COMBAT_FORCED) +/// Default combat flags for everyone else (so literally everyone but humans). +#define COMBAT_FLAGS_SPRINT_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED) -/// The user wants combat mode on -#define COMBAT_FLAG_COMBAT_TOGGLED (1<<0) /// The user wants sprint mode on -#define COMBAT_FLAG_SPRINT_TOGGLED (1<<1) -/// Combat mode is currently active -#define COMBAT_FLAG_COMBAT_ACTIVE (1<<2) +#define COMBAT_FLAG_SPRINT_TOGGLED (1<<0) /// Sprint is currently active -#define COMBAT_FLAG_SPRINT_ACTIVE (1<<3) +#define COMBAT_FLAG_SPRINT_ACTIVE (1<<1) /// Currently attempting to crawl under someone -#define COMBAT_FLAG_ATTEMPTING_CRAWL (1<<4) +#define COMBAT_FLAG_ATTEMPTING_CRAWL (1<<2) /// Currently stamcritted -#define COMBAT_FLAG_HARD_STAMCRIT (1<<5) +#define COMBAT_FLAG_HARD_STAMCRIT (1<<3) /// Currently attempting to resist up from the ground -#define COMBAT_FLAG_RESISTING_REST (1<<6) +#define COMBAT_FLAG_RESISTING_REST (1<<4) /// Intentionally resting -#define COMBAT_FLAG_INTENTIONALLY_RESTING (1<<7) +#define COMBAT_FLAG_INTENTIONALLY_RESTING (1<<5) /// Currently stamcritted but not as violently -#define COMBAT_FLAG_SOFT_STAMCRIT (1<<8) -/// Force combat mode on at all times, overrides everything including combat disable traits. -#define COMBAT_FLAG_COMBAT_FORCED (1<<9) +#define COMBAT_FLAG_SOFT_STAMCRIT (1<<6) /// Force sprint mode on at all times, overrides everything including sprint disable traits. -#define COMBAT_FLAG_SPRINT_FORCED (1<<10) +#define COMBAT_FLAG_SPRINT_FORCED (1<<7) // Helpers for getting someone's stamcrit state. Cast to living. #define NOT_STAMCRIT 0 diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 65e1d0e980..f1548bbe0f 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -69,6 +69,7 @@ #define CAT_WEAPONRY "Weaponry" #define CAT_WEAPON "Weapons" #define CAT_AMMO "Ammunition" +#define CAT_PARTS "Weapon Parts" #define CAT_ROBOT "Robots" #define CAT_MISC "Misc" #define CAT_MISCELLANEOUS "Miscellaneous" diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/flags.dm index 59c0c58b8d..2dbd4874d9 100644 --- a/code/__DEFINES/dcs/flags.dm +++ b/code/__DEFINES/dcs/flags.dm @@ -75,3 +75,11 @@ #define ID_COMPONENT_KNOWLEDGE_NONE 0 /// Has full knowledge #define ID_COMPONENT_KNOWLEDGE_FULL 1 + +// Combat mode flags. +/// The user wants combat mode on +#define COMBAT_MODE_TOGGLED (1<<0) +/// combat mode is active. +#define COMBAT_MODE_ACTIVE (1<<1) +/// combat mode is not active +#define COMBAT_MODE_INACTIVE (1<<2) \ No newline at end of file diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index bcb29d72a5..79e8060341 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -149,7 +149,8 @@ // /mob signals #define COMSIG_MOB_CLICKED_SHIFT_ON "mob_shift_click_on" //from base of /atom/ShiftClick(): (atom/A), for return values, see COMSIG_CLICK_SHIFT -#define COMSIG_MOB_FOV_VIEW "mob_visible_atoms" //from base of mob/fov_view(): (list/visible_atoms) +#define COMSIG_MOB_FOV_VIEW "mob_visible_atoms" //from base of /mob/fov_view(): (list/visible_atoms) +#define COMSIG_MOB_POINTED "mob_pointed" //from base of /mob/verb/pointed(): (atom/A) #define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A), for return values, see COMSIG_CLICK_SHIFT #define COMPONENT_EXAMINATE_BLIND 3 //outputs the "something is there but you can't see it" message. #define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) @@ -194,26 +195,27 @@ #define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" //from base of mob/swap_hand(): (obj/item) #define COMPONENT_BLOCK_SWAP 1 +// /client signals +#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client) +#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client) +#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) +#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view) +#define COMSIG_MOB_CLIENT_MOUSEMOVE "mob_client_mousemove" //from base of /client/MouseMove(): (object, location, control, params) + // /mob/living signals #define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) #define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living) #define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) #define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags) +#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented" //sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check) #define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () #define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive) -#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client) -#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client) -#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) -#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view) - #define COMSIG_MOB_RESET_PERSPECTIVE "mob_reset_perspective" //from base of /mob/reset_perspective(): (atom/target) #define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override) // This returns flags as defined for block in __DEFINES/combat.dm! #define COMSIG_LIVING_RUN_BLOCK "living_do_run_block" //from base of mob/living/do_run_block(): (real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone) -#define COMSIG_LIVING_COMBAT_ENABLED "combatmode_enabled" //from base of mob/living/enable_combat_mode() (was_forced) -#define COMSIG_LIVING_COMBAT_DISABLED "combatmode_disabled" //from base of mob/living/disable_combat_mode() (was_forced) #define COMSIG_LIVING_GET_BLOCKING_ITEMS "get_blocking_items" //from base of mob/living/get_blocking_items(): (list/items) //ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS! @@ -231,13 +233,14 @@ #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) #define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE) #define COMSIG_CARBON_TACKLED "carbon_tackled" //sends from tackle.dm on tackle completion -// /mob/living/simple_animal/hostile signals -#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" - #define COMPONENT_HOSTILE_NO_ATTACK 1 // /mob/living/silicon signals #define COMSIG_ROBOT_UPDATE_ICONS "robot_update_icons" //from base of robot/update_icons(): () +// /mob/living/simple_animal/hostile signals +#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" + #define COMPONENT_HOSTILE_NO_ATTACK 1 + // /obj signals #define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) #define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) @@ -349,6 +352,14 @@ //NTnet #define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) +//Combat mode +#define COMSIG_TOGGLE_COMBAT_MODE "toggle_combat_mode" //safely toggles combat mode. +#define COMSIG_DISABLE_COMBAT_MODE "disable_combat_mode" //safely disables combat mode. +#define COMSIG_ENABLE_COMBAT_MODE "enable_combat_mode" //safely enables combat mode. +#define COMSIG_LIVING_COMBAT_ENABLED "combatmode_enabled" //from base of datum/component/combat_mode/enable_combat_mode() (was_forced) +#define COMSIG_LIVING_COMBAT_DISABLED "combatmode_disabled" //from base of datum/component/combat_mode/disable_combat_mode() (was_forced) +#define COMSIG_COMBAT_MODE_CHECK "combatmode_check" //called when checking the combat mode flags (enabled/disabled/forced) + //Nanites #define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found #define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 9facaf5d70..abc0507bf4 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -74,8 +74,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define FLYING (1<<1) #define VENTCRAWLING (1<<2) #define FLOATING (1<<3) -#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped. -#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting. +///When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped. +#define UNSTOPPABLE (1<<4) +///Applied if you're crawling around on the ground/resting. +#define CRAWLING (1<<5) //Fire and Acid stuff, for resistance_flags #define LAVA_PROOF (1<<0) diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index e418b8b4c6..24726b8058 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -209,3 +209,5 @@ /// Make sure something is a boolean TRUE/FALSE 1/0 value, since things like bitfield & bitflag doesn't always give 1s and 0s. #define FORCE_BOOLEAN(x) ((x)? TRUE : FALSE) + +#define TILES_TO_PIXELS(tiles) (tiles * PIXELS) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index c7e1d7b672..3c777c42e1 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -9,6 +9,9 @@ #define TEXT_EAST "[EAST]" #define TEXT_WEST "[WEST]" +/// world.icon_size +#define PIXELS 32 + //These get to go at the top, because they're special //You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects) /* eg: diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 29ab67271c..8d8b9f47ae 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -126,6 +126,13 @@ #define SCREWYHUD_DEAD 2 #define SCREWYHUD_HEALTHY 3 +//Threshold levels for beauty for humans +#define BEAUTY_LEVEL_HORRID -66 +#define BEAUTY_LEVEL_BAD -33 +#define BEAUTY_LEVEL_DECENT 33 +#define BEAUTY_LEVEL_GOOD 66 +#define BEAUTY_LEVEL_GREAT 100 + //Moods levels for humans #define MOOD_LEVEL_HAPPY4 15 #define MOOD_LEVEL_HAPPY3 10 diff --git a/code/__DEFINES/profile.dm b/code/__DEFINES/profile.dm index 8929e0f05e..5fc8478901 100644 --- a/code/__DEFINES/profile.dm +++ b/code/__DEFINES/profile.dm @@ -26,4 +26,4 @@ #define PROFILE_ITEM_LEN 2 #define PROFILE_ITEM_TIME 1 -#define PROFILE_ITEM_COUNT 2 \ No newline at end of file +#define PROFILE_ITEM_COUNT 2 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 6eb38fce81..8c423ad09c 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -117,6 +117,7 @@ #define FIRE_PRIORITY_NPC 80 #define FIRE_PRIORITY_MOBS 100 #define FIRE_PRIORITY_TGUI 110 +#define FIRE_PRIORITY_PROJECTILES 200 #define FIRE_PRIORITY_TICKER 200 #define FIRE_PRIORITY_ATMOS_ADJACENCY 300 #define FIRE_PRIORITY_CHAT 400 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index e164a4ec96..7c0811ec59 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,253 +1,343 @@ -//tgstation-server DMAPI +// tgstation-server DMAPI -#define TGS_DMAPI_VERSION "5.1.1" +#define TGS_DMAPI_VERSION "5.2.1" -//All functions and datums outside this document are subject to change with any version and should not be relied on +// All functions and datums outside this document are subject to change with any version and should not be relied on. -//CONFIGURATION +// CONFIGURATION -//create this define if you want to do configuration outside of this file +/// Create this define if you want to do TGS configuration outside of this file. #ifndef TGS_EXTERNAL_CONFIGURATION -//Comment this out once you've filled in the below +// Comment this out once you've filled in the below. #error TGS API unconfigured -//Uncomment this if you wish to allow the game to interact with TGS 3 -//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()() +// Uncomment this if you wish to allow the game to interact with TGS 3. +// This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()() //#define TGS_V3_API -//Required interfaces (fill in with your codebase equivalent): +// Required interfaces (fill in with your codebase equivalent): -//create a global variable named `Name` and set it to `Value` +/// Create a global variable named `Name` and set it to `Value`. #define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) -//Read the value in the global variable `Name` +/// Read the value in the global variable `Name`. #define TGS_READ_GLOBAL(Name) -//Set the value in the global variable `Name` to `Value` +/// Set the value in the global variable `Name` to `Value`. #define TGS_WRITE_GLOBAL(Name, Value) -//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities +/// Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities. #define TGS_PROTECT_DATUM(Path) -//Display an announcement `message` from the server to all players +/// Display an announcement `message` from the server to all players. #define TGS_WORLD_ANNOUNCE(message) -//Notify current in-game administrators of a string `event` +/// Notify current in-game administrators of a string `event`. #define TGS_NOTIFY_ADMINS(event) -//Write an info `message` to a server log +/// Write an info `message` to a server log. #define TGS_INFO_LOG(message) -//Write an warning `message` to a server log +/// Write an warning `message` to a server log. #define TGS_WARNING_LOG(message) -//Write an error `message` to a server log +/// Write an error `message` to a server log. #define TGS_ERROR_LOG(message) -//Get the number of connected /clients +/// Get the number of connected /clients. #define TGS_CLIENT_COUNT #endif -//EVENT CODES +// EVENT CODES -#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //Before a reboot mode change, extras parameters are the current and new reboot mode enums -#define TGS_EVENT_PORT_SWAP -2 //Before a port change is about to happen, extra parameters is new port -#define TGS_EVENT_INSTANCE_RENAMED -3 //Before the instance is renamed, extra parameter is the new name -#define TGS_EVENT_WATCHDOG_REATTACH -4 //After the watchdog reattaches to DD, extra parameter is the new /datum/tgs_version of the server +/// Before a reboot mode change, extras parameters are the current and new reboot mode enums +#define TGS_EVENT_REBOOT_MODE_CHANGE -1 +/// Before a port change is about to happen, extra parameters is new port +#define TGS_EVENT_PORT_SWAP -2 +/// Before the instance is renamed, extra parameter is the new name +#define TGS_EVENT_INSTANCE_RENAMED -3 +/// After the watchdog reattaches to DD, extra parameter is the new [/datum/tgs_version] of the server +#define TGS_EVENT_WATCHDOG_REATTACH -4 -//See the descriptions for the parameters of these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs +/// When the repository is reset to its origin reference. Parameters: Reference name, Commit SHA #define TGS_EVENT_REPO_RESET_ORIGIN 0 +/// When the repository performs a checkout. Parameters: Checkout git object #define TGS_EVENT_REPO_CHECKOUT 1 +/// When the repository performs a fetch operation. No parameters #define TGS_EVENT_REPO_FETCH 2 +/// When the repository merges a pull request. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user #define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 +/// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path #define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 +/// Before a BYOND install operation begins. Parameters: [/datum/tgs_version] of the installing BYOND #define TGS_EVENT_BYOND_INSTALL_START 5 +/// When a BYOND install operation fails. Parameters: Error message #define TGS_EVENT_BYOND_INSTALL_FAIL 6 +/// When the active BYOND version changes. Parameters: (Nullable) [/datum/tgs_version] of the current BYOND, [/datum/tgs_version] of the new BYOND #define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7 +/// When the compiler starts running. Parameters: Game directory path, origin commit SHA #define TGS_EVENT_COMPILE_START 8 +/// When a compile is cancelled. No parameters #define TGS_EVENT_COMPILE_CANCELLED 9 +/// When a compile fails. Parameters: Game directory path, [TRUE]/[FALSE] based on if the cause for failure was DMAPI validation #define TGS_EVENT_COMPILE_FAILURE 10 -#define TGS_EVENT_COMPILE_COMPLETE 11 // Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the TGS_EVENT_DEPLOYMENT_COMPLETE instead +/// When a compile operation completes. Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the [TGS_EVENT_DEPLOYMENT_COMPLETE] instead. Parameters: Game directory path +#define TGS_EVENT_COMPILE_COMPLETE 11 +/// When an automatic update for the current instance begins. No parameters #define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12 +/// When the repository encounters a merge conflict: Parameters: Base SHA, target SHA, base reference, target reference #define TGS_EVENT_REPO_MERGE_CONFLICT 13 +/// When a deployment completes. No Parameters #define TGS_EVENT_DEPLOYMENT_COMPLETE 14 +/// Before the watchdog shuts down. Not sent for graceful shutdowns. No parameters. #define TGS_EVENT_WATCHDOG_SHUTDOWN 15 +/// Before the watchdog detaches for a TGS update/restart. No parameters. #define TGS_EVENT_WATCHDOG_DETACH 16 -//OTHER ENUMS +// OTHER ENUMS +/// The server will reboot normally. #define TGS_REBOOT_MODE_NORMAL 0 +/// The server will stop running on reboot. #define TGS_REBOOT_MODE_SHUTDOWN 1 +/// The watchdog will restart on reboot. #define TGS_REBOOT_MODE_RESTART 2 +/// DreamDaemon Trusted security level. #define TGS_SECURITY_TRUSTED 0 +/// DreamDaemon Safe security level. #define TGS_SECURITY_SAFE 1 +/// DreamDaemon Ultrasafe security level. #define TGS_SECURITY_ULTRASAFE 2 //REQUIRED HOOKS -//Call this somewhere in /world/New() that is always run -//IMPORTANT: This function may sleep! -//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels -//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated +/** + * Call this somewhere in [/world/proc/New] that is always run. This function may sleep! + * + * * event_handler - Optional user defined [/datum/tgs_event_handler]. + * * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED]. + */ /world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) return -//Call this when your initializations are complete and your game is ready to play before any player interactions happen -//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running -//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this -//This function should not be called before ..() in /world/New() +/** + * Call this when your initializations are complete and your game is ready to play before any player interactions happen. + * + * This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running. + * Before this point, note that any static files or directories may be in use by another server. Your code should account for this. + * This function should not be called before ..() in [/world/proc/New]. + */ /world/proc/TgsInitializationComplete() return -//Put this at the start of /world/Topic() +/// Put this at the start of [/world/proc/Topic]. #define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return -//Call this at the beginning of world/Reboot(reason) +/** + * Call this at the beginning of [world/proc/Reboot]. + */ /world/proc/TgsReboot() return -//DATUM DEFINITIONS -//unless otherwise specified all datums defined here should be considered read-only, warranty void if written +// DATUM DEFINITIONS +// All datums defined here should be considered read-only -//represents git revision information about the current world build +/// Represents git revision information. /datum/tgs_revision_information - var/commit //full sha of compiled commit - var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch + /// Full SHA of the commit. + var/commit + /// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch. + var/origin_commit -//represents a version of tgstation-server +/// Represents a version. /datum/tgs_version - var/suite //The suite/major version, can be >=3 + /// The suite/major version number + var/suite - //this group of variables can be null to represent a wild card - var/minor //The minor version - var/patch //The patch version - var/deprecated_patch //The legacy version + // This group of variables can be null to represent a wild card + /// The minor version number. null for wildcards + var/minor + /// The patch version number. null for wildcards + var/patch - var/raw_parameter //The unparsed parameter - var/deprefixed_parameter //The version only bit of raw_parameter + /// Legacy version number. Generally null + var/deprecated_patch -//if the tgs_version is a wildcard version + /// Unparsed string value + var/raw_parameter + /// String value minus prefix + var/deprefixed_parameter + +/** + * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards. + */ /datum/tgs_version/proc/Wildcard() return -//if the tgs_version equals some other_version +/** + * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version. + * + * other_version - The [/datum/tgs_version] to compare against. + */ /datum/tgs_version/proc/Equals(datum/tgs_version/other_version) return -//represents a merge of a GitHub pull request +/// Represents a merge of a GitHub pull request. /datum/tgs_revision_information/test_merge - var/number //pull request number - var/title //pull request title - var/body //pull request body - var/author //pull request github author - var/url //link to pull request html - var/pull_request_commit //commit of the pull request when it was merged - var/time_merged //timestamp of when the merge commit for the pull request was created - var/comment //optional comment left by the one who initiated the test merge + /// The pull request number. + var/number + /// The pull request title when it was merged. + var/title + /// The pull request body when it was merged. + var/body + /// The GitHub username of the pull request's author. + var/author + /// An http URL to the pull request. + var/url + /// The SHA of the pull request when that was merged. + var/pull_request_commit + /// ISO 8601 timestamp of when the pull request was merged. + var/time_merged + /// (Nullable) Comment left by the TGS user who initiated the merge.. + var/comment -//represents a connected chat channel +/// Represents a connected chat channel. /datum/tgs_chat_channel - var/id //internal channel representation - var/friendly_name //user friendly channel name - var/connection_name //the name of the configured chat connection - var/is_admin_channel //if the server operator has marked this channel for game admins only - var/is_private_channel //if this is a private chat channel - var/custom_tag //user defined string associated with channel + /// TGS internal channel ID. + var/id + /// User friendly name of the channel. + var/friendly_name + /// Name of the chat connection. This is the IRC server address or the Discord guild. + var/connection_name + /// [TRUE]/[FALSE] based on if the server operator has marked this channel for game admins only. + var/is_admin_channel + /// [TRUE]/[FALSE] if the channel is a private message channel for a [/datum/tgs_chat_user]. + var/is_private_channel + /// Tag string associated with the channel in TGS + var/custom_tag -//represents a chat user +// Represents a chat user /datum/tgs_chat_user - var/id //Internal user representation, requires channel to be unique - var/friendly_name //The user's public name - var/mention //The text to use to ping this user in a message - var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from + /// TGS internal user ID. + var/id + // The user's display name. + var/friendly_name + // The string to use to ping this user in a message. + var/mention + /// The [/datum/tgs_chat_channel] the user was from + var/datum/tgs_chat_channel/channel -//user definable callback for handling events -//extra parameters may be specified depending on the event +/** + * User definable callback for handling TGS events. + * + * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each + */ /datum/tgs_event_handler/proc/HandleEvent(event_code, ...) set waitfor = FALSE return -//user definable chat command +/// User definable chat command /datum/tgs_chat_command - var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command - var/help_text = "" //help text for this command - var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins + /// The string to trigger this command on a chat bot. e.g `@bot name ...` or `!tgs name ...` + var/name = "" + /// The help text displayed for this command + var/help_text = "" + /// If this command should be available to game administrators only + var/admin_only = FALSE -//override to implement command -//sender: The tgs_chat_user who send to command -//params: The trimmed string following the command name -//The return value will be stringified and sent to the appropriate chat +/** + * Process command activation. Should return a string to respond to the issuer with. + * + * sender - The [/datum/tgs_chat_user] who issued the command. + * params - The trimmed string following the command `/datum/tgs_chat_command/var/name]. + */ /datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params) CRASH("[type] has no implementation for Run()") -//FUNCTIONS +// API FUNCTIONS -//Returns the respective supported /datum/tgs_version of the API +/// Returns the maximum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMaximumAPIVersion() return +/// Returns the minimum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMinimumAPIVersion() return -//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise -//No function below this succeeds if it returns FALSE or if TgsNew() has yet to be called +/** + * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise. + */ /world/proc/TgsAvailable() return -//Forces a hard reboot of BYOND by ending the process -//unlike del(world) clients will try to reconnect -//If the service has not requested a shutdown, the next server will take over +// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called. + +/** + * Forces a hard reboot of DreamDaemon by ending the process. + * + * Unlike del(world) clients will try to reconnect. + * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again + */ /world/proc/TgsEndProcess() return -//Send a message to non-admin connected chats -//message: The message to send -//admin_only: If TRUE, message will instead be sent to only admin connected chats -/world/proc/TgsTargetedChatBroadcast(message, admin_only) +/** + * Send a message to connected chats. + * + * message - The string to send. + * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. + */ +/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE) return -//Send a private message to a specific user -//message: The message to send -//user: The /datum/tgs_chat_user to send to +/** + * Send a private message to a specific user. + * + * message - The string to send. + * user: The [/datum/tgs_chat_user] to PM. + */ /world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) return -//The following functions will sleep if a call to TgsNew() is sleeping +// The following functions will sleep if a call to TgsNew() is sleeping -//Sends a message to connected game chats -//message: The message to send -//channels: optional channels to limit the broadcast to -/world/proc/TgsChatBroadcast(message, list/channels) +/** + * Send a message to connected chats that are flagged as game-related in TGS. + * + * message - The string to send. + * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. + */ +/world/proc/TgsChatBroadcast(message, list/channels = null) return -//Gets the current /datum/tgs_version of the server tools running the server +/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. /world/proc/TgsVersion() return -//Gets the current /datum/tgs_version of the DMAPI being used +/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. /world/proc/TgsApiVersion() return -//Gets the name of the TGS instance running the game +/// Returns the name of the TGS instance running the game if TGS is present, null otherwise. /world/proc/TgsInstanceName() return -//Get the current `/datum/tgs_revision_information` +/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. /world/proc/TgsRevision() return -//Get the current BYOND security level +/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. /world/proc/TgsSecurityLevel() return -//Gets a list of active `/datum/tgs_revision_information/test_merge`s +/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. /world/proc/TgsTestMerges() return -//Gets a list of connected tgs_chat_channel +/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. /world/proc/TgsChatChannelInfo() return diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index a63a59c75f..74470cf72e 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -135,6 +135,7 @@ #define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism" #define TRAIT_QUICK_CARRY "quick-carry" #define TRAIT_QUICKER_CARRY "quicker-carry" +#define TRAIT_QUICK_BUILD "quick-build" #define TRAIT_STRONG_GRABBER "strong_grabber" #define TRAIT_CALCIUM_HEALER "calcium_healer" #define TRAIT_MAGIC_CHOKE "magic_choke" @@ -147,6 +148,8 @@ #define TRAIT_NORUNNING "norunning" // You walk! #define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites. #define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat. +#define TRAIT_NOGUT "nogutting" //Your chest cant be gutted of organs +#define TRAIT_NODECAP "nodecapping" //Your head cant be cut off in combat #define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events" #define TRAIT_NO_MIDROUND_ANTAG "no-midround-antag" //can't be turned into an antag by random events #define TRAIT_PUGILIST "pugilist" //This guy punches people for a living @@ -179,6 +182,7 @@ #define TRAIT_PARA "paraplegic" #define TRAIT_EMPATH "empath" #define TRAIT_FRIENDLY "friendly" +#define TRAIT_SNOB "snob" #define TRAIT_CULT_EYES "cult_eyes" #define TRAIT_AUTO_CATCH_ITEM "auto_catch_item" #define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman. diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 5e0ac99bae..48f54fd60f 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -154,8 +154,8 @@ /proc/log_subsystem(subsystem, text) WRITE_LOG(GLOB.subsystem_log, "[subsystem]: [text]") -/proc/log_click(object, location, control, params, client/C, event = "clicked") - WRITE_LOG(GLOB.click_log, "CLICK: [C.ckey] - [event] : [object] | [location] | [control] | [params]") +/proc/log_click(atom/object, atom/location, control, params, client/C, event = "clicked", unexpected) + WRITE_LOG(GLOB.click_log, "[unexpected? "ERROR" :"CLICK"]: [C.ckey] - [event] : [istype(object)? "[object] ([COORD(object)])" : object] | [istype(location)? "[location] ([COORD(location)])" : location] | [control] | [params]") /* Log to both DD and the logfile. */ /proc/log_world(text) diff --git a/code/__HELPERS/angles.dm b/code/__HELPERS/angles.dm new file mode 100644 index 0000000000..a3fc2404bd --- /dev/null +++ b/code/__HELPERS/angles.dm @@ -0,0 +1,39 @@ +/proc/get_projectile_angle(atom/source, atom/target) + var/sx = source.x * world.icon_size + var/sy = source.y * world.icon_size + var/tx = target.x * world.icon_size + var/ty = target.y * world.icon_size + var/atom/movable/AM + if(ismovable(source)) + AM = source + sx += AM.step_x + sy += AM.step_y + if(ismovable(target)) + AM = target + tx += AM.step_x + ty += AM.step_y + return SIMPLIFY_DEGREES(arctan(ty - sy, tx - sx)) + +/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams. + if(!start || !end) + return 0 + var/dy + var/dx + dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y) + dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x) + if(!dy) + return (dx>=0)?90:270 + .=arctan(dx/dy) + if(dy<0) + .+=180 + else if(dx<0) + .+=360 + +/proc/Get_Pixel_Angle(var/y, var/x)//for getting the angle when animating something's pixel_x and pixel_y + if(!y) + return (x>=0)?90:270 + .=arctan(x/y) + if(y<0) + .+=180 + else if(x<0) + .+=360 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index d6195b1dc6..508b737474 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -15,30 +15,8 @@ var/textb = copytext(HTMLstring, 6, 8) return rgb(255 - hex2num(textr), 255 - hex2num(textg), 255 - hex2num(textb)) -/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams. - if(!start || !end) - return 0 - var/dy - var/dx - dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y) - dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x) - if(!dy) - return (dx>=0)?90:270 - .=arctan(dx/dy) - if(dy<0) - .+=180 - else if(dx<0) - .+=360 - -/proc/Get_Pixel_Angle(var/y, var/x)//for getting the angle when animating something's pixel_x and pixel_y - if(!y) - return (x>=0)?90:270 - .=arctan(x/y) - if(y<0) - .+=180 - else if(x<0) - .+=360 - +//Better performant than an artisanal proc and more reliable than Turn(). From TGMC. +#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) //Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) /* diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 1aab96f85e..e038596151 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -242,15 +242,14 @@ GLOBAL_LIST_INIT(bitfields, list( "MOBILITY_RESIST" = MOBILITY_RESIST ), "combat_flags" = list( - "COMBAT_FLAG_COMBAT_TOGGLED" = COMBAT_FLAG_COMBAT_TOGGLED, "COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED, - "COMBAT_FLAG_COMBAT_ACTIVE" = COMBAT_FLAG_COMBAT_ACTIVE, "COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE, "COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL, "COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT, "COMBAT_FLAG_SOFT_STAMCRIT" = COMBAT_FLAG_SOFT_STAMCRIT, "COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING, - "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST + "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST, + "COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED ), "shield_flags" = list( "SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT, diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 632904202d..30321f5546 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/effect/spawner/lootdrop/welder_tools = 3, /obj/effect/spawner/lootdrop/low_tools = 5, /obj/item/relic = 3, - /obj/item/weaponcrafting/receiver = 2, + /obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 2, /obj/item/clothing/head/cone = 2, /obj/item/grenade/smokebomb = 2, /obj/item/geiger_counter = 3, diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index 9638b040f9..8e2e0c3fb5 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -24,16 +24,6 @@ return -/client - var/list/atom/selected_target[2] - var/obj/item/active_mousedown_item = null - var/mouseParams = "" - var/mouseLocation = null - var/mouseObject = null - var/mouseControlObject = null - var/middragtime = 0 - var/atom/middragatom - /client/MouseDown(object, location, control, params) if (mouse_down_icon) mouse_pointer_icon = mouse_down_icon @@ -84,12 +74,6 @@ /obj/item/proc/onMouseUp(object, location, params, mob) return -/obj/item - var/canMouseDown = FALSE - -/obj/item/gun - var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds - /obj/item/gun/CanItemAutoclick(object, location, params) . = automatic @@ -108,16 +92,10 @@ mouseLocation = location mouseObject = object mouseControlObject = control - if(mob && LAZYLEN(mob.mousemove_intercept_objects)) - for(var/datum/D in mob.mousemove_intercept_objects) - D.onMouseMove(object, location, control, params) - if(!show_popup_menus && mob) //CIT CHANGE - passes onmousemove() to mobs - mob.onMouseMove(object, location, control, params) //CIT CHANGE - ditto + if(mob) + SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOUSEMOVE, object, location, control, params) ..() -/datum/proc/onMouseMove(object, location, control, params) - return - /client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) var/list/L = params2list(params) if (L["middle"]) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 7c116cc606..3cedd92255 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -642,9 +642,6 @@ so as to remain in compliance with the most up-to-date laws." mymob.client.screen |= alert return 1 -/mob - var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly - /obj/screen/alert/Click(location, control, params) if(!usr || !usr.client) return diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 3cfa71e19d..d82f3e7cf5 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -1,7 +1,3 @@ - -/mob - var/list/screens = list() - /mob/proc/overlay_fullscreen(category, type, severity) var/obj/screen/fullscreen/screen = screens[category] if (!screen || screen.type != type) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index f054cb0c8e..57335a966e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -114,8 +114,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( return ..() -/mob - var/hud_type = /datum/hud /mob/proc/create_mob_hud() if(!client || hud_used) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 328e008f10..9380cf98aa 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -241,18 +241,11 @@ using.hud = src hotkeybuttons += using - //CIT CHANGES - rest and combat mode buttons - using = new /obj/screen/restbutton() - using.icon = tg_ui_icon_to_cit_ui(ui_style) + using = new /obj/screen/rest() + using.icon = ui_style using.screen_loc = ui_pull_resist using.hud = src static_inventory += using - - using = new /obj/screen/combattoggle() - using.icon = tg_ui_icon_to_cit_ui(ui_style) - using.screen_loc = ui_combat_toggle - using.hud = src - static_inventory += using //END OF CIT CHANGES using = new /obj/screen/human/toggle() diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 25a49c8d6b..d8ef1c525a 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -1,16 +1,4 @@ -/client - var/list/parallax_layers - var/list/parallax_layers_cached - var/atom/movable/movingmob - var/turf/previous_turf - var/dont_animate_parallax //world.time of when we can state animate()ing parallax again - var/last_parallax_shift //world.time of last update - var/parallax_throttle = 0 //ds between updates - var/parallax_movedir = 0 - var/parallax_layers_max = 3 - var/parallax_animate_timer - /datum/hud/proc/create_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 3ad0219391..e2c160503c 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -113,7 +113,7 @@ /obj/attacked_by(obj/item/I, mob/living/user) var/totitemdamage = I.force var/bad_trait - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user)) + if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) totitemdamage *= 0.5 bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. if(I.used_skills && user.mind) @@ -155,9 +155,11 @@ /mob/living/proc/pre_attacked_by(obj/item/I, mob/living/user) . = I.force var/bad_trait - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user)) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) . *= 0.5 bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. + if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) + . *= 1.5 if(!CHECK_MOBILITY(user, MOBILITY_STAND)) . *= 0.5 if(!user.mind || !I.used_skills) @@ -169,10 +171,6 @@ continue user.mind.auto_gain_experience(skill, I.skill_gain) -/mob/living/carbon/pre_attacked_by(obj/item/I, mob/living/user) - . = ..() - if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - . *= 1.5 // Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. // Click parameters is the params string from byond Click() code, see that documentation. @@ -212,7 +210,7 @@ if(!user) return var/bad_trait - if(iscarbon(user) && !(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) . *= STAM_COST_NO_COMBAT_MULT bad_trait = SKILL_COMBAT_MODE if(used_skills && user.mind) diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index cc07f8e963..96d733e8da 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -11,7 +11,11 @@ SUBSYSTEM_DEF(materials) ///Dictionary of category || list of material refs var/list/materials_by_category ///List of stackcrafting recipes for materials using rigid materials - var/list/rigid_stack_recipes = list(new/datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE)) + var/list/rigid_stack_recipes = list( + new /datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE), + new /datum/stack_recipe("toilet", /obj/structure/toilet/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE), + new /datum/stack_recipe("sink", /obj/structure/sink/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE), + ) ///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info) /datum/controller/subsystem/materials/proc/InitializeMaterials() diff --git a/code/controllers/subsystem/processing/projectiles.dm b/code/controllers/subsystem/processing/projectiles.dm index 8cd63c6949..b8d904c727 100644 --- a/code/controllers/subsystem/processing/projectiles.dm +++ b/code/controllers/subsystem/processing/projectiles.dm @@ -1,21 +1,22 @@ PROCESSING_SUBSYSTEM_DEF(projectiles) name = "Projectiles" + priority = FIRE_PRIORITY_PROJECTILES wait = 1 stat_tag = "PP" flags = SS_NO_INIT|SS_TICKER - var/global_pixel_speed = 2 - var/global_iterations_per_move = 16 + var/global_pixel_increment_amount = 4 + var/global_projectile_speed_multiplier = 1 /datum/controller/subsystem/processing/projectiles/proc/set_pixel_speed(new_speed) - global_pixel_speed = new_speed + global_pixel_increment_amount = new_speed for(var/i in processing) var/obj/item/projectile/P = i if(istype(P)) //there's non projectiles on this too. - P.set_pixel_speed(new_speed) + P.set_pixel_increment_amount(new_speed) /datum/controller/subsystem/processing/projectiles/vv_edit_var(var_name, var_value) switch(var_name) - if(NAMEOF(src, global_pixel_speed)) + if(NAMEOF(src, global_pixel_increment_amount)) set_pixel_speed(var_value) return TRUE else diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index f158574763..d816e37ddf 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -24,6 +24,7 @@ SUBSYSTEM_DEF(research) var/list/techweb_categories = list() //category name = list(node.id = TRUE) var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount)) var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default. + var/list/techweb_nodes_experimental = list() //Node ids that are exclusive to the BEPIS. var/list/techweb_point_items = list( //path = list(point type = value) /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000), @@ -508,6 +509,8 @@ SUBSYSTEM_DEF(research) D.unlocked_by += node.id if(node.hidden) techweb_nodes_hidden[node.id] = TRUE + if(node.experimental) + techweb_nodes_experimental[node.id] = TRUE CHECK_TICK generate_techweb_unlock_linking() diff --git a/code/datums/action.dm b/code/datums/action.dm index 00e7e0ad5d..0033df09d7 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -731,14 +731,6 @@ if(next_use_time > world.time) START_PROCESSING(SSfastprocess, src) - -//Stickmemes -/datum/action/item_action/stickmen - name = "Summon Stick Minions" - desc = "Allows you to summon faithful stickmen allies to aide you in battle." - icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' - button_icon_state = "art_summon" - //surf_ss13 /datum/action/item_action/bhop name = "Activate Jump Boots" diff --git a/code/datums/brain_damage/hypnosis.dm b/code/datums/brain_damage/hypnosis.dm index 37aee6df7e..f4c4541db9 100644 --- a/code/datums/brain_damage/hypnosis.dm +++ b/code/datums/brain_damage/hypnosis.dm @@ -63,7 +63,7 @@ if(prob(2)) switch(rand(1,2)) if(1) - to_chat(owner, "...[lowertext(hypnotic_phrase)]...") + to_chat(owner, "...[lowertext(hypnotic_phrase)]...") if(2) new /datum/hallucination/chat(owner, TRUE, FALSE, "[hypnotic_phrase]") diff --git a/code/datums/brain_damage/magic.dm b/code/datums/brain_damage/magic.dm new file mode 100644 index 0000000000..249907a1b8 --- /dev/null +++ b/code/datums/brain_damage/magic.dm @@ -0,0 +1,60 @@ +//Magical traumas, caused by spells and curses. +//Blurs the line between the victim's imagination and reality +//Unlike regular traumas this can affect the victim's body and surroundings + +/datum/brain_trauma/magic + resilience = TRAUMA_RESILIENCE_LOBOTOMY + +/datum/brain_trauma/magic/stalker + name = "Stalking Phantom" + desc = "Patient is stalked by a phantom only they can see." + scan_desc = "extra-sensory paranoia" + gain_text = "You feel like something wants to kill you..." + lose_text = "You no longer feel eyes on your back." + var/obj/effect/hallucination/simple/stalker_phantom/stalker + var/close_stalker = FALSE //For heartbeat + +/datum/brain_trauma/magic/stalker/on_gain() + create_stalker() + ..() + +/datum/brain_trauma/magic/stalker/proc/create_stalker() + var/turf/stalker_source = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z) //random corner + stalker = new(stalker_source, owner) + +/datum/brain_trauma/magic/stalker/on_lose() + QDEL_NULL(stalker) + ..() + +/datum/brain_trauma/magic/stalker/on_life() + // Dead and unconscious people are not interesting to the psychic stalker. + if(owner.stat != CONSCIOUS) + return + + // Not even nullspace will keep it at bay. + if(!stalker || !stalker.loc || stalker.z != owner.z) + qdel(stalker) + create_stalker() + + if(get_dist(owner, stalker) <= 1) + playsound(owner, 'sound/magic/demon_attack1.ogg', 50) + owner.visible_message("[owner] is torn apart by invisible claws!", "Ghostly claws tear your body apart!") + owner.take_bodypart_damage(rand(20, 45)) + else if(prob(50)) + stalker.forceMove(get_step_towards(stalker, owner)) + if(get_dist(owner, stalker) <= 8) + if(!close_stalker) + var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE) + owner.playsound_local(owner, slowbeat, 40, 0, channel = CHANNEL_HEARTBEAT) + close_stalker = TRUE + else + if(close_stalker) + owner.stop_sound_channel(CHANNEL_HEARTBEAT) + close_stalker = FALSE + ..() + +/obj/effect/hallucination/simple/stalker_phantom + name = "???" + desc = "It's coming closer..." + image_icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + image_state = "curseblob" diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index e076c30ae1..bb37129b95 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -265,3 +265,37 @@ ..() if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance)) owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE) + +/datum/brain_trauma/severe/hypnotic_trigger + name = "Hypnotic Trigger" + desc = "Patient has a trigger phrase set in their subconscious that will trigger a suggestible trance-like state." + scan_desc = "oneiric feedback loop" + gain_text = "You feel odd, like you just forgot something important." + lose_text = "You feel like a weight was lifted from your mind." + random_gain = FALSE + var/trigger_phrase = "Nanotrasen" + +/datum/brain_trauma/severe/hypnotic_trigger/New(phrase) + ..() + if(phrase) + trigger_phrase = phrase + +/datum/brain_trauma/severe/hypnotic_trigger/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway + ..() + owner.remove_status_effect(/datum/status_effect/trance) + +/datum/brain_trauma/severe/hypnotic_trigger/handle_hearing(datum/source, list/hearing_args) + if(!owner.can_hear()) + return + if(owner == hearing_args[HEARING_SPEAKER]) + return + + var/regex/reg = new("(\\b[REGEX_QUOTE(trigger_phrase)]\\b)","ig") + + if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg)) + addtimer(CALLBACK(src, .proc/hypnotrigger), 10) //to react AFTER the chat message + hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "*********") + +/datum/brain_trauma/severe/hypnotic_trigger/proc/hypnotrigger() + to_chat(owner, "The words trigger something deep within you, and you feel your consciousness slipping away...") + owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE) diff --git a/code/datums/components/art.dm b/code/datums/components/art.dm deleted file mode 100644 index f6d3cb6c61..0000000000 --- a/code/datums/components/art.dm +++ /dev/null @@ -1,56 +0,0 @@ - -#define BAD_ART 12.5 -#define GOOD_ART 25 -#define GREAT_ART 50 - -/datum/component/art - var/impressiveness = 0 - -/datum/component/art/Initialize(impress) - impressiveness = impress - if(isobj(parent)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine) - else - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_other_examine) - if(isstructure(parent)) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet) - -/datum/component/art/proc/apply_moodlet(mob/M, impress) - M.visible_message("[M] stops and looks intently at [parent].", \ - "You stop to take in [parent].") - switch(impress) - if (0 to BAD_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) - if (BAD_ART to GOOD_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) - if (GOOD_ART to GREAT_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) - if(GREAT_ART to INFINITY) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) - - -/datum/component/art/proc/on_other_examine(datum/source, mob/M) - apply_moodlet(M, impressiveness) - -/datum/component/art/proc/on_obj_examine(datum/source, mob/M) - var/obj/O = parent - apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity)) - -/datum/component/art/proc/on_attack_hand(datum/source, mob/M) - to_chat(M, "You start examining [parent]...") - if(!do_after(M, 20, target = parent)) - return - on_obj_examine(source, M) - -/datum/component/art/rev - -/datum/component/art/rev/apply_moodlet(mob/M, impress) - M.visible_message("[M] stops to inspect [parent].", \ - "You take in [parent], inspecting the fine craftsmanship of the proletariat.") - - if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) - else - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) diff --git a/code/datums/components/combat_mode.dm b/code/datums/components/combat_mode.dm new file mode 100644 index 0000000000..b53d407162 --- /dev/null +++ b/code/datums/components/combat_mode.dm @@ -0,0 +1,217 @@ +/** + * Combat mode component. It makes the user face whichever atom the mouse pointer is hovering, + * amongst other things designed outside of this file, namely PvP and PvE stuff, hence the name. + * Can be toggled on and off by clicking the screen hud object or by pressing the assigned hotkey (default 'C') + */ +/datum/component/combat_mode + var/mode_flags = COMBAT_MODE_INACTIVE + var/combatmessagecooldown + var/lastmousedir + var/obj/screen/combattoggle/hud_icon + var/hud_loc + +/datum/component/combat_mode/Initialize(hud_loc = ui_combat_toggle) + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + var/mob/living/L = parent + + src.hud_loc = hud_loc + + RegisterSignal(L, SIGNAL_TRAIT(TRAIT_COMBAT_MODE_LOCKED), .proc/update_combat_lock) + RegisterSignal(L, COMSIG_TOGGLE_COMBAT_MODE, .proc/user_toggle_intentional_combat_mode) + RegisterSignal(L, COMSIG_DISABLE_COMBAT_MODE, .proc/safe_disable_combat_mode) + RegisterSignal(L, COMSIG_ENABLE_COMBAT_MODE, .proc/safe_enable_combat_mode) + RegisterSignal(L, COMSIG_MOB_DEATH, .proc/on_death) + RegisterSignal(L, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout) + RegisterSignal(L, COMSIG_MOB_HUD_CREATED, .proc/on_mob_hud_created) + RegisterSignal(L, COMSIG_COMBAT_MODE_CHECK, .proc/check_flags) + + update_combat_lock() + + if(L.client) + on_mob_hud_created(L) + +/datum/component/combat_mode/Destroy() + if(parent) + safe_disable_combat_mode(parent) + if(hud_icon) + QDEL_NULL(hud_icon) + return ..() + +/// Creates the hud screen object. +/datum/component/combat_mode/proc/on_mob_hud_created(mob/source) + hud_icon = new + hud_icon.hud = source.hud_used + hud_icon.icon = tg_ui_icon_to_cit_ui(source.hud_used.ui_style) + hud_icon.screen_loc = hud_loc + source.hud_used.static_inventory += hud_icon + hud_icon.update_icon() + +/// Combat mode can be locked out, forcibly disabled by a status trait. +/datum/component/combat_mode/proc/update_combat_lock() + var/locked = HAS_TRAIT(parent, TRAIT_COMBAT_MODE_LOCKED) + var/desired = (mode_flags & COMBAT_MODE_TOGGLED) + var/actual = (mode_flags & COMBAT_MODE_ACTIVE) + if(actual) + if(locked) + disable_combat_mode(parent, FALSE, TRUE) + else if(!desired) + disable_combat_mode(parent, TRUE, TRUE) + else + if(desired && !locked) + enable_combat_mode(parent, FALSE, TRUE) + +/// Enables combat mode. Please use 'safe_enable_combat_mode' instead, if you wish to also enable the toggle flag. +/datum/component/combat_mode/proc/enable_combat_mode(mob/living/source, silent = TRUE, forced = TRUE, visible = FALSE, locked = FALSE, playsound = FALSE) + if(locked) + if(hud_icon) + hud_icon.combat_on = TRUE + hud_icon.update_icon() + return + if(mode_flags & COMBAT_MODE_ACTIVE) + return + mode_flags |= COMBAT_MODE_ACTIVE + mode_flags &= ~COMBAT_MODE_INACTIVE + SEND_SIGNAL(source, COMSIG_LIVING_COMBAT_ENABLED, forced) + if(!silent) + var/self_message = forced? "Your muscles reflexively tighten!" : "You drop into a combative stance!" + if(visible && (forced || world.time >= combatmessagecooldown)) + combatmessagecooldown = world.time + 10 SECONDS + if(!forced) + if(source.a_intent != INTENT_HELP) + source.visible_message("[source] [source.resting ? "tenses up" : "drops into a combative stance"].", self_message) + else + source.visible_message("[source] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].") + else + source.visible_message("[source] drops into a combative stance!", self_message) + else + to_chat(source, self_message) + if(playsound) + source.playsound_local(source, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay! + RegisterSignal(source, COMSIG_MOB_CLIENT_MOUSEMOVE, .proc/onMouseMove) + RegisterSignal(source, COMSIG_MOVABLE_MOVED, .proc/on_move) + RegisterSignal(source, COMSIG_MOB_CLIENT_MOVE, .proc/on_client_move) + if(hud_icon) + hud_icon.combat_on = TRUE + hud_icon.update_icon() + +/// Disables combat mode. Please use 'safe_disable_combat_mode' instead, if you wish to also disable the toggle flag. +/datum/component/combat_mode/proc/disable_combat_mode(mob/living/source, silent = TRUE, forced = TRUE, visible = FALSE, locked = FALSE, playsound = FALSE) + if(locked) + if(hud_icon) + hud_icon.combat_on = FALSE + hud_icon.update_icon() + return + if(!(mode_flags & COMBAT_MODE_ACTIVE)) + return + mode_flags &= ~COMBAT_MODE_ACTIVE + mode_flags |= COMBAT_MODE_INACTIVE + SEND_SIGNAL(source, COMSIG_LIVING_COMBAT_DISABLED, forced) + if(!silent) + var/self_message = forced? "Your muscles are forcibly relaxed!" : "You relax your stance." + if(visible) + source.visible_message("[source] relaxes [source.p_their()] stance.", self_message) + else + to_chat(source, self_message) + if(playsound) + source.playsound_local(source, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the toggleon sound! + UnregisterSignal(source, list(COMSIG_MOB_CLIENT_MOUSEMOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE)) + if(hud_icon) + hud_icon.combat_on = FALSE + hud_icon.update_icon() + +///Changes the user direction to (try) keep match the pointer. +/datum/component/combat_mode/proc/on_move(atom/movable/source, dir, atom/oldloc, forced) + var/mob/living/L = source + if(mode_flags & COMBAT_MODE_ACTIVE && L.client && lastmousedir && lastmousedir != dir) + L.setDir(lastmousedir, ismousemovement = TRUE) + +/// Added movement delay if moving backward. +/datum/component/combat_mode/proc/on_client_move(mob/source, client/client, direction, n, oldloc, added_delay) + if(oldloc != n && direction == REVERSE_DIR(source.dir)) + client.move_delay += added_delay*0.5 + +///Changes the user direction to (try) match the pointer. +/datum/component/combat_mode/proc/onMouseMove(mob/source, object, location, control, params) + if(source.client.show_popup_menus) + return + source.face_atom(object, TRUE) + lastmousedir = source.dir + +/// Toggles whether the user is intentionally in combat mode. THIS should be the proc you generally use! Has built in visual/to other player feedback, as well as an audible cue to ourselves. +/datum/component/combat_mode/proc/user_toggle_intentional_combat_mode(mob/living/source) + if(mode_flags & COMBAT_MODE_TOGGLED) + safe_disable_combat_mode(source) + else if(source.stat == CONSCIOUS && !(source.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) + safe_enable_combat_mode(source) + +/// Enables intentionally being in combat mode. Please try to use the COMSIG_COMBAT_MODE_CHECK signal for feedback when possible. +/datum/component/combat_mode/proc/safe_enable_combat_mode(mob/living/source, silent = FALSE, visible = TRUE) + if((mode_flags & COMBAT_MODE_TOGGLED) && (mode_flags & COMBAT_MODE_ACTIVE)) + return TRUE + mode_flags |= COMBAT_MODE_TOGGLED + enable_combat_mode(source, silent, FALSE, visible, HAS_TRAIT(source, TRAIT_COMBAT_MODE_LOCKED), TRUE) + if(source.client) + source.client.show_popup_menus = FALSE + if(iscarbon(source)) //I dislike this typecheck. It probably should be removed once that spoiled apple is componentized too. + var/mob/living/carbon/C = source + if(C.voremode) + C.disable_vore_mode() + return TRUE + +/// Disables intentionally being in combat mode. Please try to use the COMSIG_COMBAT_MODE_CHECK signal for feedback when possible. +/datum/component/combat_mode/proc/safe_disable_combat_mode(mob/living/source, silent = FALSE, visible = FALSE) + if(!(mode_flags & COMBAT_MODE_TOGGLED) && !(mode_flags & COMBAT_MODE_ACTIVE)) + return TRUE + mode_flags &= ~COMBAT_MODE_TOGGLED + disable_combat_mode(source, silent, FALSE, visible, !(mode_flags & COMBAT_MODE_ACTIVE), TRUE) + if(source.client) + source.client.show_popup_menus = TRUE + return TRUE + +/// Returns a field of flags that are contained in both the second arg and our bitfield variable. +/datum/component/combat_mode/proc/check_flags(mob/living/source, flags) + return mode_flags & (flags) + +/// Disables combat mode upon death. +/datum/component/combat_mode/proc/on_death(mob/living/source) + safe_disable_combat_mode(source) + +/// Disables combat mode upon logout +/datum/component/combat_mode/proc/on_logout(mob/living/source) + safe_disable_combat_mode(source) + +/// The screen button. +/obj/screen/combattoggle + name = "toggle combat mode" + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + icon_state = "combat_off" + var/mutable_appearance/flashy + var/combat_on = FALSE ///Wheter combat mode is enabled or not, so we don't have to store a reference. + +/obj/screen/combattoggle/Click() + if(hud && usr == hud.mymob) + SEND_SIGNAL(hud.mymob, COMSIG_TOGGLE_COMBAT_MODE) + +/obj/screen/combattoggle/update_icon_state() + var/mob/living/user = hud?.mymob + if(!user) + return + if(combat_on) + icon_state = "combat" + else if(HAS_TRAIT(user, TRAIT_COMBAT_MODE_LOCKED)) + icon_state = "combat_locked" + else + icon_state = "combat_off" + +/obj/screen/combattoggle/update_overlays() + . = ..() + var/mob/living/carbon/user = hud?.mymob + if(!(user?.client)) + return + + if(combat_on) + if(!flashy) + flashy = mutable_appearance('icons/mob/screen_gen.dmi', "togglefull_flash") + flashy.color = user.client.prefs.hud_toggle_color + . += flashy //TODO - beg lummox jr for the ability to force mutable appearances or images to be created rendering from their first frame of animation rather than being based entirely around the client's frame count diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm index e06583ab61..f332d53fc8 100644 --- a/code/datums/components/crafting/guncrafting.dm +++ b/code/datums/components/crafting/guncrafting.dm @@ -1,20 +1,64 @@ -//Gun crafting parts til they can be moved elsewhere - -// PARTS // +k// PARTS // /obj/item/weaponcrafting icon = 'icons/obj/improvised.dmi' -/obj/item/weaponcrafting/receiver - name = "modular receiver" - desc = "A prototype modular receiver and trigger assembly for a firearm." - icon_state = "receiver" - /obj/item/weaponcrafting/stock name = "rifle stock" desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 6) icon_state = "riflestock" /obj/item/weaponcrafting/durathread_string name = "durathread string" desc = "A long piece of durathread with some resemblance to cable coil." icon_state = "durastring" + +//////////////////////////////// +// KAT IMPROVISED WEAPON PARTS// +//////////////////////////////// + +/obj/item/weaponcrafting/improvised_parts + name = "Eerie bunch of coloured dots." + desc = "You feel the urge to report to Central that the parent type of guncrafting, which should never appear in this reality, has appeared. Whatever that means." + icon = 'icons/obj/guns/gun_parts.dmi' + icon_state = "palette" + +// BARRELS + +/obj/item/weaponcrafting/improvised_parts/barrel_rifle + name = "rifle barrel" + desc = "A pipe with a diameter just the right size to fire 7.62 rounds out of." + icon_state = "barrel_rifle" + +/obj/item/weaponcrafting/improvised_parts/barrel_shotgun + name = "shotgun barrel" + desc = "A twenty bore shotgun barrel." + icon_state = "barrel_shotgun" + +// RECEIVERS + +/obj/item/weaponcrafting/improvised_parts/rifle_receiver + name = "bolt action receiver" + desc = "A crudely constructed receiver to create an improvised bolt-action breechloaded rifle." + icon_state = "receiver_rifle" + w_class = WEIGHT_CLASS_SMALL + +/obj/item/weaponcrafting/improvised_parts/shotgun_receiver + name = "break-action assembly" + desc = "An improvised receiver to create a break-action breechloaded shotgun." + icon_state = "receiver_shotgun" + w_class = WEIGHT_CLASS_SMALL + +// MISC + +/obj/item/weaponcrafting/improvised_parts/trigger_assembly + name = "firearm trigger assembly" + desc = "A modular trigger assembly with a firing pin, this can be used to make a whole bunch of improvised firearss." + icon_state = "trigger_assembly" + w_class = WEIGHT_CLASS_SMALL + +/obj/item/weaponcrafting/improvised_parts/wooden_body + name = "wooden firearm body" + desc = "A crudely fashioned wooden body to help keep higher calibre improvised weapons from blowing themselves apart." + icon_state = "wooden_body" + diff --git a/code/datums/components/crafting/recipes/recipes_primal.dm b/code/datums/components/crafting/recipes/recipes_primal.dm index a053a537ca..e646d24018 100644 --- a/code/datums/components/crafting/recipes/recipes_primal.dm +++ b/code/datums/components/crafting/recipes/recipes_primal.dm @@ -116,4 +116,41 @@ always_availible = FALSE reqs = list(/obj/item/stack/rods = 1, /obj/item/stack/sheet/mineral/sandstone = 4) - category = CAT_PRIMAL \ No newline at end of file + category = CAT_PRIMAL + +/datum/crafting_recipe/rib + name = "Collosal Rib" + always_availible = FALSE + reqs = list( + /obj/item/stack/sheet/bone = 10, + /datum/reagent/oil = 5) + result = /obj/structure/statue/bone/rib + subcategory = CAT_PRIMAL + +/datum/crafting_recipe/skull + name = "Skull Carving" + always_availible = FALSE + reqs = list( + /obj/item/stack/sheet/bone = 6, + /datum/reagent/oil = 5) + result = /obj/structure/statue/bone/skull + category = CAT_PRIMAL + +/datum/crafting_recipe/halfskull + name = "Cracked Skull Carving" + always_availible = FALSE + reqs = list( + /obj/item/stack/sheet/bone = 3, + /datum/reagent/oil = 5) + result = /obj/structure/statue/bone/skull/half + category = CAT_PRIMAL + +/datum/crafting_recipe/boneshovel + name = "Serrated Bone Shovel" + always_availible = FALSE + reqs = list( + /obj/item/stack/sheet/bone = 4, + /datum/reagent/oil = 5, + /obj/item/shovel/spade = 1) + result = /obj/item/shovel/serrated + category = CAT_PRIMAL diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm index 206895178a..a10d02f962 100644 --- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm +++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm @@ -251,8 +251,10 @@ /datum/crafting_recipe/ishotgun name = "Improvised Shotgun" result = /obj/item/gun/ballistic/revolver/doublebarrel/improvised - reqs = list(/obj/item/weaponcrafting/receiver = 1, - /obj/item/pipe = 1, + reqs = list(/obj/item/weaponcrafting/improvised_parts/barrel_shotgun = 1, + /obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 1, + /obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1, + /obj/item/weaponcrafting/improvised_parts/wooden_body = 1, /obj/item/weaponcrafting/stock = 1, /obj/item/stack/packageWrap = 5) tools = list(TOOL_SCREWDRIVER) @@ -261,10 +263,12 @@ subcategory = CAT_WEAPON /datum/crafting_recipe/irifle - name = "Improvised Rifle(7.62mm)" + name = "Improvised Rifle (7.62mm)" result = /obj/item/gun/ballistic/shotgun/boltaction/improvised - reqs = list(/obj/item/weaponcrafting/receiver = 1, - /obj/item/pipe = 2, + reqs = list(/obj/item/weaponcrafting/improvised_parts/barrel_rifle = 1, + /obj/item/weaponcrafting/improvised_parts/rifle_receiver = 1, + /obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1, + /obj/item/weaponcrafting/improvised_parts/wooden_body = 1, /obj/item/weaponcrafting/stock = 1, /obj/item/stack/packageWrap = 5) tools = list(TOOL_SCREWDRIVER) @@ -394,3 +398,60 @@ time = 5 category = CAT_WEAPONRY subcategory = CAT_AMMO + +//////////////////// +// PARTS CRAFTING // +//////////////////// + +// BARRELS + +/datum/crafting_recipe/rifle_barrel + name = "Improvised Rifle Barrel" + result = /obj/item/weaponcrafting/improvised_parts/barrel_rifle + reqs = list(/obj/item/pipe = 2) + tools = list(TOOL_WELDER,TOOL_SAW) + time = 150 + category = CAT_WEAPONRY + subcategory = CAT_PARTS + +/datum/crafting_recipe/shotgun_barrel + name = "Improvised Shotgun Barrel" + result = /obj/item/weaponcrafting/improvised_parts/barrel_shotgun + reqs = list(/obj/item/pipe = 2) + tools = list(TOOL_WELDER,TOOL_SAW) + time = 150 + category = CAT_WEAPONRY + subcategory = CAT_PARTS + +// RECEIVERS + +/datum/crafting_recipe/rifle_receiver + name = "Improvised Rifle Receiver" + result = /obj/item/weaponcrafting/improvised_parts/rifle_receiver + reqs = list(/obj/item/stack/sheet/metal = 20) + tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) // Rifle is the easiest to craft and can be made at an autolathe, this is a very light kick in the shin for dual-wielding ishotguns. + time = 50 + category = CAT_WEAPONRY + subcategory = CAT_PARTS + +/datum/crafting_recipe/shotgun_receiver + name = "Improvised Shotgun Receiver" + result = /obj/item/weaponcrafting/improvised_parts/shotgun_receiver + reqs = list(/obj/item/stack/sheet/metal = 10, + /obj/item/stack/sheet/plasteel = 1) + tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) // Increased cost is to stop dual-wield alpha striking. ishotgun is a rvolver and can be duel-wielded + time = 50 + category = CAT_WEAPONRY + subcategory = CAT_PARTS + +// MISC + +/datum/crafting_recipe/trigger_assembly + name = "Trigger Assembly" + result = /obj/item/weaponcrafting/improvised_parts/trigger_assembly + reqs = list(/obj/item/stack/sheet/metal = 3, + /obj/item/assembly/igniter = 1) + tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) + time = 150 + category = CAT_WEAPONRY + subcategory = CAT_PARTS diff --git a/code/datums/components/empprotection.dm b/code/datums/components/empprotection.dm deleted file mode 100644 index c85cdf31c7..0000000000 --- a/code/datums/components/empprotection.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/component/empprotection - var/flags = NONE - -/datum/component/empprotection/Initialize(_flags) - if(!istype(parent, /atom)) - return COMPONENT_INCOMPATIBLE - flags = _flags - RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags) - -/datum/component/empprotection/proc/getEmpFlags(datum/source, severity) - return flags diff --git a/code/datums/components/fantasy/_fantasy.dm b/code/datums/components/fantasy/_fantasy.dm index a203264fae..8441f962f9 100644 --- a/code/datums/components/fantasy/_fantasy.dm +++ b/code/datums/components/fantasy/_fantasy.dm @@ -9,6 +9,7 @@ var/originalName var/list/affixes var/list/appliedComponents + var/list/appliedElements var/static/list/affixListing @@ -22,6 +23,7 @@ src.affixes = affixes appliedComponents = list() + appliedElements = list() randomAffixes() /datum/component/fantasy/Destroy() @@ -118,6 +120,8 @@ affix.remove(src) for(var/i in appliedComponents) qdel(i) + for(var/i in appliedElements) + master._RemoveElement(i) master.force = max(0, master.force - quality) master.throwforce = max(0, master.throwforce - quality) diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm index 5ef2ac2baf..b6de85cab0 100644 --- a/code/datums/components/fantasy/prefixes.dm +++ b/code/datums/components/fantasy/prefixes.dm @@ -45,7 +45,8 @@ /datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName) var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/tactical) + master.AddElement(/datum/element/tactical) + comp.appliedElements += list(/datum/element/tactical) return "tactical [newName]" /datum/fantasy_affix/pyromantic diff --git a/code/datums/components/forced_gravity.dm b/code/datums/components/forced_gravity.dm deleted file mode 100644 index 100bcf781c..0000000000 --- a/code/datums/components/forced_gravity.dm +++ /dev/null @@ -1,20 +0,0 @@ -/datum/component/forced_gravity - var/gravity - var/ignore_space = FALSE //If forced gravity should also work on space turfs - -/datum/component/forced_gravity/Initialize(forced_value = 1) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check) - if(isturf(parent)) - RegisterSignal(COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check) - - gravity = forced_value - -/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs) - if(!ignore_space && isspaceturf(location)) - return - gravs += gravity - -/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs) - return gravity_check(parent, gravs) \ No newline at end of file diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm index 045611ab9d..2f4401862d 100644 --- a/code/datums/components/lockon_aiming.dm +++ b/code/datums/components/lockon_aiming.dm @@ -47,14 +47,11 @@ if(icon_state) lock_icon_state = icon_state generate_lock_visuals() - var/mob/M = parent - LAZYOR(M.mousemove_intercept_objects, src) + RegisterSignal(parent, COMSIG_MOB_CLIENT_MOUSEMOVE, .proc/onMouseMove) START_PROCESSING(SSfastprocess, src) /datum/component/lockon_aiming/Destroy() - var/mob/M = parent clear_visuals() - LAZYREMOVE(M.mousemove_intercept_objects, src) STOP_PROCESSING(SSfastprocess, src) return ..() @@ -120,7 +117,7 @@ return LAZYREMOVE(immune_weakrefs, A.weak_reference) -/datum/component/lockon_aiming/onMouseMove(object,location,control,params) +/datum/component/lockon_aiming/proc/onMouseMove(object,location,control,params) var/mob/M = parent if(!istype(M) || !M.client) return diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 37d77a45bc..88ad75f345 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -321,6 +321,28 @@ if(0 to NUTRITION_LEVEL_STARVING) add_event(null, "nutrition", /datum/mood_event/starving) +/datum/component/mood/proc/update_beauty(area/A) + if(A.outdoors) //if we're outside, we don't care. + clear_event(null, "area_beauty") + return FALSE + if(HAS_TRAIT(parent, TRAIT_SNOB)) + switch(A.beauty) + if(-INFINITY to BEAUTY_LEVEL_HORRID) + add_event(null, "area_beauty", /datum/mood_event/horridroom) + return + if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD) + add_event(null, "area_beauty", /datum/mood_event/badroom) + return + switch(A.beauty) + if(-INFINITY to BEAUTY_LEVEL_DECENT) + clear_event(null, "area_beauty") + if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD) + add_event(null, "area_beauty", /datum/mood_event/decentroom) + if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT) + add_event(null, "area_beauty", /datum/mood_event/goodroom) + if(BEAUTY_LEVEL_GREAT to INFINITY) + add_event(null, "area_beauty", /datum/mood_event/greatroom) + ///Called when parent is revived. /datum/component/mood/proc/on_revive(datum/source, full_heal) START_PROCESSING(SSdcs, src) diff --git a/code/datums/components/phantomthief.dm b/code/datums/components/phantomthief.dm index 57ab75f7a3..6b7e7221c3 100644 --- a/code/datums/components/phantomthief.dm +++ b/code/datums/components/phantomthief.dm @@ -20,7 +20,7 @@ valid_slots = _valid_slots /datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(mob/living/user, was_forced = FALSE) - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) user.remove_filter("phantomthief") else user.add_filter("phantomthief", 4, list(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, color = filter_color)) diff --git a/code/datums/components/summoning.dm b/code/datums/components/summoning.dm index 61718301b3..1d66cf9307 100644 --- a/code/datums/components/summoning.dm +++ b/code/datums/components/summoning.dm @@ -59,7 +59,7 @@ var/mob/living/simple_animal/L = new chosen_mob_type(spawn_location) if(ishostile(L)) var/mob/living/simple_animal/hostile/H = L - H.friends += summoner // do not attack our summon boy + H.friends[summoner]++ // do not attack our summon boy spawned_mobs += L if(faction != null) L.faction = faction diff --git a/code/datums/components/tactical.dm b/code/datums/components/tactical.dm deleted file mode 100644 index b73c58604a..0000000000 --- a/code/datums/components/tactical.dm +++ /dev/null @@ -1,44 +0,0 @@ - -/datum/component/tactical - var/allowed_slot - -/datum/component/tactical/Initialize(allowed_slot) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - src.allowed_slot = allowed_slot - -/datum/component/tactical/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify) - -/datum/component/tactical/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - unmodify() - -/datum/component/tactical/Destroy() - unmodify() - return ..() - -/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot) - if(allowed_slot && slot != allowed_slot) - unmodify() - return - - var/obj/item/master = parent - var/image/I = image(icon = master.icon, icon_state = master.icon_state, loc = user) - I.copy_overlays(master) - I.override = TRUE - source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I) - I.layer = ABOVE_MOB_LAYER - -/datum/component/tactical/proc/unmodify(obj/item/source, mob/user) - var/obj/item/master = source || parent - if(!user) - if(!ismob(master.loc)) - return - user = master.loc - - user.remove_alt_appearance("sneaking_mission") diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 747db3d6ce..ed5104e296 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -391,16 +391,6 @@ /mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures) - if(newfeatures) - var/old_size = dna.features["body_size"] - dna.features = newfeatures - dna.update_body_size(old_size) - - if(mrace) - var/datum/species/newrace = new mrace.type - newrace.copy_properties_from(mrace) - set_species(newrace, icon_update=0) - if(newreal_name) real_name = newreal_name dna.generate_unique_enzymes() @@ -410,7 +400,17 @@ if(ui) dna.uni_identity = ui - updateappearance(icon_update=0) + updateappearance(icon_update=FALSE) + + if(newfeatures) + var/old_size = dna.features["body_size"] + dna.features = newfeatures + dna.update_body_size(old_size) + + if(mrace) + var/datum/species/newrace = new mrace.type + newrace.copy_properties_from(mrace) + set_species(newrace, icon_update=FALSE) if(LAZYLEN(mutation_index)) dna.mutation_index = mutation_index.Copy() diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm new file mode 100644 index 0000000000..960d22af56 --- /dev/null +++ b/code/datums/elements/art.dm @@ -0,0 +1,64 @@ + +#define BAD_ART 12.5 +#define GOOD_ART 25 +#define GREAT_ART 50 + +/datum/element/art + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 2 + var/impressiveness = 0 + +/datum/element/art/Attach(datum/target, impress) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !isatom(target) || isarea(target)) + return ELEMENT_INCOMPATIBLE + impressiveness = impress + if(isobj(target)) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine) + if(isstructure(target)) + RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) + if(isitem(target)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet) + else + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_other_examine) + +/datum/element/art/Detach(datum/target) + UnregisterSignal(target, list(COMSIG_PARENT_EXAMINE, COMSIG_ATOM_ATTACK_HAND, COMSIG_ITEM_ATTACK_SELF)) + return ..() + +/datum/element/art/proc/apply_moodlet(atom/source, mob/M, impress) + M.visible_message("[M] stops and looks intently at [source].", \ + "You stop to take in [source].") + switch(impress) + if (0 to BAD_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) + if (BAD_ART to GOOD_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) + if (GOOD_ART to GREAT_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) + if(GREAT_ART to INFINITY) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + +/datum/element/art/proc/on_other_examine(atom/source, mob/M) + apply_moodlet(source, M, impressiveness) + +/datum/element/art/proc/on_obj_examine(atom/source, mob/M) + var/obj/O = source + apply_moodlet(source, M, impressiveness *(O.obj_integrity/O.max_integrity)) + +/datum/element/art/proc/on_attack_hand(atom/source, mob/M) + to_chat(M, "You start examining [source]...") + if(!do_after(M, 20, target = source)) + return + on_obj_examine(source, M) + +/datum/element/art/rev + +/datum/element/art/rev/apply_moodlet(atom/source, mob/M, impress) + M.visible_message("[M] stops to inspect [source].", \ + "You take in [source], inspecting the fine craftsmanship of the proletariat.") + + if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + else + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) diff --git a/code/datums/elements/beauty.dm b/code/datums/elements/beauty.dm new file mode 100644 index 0000000000..8acfda73e1 --- /dev/null +++ b/code/datums/elements/beauty.dm @@ -0,0 +1,34 @@ +/datum/element/beauty + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 2 + var/beauty = 0 + +/datum/element/beauty/Attach(datum/target, beautyamount) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !isatom(target) || isarea(target)) + return ELEMENT_INCOMPATIBLE + beauty = beautyamount + RegisterSignal(target, COMSIG_ENTER_AREA, .proc/enter_area) + RegisterSignal(target, COMSIG_EXIT_AREA, .proc/exit_area) + var/area/A = get_area(target) + if(A) + enter_area(null, A) + +/datum/element/beauty/Detach(datum/target) + UnregisterSignal(target, list(COMSIG_ENTER_AREA, COMSIG_EXIT_AREA)) + var/area/A = get_area(target) + if(A) + exit_area(null, A) + return ..() + +/datum/element/beauty/proc/enter_area(datum/source, area/A) + if(A.outdoors) + return + A.totalbeauty += beauty + A.update_beauty() + +/datum/element/beauty/proc/exit_area(datum/source, area/A) + if(A.outdoors) + return + A.totalbeauty -= beauty + A.update_beauty() diff --git a/code/datums/elements/empprotection.dm b/code/datums/elements/empprotection.dm new file mode 100644 index 0000000000..c24914decb --- /dev/null +++ b/code/datums/elements/empprotection.dm @@ -0,0 +1,18 @@ +/datum/element/empprotection + element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE + id_arg_index = 2 + var/flags = NONE + +/datum/element/empprotection/Attach(datum/target, _flags) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) + return ELEMENT_INCOMPATIBLE + flags = _flags + RegisterSignal(target, COMSIG_ATOM_EMP_ACT, .proc/getEmpFlags) + +/datum/element/empprotection/Detach(atom/target) + UnregisterSignal(target, COMSIG_ATOM_EMP_ACT) + return ..() + +/datum/element/empprotection/proc/getEmpFlags(datum/source, severity) + return flags diff --git a/code/datums/elements/forced_gravity.dm b/code/datums/elements/forced_gravity.dm new file mode 100644 index 0000000000..0b50df5b21 --- /dev/null +++ b/code/datums/elements/forced_gravity.dm @@ -0,0 +1,30 @@ +/datum/element/forced_gravity + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + var/gravity + var/ignore_space + +/datum/element/forced_gravity/Attach(datum/target, gravity=1, ignore_space=FALSE) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.gravity = gravity + src.ignore_space = ignore_space + + RegisterSignal(target, COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check) + if(isturf(target)) + RegisterSignal(target, COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check) + +/datum/element/forced_gravity/Detach(datum/source, force) + . = ..() + var/static/list/signals_b_gone = list(COMSIG_ATOM_HAS_GRAVITY, COMSIG_TURF_HAS_GRAVITY) + UnregisterSignal(source, signals_b_gone) + +/datum/element/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs) + if(!ignore_space && isspaceturf(location)) + return + gravs += gravity + +/datum/element/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs) + return gravity_check(null, source, gravs) diff --git a/code/datums/elements/tactical.dm b/code/datums/elements/tactical.dm new file mode 100644 index 0000000000..4b49552fbe --- /dev/null +++ b/code/datums/elements/tactical.dm @@ -0,0 +1,37 @@ +/datum/element/tactical + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 2 + var/allowed_slot + +/datum/element/tactical/Attach(datum/target, allowed_slot) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !isitem(target)) + return ELEMENT_INCOMPATIBLE + + src.allowed_slot = allowed_slot + RegisterSignal(target, COMSIG_ITEM_EQUIPPED, .proc/modify) + RegisterSignal(target, COMSIG_ITEM_DROPPED, .proc/unmodify) + +/datum/element/tactical/Detach(datum/target) + UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) + unmodify(target) + return ..() + +/datum/element/tactical/proc/modify(obj/item/source, mob/user, slot) + if(allowed_slot && slot != allowed_slot) + unmodify(source, user) + return + + var/image/I = image(icon = source.icon, icon_state = source.icon_state, loc = user) + I.copy_overlays(source) + I.override = TRUE + source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I) + I.layer = ABOVE_MOB_LAYER + +/datum/element/tactical/proc/unmodify(obj/item/source, mob/user) + if(!user) + if(!ismob(source.loc)) + return + user = source.loc + + user.remove_alt_appearance("sneaking_mission") diff --git a/code/datums/martial/_martial.dm b/code/datums/martial/_martial.dm index e54a80bd81..0877e4021a 100644 --- a/code/datums/martial/_martial.dm +++ b/code/datums/martial/_martial.dm @@ -39,11 +39,11 @@ /datum/martial_art/proc/damage_roll(mob/living/carbon/human/A, mob/living/carbon/human/D) //Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode. var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) - if(!(D.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(SEND_SIGNAL(D, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) damage *= 1.5 if(!CHECK_MOBILITY(A, MOBILITY_STAND)) damage *= 0.5 - if(!(A.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(SEND_SIGNAL(A, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) damage *= 0.25 return damage @@ -83,7 +83,7 @@ var/datum/martial_art/X = H.mind.default_martial_art X.teach(H) REMOVE_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT) - + /datum/martial_art/proc/on_remove(mob/living/carbon/human/H) if(help_verb) H.verbs -= help_verb diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index c658ac215d..1a8ce755e1 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -24,6 +24,8 @@ Simple datum which is instanced once per type and is used for every object of sa var/value_per_unit = 0 ///Armor modifiers, multiplies an items normal armor vars by these amounts. var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) + ///How beautiful is this material per unit? + var/beauty_modifier = 0 ///This proc is called when the material is added to an object. /datum/material/proc/on_applied(atom/source, amount, material_flags) @@ -39,6 +41,9 @@ Simple datum which is instanced once per type and is used for every object of sa if(istype(source, /obj)) //objs on_applied_obj(source, amount, material_flags) + if(beauty_modifier) + addtimer(CALLBACK(source, /datum.proc/_AddElement, list(/datum/element/beauty, beauty_modifier * amount)), 0) + ///This proc is called when the material is added to an object specifically. /datum/material/proc/on_applied_obj(var/obj/o, amount, material_flags) if(material_flags & MATERIAL_AFFECT_STATISTICS) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index f189a91353..d4921a04d2 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -19,6 +19,7 @@ integrity_modifier = 0.1 sheet_type = /obj/item/stack/sheet/glass value_per_unit = 0.0025 + beauty_modifier = 0.05 armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok /* @@ -35,6 +36,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/silver value_per_unit = 0.025 + beauty_modifier = 0.075 ///Slight force increase /datum/material/gold @@ -46,6 +48,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/gold value_per_unit = 0.0625 + beauty_modifier = 0.15 armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1) ///Has no special properties @@ -58,6 +61,8 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/diamond value_per_unit = 0.25 + beauty_modifier = 0.3 + armor_modifiers = list("melee" = 1.3, "bullet" = 1.3, "laser" = 0.6, "energy" = 1, "bomb" = 1.2, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) ///Is slightly radioactive /datum/material/uranium @@ -68,6 +73,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/uranium value_per_unit = 0.05 + beauty_modifier = 0.3 //It shines so beautiful armor_modifiers = list("melee" = 1.5, "bullet" = 1.4, "laser" = 0.5, "energy" = 0.5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 1, "acid" = 1) /datum/material/uranium/on_applied(atom/source, amount, material_flags) @@ -88,6 +94,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/plasma value_per_unit = 0.1 + beauty_modifier = 0.15 armor_modifiers = list("melee" = 1.4, "bullet" = 0.7, "laser" = 0, "energy" = 1.2, "bomb" = 0, "bio" = 1.2, "rad" = 1, "fire" = 0, "acid" = 0.5) /datum/material/plasma/on_applied(atom/source, amount, material_flags) @@ -109,6 +116,7 @@ Unless you know what you're doing, only use the first three numbers. They're in color = list(119/255, 217/255, 396/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) alpha = 200 categories = list(MAT_CATEGORY_ORE = TRUE) + beauty_modifier = 0.5 sheet_type = /obj/item/stack/sheet/bluespace_crystal value_per_unit = 0.15 @@ -121,6 +129,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/bananium value_per_unit = 0.5 + beauty_modifier = 0.5 armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away /datum/material/bananium/on_applied(atom/source, amount, material_flags) @@ -144,6 +153,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/titanium value_per_unit = 0.0625 + beauty_modifier = 0.05 armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1) /datum/material/runite @@ -154,6 +164,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 1.3 categories = list(MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/runite + beauty_modifier = 0.5 armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle. ///Force decrease @@ -165,6 +176,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 0.85 sheet_type = /obj/item/stack/sheet/plastic value_per_unit = 0.0125 + beauty_modifier = -0.01 armor_modifiers = list("melee" = 1.5, "bullet" = 1.1, "laser" = 0.3, "energy" = 0.5, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1.1, "acid" = 1) ///Force decrease and mushy sound effect. (Not yet implemented) @@ -176,6 +188,30 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 0.8 value_per_unit = 0.025 +/datum/material/wood + name = "wood" + id = "wood" + desc = "Flexible, durable, but flamable. Hard to come across in space." + color = "#bb8e53" + strength_modifier = 0.5 + sheet_type = /obj/item/stack/sheet/mineral/wood + categories = list(MAT_CATEGORY_RIGID = TRUE) + value_per_unit = 0.06 + beauty_modifier = 0.1 + armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 0.4, "energy" = 0.4, "bomb" = 1, "bio" = 0.2, "rad" = 0, "fire" = 0, "acid" = 0.3) + +/datum/material/wood/on_applied_obj(obj/source, amount, material_flags) + . = ..() + if(material_flags & MATERIAL_AFFECT_STATISTICS) + var/obj/wooden = source + wooden.resistance_flags |= FLAMMABLE + +/datum/material/wood/on_removed_obj(obj/source, material_flags) + . = ..() + if(material_flags & MATERIAL_AFFECT_STATISTICS) + var/obj/wooden = source + wooden.resistance_flags &= ~FLAMMABLE + ///Stronk force increase /datum/material/adamantine name = "adamantine" @@ -186,6 +222,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 0.25 + beauty_modifier = 0.4 armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1) ///RPG Magic. (Admin only) @@ -197,6 +234,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE) sheet_type = /obj/item/stack/sheet/mineral/mythril value_per_unit = 0.75 + beauty_modifier = 0.5 armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2) /datum/material/mythril/on_applied_obj(atom/source, amount, material_flags) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index b7eac62e83..fb91edb2c9 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -97,9 +97,6 @@ if(current) // remove ourself from our old body's mind variable current.mind = null SStgui.on_transfer(current, new_character) - if(iscarbon(current)) - var/mob/living/carbon/C = current - C.disable_intentional_combat_mode(TRUE) if(key) if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index c56425b074..f5692c297a 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -153,7 +153,13 @@ mood_change = -4 timeout = 2400 +/datum/mood_event/graverobbing + description ="I just desecrated someone's grave... I can't believe I did that...\n" + mood_change = -8 + timeout = 3 MINUTES + //These are unused so far but I want to remember them to use them later + /datum/mood_event/cloned_corpse description = "I recently saw my own corpse...\n" mood_change = -6 @@ -162,6 +168,8 @@ description = "HE'S CUTTING ME OPEN!!\n" mood_change = -8 +//End unused + /datum/mood_event/sad_empath description = "Someone seems upset...\n" mood_change = -2 @@ -199,6 +207,8 @@ mood_change = -2 timeout = 1 MINUTES +//Cursed stuff end. + /datum/mood_event/vampcandle description = "Something is making your mind feel... loose...\n" mood_change = -15 diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index 608683c3dc..482e15c57d 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -189,6 +189,12 @@ x += mpx * (multiplier) y += mpy * (multiplier) +/datum/point/vector/proc/pixel_increment(pixels = 32, update_iteration = TRUE, realistic_iteration = FALSE) + if(update_iteration) + iteration += realistic_iteration? round(pixels / speed) : 1 + x += sin(angle) * pixels + y += cos(angle) * pixels + /datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE) var/datum/point/vector/v = copy_to() if(force_simulate) diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 8f3811ca71..933eaf082e 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -250,4 +250,12 @@ cost = 5 placement_weight = 3 always_place = TRUE - allow_duplicates = TRUE + allow_duplicates = TRUE + +/datum/map_template/ruin/lavaland/elephant_graveyard + name = "Elephant Graveyard" + id = "Graveyard" + description = "An abandoned graveyard, calling to those unable to continue." + suffix = "lavaland_surface_elephant_graveyard.dmm" + allow_duplicates = FALSE + cost = 10 diff --git a/code/datums/tgs_event_handler.dm b/code/datums/tgs_event_handler.dm index a3324121bf..731be64183 100644 --- a/code/datums/tgs_event_handler.dm +++ b/code/datums/tgs_event_handler.dm @@ -1,3 +1,6 @@ +/datum/tgs_event_handler/impl + var/datum/timedevent/reattach_timer + /datum/tgs_event_handler/impl/HandleEvent(event_code, ...) switch(event_code) if(TGS_EVENT_REBOOT_MODE_CHANGE) @@ -18,3 +21,19 @@ if(TGS_EVENT_DEPLOYMENT_COMPLETE) message_admins("TGS: Deployment complete!") to_chat(world, "Server updated, changes will be applied on the next round...") + if(TGS_EVENT_WATCHDOG_DETACH) + message_admins("TGS restarting...") + reattach_timer = addtimer(CALLBACK(src, .proc/LateOnReattach), 1 MINUTES) + if(TGS_EVENT_WATCHDOG_REATTACH) + var/datum/tgs_version/old_version = world.TgsVersion() + var/datum/tgs_version/new_version = args[2] + if(!old_version.Equals(new_version)) + to_chat(world, "TGS updated to v[old_version.deprefixed_parameter]") + else + message_admins("TGS: Back online") + if(reattach_timer) + deltimer(reattach_timer) + reattach_timer = null + +/datum/tgs_event_handler/impl/proc/LateOnReattach() + message_admins("Warning: TGS hasn't notified us of it coming back for a full minute! Is there a problem?") diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index d1b5240798..4b039aa1b5 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -10,6 +10,15 @@ lose_text = "You can taste again!" medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents." +/datum/quirk/snob + name = "Snob" + desc = "You care about the finer things, if a room doesn't look nice its just not really worth it, is it?" + value = 0 + gain_text = "You feel like you understand what things should look like." + lose_text = "Well who cares about deco anyways?" + medical_record_text = "Patient seems to be rather stuck up." + mob_trait = TRAIT_SNOB + /datum/quirk/pineapple_liker name = "Ananas Affinity" desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!" diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index a96e14d4d7..11e7e12bd8 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -11,9 +11,6 @@ if(A.attachable) return TRUE -/atom - var/datum/wires/wires = null - /atom/proc/attempt_wire_interaction(mob/user) if(!wires) return WIRE_INTERACTION_FAIL diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm index 997c77aa51..19b2b8dda8 100644 --- a/code/datums/wires/apc.dm +++ b/code/datums/wires/apc.dm @@ -30,6 +30,7 @@ if(WIRE_POWER1, WIRE_POWER2) // Short for a long while. if(!A.shorted) A.shorted = TRUE + A.update() addtimer(CALLBACK(A, /obj/machinery/power/apc.proc/reset, wire), 1200) if(WIRE_IDSCAN) // Unlock for a little while. A.locked = FALSE @@ -49,6 +50,7 @@ else A.shorted = TRUE A.shock(usr, 50) + A.update() if(WIRE_AI) // Disable AI control. if(mend) A.aidisabled = FALSE diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 5fac1a4b65..dabbe93bec 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -38,6 +38,10 @@ var/poweralm = TRUE var/lightswitch = TRUE + var/totalbeauty = 0 //All beauty in this area combined, only includes indoor area. + var/beauty = 0 // Beauty average per open turf in the area + var/beauty_threshold = 150 //If a room is too big it doesn't have beauty. + var/requires_power = TRUE /// This gets overridden to 1 for space in area/Initialize(). var/always_unpowered = FALSE @@ -65,7 +69,7 @@ /// Hides area from player Teleport function. var/hidden = FALSE /// Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers - var/safe = FALSE + var/safe = FALSE /// If false, loading multiple maps with this area type will create multiple instances. var/unique = TRUE @@ -192,6 +196,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/LateInitialize() if(!base_area) //we don't want to run it twice. power_change() // all machines set to current power level, also updates icon + update_beauty() /area/proc/reg_in_areas_in_z() if(contents.len) @@ -538,6 +543,16 @@ GLOBAL_LIST_EMPTY(teleportlocs) L.client.played = TRUE addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600) +///Divides total beauty in the room by roomsize to allow us to get an average beauty per tile. +/area/proc/update_beauty() + if(!areasize) + beauty = 0 + return FALSE + if(areasize >= beauty_threshold) + beauty = 0 + return FALSE //Too big + beauty = totalbeauty / areasize + /area/Exited(atom/movable/M) SEND_SIGNAL(src, COMSIG_AREA_EXITED, M) SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index 1241b7a240..96b621acd8 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -32,7 +32,8 @@ /area/centcom/vip name = "VIP Zone" dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - /area/centcom/winterball + +/area/centcom/winterball name = "winterball Zone" dynamic_lighting = DYNAMIC_LIGHTING_DISABLED diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm index 76f090d5e3..19a1fd503d 100644 --- a/code/game/area/areas/ruins/lavaland.dm +++ b/code/game/area/areas/ruins/lavaland.dm @@ -32,6 +32,14 @@ /area/ruin/powered/seedvault icon_state = "dk_yellow" +/area/ruin/unpowered/elephant_graveyard + name = "Elephant Graveyard" + icon_state = "dk_yellow" + +/area/ruin/powered/graveyard_shuttle + name = "Elephant Graveyard" + icon_state = "green" + /area/ruin/unpowered/syndicate_lava_base name = "Secret Base" icon_state = "dk_yellow" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1ff27bafa9..a83eaed9d3 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -47,6 +47,8 @@ ///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines. var/material_modifier = 1 + var/datum/wires/wires = null + var/icon/blood_splatter_icon var/list/fingerprints var/list/fingerprintshidden @@ -313,10 +315,11 @@ . += desc if(custom_materials) + var/list/materials_list = list() for(var/i in custom_materials) var/datum/material/M = i - . += "It is made out of [M.name]." - + materials_list += "[M.name]" + . += "It is made out of [english_list(materials_list)]." if(reagents) if(reagents.reagents_holder_flags & TRANSPARENT) . += "It contains:" diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index e1fbb636c8..e97d276296 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -2,8 +2,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) -/mob - var/datum/hSB/sandbox = null + /mob/proc/CanBuild() sandbox = new/datum/hSB sandbox.owner = src.ckey diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 0416813f4f..5402c8f41e 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -434,3 +434,45 @@ /obj/machinery/sleeper/old icon_state = "oldpod" + +/obj/machinery/sleeper/party + name = "party pod" + desc = "'Sleeper' units were once known for their healing properties, until a lengthy investigation revealed they were also dosing patients with deadly lead acetate. This appears to be one of those old 'sleeper' units repurposed as a 'Party Pod'. It’s probably not a good idea to use it." + icon_state = "partypod" + idle_power_usage = 3000 + circuit = /obj/item/circuitboard/machine/sleeper/party + var/leddit = FALSE //Get it like reddit and lead alright fine + ui_x = 310 + ui_y = 400 + + controls_inside = TRUE + possible_chems = list( + list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/laughter), + list(/datum/reagent/spraytan,/datum/reagent/barbers_aid), + list(/datum/reagent/colorful_reagent,/datum/reagent/hair_dye), + list(/datum/reagent/drug/space_drugs,/datum/reagent/baldium) + )//Exclusively uses non-lethal, "fun" chems. At an obvious downside. + var/spray_chems = list( + /datum/reagent/spraytan, /datum/reagent/hair_dye, /datum/reagent/baldium, /datum/reagent/barbers_aid + )//Chemicals that need to have a touch or vapor reaction to be applied, not the standard chamber reaction. + enter_message = "You're surrounded by some funky music inside the chamber. You zone out as you feel waves of krunk vibe within you." + +/obj/machinery/sleeper/party/inject_chem(chem, mob/user) + if(leddit) + occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, 4) //You're injecting chemicals into yourself from a recalled, decrepit medical machine. What did you expect? + else if (prob(20)) + occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, rand(1,3)) + if(chem in spray_chems) + var/datum/reagents/holder = new() + holder.add_reagent(chem_buttons[chem], 10) //I hope this is the correct way to do this. + holder.reaction(occupant, VAPOR, 0) + holder.trans_to(occupant, 10) + playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6) + if(user) + log_combat(user, occupant, "sprayed [chem] into", addition = "via [src]") + return TRUE + ..() + +/obj/machinery/sleeper/party/emag_act(mob/user) + ..() + leddit = TRUE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 3b32213509..4eeb6b8b0f 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -60,7 +60,8 @@ /datum/material/runite, /datum/material/plastic, /datum/material/adamantine, - /datum/material/mythril + /datum/material/mythril, + /datum/material/wood ) /// Base print speed diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 8819020e3a..71de04ee99 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -3,7 +3,6 @@ desc = "A remote control switch." icon = 'icons/obj/stationobjs.dmi' icon_state = "doorctrl" - plane = ABOVE_WALL_PLANE var/skin = "doorctrl" power_channel = ENVIRON var/obj/item/assembly/device @@ -17,10 +16,13 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF /obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) - if(istext(id) && mapload) - if(id[1] == "!") - id = SSmapping.get_obfuscated_id(id) + if(istext(id) && mapload && id[1] == "!") + id = SSmapping.get_obfuscated_id(id) . = ..() + var/turf/T = get_turf_pixel(src) + if(iswallturf(T)) + plane = ABOVE_WALL_PLANE + if(built) setDir(ndir) pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) @@ -28,7 +30,6 @@ panel_open = TRUE update_icon() - if(!built && !device && device_type) device = new device_type(src) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 021232f435..33e250fa59 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -75,7 +75,7 @@ // UPGRADE PROCS /obj/machinery/camera/proc/upgradeEmpProof() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/plasma(assembly)) upgrades |= CAMERA_UPGRADE_EMP_PROOF diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 967ee02f82..450967050c 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -169,13 +169,18 @@ desc = "Used for watching an empty arena." icon = 'icons/obj/stationobjs.dmi' icon_state = "telescreen" - plane = ABOVE_WALL_PLANE network = list("thunder") density = FALSE circuit = null clockwork = TRUE //it'd look very weird light_power = 0 +/obj/machinery/computer/security/telescreen/Initialize() + . = ..() + var/turf/T = get_turf_pixel(src) + if(iswallturf(T)) + plane = ABOVE_WALL_PLANE + /obj/machinery/computer/security/telescreen/update_icon_state() icon_state = initial(icon_state) if(stat & BROKEN) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 67113fcf78..a2d3cccc35 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -70,14 +70,13 @@ if(W.amount < 5) to_chat(user, "You need at least five wooden planks to make a wall!") return - else - to_chat(user, "You start adding [I] to [src]...") - if(do_after(user, 50, target=src)) - W.use(5) - var/turf/T = get_turf(src) - T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal) - qdel(src) - return + to_chat(user, "You start adding [I] to [src]...") + if(do_after(user, 50, target=src)) + W.use(5) + var/turf/T = get_turf(src) + T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal) + qdel(src) + return return ..() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1cb8471fe4..66a07e6758 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -470,15 +470,15 @@ if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(lights && hasPower()) if(locked) - lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) else if(emergency) - lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(note) note_overlay = get_airlock_overlay(notetype, note_overlay_file) @@ -496,18 +496,18 @@ else panel_overlay = get_airlock_overlay("panel_closed", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) - lights_overlay = get_airlock_overlay("lights_denied", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + lights_overlay = get_airlock_overlay("lights_denied", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(note) note_overlay = get_airlock_overlay(notetype, note_overlay_file) if(AIRLOCK_EMAG) frame_overlay = get_airlock_overlay("closed", icon) - sparks_overlay = get_airlock_overlay("sparks", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + sparks_overlay = get_airlock_overlay("sparks", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(airlock_material) filling_overlay = get_airlock_overlay("[airlock_material]_closed", overlays_file) else @@ -518,9 +518,9 @@ else panel_overlay = get_airlock_overlay("panel_closed", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) if(note) @@ -533,7 +533,7 @@ else filling_overlay = get_airlock_overlay("fill_closing", icon) if(lights && hasPower()) - lights_overlay = get_airlock_overlay("lights_closing", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + lights_overlay = get_airlock_overlay("lights_closing", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(panel_open) if(security_level) panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file) @@ -554,7 +554,7 @@ else panel_overlay = get_airlock_overlay("panel_open", overlays_file) if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_open", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + damag_overlay = get_airlock_overlay("sparks_open", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(note) note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file) @@ -565,7 +565,7 @@ else filling_overlay = get_airlock_overlay("fill_opening", icon) if(lights && hasPower()) - lights_overlay = get_airlock_overlay("lights_opening", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) + lights_overlay = get_airlock_overlay("lights_opening", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) if(panel_open) if(security_level) panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file) @@ -577,11 +577,17 @@ cut_overlays() add_overlay(frame_overlay) add_overlay(filling_overlay) - add_overlay(lights_overlay) + if(lights_overlay) + add_overlay(lights_overlay) + var/mutable_appearance/lights_vis = mutable_appearance(lights_overlay.icon, lights_overlay.icon_state) + add_overlay(lights_vis) add_overlay(panel_overlay) add_overlay(weld_overlay) add_overlay(sparks_overlay) - add_overlay(damag_overlay) + if(damag_overlay) + add_overlay(damag_overlay) + var/mutable_appearance/damage_vis = mutable_appearance(damag_overlay.icon, damag_overlay.icon_state) + add_overlay(damage_vis) add_overlay(note_overlay) check_unres() diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 87e8c8f6a7..362dde1157 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -53,7 +53,9 @@ if("opening") rad_insulation = 1 if("closing") - rad_insulation = 0.2 + rad_insulation = -0.5 + +// A 3x3 N2 SM setup won't irradiate you if you're behind the shutter at -0.9 insulation. If it starts to delam, it'll start irradiating you slowly. Keep the value between -0.1 to -0.9 /obj/machinery/door/poddoor/shutters/window name = "windowed shutters" diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm new file mode 100644 index 0000000000..1b57f61b79 --- /dev/null +++ b/code/game/machinery/hypnochair.dm @@ -0,0 +1,205 @@ +/obj/machinery/hypnochair + name = "enhanced interrogation chamber" + desc = "A device used to perform \"enhanced interrogation\" through invasive mental conditioning." + icon = 'icons/obj/machines/implantchair.dmi' + icon_state = "hypnochair" + circuit = /obj/item/circuitboard/machine/hypnochair + density = TRUE + opacity = 0 + ui_x = 375 + ui_y = 480 + var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away + var/interrogating = FALSE ///Is the device currently interrogating someone? + var/start_time = 0 ///Time when the interrogation was started, to calculate effect in case of interruption + var/trigger_phrase = "" ///Trigger phrase to implant + var/timerid = 0 ///Timer ID for interrogations + + var/message_cooldown = 0 ///Cooldown for breakout message + +/obj/machinery/hypnochair/Initialize() + . = ..() + open_machine() + update_icon() + +/obj/machinery/hypnochair/attackby(obj/item/I, mob/user, params) + if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I)) + update_icon() + return + + if(default_pry_open(I)) + return + + if(default_deconstruction_crowbar(I)) + return + + return ..() + +/obj/machinery/hypnochair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "hypnochair", name, ui_x, ui_y, master_ui, state) + ui.open() + +/obj/machinery/hypnochair/ui_data() + var/list/data = list() + data["occupied"] = occupant ? TRUE : FALSE + data["open"] = state_open + data["interrogating"] = interrogating + + data["occupant"] = list() + if(occupant) + var/mob/living/mob_occupant = occupant + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat + + data["trigger"] = trigger_phrase + + return data + +/obj/machinery/hypnochair/ui_act(action, params) + if(..()) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + if(!interrogating) + open_machine() + . = TRUE + if("set_phrase") + set_phrase(params["phrase"]) + . = TRUE + if("interrogate") + if(!interrogating) + interrogate() + else + interrupt_interrogation() + . = TRUE + +/obj/machinery/hypnochair/proc/set_phrase(phrase) + trigger_phrase = phrase + +/obj/machinery/hypnochair/proc/interrogate() + if(!trigger_phrase) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE) + return + var/mob/living/carbon/C = occupant + if(!istype(C)) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE) + return + victim = C + if(!(C.get_eye_protection() > 0)) + to_chat(C, "Strobing coloured lights assault you relentlessly! You're losing your ability to think straight!") + C.become_blind("hypnochair") + ADD_TRAIT(C, TRAIT_DEAF, "hypnochair") + interrogating = TRUE + START_PROCESSING(SSobj, src) + start_time = world.time + update_icon() + timerid = addtimer(CALLBACK(src, .proc/finish_interrogation), 450, TIMER_STOPPABLE) + +/obj/machinery/hypnochair/process() + var/mob/living/carbon/C = occupant + if(!istype(C) || C != victim) + interrupt_interrogation() + return + if(prob(10) && !(C.get_eye_protection() > 0)) + to_chat(C, "[pick(\ + "...blue... red... green... blue, red, green, blueredgreenblueredgreen",\ + "...pretty colors...",\ + "...you keep hearing words, but you can't seem to understand them...",\ + "...so peaceful...",\ + "...an annoying buzz in your ears..."\ + )]") + +/obj/machinery/hypnochair/proc/finish_interrogation() + interrogating = FALSE + STOP_PROCESSING(SSobj, src) + update_icon() + var/temp_trigger = trigger_phrase + trigger_phrase = "" //Erase evidence, in case the subject is able to look at the panel afterwards + audible_message("[src] pings!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + + if(QDELETED(victim) || victim != occupant) + victim = null + return + victim.cure_blind("hypnochair") + REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair") + if(!(victim.get_eye_protection() > 0)) + victim.cure_trauma_type(/datum/brain_trauma/severe/hypnotic_trigger, TRAUMA_RESILIENCE_SURGERY) + if(prob(90)) + victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_trigger(temp_trigger), TRAUMA_RESILIENCE_SURGERY) + else + victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_stupor(), TRAUMA_RESILIENCE_SURGERY) + victim = null + +/obj/machinery/hypnochair/proc/interrupt_interrogation() + deltimer(timerid) + interrogating = FALSE + STOP_PROCESSING(SSobj, src) + update_icon() + + if(QDELETED(victim)) + victim = null + return + victim.cure_blind("hypnochair") + REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair") + if(!(victim.get_eye_protection() > 0)) + var/time_diff = world.time - start_time + switch(time_diff) + if(0 to 100) + victim.confused += 10 + victim.Dizzy(100) + victim.blur_eyes(5) + if(101 to 200) + victim.confused += 15 + victim.Dizzy(200) + victim.blur_eyes(10) + if(prob(25)) + victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE) + if(201 to INFINITY) + victim.confused += 20 + victim.Dizzy(300) + victim.blur_eyes(15) + if(prob(65)) + victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE) + victim = null + +/obj/machinery/hypnochair/update_icon_state() + icon_state = initial(icon_state) + if(state_open) + icon_state += "_open" + if(occupant) + if(interrogating) + icon_state += "_active" + else + icon_state += "_occupied" + +/obj/machinery/hypnochair/container_resist(mob/living/user) + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message("You see [user] kicking against the door of [src]!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)", \ + "You hear a metallic creaking from [src].") + if(do_after(user,(600), target = src)) + if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) + return + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") + open_machine() + +/obj/machinery/hypnochair/relaymove(mob/user) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") + +/obj/machinery/hypnochair/MouseDrop_T(mob/target, mob/user) + if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) + return + if(isliving(user)) + var/mob/living/L = user + if(!(L.mobility_flags & MOBILITY_STAND)) + return + close_machine(target) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index ff79038a96..1887ee46c0 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -679,7 +679,7 @@ /obj/machinery/porta_turret/syndicate/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/porta_turret/syndicate/energy icon_state = "standard_stun" @@ -788,7 +788,7 @@ /obj/machinery/porta_turret/centcom_shuttle/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/porta_turret/centcom_shuttle/assess_perp(mob/living/carbon/human/perp) return 0 diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index 69aa3fb654..0954d12790 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -51,6 +51,7 @@ icon = 'icons/obj/contraband.dmi' plane = ABOVE_WALL_PLANE anchored = TRUE + buildable_sign = FALSE //Cannot be unwrenched from a wall. var/ruined = FALSE var/random_basetype var/never_random = FALSE // used for the 'random' subclasses. @@ -69,6 +70,8 @@ name = "poster - [name]" desc = "A large piece of space-resistant printed paper. [desc]" + addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 300)), 0) + /obj/structure/sign/poster/proc/randomise(base_type) var/list/poster_types = subtypesof(base_type) var/list/approved_types = list() diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 5720d5ce34..34996177af 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -5,6 +5,7 @@ var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one? + var/beauty = 0 /obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases) . = ..() @@ -26,6 +27,8 @@ if(LAZYLEN(diseases_to_add)) AddComponent(/datum/component/infective, diseases_to_add) + addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, beauty)), 0) + /obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal if(mergeable_decal) qdel(C) diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 3afc0ef671..fa4bfe7e67 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -3,6 +3,7 @@ name = "xeno blood" desc = "It's green and acidic. It looks like... blood?" color = BLOOD_COLOR_XENO + beauty = -250 /obj/effect/decal/cleanable/blood/splatter/xeno color = BLOOD_COLOR_XENO diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index ab0d1caca4..a5acc7d394 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -7,6 +7,7 @@ blood_state = BLOOD_STATE_BLOOD bloodiness = BLOOD_AMOUNT_PER_DECAL color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere. + beauty = -100 /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) if (C.blood_DNA) @@ -45,12 +46,14 @@ icon_state = "tracks" desc = "They look like tracks left by wheels." random_icon_states = null + beauty = -50 /obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose name = "blood" icon_state = "ltrails_1" desc = "Your instincts say you shouldn't be following these." random_icon_states = null + beauty = -50 var/list/existing_dirs = list() /obj/effect/decal/cleanable/trail_holder/update_icon() diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index e06c172519..2e45bbfca5 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -3,6 +3,7 @@ desc = "Someone should clean that up." icon = 'icons/obj/objects.dmi' icon_state = "shards" + beauty = -50 /obj/effect/decal/cleanable/ash name = "ashes" @@ -10,6 +11,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "ash" mergeable_decal = FALSE + beauty = -50 /obj/effect/decal/cleanable/ash/Initialize() . = ..() @@ -24,6 +26,7 @@ /obj/effect/decal/cleanable/ash/large name = "large pile of ashes" icon_state = "big_ash" + beauty = -100 /obj/effect/decal/cleanable/ash/large/Initialize() . = ..() @@ -34,6 +37,7 @@ desc = "Back to sand." icon = 'icons/obj/shards.dmi' icon_state = "tiny" + beauty = -100 /obj/effect/decal/cleanable/glass/Initialize() . = ..() @@ -52,6 +56,7 @@ canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall) smooth = SMOOTH_FALSE mouse_opacity = MOUSE_OPACITY_TRANSPARENT + beauty = -75 /obj/effect/decal/cleanable/dirt/Initialize() . = ..() @@ -72,6 +77,10 @@ desc = "It's still good. Four second rule!" icon_state = "flour" +/obj/effect/decal/cleanable/dirt/dust + name = "dust" + desc = "A thin layer of dust coating the floor." + /obj/effect/decal/cleanable/greenglow/ecto name = "ectoplasmic puddle" desc = "You know who to call." @@ -80,8 +89,11 @@ /obj/effect/decal/cleanable/greenglow name = "glowing goo" desc = "Jeez. I hope that's not for lunch." + light_power = 1 + light_range = 1 light_color = LIGHT_COLOR_GREEN icon_state = "greenglow" + beauty = -300 /obj/effect/decal/cleanable/greenglow/Initialize(mapload) . = ..() @@ -97,6 +109,7 @@ layer = WALL_OBJ_LAYER icon_state = "cobweb1" resistance_flags = FLAMMABLE + beauty = -100 /obj/effect/decal/cleanable/cobweb/cobweb2 icon_state = "cobweb2" @@ -108,10 +121,12 @@ icon = 'icons/effects/effects.dmi' icon_state = "molten" mergeable_decal = FALSE + beauty = -150 /obj/effect/decal/cleanable/molten_object/large name = "big gooey grey mass" icon_state = "big_molten" + beauty = -300 //Vomit (sorry) /obj/effect/decal/cleanable/vomit @@ -120,6 +135,7 @@ icon = 'icons/effects/blood.dmi' icon_state = "vomit_1" random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") + beauty = -150 /obj/effect/decal/cleanable/vomit/attack_hand(mob/user) . = ..() @@ -152,6 +168,7 @@ gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3") + beauty = -100 /obj/effect/decal/cleanable/plant_smudge name = "plant smudge" diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index cf030df120..2765330977 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -10,6 +10,7 @@ blood_state = BLOOD_STATE_OIL bloodiness = BLOOD_AMOUNT_PER_DECAL mergeable_decal = FALSE + beauty = -50 /obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases) . = ..() @@ -50,6 +51,7 @@ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_OIL bloodiness = BLOOD_AMOUNT_PER_DECAL + beauty = -100 /obj/effect/decal/cleanable/oil/Initialize() . = ..() @@ -58,6 +60,7 @@ /obj/effect/decal/cleanable/oil/streak random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5") + beauty = -50 /obj/effect/decal/cleanable/oil/slippery diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 2a4b6d7df5..55549f5fc4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -138,6 +138,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/skill_difficulty = THRESHOLD_UNTRAINED //how difficult it's to use this item in general. var/skill_gain = DEF_SKILL_GAIN //base skill value gain from using this item. + var/canMouseDown = FALSE + + /obj/item/Initialize() if (attack_verb) @@ -420,14 +423,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return usr.client.Click(src, src_location, src_control, params) var/list/directaccess = usr.DirectAccess() //This, specifically, is what requires the copypaste. If this were after the adjacency check, then it'd be impossible to use items in your inventory, among other things. //If this were before the above checks, then trying to click on items would act a little funky and signal overrides wouldn't work. - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - if((C.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && ((C.CanReach(src) || (src in directaccess)) && (C.CanReach(over) || (over in directaccess)))) - if(!C.get_active_held_item()) - C.UnarmedAttack(src, TRUE) - if(C.get_active_held_item() == src) - melee_attack_chain(C, over) - return TRUE //returning TRUE as a "is this overridden?" flag + if(SEND_SIGNAL(usr, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) && ((usr.CanReach(src) || (src in directaccess)) && (usr.CanReach(over) || (over in directaccess)))) + if(!usr.get_active_held_item()) + usr.UnarmedAttack(src, TRUE) + if(usr.get_active_held_item() == src) + melee_attack_chain(usr, over) + return TRUE //returning TRUE as a "is this overridden?" flag if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index cb44b82ad2..5d9c6ee267 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -745,7 +745,7 @@ RLD if(istype(A, /obj/machinery/light/)) if(checkResource(deconcost, user)) to_chat(user, "You start deconstructing [A]...") - user.Beam(A,icon_state="nzcrentrs_power",time=15) + user.Beam(A,icon_state="light_beam",time=15) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) if(do_after(user, decondelay, target = A)) if(!useResource(deconcost, user)) @@ -759,7 +759,7 @@ RLD var/turf/closed/wall/W = A if(checkResource(floorcost, user)) to_chat(user, "You start building a wall light...") - user.Beam(A,icon_state="nzcrentrs_power",time=15) + user.Beam(A,icon_state="light_beam",time=15) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 0) if(do_after(user, floordelay, target = A)) @@ -805,7 +805,7 @@ RLD var/turf/open/floor/F = A if(checkResource(floorcost, user)) to_chat(user, "You start building a floor light...") - user.Beam(A,icon_state="nzcrentrs_power",time=15) + user.Beam(A,icon_state="light_beam",time=15) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 1) if(do_after(user, floordelay, target = A)) @@ -834,6 +834,12 @@ RLD return TRUE return FALSE +/obj/item/construction/rld/mini + name = "mini-rapid-light-device (MRLD)" + desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges." + matter = 100 + max_matter = 100 + /obj/item/rcd_upgrade name = "RCD advanced design disk" desc = "It seems to be empty." diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index 35843c1030..01b351edd0 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -7,7 +7,7 @@ RSF name = "\improper Rapid-Service-Fabricator" desc = "A device used to rapidly deploy service items." icon = 'icons/obj/tools.dmi' - icon_state = "rcd" + icon_state = "rsf" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' opacity = 0 @@ -110,7 +110,7 @@ RSF name = "Cookie Synthesizer" desc = "A self-recharging device used to rapidly deploy cookies." icon = 'icons/obj/tools.dmi' - icon_state = "rcd" + icon_state = "rsf" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' var/matter = 10 diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 45fea91e49..b6be778456 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -125,3 +125,112 @@ user.put_in_hands(ink) to_chat(user, "You remove [ink] from [src].") ink = null + + +/obj/item/airlock_painter/decal + name = "decal painter" + desc = "An airlock painter, reprogramed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed. Alt-Click to change design." + icon = 'icons/obj/objects.dmi' + icon_state = "decal_sprayer" + item_state = "decalsprayer" + custom_materials = list(/datum/material/iron=2000, /datum/material/glass=500) + var/stored_dir = 2 + var/stored_color = "" + var/stored_decal = "warningline" + var/stored_decal_total = "warningline" + var/color_list = list("","red","white") + var/dir_list = list(1,2,4,8) + var/decal_list = list(list("Warning Line","warningline"), + list("Warning Line Corner","warninglinecorner"), + list("Caution Label","caution"), + list("Directional Arrows","arrows"), + list("Stand Clear Label","stand_clear"), + list("Box","box"), + list("Box Corner","box_corners"), + list("Delivery Marker","delivery"), + list("Warning Box","warn_full")) + +/obj/item/airlock_painter/decal/afterattack(atom/target, mob/user, proximity) + . = ..() + var/turf/open/floor/F = target + if(!proximity) + to_chat(user, "You need to get closer!") + return + if(use_paint(user) && isturf(F)) + F.AddComponent(/datum/component/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha) + +/obj/item/airlock_painter/decal/attack_self(mob/user) + if((ink) && (ink.charges >= 1)) + to_chat(user, "[src] beeps to prevent you from removing the toner until out of charges.") + return + . = ..() + +/obj/item/airlock_painter/decal/AltClick(mob/user) + . = ..() + ui_interact(user) + +/obj/item/airlock_painter/decal/Initialize() + . = ..() + ink = new /obj/item/toner/large(src) + +/obj/item/airlock_painter/decal/proc/update_decal_path() + var/yellow_fix = "" //This will have to do until someone refactor's markings.dm + if (stored_color) + yellow_fix = "_" + stored_decal_total = "[stored_decal][yellow_fix][stored_color]" + return + +/obj/item/airlock_painter/decal/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) + ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state) + ui.open() + +/obj/item/airlock_painter/decal/ui_data(mob/user) + var/list/data = list() + data["decal_direction"] = stored_dir + data["decal_color"] = stored_color + data["decal_style"] = stored_decal + data["decal_list"] = list() + data["color_list"] = list() + data["dir_list"] = list() + + for(var/i in decal_list) + data["decal_list"] += list(list( + "name" = i[1], + "decal" = i[2] + )) + for(var/j in color_list) + data["color_list"] += list(list( + "colors" = j + )) + for(var/k in dir_list) + data["dir_list"] += list(list( + "dirs" = k + )) + return data + +/obj/item/airlock_painter/decal/ui_act(action,list/params) + if(..()) + return + switch(action) + //Lists of decals and designs + if("select decal") + var/selected_decal = params["decals"] + stored_decal = selected_decal + if("select color") + var/selected_color = params["colors"] + stored_color = selected_color + if("selected direction") + var/selected_direction = text2num(params["dirs"]) + stored_dir = selected_direction + update_decal_path() + . = TRUE + +/obj/item/airlock_painter/decal/debug + name = "extreme decal painter" + icon_state = "decal_sprayer_ex" + +/obj/item/airlock_painter/decal/debug/Initialize() + . = ..() + ink = new /obj/item/toner/extreme(src) \ No newline at end of file diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 0e3744cd84..b90fd1c1af 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -692,6 +692,17 @@ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) needs_anchored = FALSE +/obj/item/circuitboard/machine/chem_dispenser/apothecary + name = "Apotechary Chem Dispenser (Machine Board)" + build_path = /obj/machinery/chem_dispenser/apothecary + req_components = list( + /obj/item/stock_parts/matter_bin = 1, + /obj/item/stock_parts/capacitor = 1, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell = 1) + def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/upgraded/plus) + /obj/item/circuitboard/machine/chem_dispenser/drinks name = "Soda Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/drinks @@ -707,6 +718,10 @@ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) needs_anchored = FALSE +/obj/item/circuitboard/machine/sleeper/party + name = "Party Pod (Machine Board)" + build_path = /obj/machinery/sleeper/party + /obj/item/circuitboard/machine/smoke_machine name = "Smoke Machine (Machine Board)" build_path = /obj/machinery/smoke_machine @@ -884,6 +899,16 @@ name = "Departmental Protolathe - Service (Machine Board)" build_path = /obj/machinery/rnd/production/protolathe/department/service +/obj/item/circuitboard/machine/bepis + name = "BEPIS Chamber (Machine Board)" + build_path = /obj/machinery/rnd/bepis + req_components = list( + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/capacitor = 1, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/micro_laser = 1, + /obj/item/stock_parts/scanning_module = 1) + /obj/item/circuitboard/machine/techfab name = "\improper Techfab (Machine Board)" build_path = /obj/machinery/rnd/production/techfab @@ -1068,3 +1093,12 @@ /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1, /obj/item/stack/sheet/glass = 1) + +/obj/item/circuitboard/machine/hypnochair + name = "Enhanced Interrogation Chamber (Machine Board)" + icon_state = "security" + build_path = /obj/machinery/hypnochair + req_components = list( + /obj/item/stock_parts/micro_laser = 2, + /obj/item/stock_parts/scanning_module = 2 + ) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 5b332cda46..7450cb937c 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -99,7 +99,7 @@ if(href_list["reset_radio_short"]) pai.unshort_radio() if(href_list["setlaws"]) - var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN) + var/newlaws = stripped_multiline_input(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", "", MAX_MESSAGE_LEN) if(newlaws && pai) pai.add_supplied_law(0,newlaws) if(href_list["toggle_holo"]) diff --git a/code/game/objects/items/devices/polycircuit.dm b/code/game/objects/items/devices/polycircuit.dm new file mode 100644 index 0000000000..fb15ce45dc --- /dev/null +++ b/code/game/objects/items/devices/polycircuit.dm @@ -0,0 +1,52 @@ +/obj/item/stack/circuit_stack + name = "polycircuit aggregate" + desc = "A dense, overdesigned cluster of electronics which attempted to function as a multipurpose circuit electronic. Circuits can be removed from it... if you don't bleed out in the process." + icon_state = "circuit_mess" + item_state = "rods" + w_class = WEIGHT_CLASS_TINY + max_amount = 8 + var/circuit_type = /obj/item/electronics/airlock + var/chosen_circuit = "airlock" + +/obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it. + to_chat(user, "You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.") + +/obj/item/stack/circuit_stack/attack_hand(mob/user) + var/mob/living/carbon/human/H = user + if(!user.get_inactive_held_item() == src) + return ..() + else + if(zero_amount()) + return + chosen_circuit = input("What type of circuit would you like to remove?", "Choose a Circuit Type", chosen_circuit) in list("airlock","firelock","fire alarm","air alarm","APC") + if(zero_amount()) + return + switch(chosen_circuit) + if("airlock") + circuit_type = /obj/item/electronics/airlock + if("firelock") + circuit_type = /obj/item/electronics/firelock + if("fire alarm") + circuit_type = /obj/item/electronics/firealarm + if("air alarm") + circuit_type = /obj/item/electronics/airalarm + if("APC") + circuit_type = /obj/item/electronics/apc + to_chat(user, "You spot your circuit, and carefully attempt to remove it from [src], hold still!") + if(do_after(user, 30, target = user)) + if(!src || QDELETED(src))//Sanity Check. + return + var/returned_circuit = new circuit_type(src) + user.put_in_hands(returned_circuit) + use(1) + if(!amount) + to_chat(user, "You navigate the sharp edges of circuitry and remove the last board.") + else + to_chat(user, "You navigate the sharp edges of circuitry and remove a single board from [src]") + else + H.apply_damage(15, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + to_chat(user, "You give yourself a wicked cut on [src]'s many sharp corners and edges!") + ..() + +/obj/item/stack/circuit_stack/full + amount = 8 diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 897f452091..5fe9de75aa 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -98,7 +98,7 @@ /obj/item/radio/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) /obj/item/radio/interact(mob/user) if(unscrewed && !isAI(user)) diff --git a/code/game/objects/items/grenades/antigravity.dm b/code/game/objects/items/grenades/antigravity.dm index 43b2f94986..a4bc207be0 100644 --- a/code/game/objects/items/grenades/antigravity.dm +++ b/code/game/objects/items/grenades/antigravity.dm @@ -2,16 +2,16 @@ name = "antigravity grenade" icon_state = "emp" item_state = "emp" - + var/range = 7 var/forced_value = 0 var/duration = 300 /obj/item/grenade/antigravity/prime() update_mob() - + for(var/turf/T in view(range,src)) - var/datum/component/C = T.AddComponent(/datum/component/forced_gravity,forced_value) - QDEL_IN(C,duration) - + T.AddElement(/datum/element/forced_gravity, forced_value) + addtimer(CALLBACK(T, /datum/.proc/_RemoveElement, list(forced_value)), duration) + qdel(src) diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 66869d6f04..fe2a27f1a8 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -26,7 +26,7 @@ /obj/item/grenade/plastic/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) /obj/item/grenade/plastic/Destroy() qdel(nadeassembly) diff --git a/code/game/objects/items/implants/implant_abductor.dm b/code/game/objects/items/implants/implant_abductor.dm index 0c50beadea..e0765e7951 100644 --- a/code/game/objects/items/implants/implant_abductor.dm +++ b/code/game/objects/items/implants/implant_abductor.dm @@ -5,36 +5,30 @@ icon_state = "implant" activated = 1 var/obj/machinery/abductor/pad/home - var/cooldown = 30 + var/next_use = 0 /obj/item/implant/abductor/activate() . = ..() - if(cooldown == initial(cooldown)) + if(next_use <= world.time) home.Retrieve(imp_in,1) - cooldown = 0 - START_PROCESSING(SSobj, src) + next_use = world.time + 60 SECONDS else - to_chat(imp_in, "You must wait [30 - cooldown] seconds to use [src] again!") - -/obj/item/implant/abductor/process() - if(cooldown < initial(cooldown)) - cooldown++ - if(cooldown == initial(cooldown)) - STOP_PROCESSING(SSobj, src) + to_chat(imp_in, "You must wait [DisplayTimeText(next_use - world.time)] to use [src] again!") /obj/item/implant/abductor/implant(mob/living/target, mob/user) - if(..()) - var/obj/machinery/abductor/console/console - if(ishuman(target)) - var/datum/antagonist/abductor/A = target.mind.has_antag_datum(/datum/antagonist/abductor) - if(A) - console = get_abductor_console(A.team.team_number) - home = console.pad - - if(!home) - var/list/consoles = list() - for(var/obj/machinery/abductor/console/C in GLOB.machines) - consoles += C - console = pick(consoles) + . = ..() + if(!.) + return + var/obj/machinery/abductor/console/console + if(ishuman(target)) + var/datum/antagonist/abductor/A = target.mind.has_antag_datum(/datum/antagonist/abductor) + if(A) + console = get_abductor_console(A.team.team_number) home = console.pad - return TRUE + + if(!home) + var/list/consoles = list() + for(var/obj/machinery/abductor/console/C in GLOB.machines) + consoles += C + console = pick(consoles) + home = console.pad diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 168bca0b9a..77d9f09eff 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -104,10 +104,10 @@ desc = "An occult looking dagger that is cold to the touch. Somehow, the flawless orb on the pommel is made entirely of liquid blood." icon = 'icons/obj/ice_moon/artifacts.dmi' icon_state = "bloodletter" - w_class = WEIGHT_CLASS_NORMAL + w_class = WEIGHT_CLASS_NORMAL /// Bleed stacks applied when an organic mob target is hit var/bleed_stacks_per_hit = 3 - + /obj/item/kitchen/knife/bloodletter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() if(!isliving(target) || !proximity_flag) @@ -198,6 +198,7 @@ throw_speed = 3 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 1.5) attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") custom_price = 200 diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 1ca314f749..2f697553f5 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -419,7 +419,7 @@ A.BB.damage = hitdamage if(hitdamage) A.BB.nodamage = FALSE - A.BB.speed = 0.5 + A.BB.pixels_per_second = TILES_TO_PIXELS(20) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) A.fire_casing(target, user, params, 0, 0, null, 0, src) user.visible_message("[user] blasts a flying lollipop at [target]!") @@ -434,7 +434,7 @@ A.BB.damage = hitdamage if(hitdamage) A.BB.nodamage = FALSE - A.BB.speed = 0.5 + A.BB.pixels_per_second = TILES_TO_PIXELS(20) A.BB.color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) playsound(src.loc, 'sound/weapons/bulletflyby3.ogg', 50, 1) A.fire_casing(target, user, params, 0, 0, null, 0, src) @@ -671,13 +671,13 @@ if(track_projectile) tracked[P] = P.damage P.damage *= projectile_damage_coefficient - P.speed *= projectile_speed_coefficient + P.pixels_per_second *= projectile_speed_coefficient P.add_overlay(projectile_effect) /obj/item/borg/projectile_dampen/proc/restore_projectile(obj/item/projectile/P) tracked -= P P.damage *= (1/projectile_damage_coefficient) - P.speed *= (1/projectile_speed_coefficient) + P.pixels_per_second *= (1/projectile_speed_coefficient) P.cut_overlay(projectile_effect) /********************************************************************** diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 1459afeb2d..b9cde1664f 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -107,7 +107,7 @@ return TRUE /obj/item/shield/proc/user_shieldbash(mob/living/user, atom/target, harmful) - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //Combat mode has to be enabled for shield bashing + if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) //Combat mode has to be enabled for shield bashing return FALSE if(!(shield_flags & SHIELD_CAN_BASH)) to_chat(user, "[src] can't be used to shield bash!") @@ -274,7 +274,7 @@ obj/item/shield/riot/bullet_proof item_state = "buckler" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - custom_materials = null + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 10) resistance_flags = FLAMMABLE repair_material = /obj/item/stack/sheet/mineral/wood block_chance = 30 diff --git a/code/game/objects/items/stacks/cash.dm b/code/game/objects/items/stacks/cash.dm index a06b96ad9c..ce0bc6591a 100644 --- a/code/game/objects/items/stacks/cash.dm +++ b/code/game/objects/items/stacks/cash.dm @@ -71,3 +71,9 @@ icon_state = "spacecash1000" singular_name = "one thousand credit bill" value = 1000 + +/obj/item/stack/spacecash/c10000 + icon_state = "spacecash10000" + singular_name = "ten thousand credit bill" + value = 10000 + diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index e919f3fe02..4c2c21a7db 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -89,3 +89,19 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ /obj/item/stack/rods/fifty amount = 50 + +/obj/item/stack/rods/lava + name = "heat resistant rod" + desc = "Treated, specialized metal rods. When exposed to the vaccum of space their coating breaks off, but they can hold up against the extreme heat of active lava." + singular_name = "heat resistant rod" + icon_state = "rods" + item_state = "rods" + color = "#5286b9ff" + flags_1 = CONDUCT_1 + w_class = WEIGHT_CLASS_NORMAL + custom_materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000) + max_amount = 30 + resistance_flags = FIRE_PROOF | LAVA_PROOF + +/obj/item/stack/rods/lava/thirty + amount = 30 diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index aebc5121cd..6553cd2f7c 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \ new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \ null, \ - new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \ null, \ new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ @@ -240,6 +240,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new /datum/stack_recipe("pew (right)", /obj/structure/chair/pew/right, 3, one_per_turf = TRUE, on_floor = TRUE),\ )), null, \ + new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 40), \ new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \ new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \ @@ -279,11 +280,13 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ icon_state = "sheet-wood" item_state = "sheet-wood" icon = 'icons/obj/stack_objects.dmi' + custom_materials = list(/datum/material/wood=MINERAL_MATERIAL_AMOUNT) sheettype = "wood" armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE + material_type = /datum/material/wood grind_results = list(/datum/reagent/carbon = 20) /obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there. @@ -402,8 +405,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ resistance_flags = FLAMMABLE force = 0 throwforce = 0 - pull_effort = 90 - is_fabric = TRUE merge_type = /obj/item/stack/sheet/cloth /obj/item/stack/sheet/cloth/get_main_recipes() @@ -424,7 +425,7 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \ new/datum/stack_recipe("durathread bandana", /obj/item/clothing/mask/bandana/durathread, 1, time = 25), \ - new/datum/stack_recipe("durathread string", /obj/item/weaponcrafting/durathread_string, 1, time = 40) \ + new/datum/stack_recipe("durathread string", /obj/item/weaponcrafting/durathread_string, 1, time = 40), \ )) /obj/item/stack/sheet/durathread @@ -816,13 +817,12 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra max_amount = 80 singular_name = "raw cotton ball" icon_state = "sheet-cotton" - is_fabric = TRUE resistance_flags = FLAMMABLE force = 0 throwforce = 0 merge_type = /obj/item/stack/sheet/cotton - pull_effort = 30 - loom_result = /obj/item/stack/sheet/cloth + var/pull_effort = 30 + var/loom_result = /obj/item/stack/sheet/cloth /obj/item/stack/sheet/cotton/ten amount = 10 diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 378855707e..dfba533247 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -13,9 +13,6 @@ mats_per_stack = MINERAL_MATERIAL_AMOUNT var/sheettype = null //this is used for girders in the creation of walls/false walls var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity - var/is_fabric = FALSE //is this a valid material for the loom? - var/loom_result //result from pulling on the loom - var/pull_effort = 0 //amount of delay when pulling on the loom var/shard_type // the shard debris typepath left over by solar panels and windows etc. /obj/item/stack/sheet/Initialize(mapload, new_amount, merge) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index add9ebd6b2..2c8e700316 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -201,8 +201,13 @@ if(!building_checks(R, multiplier)) return if (R.time) + var/adjusted_time = 0 usr.visible_message("[usr] starts building [R.title].", "You start building [R.title]...") - if (!do_after(usr, R.time, target = usr)) + if(HAS_TRAIT(usr, R.trait_booster)) + adjusted_time = (R.time * R.trait_modifier) + else + adjusted_time = R.time + if (!do_after(usr, adjusted_time, target = usr)) return if(!building_checks(R, multiplier)) return @@ -457,8 +462,10 @@ var/window_checks = FALSE var/placement_checks = FALSE var/applies_mats = FALSE + var/trait_booster = null + var/trait_modifier = 1 -/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE) +/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1) src.title = title @@ -472,6 +479,8 @@ src.window_checks = window_checks src.placement_checks = placement_checks src.applies_mats = applies_mats + src.trait_booster = trait_booster + src.trait_modifier = trait_modifier /* * Recipe list datum */ diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index de98963693..092648ee3c 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -223,6 +223,8 @@ /obj/item/storage/pill_bottle/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT + STR.max_volume = 14 STR.allow_quick_gather = TRUE STR.click_gather = TRUE STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice)) @@ -244,7 +246,7 @@ desc = "Contains pills used to counter radiation poisoning." /obj/item/storage/pill_bottle/anitrad/PopulateContents() - for(var/i in 1 to 5) + for(var/i in 1 to 4) new /obj/item/reagent_containers/pill/antirad(src) /obj/item/storage/pill_bottle/epinephrine @@ -276,7 +278,7 @@ desc = "Guaranteed to give you that extra burst of energy during a long shift!" /obj/item/storage/pill_bottle/stimulant/PopulateContents() - for(var/i in 1 to 5) + for(var/i in 1 to 4) new /obj/item/reagent_containers/pill/stimulant(src) /obj/item/storage/pill_bottle/mining diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 634537e5a2..e9364bcede 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -16,7 +16,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) var/stamforce = 35 - var/status = FALSE + var/turned_on = FALSE var/knockdown = TRUE var/obj/item/stock_parts/cell/cell var/hitcost = 750 @@ -49,7 +49,7 @@ /obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() //Only mob/living types have stun handling - if(status && prob(throw_hit_chance) && iscarbon(hit_atom)) + if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom)) baton_stun(hit_atom) /obj/item/melee/baton/loaded //this one starts with a cell pre-installed. @@ -66,16 +66,16 @@ copper_top.use(min(chrgdeductamt, copper_top.charge), explode) if(QDELETED(src)) return FALSE - if(status && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY)))) + if(turned_on && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY)))) //we're below minimum, turn off switch_status(FALSE) /obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE) - if(status != new_status) - status = new_status + if(turned_on != new_status) + turned_on = new_status if(!silent) playsound(loc, "sparks", 75, 1, -1) - if(status) + if(turned_on) START_PROCESSING(SSobj, src) else STOP_PROCESSING(SSobj, src) @@ -85,7 +85,7 @@ deductcharge(round(hitcost * STUNBATON_DEPLETION_RATE), FALSE, FALSE) /obj/item/melee/baton/update_icon_state() - if(status) + if(turned_on) icon_state = "[initial(name)]_active" else if(!cell) icon_state = "[initial(name)]_nocell" @@ -134,8 +134,8 @@ else to_chat(user, "[src] is out of charge.") else - switch_status(!status) - to_chat(user, "[src] is now [status ? "on" : "off"].") + switch_status(!turned_on) + to_chat(user, "[src] is now [turned_on ? "on" : "off"].") add_fingerprint(user) /obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user) @@ -151,7 +151,7 @@ /obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE) if(iscyborg(M) || !isliving(M)) //can't baton cyborgs return FALSE - if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) + if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) clowning_around(user) if(IS_STAMCRIT(user)) //CIT CHANGE - makes it impossible to baton in stamina softcrit to_chat(user, "You're too exhausted for that.") @@ -160,7 +160,7 @@ var/mob/living/carbon/human/L = M if(check_martial_counter(L, user)) return TRUE - if(status) + if(turned_on) if(baton_stun(M, user, disarming)) user.do_attack_animation(M) user.adjustStaminaLossBuffered(getweight(user, STAM_COST_BATON_MOB_MULT)) @@ -292,6 +292,48 @@ sparkler?.activate() . = ..() +/obj/item/melee/baton/boomerang + name = "\improper OZtek Boomerang" + desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!" + throw_speed = 1 + icon_state = "boomerang" + item_state = "boomerang" + force = 5 + throwforce = 5 + throw_range = 5 + hitcost = 2000 + throw_hit_chance = 99 //Have you prayed today? + custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000) + +/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force) + if(turned_on) + if(ishuman(thrower)) + var/mob/living/carbon/human/H = thrower + H.throw_mode_off() //so they can catch it on the return. + return ..() + +/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(turned_on) + var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum) + if(ishuman(hit_atom) && !caught && prob(throw_hit_chance))//if they are a carbon and they didn't catch it + baton_stun(hit_atom) + if(thrownby && !caught) + sleep(1) + if(!QDELETED(src)) + throw_at(thrownby, throw_range+2, throw_speed, null, TRUE) + else + return ..() + +/obj/item/melee/baton/boomerang/update_icon() + if(turned_on) + icon_state = "[initial(icon_state)]_active" + else if(!cell) + icon_state = "[initial(icon_state)]_nocell" + else + icon_state = "[initial(icon_state)]" + +/obj/item/melee/baton/boomerang/loaded //Same as above, comes with a cell. + preload_cell_type = /obj/item/stock_parts/cell/high #undef STUNBATON_CHARGE_LENIENCY #undef STUNBATON_DEPLETION_RATE diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index e81294ceea..817258d1c7 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -14,13 +14,15 @@ var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not var/datum/effect_system/trail_follow/ion/ion_trail -/obj/item/tank/jetpack/New() +/obj/item/tank/jetpack/Initialize() ..() + ion_trail = new + ion_trail.set_up(src) + +/obj/item/tank/jetpack/populate_gas() if(gas_type) air_contents.gases[gas_type] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - ion_trail = new - ion_trail.set_up(src) /obj/item/tank/jetpack/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/toggle_jetpack)) @@ -188,8 +190,8 @@ var/obj/item/tank/internals/tank = null var/mob/living/carbon/human/cur_user -/obj/item/tank/jetpack/suit/New() - ..() +/obj/item/tank/jetpack/suit/Initialize() + . = ..() STOP_PROCESSING(SSobj, src) temp_air_contents = air_contents diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 0e6dfaa1b3..8f5303da8e 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -12,15 +12,13 @@ */ /obj/item/tank/internals/oxygen name = "oxygen tank" - desc = "A tank of oxygen." + desc = "A tank of oxygen, this one is blue." icon_state = "oxygen" distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE force = 10 dog_fashion = /datum/dog_fashion/back - -/obj/item/tank/internals/oxygen/New() - ..() +/obj/item/tank/internals/oxygen/populate_gas() air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -35,6 +33,8 @@ icon_state = "oxygen_fr" dog_fashion = null +/obj/item/tank/internals/oxygen/empty/populate_gas() + return /* * Anesthetic @@ -46,11 +46,9 @@ item_state = "an_tank" force = 10 -/obj/item/tank/internals/anesthetic/New() - ..() +/obj/item/tank/internals/anesthetic/populate_gas() air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD air_contents.gases[/datum/gas/nitrous_oxide] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD - return /* * Air @@ -63,11 +61,9 @@ force = 10 dog_fashion = /datum/dog_fashion/back -/obj/item/tank/internals/air/New() - ..() +/obj/item/tank/internals/air/populate_gas() air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD air_contents.gases[/datum/gas/nitrogen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD - return /* @@ -82,10 +78,8 @@ force = 8 -/obj/item/tank/internals/plasma/New() - ..() +/obj/item/tank/internals/plasma/populate_gas() air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - return /obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/flamethrower)) @@ -100,10 +94,8 @@ else return ..() -/obj/item/tank/internals/plasma/full/New() - ..() // Plasma asserted in parent +/obj/item/tank/internals/plasma/full/populate_gas() air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - return /* @@ -118,13 +110,10 @@ force = 10 distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE -/obj/item/tank/internals/plasmaman/New() - ..() +/obj/item/tank/internals/plasmaman/populate_gas() air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - return -/obj/item/tank/internals/plasmaman/full/New() - ..() // Plasma asserted in parent +/obj/item/tank/internals/plasmaman/full/populate_gas() air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -137,12 +126,12 @@ volume = 6 w_class = WEIGHT_CLASS_SMALL //thanks i forgot this -/obj/item/tank/internals/plasmaman/belt/full/New() - ..() // Plasma asserted in parent +/obj/item/tank/internals/plasmaman/belt/full/populate_gas() air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return - +/obj/item/tank/internals/plasmaman/belt/empty/populate_gas() + return /* * Emergency Oxygen @@ -159,17 +148,25 @@ volume = 3 //Tiny. Real life equivalents only have 21 breaths of oxygen in them. They're EMERGENCY tanks anyway -errorage (dangercon 2011) -/obj/item/tank/internals/emergency_oxygen/New() - ..() +/obj/item/tank/internals/emergency_oxygen/populate_gas() air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return +/obj/item/tank/internals/emergency_oxygen/empty/populate_gas() + return + /obj/item/tank/internals/emergency_oxygen/engi name = "extended-capacity emergency oxygen tank" icon_state = "emergency_engi" volume = 6 +/obj/item/tank/internals/emergency_oxygen/engi/empty/populate_gas() + return + /obj/item/tank/internals/emergency_oxygen/double name = "double emergency oxygen tank" icon_state = "emergency_double" volume = 10 + +/obj/item/tank/internals/emergency_oxygen/double/empty/populate_gas() + return \ No newline at end of file diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 1c92ed4e61..95712f386a 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -60,14 +60,19 @@ H.update_action_buttons_icon() -/obj/item/tank/New() - ..() +/obj/item/tank/Initialize() + . = ..() air_contents = new(volume) //liters air_contents.temperature = T20C + populate_gas() + START_PROCESSING(SSobj, src) +/obj/item/tank/proc/populate_gas() + return + /obj/item/tank/Destroy() if(air_contents) qdel(air_contents) @@ -78,9 +83,9 @@ /obj/item/tank/examine(mob/user) var/obj/icon = src . = ..() - if (istype(src.loc, /obj/item/assembly)) + if(istype(src.loc, /obj/item/assembly)) icon = src.loc - if(!in_range(src, user)) + if(!in_range(src, user) && !isobserver(user)) if (icon == src) . += "If you want any more information you'll need to get closer." return diff --git a/code/game/objects/items/tools/saw.dm b/code/game/objects/items/tools/saw.dm new file mode 100644 index 0000000000..aab59c00be --- /dev/null +++ b/code/game/objects/items/tools/saw.dm @@ -0,0 +1,47 @@ +/obj/item/hatchet/saw + name = "handsaw" + desc = "A very sharp handsaw, it's compact." + icon = 'icons/obj/tools.dmi' + icon_state = "saw" + item_state = "sawhandle_greyscale" + lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' + tool_behaviour = TOOL_SAW + force = 10 + throwforce = 8 + throw_speed = 3 + throw_range = 5 + custom_materials = list(/datum/material/iron = 5000) + attack_verb = list("sawed", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = IS_SHARP + var/random_color = TRUE //code taken from screwdrivers.dm; cool handles are cool. + var/static/list/saw_colors = list( + "blue" = rgb(24, 97, 213), + "red" = rgb(255, 0, 0), + "pink" = rgb(213, 24, 141), + "brown" = rgb(160, 82, 18), + "green" = rgb(14, 127, 27), + "cyan" = rgb(24, 162, 213), + "yellow" = rgb(255, 165, 0) + ) + +/obj/item/hatchet/saw/Initialize() + . = ..() + if(random_color) + icon_state = "sawhandle_greyscale" + var/our_color = pick(saw_colors) + add_atom_colour(saw_colors[our_color], FIXED_COLOUR_PRIORITY) + update_icon() + if(prob(75)) + pixel_y = rand(-8, 8) + +/obj/item/hatchet/saw/update_overlays() + . = ..() + if(!random_color) //icon override + return + var/mutable_appearance/base_overlay = mutable_appearance(icon, "sawblade") + base_overlay.appearance_flags = RESET_COLOR + . += base_overlay + +// END \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 171355bef3..e545d74e12 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -782,6 +782,7 @@ var/cooldown = 0 var/obj/machinery/computer/holodeck/holo = null // Holodeck cards should not be infinite var/list/cards = list() + var/original_size = 52 /obj/item/toy/cards/deck/Initialize() . = ..() @@ -839,11 +840,11 @@ /obj/item/toy/cards/deck/update_icon_state() switch(cards.len) - if(27 to INFINITY) + if(INFINITY to original_size/2) icon_state = "deck_[deckstyle]_full" - if(11 to 27) + if(original_size/2 to original_size/4) icon_state = "deck_[deckstyle]_half" - if(1 to 11) + if(original_size/4 to 1) icon_state = "deck_[deckstyle]_low" else icon_state = "deck_[deckstyle]_empty" diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index dc39f7f89d..3a74b644ff 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -477,20 +477,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 throw_speed = 5 throw_range = 2 attack_verb = list("busted") + var/impressiveness = 45 -/obj/item/statuebust/attack_self(mob/living/user) - add_fingerprint(user) - user.examinate(src) - -/obj/item/statuebust/examine(mob/living/user) +/obj/item/statuebust/Initialize() . = ..() - if(.) - return - if (!isliving(user)) - return - user.visible_message("[user] stops to admire [src].", \ - "You take in [src], admiring its fine craftsmanship.") - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) + AddElement(/datum/element/art, impressiveness) + addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 1000)), 0) /obj/item/tailclub name = "tail club" @@ -566,6 +558,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 force = 10 throwforce = 12 attack_verb = list("beat", "smacked") + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5) w_class = WEIGHT_CLASS_BULKY var/homerun_ready = 0 var/homerun_able = 0 diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 98f772a116..fcc26d1313 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -240,7 +240,7 @@ /obj/structure/sign/painting/Initialize(mapload, dir, building) . = ..() SSpersistence.painting_frames += src - AddComponent(/datum/component/art, 20) + AddElement(/datum/element/art, 20) if(dir) setDir(dir) if(building) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 57d7e08862..bd6dcb2aff 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -261,6 +261,11 @@ LINEN BINS var/list/sheets = list() var/obj/item/hidden = null +/obj/structure/bedsheetbin/empty + amount = 0 + icon_state = "linenbin-empty" + anchored = FALSE + /obj/structure/bedsheetbin/examine(mob/user) . = ..() if(amount < 1) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index daa3631a46..ce78b92f38 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -302,7 +302,8 @@ /obj/item/kirbyplants/ComponentInitialize() . = ..() - AddComponent(/datum/component/tactical) + AddElement(/datum/element/tactical) + addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 500)), 0) AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_unwielded=10, force_wielded=10) /obj/item/kirbyplants/random diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index fd62ffd368..cacf361722 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -6,6 +6,7 @@ density = TRUE var/state = GIRDER_NORMAL var/girderpasschance = 20 // percentage chance that a projectile passes through the girder. + var/next_beep = 0 //Prevents spamming of the construction sound var/can_displace = TRUE //If the girder can be moved around by wrenching it max_integrity = 200 rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -27,11 +28,17 @@ . += "[src] is disassembled! You probably shouldn't be able to see this examine message." /obj/structure/girder/attackby(obj/item/W, mob/user, params) + var/platingmodifier = 1 + if(HAS_TRAIT(user, TRAIT_QUICK_BUILD)) + platingmodifier = 0.7 + if(next_beep <= world.time) + next_beep = world.time + 10 + playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE) add_fingerprint(user) if(istype(W, /obj/item/gun/energy/plasmacutter)) to_chat(user, "You start slicing apart the girder...") - if(W.use_tool(src, user, 40, volume=100)) + if(W.use_tool(src, user, 40*platingmodifier, volume=100)) to_chat(user, "You slice apart the girder.") var/obj/item/stack/sheet/metal/M = new (loc, 2) M.add_fingerprint(user) @@ -62,7 +69,7 @@ to_chat(user, "You need at least two rods to create a false wall!") return to_chat(user, "You start building a reinforced false wall...") - if(do_after(user, 20, target = src)) + if(do_after(user, 20*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) @@ -75,7 +82,7 @@ to_chat(user, "You need at least five rods to add plating!") return to_chat(user, "You start adding plating...") - if(do_after(user, 40, target = src)) + if(do_after(user, 40*platingmodifier, target = src)) if(S.get_amount() < 5) return S.use(5) @@ -96,7 +103,7 @@ to_chat(user, "You need two sheets of metal to create a false wall!") return to_chat(user, "You start building a false wall...") - if(do_after(user, 20, target = src)) + if(do_after(user, 20*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) @@ -109,7 +116,7 @@ to_chat(user, "You need two sheets of metal to finish a wall!") return to_chat(user, "You start adding plating...") - if (do_after(user, 40, target = src)) + if (do_after(user, 40*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) @@ -126,7 +133,7 @@ to_chat(user, "You need at least two sheets to create a false wall!") return to_chat(user, "You start building a reinforced false wall...") - if(do_after(user, 20, target = src)) + if(do_after(user, 20*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) @@ -139,7 +146,7 @@ if(S.get_amount() < 1) return to_chat(user, "You start finalizing the reinforced wall...") - if(do_after(user, 50, target = src)) + if(do_after(user, 50*platingmodifier, target = src)) if(S.get_amount() < 1) return S.use(1) @@ -153,7 +160,7 @@ if(S.get_amount() < 1) return to_chat(user, "You start reinforcing the girder...") - if(do_after(user, 60, target = src)) + if(do_after(user, 60*platingmodifier, target = src)) if(S.get_amount() < 1) return S.use(1) @@ -172,7 +179,7 @@ if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to create a false wall!") return - if(do_after(user, 20, target = src)) + if(do_after(user, 20*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) @@ -188,7 +195,7 @@ to_chat(user, "You need at least two sheets to add plating!") return to_chat(user, "You start adding plating...") - if (do_after(user, 40, target = src)) + if (do_after(user, 40*platingmodifier, target = src)) if(S.get_amount() < 2) return S.use(2) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c41d6d32af..6e497cff60 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -149,3 +149,30 @@ pixel_x = 0 pixel_y = 0 return TRUE + +/obj/structure/lattice/lava + name = "heatproof support lattice" + desc = "A specialized support beam for building across lava. Watch your step." + icon = 'icons/obj/smooth_structures/catwalk.dmi' + icon_state = "catwalk" + number_of_rods = 1 + color = "#5286b9ff" + smooth = SMOOTH_TRUE + canSmoothWith = null + obj_flags = CAN_BE_HIT | BLOCK_Z_FALL + resistance_flags = FIRE_PROOF | LAVA_PROOF + +/obj/structure/lattice/lava/deconstruction_hints(mob/user) + return "The rods look like they could be cut, but the heat treatment will shatter off. There's space for a tile." + +/obj/structure/lattice/lava/attackby(obj/item/C, mob/user, params) + . = ..() + if(istype(C, /obj/item/stack/tile/plasteel)) + var/obj/item/stack/tile/plasteel/P = C + if(P.use(1)) + to_chat(user, "You construct a floor plating, as lava settles around the rods.") + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /turf/open/floor/plating(locate(x, y, z)) + else + to_chat(user, "You need one floor tile to build atop [src].") + return diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm index ad128b01c2..164e597117 100644 --- a/code/game/objects/structures/loom.dm +++ b/code/game/objects/structures/loom.dm @@ -21,21 +21,21 @@ return TRUE ///Handles the weaving. -/obj/structure/loom/proc/weave(obj/item/stack/sheet/S, mob/user) - if(!istype(S) || !S.is_fabric) +/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user) + if(!istype(W)) return FALSE if(!anchored) user.show_message("The loom needs to be wrenched down.", MSG_VISUAL) return FALSE - if(S.amount < FABRIC_PER_SHEET) - user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", 1) + if(W.amount < FABRIC_PER_SHEET) + user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", MSG_VISUAL) return FALSE - user.show_message("You start weaving \the [S.name] through the loom..", MSG_VISUAL) - if(S.use_tool(src, user, S.pull_effort)) - if(S.amount >= FABRIC_PER_SHEET) - new S.loom_result(drop_location()) - S.use(FABRIC_PER_SHEET) - user.show_message("You weave \the [S.name] into a workable fabric.", MSG_VISUAL) + user.show_message("You start weaving \the [W.name] through the loom..", MSG_VISUAL) + if(W.use_tool(src, user, W.pull_effort)) + if(W.amount >= FABRIC_PER_SHEET) + new W.loom_result(drop_location()) + W.use(FABRIC_PER_SHEET) + user.show_message("You weave \the [W.name] into a workable fabric.", MSG_VISUAL) return TRUE #undef FABRIC_PER_SHEET \ No newline at end of file diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index a1de5fe6a3..aa31fe9542 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -36,6 +36,7 @@ "You unfasten [src].") var/obj/item/sign_backing/SB = new (get_turf(user)) SB.icon_state = icon_state + SB.set_custom_materials(custom_materials) //This is here so picture frames and wooden things don't get messed up. SB.sign_path = type SB.setDir(dir) qdel(src) diff --git a/code/game/objects/structures/signs/signs_plaques.dm b/code/game/objects/structures/signs/signs_plaques.dm index 78c88cd09d..d1067f1963 100644 --- a/code/game/objects/structures/signs/signs_plaques.dm +++ b/code/game/objects/structures/signs/signs_plaques.dm @@ -46,3 +46,4 @@ name = "Mr. Deempisi portrait" desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'" icon_state = "monkey_painting" + custom_materials = list(/datum/material/wood = 2000) //The same as /obj/structure/sign/picture_frame diff --git a/code/game/objects/structures/signs/signs_warning.dm b/code/game/objects/structures/signs/signs_warning.dm index f735ed7bc9..3138d44e9d 100644 --- a/code/game/objects/structures/signs/signs_warning.dm +++ b/code/game/objects/structures/signs/signs_warning.dm @@ -73,3 +73,8 @@ name = "\improper ENGINEERING SAFETY" desc = "A sign detailing the various safety protocols when working on-site to ensure a safe shift." icon_state = "safety" + +/obj/structure/sign/warning/explosives + name = "\improper HIGH EXPLOSIVES sign" + desc = "A warning sign which reads 'HIGH EXPLOSIVES'." + icon_state = "explosives" diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 1f9491f4cf..466912f93e 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -11,6 +11,12 @@ var/impressiveness = 15 CanAtmosPass = ATMOS_PASS_DENSITY + +/obj/structure/statue/Initialize() + . = ..() + AddElement(/datum/element/art, impressiveness) + addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, impressiveness * 75)), 0) + /obj/structure/statue/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) if(!(flags_1 & NODECONSTRUCT_1)) @@ -29,29 +35,6 @@ return return ..() -/obj/structure/statue/attack_hand(mob/living/user) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) - add_fingerprint(user) - if(!do_after(user, 20, target = src)) - return - user.visible_message("[user] rubs some dust off [src].", \ - "You take in [src], rubbing some dust off its surface.") - if(!ishuman(user)) // only humans have the capacity to appreciate art - return - var/totalimpressiveness = (impressiveness *(obj_integrity/max_integrity)) - switch(totalimpressiveness) - if(GREAT_ART to 100) - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) - if (GOOD_ART to GREAT_ART) - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) - if (BAD_ART to GOOD_ART) - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) - if (0 to BAD_ART) - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) - /obj/structure/statue/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(material_drop_type) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 3d552fa236..012d92e103 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -163,6 +163,9 @@ if(istype(I, /obj/item/storage/bag/tray)) var/obj/item/storage/bag/tray/T = I if(T.contents.len > 0) // If the tray isn't empty + for(var/x in T.contents) + var/obj/item/item = x + AfterPutItemOnTable(item, user) SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) user.visible_message("[user] empties [I] on [src].") return @@ -177,10 +180,14 @@ //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) - return 1 + AfterPutItemOnTable(I, user) + return TRUE else return ..() +/obj/structure/table/proc/AfterPutItemOnTable(obj/item/I, mob/living/user) + return + /obj/structure/table/alt_attack_hand(mob/user) if(user && Adjacent(user) && !user.incapacitated()) user.changeNext_move(CLICK_CD_MELEE*0.5) @@ -214,6 +221,37 @@ material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS buildstack = null //No buildstack, so generate from mat datums +///Table on wheels +/obj/structure/table/rolling + name = "Rolling table" + desc = "A NT brand \"Rolly poly\" rolling table. It can and will move." + anchored = FALSE + smooth = SMOOTH_FALSE + canSmoothWith = list() + icon = 'icons/obj/smooth_structures/rollingtable.dmi' + icon_state = "rollingtable" + var/list/attached_items = list() + +/obj/structure/table/rolling/AfterPutItemOnTable(obj/item/I, mob/living/user) + . = ..() + attached_items += I + RegisterSignal(I, COMSIG_MOVABLE_MOVED, .proc/RemoveItemFromTable) //Listen for the pickup event, unregister on pick-up so we aren't moved + +/obj/structure/table/rolling/proc/RemoveItemFromTable(datum/source, newloc, dir) + if(newloc != loc) //Did we not move with the table? because that shit's ok + return FALSE + attached_items -= source + UnregisterSignal(source, COMSIG_MOVABLE_MOVED) + +/obj/structure/table/rolling/Moved(atom/OldLoc, Dir) + for(var/mob/M in OldLoc.contents)//Kidnap everyone on top + M.forceMove(loc) + for(var/x in attached_items) + var/atom/movable/AM = x + if(!AM.Move(loc)) + RemoveItemFromTable(AM, AM.loc) + return TRUE + /* * Glass tables */ diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 95edd15951..ddf7fa6bc6 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -11,6 +11,8 @@ var/cistern = 0 //if the cistern bit is open var/w_items = 0 //the combined w_class of all the items in the cistern var/mob/living/swirlie = null //the mob being given a swirlie + var/buildstacktype = /obj/item/stack/sheet/metal //they're metal now, shut up + var/buildstackamount = 1 /obj/structure/toilet/Initialize() . = ..() @@ -72,7 +74,18 @@ /obj/structure/toilet/update_icon_state() icon_state = "toilet[open][cistern]" +/obj/structure/toilet/deconstruct() + if(!(flags_1 & NODECONSTRUCT_1)) + if(buildstacktype) + new buildstacktype(loc,buildstackamount) + else + for(var/i in custom_materials) + var/datum/material/M = i + new M.sheet_type(loc, FLOOR(custom_materials[M] / MINERAL_MATERIAL_AMOUNT, 1)) + ..() + /obj/structure/toilet/attackby(obj/item/I, mob/living/user, params) + add_fingerprint(user) if(istype(I, /obj/item/crowbar)) to_chat(user, "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...") playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) @@ -80,7 +93,9 @@ 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() - + else if(I.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1)) + I.play_tool_sound(src) + deconstruct() else if(cistern) if(user.a_intent != INTENT_HARM) if(I.w_class > WEIGHT_CLASS_NORMAL) @@ -95,6 +110,10 @@ w_items += I.w_class to_chat(user, "You carefully place [I] into the cistern.") + if(istype(I, /obj/item/reagent_containers/food/snacks/cube)) + var/obj/item/reagent_containers/food/snacks/cube/cube = I + cube.Expand() + return else if(istype(I, /obj/item/reagent_containers)) if (!open) return @@ -130,6 +149,11 @@ /obj/structure/toilet/secret/prison secret_type = /obj/effect/spawner/lootdrop/prison_loot_toilet +/obj/structure/toilet/greyscale + + material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR + buildstacktype = null + /obj/structure/urinal name = "urinal" desc = "The HU-452, an experimental urinal. Comes complete with experimental urinal cake." @@ -459,6 +483,8 @@ anchored = TRUE var/busy = FALSE //Something's being washed at the moment var/dispensedreagent = /datum/reagent/water // for whenever plumbing happens + var/buildstacktype = /obj/item/stack/sheet/metal + var/buildstackamount = 1 /obj/structure/sink/attack_hand(mob/living/user) . = ..() @@ -520,7 +546,7 @@ if(istype(O, /obj/item/melee/baton)) var/obj/item/melee/baton/B = O if(B.cell) - if(B.cell.charge > 0 && B.status == 1) + if(B.cell.charge > 0 && B.turned_on) flick("baton_active", src) var/stunforce = B.stamforce user.DefaultCombatKnockdown(stunforce * 2) @@ -537,6 +563,11 @@ playsound(loc, 'sound/effects/slosh.ogg', 25, 1) return + if(O.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1)) + O.play_tool_sound(src) + deconstruct() + return + if(istype(O, /obj/item/stack/medical/gauze)) var/obj/item/stack/medical/gauze/G = O new /obj/item/reagent_containers/rag(src.loc) @@ -568,9 +599,18 @@ else return ..() -/obj/structure/sink/deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/metal (loc, 3) - qdel(src) +/obj/structure/sink/deconstruct() + if(!(flags_1 & NODECONSTRUCT_1)) + drop_materials() + ..() + +/obj/structure/sink/proc/drop_materials() + if(buildstacktype) + new buildstacktype(loc,buildstackamount) + else + for(var/i in custom_materials) + var/datum/material/M = i + new M.sheet_type(loc, FLOOR(custom_materials[M] / MINERAL_MATERIAL_AMOUNT, 1)) /obj/structure/sink/kitchen name = "kitchen sink" @@ -655,6 +695,11 @@ icon_state = "puddle" resistance_flags = UNACIDABLE +/obj/structure/sink/greyscale + icon_state = "sink_greyscale" + material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR + buildstacktype = null + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/structure/sink/puddle/attack_hand(mob/M) icon_state = "puddle-splash" @@ -669,6 +714,10 @@ /obj/structure/sink/puddle/deconstruct(disassembled = TRUE) qdel(src) +/obj/structure/sink/greyscale + material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR + buildstacktype = null + //Shower Curtains// //Defines used are pre-existing in layers.dm// diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index c9b429cecc..06cd38a4c3 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -11,6 +11,7 @@ desc = "Stylish dark wood." icon_state = "wood" floor_tile = /obj/item/stack/tile/wood + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 0.25) broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") footstep = FOOTSTEP_WOOD barefootstep = FOOTSTEP_WOOD_BAREFOOT diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm index af48160ef1..0f366fae03 100644 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ b/code/game/turfs/simulated/floor/plasteel_floor.dm @@ -146,3 +146,95 @@ /turf/open/floor/plasteel/sepia icon_state = "sepia" + +/////////////////////////////// +// Pre-Applied Decal Floors // +////////////////////////////// + +// Neutral +/turf/open/floor/plasteel/neutral + icon_state = "neutral_full" +/turf/open/floor/plasteel/neutral/side + icon_state = "neutral" +/turf/open/floor/plasteel/neutral/corner + icon_state = "neutral_corner" + +// Dark Neutral +/turf/open/floor/plasteel/dark/neutral + icon_state = "dark_neutral_full" +/turf/open/floor/plasteel/dark/neutral/checker + icon_state = "dark_neutral_checker" +/turf/open/floor/plasteel/dark/neutral/side + icon_state = "dark_neutral" +/turf/open/floor/plasteel/dark/neutral/corner + icon_state = "dark_neutral_corner" + +// Dark Security +/turf/open/floor/plasteel/dark/security + icon_state = "dark_red_full" +/turf/open/floor/plasteel/dark/security/checker + icon_state = "dark_red_checker" +/turf/open/floor/plasteel/dark/security/side + icon_state = "dark_red" +/turf/open/floor/plasteel/dark/security/corner + icon_state = "dark_red_corner" + +// Engineering +/turf/open/floor/plasteel/engineering + icon_state = "engineering_full" +/turf/open/floor/plasteel/engineering/side + icon_state = "engineering" +/turf/open/floor/plasteel/engineering/corner + icon_state = "engineering_corner" + +// Atmospherics +/turf/open/floor/plasteel/atmospherics + icon_state = "atmospherics_full" +/turf/open/floor/plasteel/atmospherics/side + icon_state = "atmospherics" +/turf/open/floor/plasteel/atmospherics/corner + icon_state = "atmospherics_corner" + +// Command +/turf/open/floor/plasteel/command + icon_state = "command_full" +/turf/open/floor/plasteel/command/side + icon_state = "command" +/turf/open/floor/plasteel/command/corner + icon_state = "command_corner" + +// Medical +/turf/open/floor/plasteel/medical + icon_state = "medical_full" +/turf/open/floor/plasteel/medical/alt + icon_state = "medical_alt" +/turf/open/floor/plasteel/medical/side + icon_state = "medical" +/turf/open/floor/plasteel/medical/corner + icon_state = "medical_corner" + +// Security +/turf/open/floor/plasteel/security + icon_state = "security_full" +/turf/open/floor/plasteel/security/side + icon_state = "security" +/turf/open/floor/plasteel/security/corner + icon_state = "security_corner" + +// Cargo +/turf/open/floor/plasteel/cargo + icon_state = "cargo_full" +/turf/open/floor/plasteel/cargo/side + icon_state = "cargo" +/turf/open/floor/plasteel/cargo/corner + icon_state = "cargo_corner" + +// Misc +/turf/open/floor/plasteel/showroomfloor/shower + icon_state = "shower" +/turf/open/floor/plasteel/goonplaque/alien + icon_state = "plaque1" + desc = "\"This is a plaque is a collaboration of iconography celebrating the peaceful collaboration between the people of Earth and distant alien species." +/turf/open/floor/plasteel/goonplaque/charter + icon_state = "plaque2" + desc = "\"A golden plaque. Etched into it is the introductory article for a cross-species interplanetary constitution, guaranteeing equal rights between species that Nanotrasen relunctantly agreed to." diff --git a/code/game/turfs/simulated/floor/plating/misc_plating.dm b/code/game/turfs/simulated/floor/plating/misc_plating.dm index 23e32ebfe3..5323db001f 100644 --- a/code/game/turfs/simulated/floor/plating/misc_plating.dm +++ b/code/game/turfs/simulated/floor/plating/misc_plating.dm @@ -198,8 +198,7 @@ /turf/open/floor/plating/ice/smooth icon_state = "smooth" smooth = SMOOTH_MORE | SMOOTH_BORDER - canSmoothWith = list(/turf/open/floor/plating/ice/smooth, /turf/open/floor/plating/ice) - /turf/open/floor/plating/ice/colder + canSmoothWith = list(/turf/open/floor/plating/ice/smooth, /turf/open/floor/plating/ice, /turf/open/floor/plating/ice/colder) /turf/open/floor/plating/ice/colder temperature = 140 diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm index dd2b9dfa18..2f223f2c40 100644 --- a/code/game/turfs/simulated/lava.dm +++ b/code/game/turfs/simulated/lava.dm @@ -81,10 +81,25 @@ /turf/open/lava/TakeTemperature(temp) +/turf/open/lava/attackby(obj/item/C, mob/user, params) + ..() + if(istype(C, /obj/item/stack/rods/lava)) + var/obj/item/stack/rods/lava/R = C + var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src) + if(H) + to_chat(user, "There is already a lattice here!") + return + if(R.use(1)) + to_chat(user, "You construct a lattice.") + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /obj/structure/lattice/lava(locate(x, y, z)) + else + to_chat(user, "You need one rod to build a heatproof lattice.") + return /turf/open/lava/proc/is_safe() //if anything matching this typecache is found in the lava, we don't burn things - var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile)) + var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile, /obj/structure/lattice/lava)) var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache) for(var/obj/structure/stone_tile/S in found_safeties) if(S.fallen) diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index a7f4838228..0f1ec6fa85 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -832,7 +832,7 @@ initial_gas_mix = OPENTURF_DEFAULT_ATMOS defer_change = TRUE - + /turf/closed/mineral/gibtonite/ice environment_type = "snow_cavern" icon_state = "icerock_Gibtonite" @@ -846,3 +846,55 @@ turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon initial_gas_mix = ICEMOON_DEFAULT_ATMOS + +/turf/closed/mineral/strong + name = "Very strong rock" + desc = "Seems to be stronger than the other rocks in the area. Only a master of mining techniques could destroy this." + environment_type = "basalt" + turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface + baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface + initial_gas_mix = LAVALAND_DEFAULT_ATMOS + defer_change = 1 + smooth_icon = 'icons/turf/walls/rock_wall.dmi' + +/* +/turf/closed/mineral/strong/attackby(obj/item/I, mob/user, params) + if(!ishuman(user)) + to_chat(usr, "Only a more advanced species could break a rock such as this one!") + return FALSE + var/mob/living/carbon/human/H = user + if(H.mind.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER) + . = ..() + else + to_chat(usr, "The rock seems to be too strong to destroy. Maybe I can break it once I become a master miner.") +*/ + +/turf/closed/mineral/strong/gets_drilled(mob/user) + if(!ishuman(user)) + return // see attackby + /* + var/mob/living/carbon/human/H = user + if(!(H.mind.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER)) + return + */ + drop_ores() +// H.client.give_award(/datum/award/achievement/skill/legendary_miner, H) + var/flags = NONE + if(defer_change) // TODO: make the defer change var a var for any changeturf flag + flags = CHANGETURF_DEFER_CHANGE + ScrapeAway(flags=flags) + addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE) + playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction +// H.mind.adjust_experience(/datum/skill/mining, 100) //yay! + +/turf/closed/mineral/strong/proc/drop_ores() + if(prob(10)) + new /obj/item/stack/sheet/mineral/mythril(src, 5) + else + new /obj/item/stack/sheet/mineral/adamantine(src, 5) + +/turf/closed/mineral/strong/acid_melt() + return + +/turf/closed/mineral/strong/ex_act(severity, target) + return diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index e2ddcdcf6a..9b15729a9e 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -142,3 +142,51 @@ GLOBAL_LIST(round_end_notifiees) log_admin("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") message_admins("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") return "[params] has been added to the current round's bunker bypass list." + +// More (silly) chat commands citadel added. +/datum/tgs_chat_command/wheelofsalt + name = "wheelofsalt" + help_text = "What are Citadel Station 13 players salting about today? Spin the wheel and find out!" + +/datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) + var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " + var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" + var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]" + if(prob(10)) + saltresult += "@here for your salt, all day every day" + if(prob(1)) + saltresult += " @everyone gets some salt this time too" + else + saltresult += "[saltprimarysubject] [saltsecondarysubject]" + return "[saltresult]!" + +/datum/tgs_chat_command/valentine + name = "valentine" + help_text = "Get a random flirt line." + +/datum/tgs_chat_command/valentine/Run(datum/tgs_chat_user/sender, params) + return "[pick(GLOB.flirts)]" + +/datum/tgs_chat_command/despacito + name = "despacito" //someone please high effort this sometime and make it a full on ytdl search + help_text = "This is so sad." + +/datum/tgs_chat_command/despacito/Run() + return "https://www.youtube.com/watch?v=kJQP7kiw5Fk" + +/datum/tgs_chat_command/poly + name = "poly" + help_text = "The Lewder, more applicable Poly speak for Citadel Station 13." + var/list/speech_buffer + +/datum/tgs_chat_command/poly/Run() + LAZYINITLIST(speech_buffer) //I figure this is just safe to do for everything at this point + if(length(speech_buffer)) //Let's not look up the whole json EVERY TIME, just the first time. + return "[pick(speech_buffer)]" + else + var/json_file = file("data/npc_saves/Poly.json") + if(!fexists(json_file)) + return "**BAWWWWWK!** LEAVE THE HEADSET! ***BAWKKKKK!!***" + var/list/json = json_decode(file2text(json_file)) + speech_buffer = json["phrases"] + return "[pick(speech_buffer)]" diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm index 0feb6dfa7e..888db8193b 100644 --- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm +++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm @@ -39,7 +39,7 @@ var/passive_blood_drain = -0.1 //The amount of blood we loose each bloodsucker life() tick // LISTS var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_NIGHT_VISION, \ - TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_VIRUSIMMUNE) + TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_VIRUSIMMUNE, TRAIT_NODECAP, TRAIT_NOGUT) /datum/antagonist/bloodsucker/on_gain() SSticker.mode.bloodsuckers |= owner // Add if not already in here (and you might be, if you were picked at round start) diff --git a/code/modules/antagonists/bloodsucker/powers/feed.dm b/code/modules/antagonists/bloodsucker/powers/feed.dm index cbb9693fba..a113f9c083 100644 --- a/code/modules/antagonists/bloodsucker/powers/feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/feed.dm @@ -43,10 +43,14 @@ to_chat(owner, "Lesser beings require a tighter grip.") return FALSE // Bloodsuckers: - else if(iscarbon(target) && target.mind && target.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) - if(display_error) - to_chat(owner, "Other Bloodsuckers will not fall for your subtle approach.") - return FALSE + else if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(!H.can_inject(owner, TRUE, BODY_ZONE_CHEST)) + return FALSE + if(target.mind && target.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) + if(display_error) + to_chat(owner, "Other Bloodsuckers will not fall for your subtle approach.") + return FALSE // Must have Target if(!target) // || !ismob(target) if(display_error) @@ -63,6 +67,8 @@ return FALSE if(ishuman(target)) var/mob/living/carbon/human/H = target + if(!H.can_inject(owner, TRUE, BODY_ZONE_HEAD) && target == owner.pulling && owner.grab_state < GRAB_AGGRESSIVE) + return FALSE if(NOBLOOD in H.dna.species.species_traits)// || owner.get_blood_id() != target.get_blood_id()) if(display_error) to_chat(owner, "Your victim's blood is not suitable for you to take.") diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm index a4b19f2d40..f1ce13a90f 100644 --- a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm @@ -113,6 +113,8 @@ "You start tenderly lifting [skewee] off of [src]...") if(!do_after(user, 60, target = skewee)) skewee.visible_message("[skewee] painfully slides back down [src].") + if(skewee.stat >= UNCONSCIOUS) + return //by ratvar, no more spamming my deadchat, holy fuck skewee.say("Oof, ouch owwie!!", forced = "fail brass skewer removal") return skewee.visible_message("[skewee] comes free of [src] with a squelching pop!", \ diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 93927f4420..58e826b36d 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -244,6 +244,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) if(!ispath(path)) path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around gases[path] = text2num(gas[id]) + archive() return 1 /datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index 22b15ea868..d89598f6cb 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -17,11 +17,6 @@ //eg: "Bloody screen" > "goggles colour" as the former is much more important -/mob - var/list/client_colours = list() - - - /* Adds an instance of colour_type to the mob's client_colours list colour_type - a typepath (subtyped from /datum/client_colour) @@ -113,4 +108,4 @@ priority = INFINITY //we can't see colors anyway! /datum/client_colour/monochrome/trance - priority = 1 \ No newline at end of file + priority = 1 diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 47255d9535..7d87a82afb 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -99,5 +99,37 @@ /// custom movement keys for this client var/list/movement_keys = list() + ///Autoclick list of two elements, first being the clicked thing, second being the parameters. + var/list/atom/selected_target[2] + ///Autoclick variable referencing the associated item. + var/obj/item/active_mousedown_item = null + ///Used in MouseDrag to preserve the original mouse click parameters + var/mouseParams = "" + ///Used in MouseDrag to preserve the last mouse-entered location. + var/mouseLocation = null + ///Used in MouseDrag to preserve the last mouse-entered object. + var/mouseObject = null + var/mouseControlObject = null + //Middle-mouse-button click dragtime control for aimbot exploit detection. + var/middragtime = 0 + //Middle-mouse-button clicked object control for aimbot exploit detection. + var/atom/middragatom + /// Messages currently seen by this client var/list/seen_messages + ///When was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns + var/cryo_warned = -5 MINUTES + + var/list/parallax_layers + var/list/parallax_layers_cached + var/atom/movable/movingmob + var/turf/previous_turf + ///world.time of when we can state animate()ing parallax again + var/dont_animate_parallax + ///world.time of last parallax update + var/last_parallax_shift + ///ds between parallax updates + var/parallax_throttle = 0 + var/parallax_movedir = 0 + var/parallax_layers_max = 3 + var/parallax_animate_timer diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index ce7ef441c4..d575a53afa 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -789,9 +789,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) log_game("[key_name(src)] is using the middle click aimbot exploit") message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit") add_system_note("aimbot", "Is using the middle click aimbot exploit") - log_click(object, location, control, params, src, "lockout (spam - minute ab c [ab] s [middragtime])") + log_click(object, location, control, params, src, "lockout (spam - minute ab c [ab] s [middragtime])", TRUE) else - log_click(object, location, control, params, src, "lockout (spam - minute)") + log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE) log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") to_chat(src, "[msg]") @@ -811,7 +811,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) return if(ab) //Citadel edit, things with stuff. - log_click(object, location, control, params, src, "dropped (ab c [ab] s [middragtime])") + log_click(object, location, control, params, src, "dropped (ab c [ab] s [middragtime])", TRUE) return if(prefs.log_clicks) diff --git a/code/modules/clothing/glasses/phantomthief.dm b/code/modules/clothing/glasses/phantomthief.dm index fecf660450..6d209ec695 100644 --- a/code/modules/clothing/glasses/phantomthief.dm +++ b/code/modules/clothing/glasses/phantomthief.dm @@ -24,7 +24,7 @@ . += "[DisplayTimeText(nextadrenalinepop - world.time)] left before the adrenaline injector can be used again." /obj/item/clothing/glasses/phantomthief/syndicate/proc/injectadrenaline(mob/living/user, was_forced = FALSE) - if(user.combat_flags & COMBAT_FLAG_COMBAT_TOGGLED && world.time >= nextadrenalinepop) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_TOGGLED) && world.time >= nextadrenalinepop) nextadrenalinepop = world.time + 5 MINUTES user.reagents.add_reagent(/datum/reagent/syndicateadrenals, 5) user.playsound_local(user, 'sound/misc/adrenalinject.ogg', 100, 0, pressure_affected = FALSE) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 63521c9b75..31e9407cdb 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -13,6 +13,53 @@ custom_price = 1200 custom_premium_price = 1200 +/obj/item/toy/sprayoncan + name = "spray-on insulation applicator" + desc = "What is the number one problem facing our station today?" + icon = 'icons/obj/clothing/gloves.dmi' + icon_state = "sprayoncan" + +/obj/item/toy/sprayoncan/afterattack(atom/target, mob/living/carbon/user, proximity) + if(iscarbon(target) && proximity) + var/mob/living/carbon/C = target + var/mob/living/carbon/U = user + var/success = C.equip_to_slot_if_possible(new /obj/item/clothing/gloves/color/yellow/sprayon, ITEM_SLOT_GLOVES, TRUE, TRUE) + if(success) + if(C == user) + C.visible_message("[U] sprays their hands with glittery rubber!") + else + C.visible_message("[U] sprays glittery rubber on the hands of [C]!") + else + C.visible_message("The rubber fails to stick to [C]'s hands!") + + qdel(src) + +/obj/item/clothing/gloves/color/yellow/sprayon + desc = "How're you gonna get 'em off, nerd?" + name = "spray-on insulated gloves" + icon_state = "sprayon" + item_state = "sprayon" + permeability_coefficient = 0 + resistance_flags = ACID_PROOF + var/shocks_remaining = 10 + +/obj/item/clothing/gloves/color/yellow/sprayon/Initialize() + .=..() + ADD_TRAIT(src, TRAIT_NODROP, GLOVE_TRAIT) + +/obj/item/clothing/gloves/color/yellow/sprayon/equipped(mob/user, slot) + . = ..() + RegisterSignal(user, COMSIG_LIVING_SHOCK_PREVENTED, .proc/Shocked) + +/obj/item/clothing/gloves/color/yellow/sprayon/proc/Shocked() + shocks_remaining-- + if(shocks_remaining < 0) + qdel(src) //if we run out of uses, the gloves crumble away into nothing, just like my dreams after working with .dm + +/obj/item/clothing/gloves/color/yellow/sprayon/dropped() + .=..() + qdel(src) //loose nodrop items bad + /obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly." name = "budget insulated gloves" @@ -202,6 +249,17 @@ permeability_coefficient = 0.3 resistance_flags = FIRE_PROOF | ACID_PROOF +/obj/item/clothing/gloves/color/latex/engineering + name = "tinker's gloves" + desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn." + icon = 'icons/obj/clothing/clockwork_garb.dmi' + icon_state = "clockwork_gauntlets" + item_state = "clockwork_gauntlets" + siemens_coefficient = 0.8 + permeability_coefficient = 0.3 + carrytrait = TRAIT_QUICK_BUILD + custom_materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000) + /obj/item/clothing/gloves/color/white name = "white gloves" desc = "These look pretty fancy." diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index ffd50cbfbe..80d0b7c8a8 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -60,6 +60,16 @@ cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT +/obj/item/clothing/head/hardhat/red/upgraded + name = "workplace-ready firefighter helmet" + desc = "By applying state of the art lighting technology to a fire helmet, and using photo-chemical hardening methods, this hardhat will protect you from robust workplace hazards." + icon_state = "hardhat0_purple" + item_state = "hardhat0_purple" + brightness_on = 5 + resistance_flags = FIRE_PROOF | ACID_PROOF + custom_materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 3000, /datum/material/silver = 500) + hat_type = "purple" + /obj/item/clothing/head/hardhat/white icon_state = "hardhat0_white" item_state = "hardhat0_white" diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 90b3d7d86b..2778c6abeb 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -198,6 +198,7 @@ desc = "A creepy wooden mask. Surprisingly expressive for a poorly carved bit of wood." icon_state = "tiki_eyebrow" item_state = "tiki_eyebrow" + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 1.25) resistance_flags = FLAMMABLE max_integrity = 100 actions_types = list(/datum/action/item_action/adjust) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 9c6c81372a..b197f4cf38 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -45,6 +45,7 @@ desc = "A pair of rather plain wooden sandals." name = "sandals" icon_state = "wizard" + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 0.5) strip_delay = 50 equip_delay_other = 50 permeability_coefficient = 0.9 diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index f4fd3f7bf3..3d55e569dc 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -444,7 +444,6 @@ Contains: desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted." armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) slowdown = 0.8 - obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints. helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old charges = 12 @@ -470,7 +469,6 @@ Contains: desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome." armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) slowdown = 0.8 - obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints. helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old charges = 6 diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index e392a6b2d1..047dc7b7a3 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -165,31 +165,134 @@ var/robe_charge = TRUE actions_types = list(/datum/action/item_action/stickmen) +/obj/item/clothing/suit/wizrobe/paper/item_action_slot_check(slot, mob/user, datum/action/A) + if(A.type == /datum/action/item_action/stickmen && slot != SLOT_WEAR_SUIT) + return FALSE + return ..() -/obj/item/clothing/suit/wizrobe/paper/ui_action_click(mob/user, action) - stickmen() +//Stickmemes. VV-friendly. +/datum/action/item_action/stickmen + name = "Summon Stick Minions" + desc = "Allows you to summon faithful stickmen allies to aide you in battle." + icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' + button_icon_state = "art_summon" + var/ready = TRUE + var/list/summoned_stickmen = list() + var/summoned_mob_path = /mob/living/simple_animal/hostile/stickman //Must be an hostile animal path. + var/max_stickmen = 8 + var/cooldown = 3 SECONDS + var/list/book_of_grudges = list() + +/datum/action/item_action/stickmen/New(Target) + ..() + if(isitem(Target)) + RegisterSignal(Target, COMSIG_PARENT_EXAMINE, .proc/give_infos) + +/datum/action/item_action/stickmen/Destroy() + for(var/A in summoned_stickmen) + var/mob/living/simple_animal/hostile/S = A + if(S.client) + to_chat(S, "A dizzying sensation strikes you as the comglomerate of pencil lines you call \ + your body crumbles under the pressure of an invisible eraser, soon to join bilions discarded sketches. \ + It seems whatever was keeping you in this realm has come to an end, like all things.") + animate(S, alpha = 0, time = 5 SECONDS) + QDEL_IN(S, 5 SECONDS) + return ..() + +/datum/action/item_action/stickmen/proc/give_infos(atom/source, mob/user, list/examine_list) + examine_list += "Making sure you are properly wearing or holding it, \ + point at whatever you want to rally your minions to its position." + examine_list += "While on harm intent, pointed mobs (minus you and the minions) \ + will also be marked as foes for your minions to attack for the next 2 minutes." + +/datum/action/item_action/stickmen/Grant(mob/M) + . = ..() + if(owner) + RegisterSignal(M, COMSIG_MOB_POINTED, .proc/rally) + if(book_of_grudges[M]) //Stop attacking your new master. + book_of_grudges -= M + for(var/A in summoned_stickmen) + var/mob/living/simple_animal/hostile/S = A + if(!S.mind) + S.LoseTarget() -/obj/item/clothing/suit/wizrobe/paper/verb/stickmen() - set category = "Object" - set name = "Summon Stick Minions" - set src in usr - if(!isliving(usr)) +/datum/action/item_action/stickmen/Remove(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_POINTED) + +/datum/action/item_action/stickmen/Trigger() + . = ..() + if(!.) return - if(!robe_charge) - to_chat(usr, "\The robe's internal magic supply is still recharging!") + if(!ready) + to_chat(owner, "[src]'s internal magic supply is still recharging!") + return FALSE + var/summon = TRUE + if(length(summoned_stickmen) >= max_stickmen) + var/mob/living/simple_animal/hostile/S = popleft(summoned_stickmen) + if(!S.client) + qdel(S) + else + S.forceMove(owner.drop_location()) + S.revive(TRUE) + summoned_stickmen[S] = TRUE + summon = FALSE + + owner.say("Rise, my creation! Off your page into this realm!", forced = "stickman summoning") + playsound(owner, 'sound/magic/summon_magic.ogg', 50, 1, 1) + if(summon) + var/mob/living/simple_animal/hostile/S = new summoned_mob_path (get_turf(usr)) + S.faction = owner.faction + S.foes = book_of_grudges + RegisterSignal(S, COMSIG_PARENT_QDELETING, .proc/remove_from_list) + ready = FALSE + addtimer(CALLBACK(src, .proc/ready_again), cooldown) + +/datum/action/item_action/stickmen/proc/remove_from_list(datum/source, forced) + summoned_stickmen -= source + +/datum/action/item_action/stickmen/proc/ready_again() + ready = TRUE + if(owner) + to_chat(owner, "[src] hums, its internal magic supply restored.") + +/** + * Rallies your army of stickmen to whichever target the user is pointing. + * Should the user be on harm intent and the target be a living mob that's not the user or a fellow stickman, + * said target will be added to a list of foes which the stickmen will gladly dispose regardless of faction. + * This is designed so stickmen will move toward whatever you point at even when you don't want to, that's the downside. + */ +/datum/action/item_action/stickmen/proc/rally(mob/source, atom/A) + var/turf/T = get_turf(A) + var/list/surrounding_turfs = block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + 1, T.y + 1, T.z)) + if(!surrounding_turfs.len) return + if(source.a_intent == INTENT_HARM && A != source && !summoned_stickmen[A]) + var/mob/living/L + if(isliving(A)) //Gettem boys! + L = A + else if(ismecha(A)) + var/obj/mecha/M = A + L = M.occupant + if(L && L.stat != DEAD && !HAS_TRAIT(L, TRAIT_DEATHCOMA)) //Taking revenge on the deads would be proposterous. + addtimer(CALLBACK(src, .proc/clear_grudge, L), 2 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE) + if(!book_of_grudges[L]) + RegisterSignal(L, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH), .proc/grudge_settled) + book_of_grudges[L] = TRUE + for(var/k in summoned_stickmen) //Shamelessly copied from the blob rally power + var/mob/living/simple_animal/hostile/S = k + if(!S.mind && isturf(S.loc) && get_dist(S, T) <= 10) + S.LoseTarget() + S.Goto(pick(surrounding_turfs), S.move_to_delay) - usr.say("Rise, my creation! Off your page into this realm!", forced = "stickman summoning") - playsound(src.loc, 'sound/magic/summon_magic.ogg', 50, 1, 1) - var/mob/living/M = new /mob/living/simple_animal/hostile/stickman(get_turf(usr)) - var/list/factions = usr.faction - M.faction = factions - src.robe_charge = FALSE - sleep(30) - src.robe_charge = TRUE - to_chat(usr, "\The robe hums, its internal magic supply restored.") +/datum/action/item_action/stickmen/proc/clear_grudge(mob/living/L) + if(!QDELETED(L)) + book_of_grudges -= L +/datum/action/item_action/stickmen/proc/grudge_settled(mob/living/L) + UnregisterSignal(L, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH)) + book_of_grudges -= L //Shielded Armour diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 77bb7661ba..48fb688d70 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -40,6 +40,7 @@ /datum/reagent/pax, /datum/reagent/consumable/laughter, /datum/reagent/concentrated_barbers_aid, + /datum/reagent/baldium, /datum/reagent/colorful_reagent, /datum/reagent/peaceborg_confuse, /datum/reagent/peaceborg_tire, diff --git a/code/modules/fields/gravity.dm b/code/modules/fields/gravity.dm index 8b16bb6487..2334a84e04 100644 --- a/code/modules/fields/gravity.dm +++ b/code/modules/fields/gravity.dm @@ -2,16 +2,17 @@ name = "modified gravity zone" setup_field_turfs = TRUE var/gravity_value = 0 - var/list/grav_components = list() + var/list/modified_turfs = list() field_shape = FIELD_SHAPE_RADIUS_SQUARE /datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/T) . = ..() - grav_components[T] = T.AddComponent(/datum/component/forced_gravity,gravity_value) + T.AddElement(/datum/element/forced_gravity, gravity_value) + modified_turfs[T] = gravity_value /datum/proximity_monitor/advanced/gravity/cleanup_field_turf(turf/T) . = ..() - var/datum/component/forced_gravity/G = grav_components[T] - grav_components -= T - if(G) - qdel(G) \ No newline at end of file + if(isnull(modified_turfs[T])) + return + T.RemoveElement(/datum/element/forced_gravity, modified_turfs[T]) + modified_turfs -= T \ No newline at end of file diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm index 3e47904e6e..5b81c54bc5 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm @@ -15,7 +15,7 @@ result = /obj/item/reagent_containers/food/snacks/banana_split subcategory = CAT_ICE - /datum/crafting_recipe/food/bluecharrie_float +/datum/crafting_recipe/food/bluecharrie_float name = "Blue Cherry Shake" always_availible = FALSE reqs = list( @@ -276,4 +276,4 @@ /datum/reagent/consumable/laughter = 5 ) result = /obj/item/reagent_containers/food/snacks/snowcones/clown - subcategory = CAT_ICE \ No newline at end of file + subcategory = CAT_ICE diff --git a/code/modules/games/unum.dm b/code/modules/games/unum.dm new file mode 100644 index 0000000000..9820fa6754 --- /dev/null +++ b/code/modules/games/unum.dm @@ -0,0 +1,22 @@ +/// A deck of unum cards. Classic. +/obj/item/toy/cards/deck/unum + name = "\improper UNUM deck" + desc = "A deck of unum cards. House rules to argue over not included." + icon = 'icons/obj/toy.dmi' + icon_state = "deck_unum_full" + deckstyle = "unum" + original_size = 108 + +//Populate the deck. +/obj/item/toy/cards/deck/unum/populate_deck() + for(var/colour in list("Red","Yellow","Green","Blue")) + cards += "[colour] 0" //Uno, i mean, cough cough, Unum decks have only one colour of each 0, weird huh? + for(var/k in 0 to 1) //two of each colour of number + cards += "[colour] skip" + cards += "[colour] reverse" + cards += "[colour] draw 2" + for(var/i in 1 to 9) + cards += "[colour] [i]" + for(var/k in 0 to 3) //4 wilds and draw 4s + cards += "Wildcard" + cards += "Draw 4" diff --git a/code/modules/holiday/halloween/bartholomew.dm b/code/modules/holiday/halloween/bartholomew.dm index f51b8b7ea1..4ef00e29cb 100644 --- a/code/modules/holiday/halloween/bartholomew.dm +++ b/code/modules/holiday/halloween/bartholomew.dm @@ -117,7 +117,7 @@ /obj/item/weldingtool = 3, /obj/item/wirecutters = 2, /obj/item/wrench = 4, - /obj/item/weaponcrafting/receiver = 1, + /obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 1, /obj/item/geiger_counter = 3, /obj/item/reagent_containers/food/snacks/grown/citrus/orange = 5, /obj/item/assembly/infra = 1, diff --git a/code/modules/keybindings/keybind/living.dm b/code/modules/keybindings/keybind/living.dm index 0408d0889b..38c666e186 100644 --- a/code/modules/keybindings/keybind/living.dm +++ b/code/modules/keybindings/keybind/living.dm @@ -22,12 +22,8 @@ full_name = "Toggle combat mode" description = "Toggles whether or not you're in combat mode." -/datum/keybinding/living/toggle_combat_mode/can_use(client/user) - return iscarbon(user.mob) // for now, only carbons should be using combat mode, although all livings have combat mode implemented. - /datum/keybinding/living/toggle_combat_mode/down(client/user) - var/mob/living/carbon/C = user.mob - C.user_toggle_intentional_combat_mode() + SEND_SIGNAL(user.mob, COMSIG_TOGGLE_COMBAT_MODE) return TRUE /datum/keybinding/living/toggle_resting diff --git a/code/modules/mapping/mapping_helpers/network_builder/_network_builder.dm b/code/modules/mapping/mapping_helpers/network_builder/_network_builder.dm index 78a835cffa..69a75148dd 100644 --- a/code/modules/mapping/mapping_helpers/network_builder/_network_builder.dm +++ b/code/modules/mapping/mapping_helpers/network_builder/_network_builder.dm @@ -12,7 +12,6 @@ /obj/effect/mapping_helpers/network_builder/Initialize(mapload) . = ..() - to_chat(world, "DEBUG: Initializing [COORD(src)]") var/conflict = check_duplicates() if(conflict) stack_trace("WARNING: [type] network building helper found check_duplicates() conflict [conflict] in its location.!") @@ -27,7 +26,6 @@ /// How this works: On LateInitialize, detect all directions that this should be applicable to, and do what it needs to do, and then inform all network builders in said directions that it's been around since it won't be around afterwards. /obj/effect/mapping_helpers/network_builder/LateInitialize() - to_chat(world, "DEBUG: LateInitializing [COORD(src)]") scan_directions() build_network() if(!custom_spawned) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 0998ccf36f..745c46b131 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -425,7 +425,7 @@ marker.icon_state = "chronobolt" marker.damage = bonus_value marker.nodamage = FALSE - marker.speed = 2 + marker.pixels_per_second = TILES_TO_PIXELS(5) deadly_shot = FALSE /obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(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 f8b155cb9f..db826fdb49 100644 --- a/code/modules/mining/equipment/lazarus_injector.dm +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -33,7 +33,7 @@ if(malfunctioning) H.faction |= list("lazarus", "[REF(user)]") H.robust_searching = 1 - H.friends += user + H.friends[user]++ H.attack_same = 1 log_game("[key_name(user)] has revived hostile mob [key_name(target)] with a malfunctioning lazarus injector") else diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index ce76ad04fc..50a3dec9dd 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -168,3 +168,17 @@ throwforce = 7 custom_materials = list(/datum/material/iron=50) w_class = WEIGHT_CLASS_SMALL + +/obj/item/shovel/serrated + name = "serrated bone shovel" + desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient lavaland tribal designs." + icon_state = "shovel_bone" + item_state = "shovel_bone" + lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' + force = 15 + throwforce = 12 + w_class = WEIGHT_CLASS_NORMAL + toolspeed = 0.7 + attack_verb = list("slashed", "impaled", "stabbed", "sliced") + sharpness = IS_SHARP diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index bbab74689c..ab0356aa66 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -270,6 +270,7 @@ desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims." icon = 'icons/turf/walls/survival_pod_walls.dmi' icon_state = "ntpod" + buildable_sign = FALSE /obj/structure/sign/mining/survival name = "shelter sign" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 838de24b60..5364486b04 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -287,12 +287,12 @@ Works together with spawning an observer, noted above. var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime) penalty = CANT_REENTER_ROUND - if(!(ckey in GLOB.client_ghost_timeouts)) - GLOB.client_ghost_timeouts += ckey - GLOB.client_ghost_timeouts[ckey] = 0 - else if(GLOB.client_ghost_timeouts[ckey] == CANT_REENTER_ROUND) + if(!(ghost.ckey in GLOB.client_ghost_timeouts)) + GLOB.client_ghost_timeouts += ghost.ckey + GLOB.client_ghost_timeouts[ghost.ckey] = 0 + else if(GLOB.client_ghost_timeouts[ghost.ckey] == CANT_REENTER_ROUND) return - GLOB.client_ghost_timeouts[ckey] = max(GLOB.client_ghost_timeouts[ckey],penalty) + GLOB.client_ghost_timeouts[ghost.ckey] = max(GLOB.client_ghost_timeouts[ghost.ckey],penalty) // needs to be done AFTER the ckey transfer, too return ghost diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 6d3bf648f6..687442c1f8 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -137,11 +137,11 @@ if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD)) if(prob(80)) - gain_trauma_type(BRAIN_TRAUMA_MILD) + gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE) else if(prob(50)) - gain_trauma_type(BRAIN_TRAUMA_SEVERE) + gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE) else - gain_trauma_type(BRAIN_TRAUMA_SPECIAL) + gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE) return if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain @@ -253,16 +253,16 @@ damage_delta = damage - prev_damage if(damage > BRAIN_DAMAGE_MILD) if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit - gain_trauma_type(BRAIN_TRAUMA_MILD) + gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE) if(prev_damage <= BRAIN_DAMAGE_MILD && owner) var/datum/skill_modifier/S ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner, S) if(damage > BRAIN_DAMAGE_SEVERE) if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% if(prob(20)) - gain_trauma_type(BRAIN_TRAUMA_SPECIAL) + gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE) else - gain_trauma_type(BRAIN_TRAUMA_SEVERE) + gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE) if(prev_damage <= BRAIN_DAMAGE_SEVERE && owner) var/datum/skill_modifier/S ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner, S) @@ -308,7 +308,7 @@ if(istype(BT, brain_trauma_type) && (BT.resilience <= resilience)) . += BT -/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience) +/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience, natural_gain = FALSE) if(!ispath(trauma)) trauma = trauma.type if(!initial(trauma.can_gain)) @@ -341,7 +341,7 @@ if(TRAUMA_RESILIENCE_ABSOLUTE) max_traumas = TRAUMA_LIMIT_ABSOLUTE - if(resilience_tier_count >= max_traumas) + if(natural_gain && resilience_tier_count >= max_traumas) return FALSE return TRUE @@ -381,11 +381,11 @@ return actual_trauma //Add a random trauma of a certain subtype -/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience) +/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience, natural_gain = FALSE) var/list/datum/brain_trauma/possible_traumas = list() for(var/T in subtypesof(brain_trauma_type)) var/datum/brain_trauma/BT = T - if(can_gain_trauma(BT, resilience) && initial(BT.random_gain)) + if(can_gain_trauma(BT, resilience, natural_gain) && initial(BT.random_gain)) possible_traumas += BT if(!LAZYLEN(possible_traumas)) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 00d929a1e0..a4da38c4da 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -24,12 +24,12 @@ if(!eye_blind) blind_eyes(1) update_mobility() - else - if(stat == UNCONSCIOUS) - stat = CONSCIOUS - if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) - set_resting(FALSE, TRUE) + else if(stat == UNCONSCIOUS) + stat = CONSCIOUS + if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) + set_resting(FALSE, TRUE) + if(eye_blind <= 1) adjust_blindness(-1) - update_mobility() + update_mobility() update_damage_hud() update_health_hud() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index dfc6fd735a..b13e7640f2 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -440,14 +440,14 @@ //dropItemToGround(I) CIT CHANGE - makes it so the item doesn't drop if the modifier rolls above 100 - var/modifier = 0 + var/modifier = 50 if(HAS_TRAIT(src, TRAIT_CLUMSY)) modifier -= 40 //Clumsy people are more likely to hit themselves -Honk! //CIT CHANGES START HERE - else if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) - modifier += 50 + else if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) + modifier -= 50 if(modifier < 100) dropItemToGround(I) @@ -825,16 +825,17 @@ return if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT))) stat = UNCONSCIOUS - disable_intentional_combat_mode(FALSE, FALSE) + SEND_SIGNAL(src, COMSIG_DISABLE_COMBAT_MODE) if(!eye_blind) blind_eyes(1) else if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) stat = SOFT_CRIT - disable_intentional_combat_mode(FALSE, FALSE) + SEND_SIGNAL(src, COMSIG_DISABLE_COMBAT_MODE) else stat = CONSCIOUS - adjust_blindness(-1) + if(eye_blind <= 1) + adjust_blindness(-1) update_mobility() update_damage_hud() update_health_hud() @@ -1120,10 +1121,6 @@ if(mood.sanity < SANITY_UNSTABLE) return TRUE -/mob/living/carbon/transfer_ckey(mob/new_mob, send_signal = TRUE) - disable_intentional_combat_mode(TRUE, FALSE) - return ..() - /mob/living/carbon/can_see_reagents() . = ..() if(.) //No need to run through all of this if it's already true. diff --git a/code/modules/mob/living/carbon/carbon_combat.dm b/code/modules/mob/living/carbon/carbon_combat.dm deleted file mode 100644 index f43d850401..0000000000 --- a/code/modules/mob/living/carbon/carbon_combat.dm +++ /dev/null @@ -1,6 +0,0 @@ -/mob/living/carbon/enable_intentional_combat_mode() - . = ..() - if(.) - if(voremode) - toggle_vore_mode() - diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 94589b3a4a..6303cf4c5c 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -78,12 +78,6 @@ /mob/living/carbon/attacked_by(obj/item/I, mob/living/user) var/totitemdamage = pre_attacked_by(I, user) - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - totitemdamage *= 0.5 - if(!CHECK_MOBILITY(user, MOBILITY_STAND)) - totitemdamage *= 0.5 - if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - totitemdamage *= 1.5 var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected) if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, null) & BLOCK_SUCCESS)) return FALSE diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 4cf82bb0b4..c3e849efa6 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -8,8 +8,6 @@ if(!gibbed) emote("deathgasp") - disable_intentional_combat_mode(TRUE, FALSE) - . = ..() for(var/T in get_traumas()) @@ -62,7 +60,3 @@ var/obj/item/bodypart/BP = X BP.drop_limb() BP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5) - -/mob/living/carbon/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE) - disable_intentional_combat_mode(TRUE, FALSE) - return ..() diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 1ee3369701..8dbfba47b1 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -90,7 +90,7 @@ if(digitalcamo) . += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner." - if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) + if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) . += "[t_He] [t_is] visibly tense[CHECK_MOBILITY(src, MOBILITY_STAND) ? "." : ", and [t_is] standing in combative stance."]" var/trait_exam = common_trait_examine() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 007bca3518..de703b8ad4 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -39,6 +39,7 @@ . = ..() if(!CONFIG_GET(flag/disable_human_mood)) AddComponent(/datum/component/mood) + AddComponent(/datum/component/combat_mode) AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text") AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!") AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 733f792109..63ca3f372e 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -16,8 +16,6 @@ if(!SSI) SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase) . -= SSI.config_entry_value - if(wrongdirmovedelay) - . += 1 if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP)) . -= 1.5 diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index a1de0bf532..901232e98f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1473,11 +1473,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/punchedbrute = target.getBruteLoss() //CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage - if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(!SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) damage *= 1.5 if(!CHECK_MOBILITY(user, MOBILITY_STAND)) damage *= 0.5 - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) damage *= 0.25 //END OF CITADEL CHANGES @@ -1625,11 +1625,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) log_combat(user, target, "disarmed out of grab from") return var/randn = rand(1, 100) - if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) // CITADEL CHANGE + if(SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) // CITADEL CHANGE randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE randn += 100 //CITADEL CHANGE - No kosher disarming if you're resting - if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CITADEL CHANGE + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) //CITADEL CHANGE randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode if(user.pulling == target) randn -= 20 //If you have the time to get someone in a grab, you should have a greater chance at snatching the thing in their hand. Will be made completely obsolete by the grab rework but i've got a poor track record for releasing big projects on time so w/e i guess @@ -1827,7 +1827,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(IS_STAMCRIT(user)) to_chat(user, "You're too exhausted for that.") return - if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) to_chat(user, "You need combat mode to be active to that!") return if(user.IsKnockdown() || user.IsParalyzed() || user.IsStun()) diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm index dfeff24141..bc5f198b4d 100644 --- a/code/modules/mob/living/carbon/human/species_types/dwarves.dm +++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm @@ -6,8 +6,8 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // name = "Dwarf" id = "dwarf" //Also called Homo sapiens pumilionis default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR,TRAIT_DWARF) - inherent_traits = list() + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS) + inherent_traits = list(TRAIT_DWARF,TRAIT_SNOB) limbs_id = "human" use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL @@ -87,9 +87,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // var/heal_rate = 0.5 //The rate they heal damages over 400 alcohol stored. Default is 0.5 so we times 3 since 3 seconds. var/alcohol_rate = 0.25 //The rate the alcohol ticks down per each iteration of dwarf_eth_ticker completing. //These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world. - var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds. var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds - var/last_filth_spam var/last_alcohol_spam /obj/item/organ/dwarfgland/prepare_eat() @@ -100,64 +98,10 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // /obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops.. . = ..() if(owner && owner.stat != DEAD) - dwarf_cycle_ticker() - -//Handles the delayed tick cycle by just adding on increments per each on_life() tick -/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker() - dwarf_eth_ticker++ - dwarf_filth_ticker++ - - if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds. - dwarf_filth_cycle() //On_life will adjust regarding other factors, so we are along for the ride. - dwarf_filth_ticker = 0 //We set the ticker back to 0 to go again. - if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds. - dwarf_eth_cycle() - dwarf_eth_ticker = 0 - -//If this still friggin uses too much CPU, I'll make a for view subsystem If I have to. -/obj/item/organ/dwarfgland/proc/dwarf_filth_cycle() - if(!owner?.client || !owner?.mind) - return - //Filth Reactions - Since miasma now exists - var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically. - for(var/fuck in owner.fov_view(7)) //hello byond for view loop. - if(istype(fuck, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = fuck - if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH))) - filth_counter += 10 - if(istype(fuck, /obj/effect/decal/cleanable/blood)) - if(istype(fuck, /obj/effect/decal/cleanable/blood/gibs)) - filth_counter += 1 - else - filth_counter += 0.1 - if(istype(fuck,/obj/effect/decal/cleanable/vomit)) //They are disgusted by their own vomit too. - filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral. - switch(filth_counter) - if(11 to 25) - if(last_filth_spam + 40 SECONDS < world.time) - to_chat(owner, "Someone should really clean up in here!") - last_filth_spam = world.time - if(26 to 50) - if(prob(6)) //And then the probability they vomit along with it. - to_chat(owner, "The stench makes you queasy.") - owner.vomit(10) //I think vomit should stay over a disgust adjustment. - if(51 to 75) - if(prob(9)) - to_chat(owner, "By Armok! You won't be able to keep alcohol down at all!") - owner.vomit(20) //Its more funny - if(76 to 100) - if(prob(11)) - to_chat(owner, "You can't live in such FILTH!") - owner.adjustToxLoss(10) //Now they start dying. - owner.vomit(20) - if(101 to INFINITY) //Now they will really start dying - if(last_filth_spam + 12 SECONDS < world.time) - to_chat(owner, " THERES TOO MUCH FILTH, OH GODS THE FILTH!") - last_filth_spam = world.time - if(prob(40)) - owner.adjustToxLoss(15) - owner.vomit(30) - CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least) + dwarf_eth_ticker++ + if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds. + dwarf_eth_cycle() + dwarf_eth_ticker = 0 //Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker. /obj/item/organ/dwarfgland/proc/dwarf_eth_cycle() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index e85769ca12..4e5b033688 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -523,7 +523,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put //this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc.. /mob/living/carbon/handle_status_effects() ..() - if(getStaminaLoss() && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CIT CHANGE - prevents stamina regen while combat mode is active + if(getStaminaLoss() && !SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) //CIT CHANGE - prevents stamina regen while combat mode is active adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && incomingstammult != 1) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 502ebcbe5d..c1038fbb41 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -322,7 +322,7 @@ set_pull_offsets(M, state) /mob/living/proc/set_pull_offsets(mob/living/M, grab_state = GRAB_PASSIVE) - if(M.buckled || M.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) + if(M.buckled || SEND_SIGNAL(M, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) return //don't make them change direction or offset them if they're buckled into something or in combat mode. var/offset = 0 switch(grab_state) diff --git a/code/modules/mob/living/living_combat.dm b/code/modules/mob/living/living_combat.dm deleted file mode 100644 index dbdcd1ea5b..0000000000 --- a/code/modules/mob/living/living_combat.dm +++ /dev/null @@ -1,93 +0,0 @@ -/mob/living/ComponentInitialize() - . = ..() - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_COMBAT_MODE_LOCKED), .proc/update_combat_lock) - -/mob/living/proc/update_combat_lock() - var/locked = HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED) - var/desired = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) - var/actual = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) - if(actual) - if(locked) - disable_combat_mode(FALSE, TRUE, FALSE, FALSE) - else if(!desired) - disable_combat_mode(TRUE, TRUE, FALSE, FALSE) - else - if(desired && !locked) - enable_combat_mode(FALSE, TRUE, FALSE, FALSE) - update_combat_mode_icon() - -/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE) - if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) || (combat_flags & COMBAT_FLAG_COMBAT_FORCED)) - return - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE) - SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced) - if(visible) - visible_message("[src] goes limp.", "Your muscles are forcibly relaxed!") - else if(!silent) - to_chat(src, was_forced? "Your muscles are forcibly relaxed!" : "You relax your muscles.") - if(update_icon) - update_combat_mode_icon() - -/mob/living/proc/enable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE) - if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) - return - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE) - SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_ENABLED, was_forced) - if(visible) - visible_message("[src] drops into a combative stance!", "You drop into a combative stance!") - else if(!silent) - to_chat(src, was_forced? "Your muscles reflexively tighten!" : "You tighten your muscles.") - if(update_icon) - update_combat_mode_icon() - -/// Updates the combat mode HUD icon. -/mob/living/proc/update_combat_mode_icon() - var/obj/screen/combattoggle/T = locate() in hud_used?.static_inventory - T?.update_icon() - -/// Enables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible. -/mob/living/proc/enable_intentional_combat_mode(silent = TRUE, visible = FALSE) - if((combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - return - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED) - if(!HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - enable_combat_mode(silent, FALSE, visible, FALSE) - update_combat_mode_icon() - client?.show_popup_menus = FALSE - return TRUE - -/// Disables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible. -/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE) - if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - return - if(combat_flags & COMBAT_FLAG_COMBAT_FORCED) - return - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED) - if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) - disable_combat_mode(silent, FALSE, visible, FALSE) - update_combat_mode_icon() - client?.show_popup_menus = TRUE - return TRUE - -/// Toggles whether the user is intentionally in combat mode. THIS should be the proc you generally use! Has built in visual/to other player feedback, as well as an audible cue to ourselves. -/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE) - var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) - if(old) - if(combat_flags & COMBAT_FLAG_COMBAT_FORCED) - to_chat(src, "You are unable to relax your muscles.") - return - disable_intentional_combat_mode() - playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above! - else if(CAN_TOGGLE_COMBAT_MODE(src)) - enable_intentional_combat_mode() - var/current = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) //because we could be locked - if(current != old) //only sound effect if you succeeded. Could have the feedback system be better but shrug, someone else can do it. - if(current) - playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay! - if(visible) - if(world.time >= combatmessagecooldown) - combatmessagecooldown = world.time + 10 SECONDS - if(a_intent != INTENT_HELP) - visible_message("[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].") - else - visible_message("[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].") diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index f8abf94083..282dab79a8 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -122,7 +122,7 @@ //// CITADEL STATION COMBAT //// /// See __DEFINES/combat.dm - var/combat_flags = COMBAT_FLAGS_STAMSYSTEM_EXEMPT + var/combat_flags = COMBAT_FLAGS_SPRINT_EXEMPT /// Next world.time when we will show a visible message on entering combat mode voluntarily again. var/combatmessagecooldown = 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 98a5f0f234..633135b3d2 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -14,7 +14,7 @@ spark_system.attach(src) wires = new /datum/wires/robot(src) - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) robot_modules_background = new() robot_modules_background.icon_state = "block" diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index 860d531608..b3be01e1b0 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -9,6 +9,8 @@ maxHealth = 100 health = 100 + combat_flags = COMBAT_FLAGS_DEFAULT + var/custom_name = "" var/braintype = "Cyborg" var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a4aeeb2ffc..0d0f7f9c97 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -15,8 +15,6 @@ speech_span = SPAN_ROBOT flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1 vore_flags = NO_VORE - /// Enable sprint system but not stamina - combat_flags = COMBAT_FLAGS_STAMEXEMPT_YESSPRINT var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS var/last_lawchange_announce = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 59fa94a1fa..e9bc3c549d 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -500,3 +500,33 @@ user.visible_message("[user] milks [src] using \the [O].", "You milk [src] using \the [O].") else to_chat(user, "The udder is dry. Wait a bit longer...") + +/mob/living/simple_animal/deer + name = "doe" + desc = "A gentle, peaceful forest animal. How did this get into space?" + icon_state = "deer-doe" + icon_living = "deer-doe" + icon_dead = "deer-doe-dead" + gender = FEMALE + mob_biotypes = MOB_ORGANIC|MOB_BEAST + speak = list("Weeeeeeee?","Weeee","WEOOOOOOOOOO") + speak_emote = list("grunts","grunts lowly") + emote_hear = list("brays.") + emote_see = list("shakes its head.") + speak_chance = 1 + turns_per_move = 5 + see_in_dark = 6 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently nudges" + response_disarm_simple = "gently nudge" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "bucks" + attack_verb_simple = "buck" + attack_sound = 'sound/weapons/punch1.ogg' + health = 75 + maxHealth = 75 + blood_volume = BLOOD_VOLUME_NORMAL + footstep_type = FOOTSTEP_MOB_SHOE \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm index 83fe42a7a4..df416047e2 100644 --- a/code/modules/mob/living/simple_animal/friendly/sloth.dm +++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm @@ -27,7 +27,7 @@ glide_size = 2 footstep_type = FOOTSTEP_MOB_CLAW -/mob/living/simple_animal/pet/fox/ComponentInitialize() +/mob/living/simple_animal/pet/sloth/ComponentInitialize() . = ..() AddElement(/datum/element/mob_holder, "sloth") //finally oranges can be held diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm index b1a4f05e8c..a2fc3aec88 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm @@ -23,29 +23,21 @@ for(var/ab in boss_abilities) boss_abilities -= ab var/datum/action/boss/AB = new ab() - AB.boss = src AB.Grant(src) boss_abilities += AB atb.assign_abilities(boss_abilities) - /mob/living/simple_animal/hostile/boss/Destroy() - qdel(atb) - atb = null - for(var/ab in boss_abilities) - var/datum/action/boss/AB = ab - AB.boss = null - AB.Remove(src) - qdel(AB) - boss_abilities.Cut() + QDEL_NULL(atb) + QDEL_LIST(boss_abilities) return ..() - //Action datum for bosses //Override Trigger() as shown below to do things /datum/action/boss check_flags = AB_CHECK_CONSCIOUS //Incase the boss is given a player + required_mobility_flags = NONE var/boss_cost = 100 //Cost of usage for the boss' AI 1-100 var/usage_probability = 100 var/mob/living/simple_animal/hostile/boss/boss @@ -53,23 +45,34 @@ var/needs_target = TRUE //Does the boss need to have a target? (Only matters for the AI) var/say_when_triggered = "" //What does the boss Say() when the ability triggers? +/datum/action/boss/Destroy() + boss = null + return ..() + +/datum/action/boss/Grant(mob/M) + . = ..() + boss = owner + +/datum/action/boss/Remove(mob/M) + . = ..() + boss = null + /datum/action/boss/Trigger() . = ..() - if(.) - if(!istype(boss, boss_type)) - return 0 - if(!boss.atb) - return 0 - if(boss.atb.points < boss_cost) - return 0 - if(!boss.client) - if(needs_target && !boss.target) - return 0 - if(boss) - if(say_when_triggered) - boss.say(say_when_triggered, forced = "boss action") - if(!boss.atb.spend(boss_cost)) - return 0 + if(!.) + return + if(!istype(boss, boss_type)) + return FALSE + if(!boss.atb) + return FALSE + if(boss.atb.points < boss_cost) + return FALSE + if(!boss.client && needs_target && !boss.target) + return FALSE + if(!boss.atb.spend(boss_cost)) + return FALSE + if(say_when_triggered) + boss.say(say_when_triggered, forced = "boss action") //Example: /* @@ -83,7 +86,8 @@ /datum/boss_active_timed_battle var/list/abilities //a list of /datum/action/boss owned by a boss mob var/point_regen_delay = 5 - var/points = 50 //1-100, start with 50 so we can use some abilities but not insta-buttfug somebody + var/max_points = 100 + var/points = 50 //start with 50 so we can use some abilities but not insta-buttfug somebody var/next_point_time = 0 var/chance_to_hold_onto_points = 50 var/highest_cost = 0 @@ -108,22 +112,22 @@ /datum/boss_active_timed_battle/proc/spend(cost) if(cost <= points) points = max(0,points-cost) - return 1 - return 0 + return TRUE + return FALSE /datum/boss_active_timed_battle/proc/refund(cost) - points = min(points+cost, 100) + points = min(points+cost, max_points) /datum/boss_active_timed_battle/process() - if(world.time >= next_point_time) + if(world.time >= next_point_time && points < max_points) next_point_time = world.time + point_regen_delay - points = min(100, ++points) //has to be out of 100 + points = min(max_points, ++points) //has to be out of 100 if(abilities) chance_to_hold_onto_points = highest_cost*0.5 - if(points != 100 && prob(chance_to_hold_onto_points)) + if(points != max_points && prob(chance_to_hold_onto_points)) return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!) if(!boss.client) abilities = shuffle(abilities) @@ -135,5 +139,5 @@ /datum/boss_active_timed_battle/Destroy() abilities = null - SSobj.processing.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm index aef3fb714d..4d45120a59 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm @@ -32,25 +32,47 @@ name = "Summon Minions" icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' button_icon_state = "art_summon" - usage_probability = 40 + usage_probability = 20 boss_cost = 30 boss_type = /mob/living/simple_animal/hostile/boss/paper_wizard needs_target = FALSE say_when_triggered = "Rise, my creations! Jump off your pages and into this realm!" - var/static/summoned_minions = 0 + var/list/summoned_minions = list() + var/maximum_stickmen = 6 + var/stickmen_to_summon = 3 /datum/action/boss/wizard_summon_minions/Trigger() - if(summoned_minions <= 6 && ..()) - var/list/minions = list( - /mob/living/simple_animal/hostile/stickman, - /mob/living/simple_animal/hostile/stickman/ranged, - /mob/living/simple_animal/hostile/stickman/dog) - var/list/directions = GLOB.cardinals.Copy() - for(var/i in 1 to 3) - var/minions_chosen = pick_n_take(minions) - new minions_chosen (get_step(boss,pick_n_take(directions)), 1) - summoned_minions += 3; + . =..() + if(!.) + return + var/to_summon = stickmen_to_summon + var/current_len = length(summoned_minions) + if(current_len > maximum_stickmen - stickmen_to_summon) + for(var/a in (maximum_stickmen - stickmen_to_summon) to current_len) + var/mob/living/simple_animal/hostile/stickman/S = popleft(summoned_minions) + if(!S.client) + qdel(S) + else + S.forceMove(boss.drop_location()) + S.revive(TRUE) + summoned_minions += S + to_summon-- + var/static/list/minions = list( + /mob/living/simple_animal/hostile/stickman, + /mob/living/simple_animal/hostile/stickman/ranged, + /mob/living/simple_animal/hostile/stickman/dog) + + var/list/directions = GLOB.cardinals.Copy() + for(var/i in 1 to to_summon) + var/minions_chosen = pick(minions) + var/mob/living/simple_animal/hostile/stickman/S = new minions_chosen (get_step(boss,pick_n_take(directions)), 1) + S.faction = boss.faction + RegisterSignal(S, COMSIG_PARENT_QDELETING, .proc/remove_from_list) + summoned_minions += S + +/datum/action/boss/wizard_summon_minions/proc/remove_from_list(datum/source, forced) + summoned_minions -= source //Mimic Ability //Summons mimics of himself with magical papercraft @@ -66,28 +88,32 @@ say_when_triggered = "" /datum/action/boss/wizard_mimic/Trigger() - if(..()) - var/mob/living/target - if(!boss.client) //AI's target - target = boss.target - else //random mob - var/list/threats = boss.PossibleThreats() - if(threats.len) - target = pick(threats) - if(target) - var/mob/living/simple_animal/hostile/boss/paper_wizard/wiz = boss - var/directions = GLOB.cardinals.Copy() - for(var/i in 1 to 3) - var/mob/living/simple_animal/hostile/boss/paper_wizard/copy/C = new (get_step(target,pick_n_take(directions))) - wiz.copies += C - C.original = wiz - C.say("My craft defines me, you could even say it IS me!") - wiz.say("My craft defines me, you could even say it IS me!") - wiz.forceMove(get_step(target,pick_n_take(directions))) - wiz.minimum_distance = 1 //so he doesn't run away and ruin everything - wiz.retreat_distance = 0 + . = ..() + if(!.) + return + var/mob/living/target + if(!boss.client) //AI's target + target = boss.target + else //random mob + var/list/threats = boss.PossibleThreats() + if(threats.len) + target = pick(threats) else - boss.atb.refund(boss_cost) + to_chat(owner, "There is no potential foe of different faction around to attack") + if(target) + var/mob/living/simple_animal/hostile/boss/paper_wizard/wiz = boss + var/directions = GLOB.cardinals.Copy() + for(var/i in 1 to 3) + var/mob/living/simple_animal/hostile/boss/paper_wizard/copy/C = new (get_step(target,pick_n_take(directions))) + wiz.copies += C + C.original = wiz + C.say("My craft defines me, you could even say it IS me!") + wiz.say("My craft defines me, you could even say it IS me!") + wiz.forceMove(get_step(target,pick_n_take(directions))) + wiz.minimum_distance = 1 //so he doesn't run away and ruin everything + wiz.retreat_distance = 0 + else + boss.atb.refund(boss_cost) /mob/living/simple_animal/hostile/boss/paper_wizard/copy desc = "'Tis a ruse!" diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index cae8948fdd..e41fa7c896 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -20,6 +20,7 @@ var/casingtype //set ONLY it and NULLIFY projectiletype, if we have projectile IN CASING var/move_to_delay = 3 //delay for the automated movement. var/list/friends = list() + var/list/foes = list() var/list/emote_taunt = list() var/taunt_chance = 0 @@ -62,6 +63,8 @@ /mob/living/simple_animal/hostile/Destroy() targets_from = null + friends = null + foes = null return ..() /mob/living/simple_animal/hostile/Life() @@ -193,7 +196,7 @@ // Please do not add one-off mob AIs here, but override this function for your mob /mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target? - if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids + if(!the_target || the_target.type == /atom/movable/lighting_object || isturf(the_target)) // bail out on invalids return FALSE if(ismob(the_target)) //Target is in godmode, ignore it. @@ -208,13 +211,13 @@ if(search_objects < 2) if(isliving(the_target)) var/mob/living/L = the_target - var/faction_check = faction_check_mob(L) + var/faction_check = !foes[L] && faction_check_mob(L) if(robust_searching) if(faction_check && !attack_same) return FALSE - if(L.stat > stat_attack) + if(L.stat > stat_attack || (L.stat == UNCONSCIOUS && stat_attack == UNCONSCIOUS && HAS_TRAIT(L, TRAIT_DEATHCOMA))) return FALSE - if(L in friends) + if(friends[L] > 0 && foes[L] < 1) return FALSE else if((faction_check && !attack_same) || L.stat) 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 8c358fd625..3ef4ef9be9 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 @@ -75,7 +75,7 @@ Difficulty: Medium /obj/item/projectile/kinetic/miner damage = 40 - speed = 0.9 + pixels_per_second = TILES_TO_PIXELS(11.111) icon_state = "ka_tracer" range = MINER_DASH_RANGE 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 be3552822f..04ff9413aa 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -212,7 +212,7 @@ Difficulty: Very Hard icon_state= "chronobolt" damage = 25 armour_penetration = 100 - speed = 2 + pixels_per_second = TILES_TO_PIXELS(5) eyeblur = 0 damage_type = BRUTE pass_flags = PASSTABLE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 88e33ed91a..5e866f95f1 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -71,7 +71,10 @@ Difficulty: Extremely Hard /mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/OpenFire() check_enraged() - projectile_speed_multiplier = 1 - enraged * 0.25 + if(enraged) + projectile_speed_multiplier = 1.33 + else + projectile_speed_multiplier = 1 SetRecoveryTime(100, 100) if(client) @@ -109,7 +112,7 @@ Difficulty: Extremely Hard icon_state = "ice_1" damage = 20 armour_penetration = 100 - speed = 10 + pixels_per_second = TILES_TO_PIXELS(1) homing_turn_speed = 30 damage_type = BURN @@ -123,7 +126,7 @@ Difficulty: Extremely Hard icon_state = "nuclear_particle" damage = 5 armour_penetration = 100 - speed = 4 + pixels_per_second = TILES_TO_PIXELS(2.5) damage_type = BRUTE /obj/item/projectile/ice_blast @@ -131,7 +134,7 @@ Difficulty: Extremely Hard icon_state = "ice_2" damage = 15 armour_penetration = 100 - speed = 4 + pixels_per_second = TILES_TO_PIXELS(2.5) damage_type = BRUTE /obj/item/projectile/ice_blast/on_hit(atom/target, blocked = FALSE) @@ -185,7 +188,7 @@ Difficulty: Extremely Hard if(!startloc || !endloc) break var/obj/item/projectile/ice_blast/P = new(startloc) - P.speed *= projectile_speed_multiplier + P.pixels_per_second *= projectile_speed_multiplier P.preparePixelProjectile(endloc, startloc, null, angle + rand(-10, 10)) P.firer = firer if(original) @@ -201,7 +204,7 @@ Difficulty: Extremely Hard if(!endloc) break var/obj/item/projectile/P = new /obj/item/projectile/snowball(startloc) - P.speed *= projectile_speed_multiplier + P.pixels_per_second *= projectile_speed_multiplier P.preparePixelProjectile(endloc, startloc, null, rand(-spread, spread)) P.firer = src if(target) @@ -220,7 +223,7 @@ Difficulty: Extremely Hard if(!endloc) break var/obj/item/projectile/P = new /obj/item/projectile/ice_blast(startloc) - P.speed *= projectile_speed_multiplier + P.pixels_per_second *= projectile_speed_multiplier P.preparePixelProjectile(endloc, startloc, null, spread) P.firer = src if(target) 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 47756688c8..7009f13f36 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -145,6 +145,7 @@ /mob/living/simple_animal/hostile/megafauna/proc/SetRecoveryTime(buffer_time) recovery_time = world.time + buffer_time + ranged_cooldown = max(ranged_cooldown, world.time + buffer_time) // CITADEL BANDAID FIX FOR MEGAFAUNA NOT RESPECTING RECOVERY TIME. /mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype, scoretype, crusher_kill) if(!medal_type || (flags_1 & ADMIN_SPAWNED_1)) //Don't award medals if the medal type isn't set diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index b69a4b69cf..306011dc80 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -84,8 +84,33 @@ crusher_loot = /obj/item/crusher_trophy/watcher_wing loot = list() butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1) + search_objects = 1 + wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond) field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball. +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/Life() + . = ..() + if(stat == CONSCIOUS) + consume_bait() + +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait() + var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in oview(src, 9) + var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in oview(src, 9) + if(!diamonds && !bait) + return + if(diamonds) + var/distanced = 0 + distanced = get_dist(loc,diamonds.loc) + if(distanced <= 1 && diamonds) + qdel(diamonds) + src.visible_message("[src] consumes [diamonds], and it disappears! ...At least, you think.") + if(bait) + var/distanceb = 0 + distanceb = get_dist(loc,bait.loc) + if(distanceb <= 1 && bait) + qdel(bait) + visible_message("[src] examines [bait] closer, and telekinetically shatters the pen.") + /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize() . = ..() if(prob(1)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 106cb20efc..78b24acfb0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -217,7 +217,7 @@ icon_state= "chronobolt" damage = 15 armour_penetration = 60 - speed = 2 + pixels_per_second = TILES_TO_PIXELS(5) eyeblur = 0 damage_type = BRUTE pass_flags = PASSTABLE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index c2faa002bc..31f925fb2b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -298,5 +298,5 @@ var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc) A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) A.GiveTarget(target) - A.friends = user + A.friends[user]++ A.faction = user.faction.Copy() diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm index 2edcc4021a..226af952b1 100644 --- a/code/modules/mob/living/simple_animal/hostile/stickman.dm +++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm @@ -13,7 +13,7 @@ speed = 0 blood_volume = 0 stat_attack = UNCONSCIOUS - robust_searching = 1 + robust_searching = TRUE //This is also required for the paper robe rallying to work. environment_smash = ENVIRONMENT_SMASH_NONE maxHealth = 100 health = 100 @@ -30,8 +30,6 @@ faction = list("hostile","stickman") check_friendly_fire = 1 status_flags = CANPUSH - var/datum/action/boss/wizard_summon_minions/changesummons = /datum/action/boss/wizard_summon_minions - var/summoned_by_wizard = 0 /mob/living/simple_animal/hostile/stickman/ranged ranged = 1 @@ -43,7 +41,6 @@ projectilesound = 'sound/misc/bang.ogg' loot = list(/obj/item/gun/ballistic/automatic/pistol/stickman) - /mob/living/simple_animal/hostile/stickman/dog name = "Angry Stick Dog" desc = "Stickman's best friend, if he could see him at least." @@ -52,12 +49,6 @@ icon_dead = "stickdog_dead" mob_biotypes = MOB_BEAST -/mob/living/simple_animal/hostile/stickman/Initialize(mapload, var/wizard_summoned) +/mob/living/simple_animal/hostile/stickman/Initialize(mapload) . = ..() new /obj/effect/temp_visual/paper_scatter(src) - summoned_by_wizard = wizard_summoned - -/mob/living/simple_animal/hostile/stickman/death() - ..() - if(summoned_by_wizard == 1) - changesummons.summoned_minions -- diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 0d41347179..0029300936 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -571,12 +571,13 @@ /mob/living/proc/cure_blind(source) REMOVE_TRAIT(src, TRAIT_BLIND, source) if(!HAS_TRAIT(src, TRAIT_BLIND)) - update_blindness() + if(eye_blind <= 1) //little hack now that we don't actively check for trait and unconsciousness on update_blindness. + adjust_blindness(-1) /mob/living/proc/become_blind(source) if(!HAS_TRAIT(src, TRAIT_BLIND)) // not blind already, add trait then overlay ADD_TRAIT(src, TRAIT_BLIND, source) - update_blindness() + blind_eyes(1) else ADD_TRAIT(src, TRAIT_BLIND, source) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e7c5373543..30d9755a4a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -128,15 +128,13 @@ * * target (optional) is the other mob involved with the visible message. For example, the attacker in many combat messages. * * target_message (optional) is what the target mob will see e.g. "[src] does something to you!" */ -/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, mob/target, target_message) +/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, ignored_mobs, mob/target, target_message) var/turf/T = get_turf(src) if(!T) return var/list/hearers = get_hearers_in_view(vision_distance, src) //caches the hearers and then removes ignored mobs. if(!length(hearers)) return - if(!islist(ignored_mobs)) - ignored_mobs = list(ignored_mobs) hearers -= ignored_mobs if(target_message && target && istype(target) && target.client) @@ -150,7 +148,7 @@ msg = blind_message if(msg) target.show_message(msg, MSG_VISUAL,blind_message, MSG_AUDIBLE) - else if(self_message) + if(self_message) hearers -= src for(var/mob/M in hearers) if(!M.client) @@ -185,15 +183,13 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA * * hearing_distance (optional) is the range, how many tiles away the message can be heard. * * ignored_mobs (optional) doesn't show any message to any given mob in the list. */ -/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs) +/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, ignored_mobs) var/turf/T = get_turf(src) if(!T) return var/list/hearers = get_hearers_in_view(hearing_distance, src) if(!length(hearers)) return - if(!islist(ignored_mobs)) - ignored_mobs = list(ignored_mobs) hearers -= ignored_mobs if(self_message) hearers -= src @@ -377,7 +373,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA return FALSE new /obj/effect/temp_visual/point(A,invisibility) - + SEND_SIGNAL(src, COMSIG_MOB_POINTED, A) return TRUE /mob/proc/can_resist() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 9947c8ca1e..9dcfb4e99a 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -127,6 +127,13 @@ var/registered_z + var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly + var/list/screens = list() + var/list/client_colours = list() + var/hud_type = /datum/hud + + var/datum/hSB/sandbox = null + var/mob/audiovisual_redirect //Mob to redirect messages, speech, and sounds to var/siliconaccessareas = list() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 2bcfd47344..9867da1ed4 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -101,10 +101,10 @@ mob.throwing.finalize(FALSE) var/atom/movable/AM = L.pulling - if(AM && AM.density && !(L.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && !ismob(AM)) + if(AM && AM.density && !SEND_SIGNAL(L, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) && !ismob(AM)) L.setDir(turn(L.dir, 180)) - SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc) + SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc, add_delay) /// Process_Grab(): checks for grab, attempts to break if so. Return TRUE to prevent movement. /client/proc/Process_Grab() diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 6be1afb5de..fbef8fd244 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -23,9 +23,9 @@ * Sets a mob's blindness to an amount if it was not above it already, similar to how status effects work */ /mob/proc/blind_eyes(amount) - var/old_blind = eye_blind || HAS_TRAIT(src, TRAIT_BLIND) - eye_blind = max(eye_blind, amount) - var/new_blind = eye_blind || HAS_TRAIT(src, TRAIT_BLIND) + var/old_blind = eye_blind + eye_blind = max((!eye_blind && stat == UNCONSCIOUS || HAS_TRAIT(src, TRAIT_BLIND)) ? 1 : eye_blind , amount) + var/new_blind = eye_blind if(old_blind != new_blind) update_blindness() @@ -36,21 +36,21 @@ */ /mob/proc/adjust_blindness(amount) var/old_eye_blind = eye_blind - eye_blind = max(0, eye_blind + amount) - if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND)) + eye_blind = max((stat == UNCONSCIOUS || HAS_TRAIT(src, TRAIT_BLIND)) ? 1 : 0, eye_blind + amount) + if(!old_eye_blind || !eye_blind) update_blindness() /** * Force set the blindness of a mob to some level */ /mob/proc/set_blindness(amount) var/old_eye_blind = eye_blind - eye_blind = max(amount, 0) - if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND)) + eye_blind = max(amount, (stat == UNCONSCIOUS || HAS_TRAIT(src, TRAIT_BLIND)) ? 1 : 0) + if(!old_eye_blind || !eye_blind) update_blindness() /// proc that adds and removes blindness overlays when necessary /mob/proc/update_blindness() - if(stat == UNCONSCIOUS || HAS_TRAIT(src, TRAIT_BLIND) || eye_blind) // UNCONSCIOUS or has blind trait, or has temporary blindness + if(eye_blind) // UNCONSCIOUS or has blind trait, or has temporary blindness if(stat == CONSCIOUS || stat == SOFT_CRIT) throw_alert("blind", /obj/screen/alert/blind) overlay_fullscreen("blind", /obj/screen/fullscreen/blind) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 35a2b3f058..aed3ff5848 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -384,3 +384,6 @@ /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" + +/obj/item/paper/crumpled/muddy + icon_state = "scrap_mud" diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index ca5219375f..1c14a30a8a 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -220,3 +220,17 @@ item_state = initial(item_state) lefthand_file = initial(lefthand_file) righthand_file = initial(righthand_file) + +/obj/item/pen/survival + name = "survival pen" + desc = "The latest in portable survival technology, this pen was designed as a miniature diamond pickaxe. Watchers find them very desirable for their diamond exterior." + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "digging_pen" + item_state = "pen" + force = 3 + w_class = WEIGHT_CLASS_TINY + custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10) + pressure_resistance = 2 + grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1) + tool_behaviour = TOOL_MINING //For the classic "digging out of prison with a spoon but you're in space so this analogy doesn't work" situation. + toolspeed = 10 //You will never willingly choose to use one of these over a shovel. diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 8db531aa5e..3c4aebdba3 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -337,3 +337,15 @@ grind_results = list(/datum/reagent/iodine = 40, /datum/reagent/iron = 10) var/charges = 5 var/max_charges = 5 + +/obj/item/toner/large + name = "large toner cartridge" + grind_results = list(/datum/reagent/iodine = 90, /datum/reagent/iron = 10) + charges = 15 + max_charges = 15 + +/obj/item/toner/extreme + name = "extremely large toner cartridge" + desc = "Why would ANYONE need THIS MUCH TONER?" + charges = 200 + max_charges = 200 diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index 11ad81ebf0..9e6f827629 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -4,7 +4,7 @@ name = "picture frame" desc = "The perfect showcase for your favorite deathtrap memories." icon = 'icons/obj/decals.dmi' - custom_materials = null + custom_materials = list(/datum/material/wood = 2000) flags_1 = 0 icon_state = "frame-empty" result_path = /obj/structure/sign/picture_frame @@ -64,6 +64,7 @@ desc = "Every time you look it makes you laugh." icon = 'icons/obj/decals.dmi' icon_state = "frame-empty" + custom_materials = list(/datum/material/wood = 2000) var/obj/item/photo/framed var/persistence_id var/can_decon = TRUE diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index f1108189c7..dc091cb451 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1411,6 +1411,7 @@ if(WIRE_POWER1, WIRE_POWER2) if(!wires.is_cut(WIRE_POWER1) && !wires.is_cut(WIRE_POWER2)) shorted = FALSE + update() if(WIRE_AI) if(!wires.is_cut(WIRE_AI)) aidisabled = FALSE diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index cc321fdb4d..c788b9b033 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -227,6 +227,7 @@ icon_state = "h+cell" maxcharge = 15000 chargerate = 2250 + rating = 2 /obj/item/stock_parts/cell/high/empty start_charged = FALSE @@ -237,6 +238,7 @@ maxcharge = 20000 custom_materials = list(/datum/material/glass=300) chargerate = 2000 + rating = 3 /obj/item/stock_parts/cell/super/empty start_charged = FALSE @@ -247,6 +249,7 @@ maxcharge = 30000 custom_materials = list(/datum/material/glass=400) chargerate = 3000 + rating = 4 /obj/item/stock_parts/cell/hyper/empty start_charged = FALSE @@ -258,6 +261,7 @@ maxcharge = 40000 custom_materials = list(/datum/material/glass=600) chargerate = 4000 + rating = 5 /obj/item/stock_parts/cell/bluespace/empty start_charged = FALSE @@ -313,7 +317,7 @@ /obj/item/stock_parts/cell/emproof/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF) /obj/item/stock_parts/cell/emproof/empty start_charged = FALSE diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 344d41071d..3c3f3c9541 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -314,8 +314,11 @@ . = ..() SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(on && status == LIGHT_OK) - SSvis_overlays.add_vis_overlay(src, overlayicon, base_state, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE, dir, clamp(light_power*250, 30, 200)) - + var/overlay_alpha = clamp(light_power*250, 30, 200) + SSvis_overlays.add_vis_overlay(src, overlayicon, base_state, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE, dir, overlay_alpha) + var/mutable_appearance/M = mutable_appearance(overlayicon, base_state) + M.alpha = overlay_alpha + . += M // update the icon_state and luminosity of the light depending on its state /obj/machinery/light/proc/update(trigger = TRUE) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 4cec49945a..f84b639d68 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -310,6 +310,7 @@ if(H.gloves) var/obj/item/clothing/gloves/G = H.gloves if(G.siemens_coefficient == 0) + SEND_SIGNAL(M, COMSIG_LIVING_SHOCK_PREVENTED, power_source, source, siemens_coeff, dist_check) return 0 //to avoid spamming with insulated glvoes on var/area/source_area diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index d57f78e5b6..0d182e0a1b 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -75,7 +75,7 @@ /obj/machinery/power/emitter/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/power/emitter/RefreshParts() var/max_firedelay = 120 diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 950e34098c..af2237a426 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -61,7 +61,7 @@ field_generator power level display /obj/machinery/field/generator/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/field/generator/process() if(active == FG_ONLINE) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index cf9e606ffc..ef28c76da9 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -76,17 +76,18 @@ var/datum/action/item_action/toggle_scope_zoom/azoom var/dualwield_spread_mult = 1 //dualwield spread multiplier - + /// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun. var/projectile_damage_multiplier = 1 + var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds + /obj/item/gun/Initialize() . = ..() - if(pin) - if(no_pin_required) - pin = null - else - pin = new pin(src) + if(no_pin_required) + pin = null + else if(pin) + pin = new pin(src) if(gun_light) alight = new (src) if(zoomable) @@ -214,8 +215,9 @@ var/bonus_spread = 0 var/loop_counter = 0 - bonus_spread += getinaccuracy(user) //CIT CHANGE - adds bonus spread while not aiming - if(ishuman(user) && user.a_intent == INTENT_HARM) + if(user) + bonus_spread += getinaccuracy(user) //CIT CHANGE - adds bonus spread while not aiming + if(ishuman(user) && user.a_intent == INTENT_HARM && weapon_weight <= WEAPON_LIGHT) var/mob/living/carbon/human/H = user for(var/obj/item/gun/G in H.held_items) if(G == src || G.weapon_weight >= WEAPON_MEDIUM) @@ -564,12 +566,7 @@ chambered = null update_icon() -/obj/item/gun/proc/getinaccuracy(mob/living/user) - if(!isliving(user)) - return FALSE - else - var/mob/living/holdingdude = user - if(istype(holdingdude) && (holdingdude.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - return 0 - else - return ((weapon_weight * 25) * inaccuracy_modifier) +/obj/item/gun/proc/getinaccuracy(mob/user) + if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) + return ((weapon_weight * 25) * inaccuracy_modifier) + return 0 diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index afe2b9ca3e..12e7da90c9 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -313,19 +313,24 @@ else to_chat(user, "[src] is empty!") -// IMPROVISED SHOTGUN // +///////////////////////////// +// IMPROVISED SHOTGUN // +///////////////////////////// /obj/item/gun/ballistic/revolver/doublebarrel/improvised name = "improvised shotgun" desc = "Essentially a tube that aims shotgun shells." + desc = "A shoddy break-action breechloaded shotgun. Its lacklustre construction will probably result in it hurting people less than a normal shotgun." icon_state = "ishotgun" item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_MEDIUM force = 10 slot_flags = null mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm just here for the gasoline." unique_reskin = null + projectile_damage_multiplier = 0.8 var/slung = FALSE /obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 4894a8d8eb..e438b351b3 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -126,8 +126,9 @@ /obj/item/gun/ballistic/shotgun/boltaction/improvised name = "Makeshift 7.62mm Rifle" icon_state = "ishotgun" + icon_state = "irifle" item_state = "shotgun" - desc = "A large zip gun more or less that takes a single 7.62mm bullet" + desc = "A bolt-action breechloaded rifle that takes 7.62mm bullets." mag_type = /obj/item/ammo_box/magazine/internal/boltaction/improvised can_bayonet = FALSE diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index f8ddcb5aae..bcb074023f 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -77,7 +77,6 @@ var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty") var/datum/action/item_action/zoom_lock_action/zoom_lock_action - var/mob/listeningTo /obj/item/gun/energy/beam_rifle/debug delay = 0 @@ -178,7 +177,6 @@ STOP_PROCESSING(SSfastprocess, src) set_user(null) QDEL_LIST(current_tracers) - listeningTo = null return ..() /obj/item/gun/energy/beam_rifle/proc/aiming_beam(force_update = FALSE) @@ -260,17 +258,12 @@ if(user == current_user) return stop_aiming(current_user) - if(listeningTo) - UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED) - listeningTo = null - if(istype(current_user)) - LAZYREMOVE(current_user.mousemove_intercept_objects, src) + if(current_user) + UnregisterSignal(current_user, COMSIG_MOVABLE_MOVED) current_user = null if(istype(user)) current_user = user - LAZYOR(current_user.mousemove_intercept_objects, src) RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move) - listeningTo = user /obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) if(aiming) @@ -295,7 +288,7 @@ if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher)) return process_aim() - if(fire_check()) + if(fire_check() && can_trigger_gun(M)) sync_ammo() do_fire(M.client.mouseObject, M, FALSE, M.client.mouseParams, M.zone_selected) stop_aiming() diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 8a1db49762..cef730366e 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -13,11 +13,16 @@ var/pin_removeable = 0 // Can be replaced by any pin. var/obj/item/gun/gun -/obj/item/firing_pin/New(newloc) - ..() +/obj/item/firing_pin/Initialize(newloc) + . = ..() if(istype(newloc, /obj/item/gun)) gun = newloc +/obj/item/firing_pin/Destroy() + if(gun) + gun.pin = null + return ..() + /obj/item/firing_pin/afterattack(atom/target, mob/user, proximity_flag) . = ..() if(proximity_flag) @@ -224,24 +229,6 @@ suit_requirement = /obj/item/clothing/suit/bluetag tagcolor = "blue" -/obj/item/firing_pin/Destroy() - if(gun) - gun.pin = null - return ..() - -//Station Locked - -/obj/item/firing_pin/away - name = "station locked pin" - desc = "A firing pin that only will fire when off the station." - -/obj/item/firing_pin/away/pin_auth(mob/living/user) - var/area/station_area = get_area(src) - if(!station_area || is_station_level(station_area.z)) - to_chat(user, "The pin beeps, refusing to fire.") - return FALSE - return TRUE - /obj/item/firing_pin/security_level name = "security level firing pin" desc = "A sophisticated firing pin that authorizes operation based on its settings and current security level." @@ -325,3 +312,18 @@ /obj/item/firing_pin/security_level/pin_auth(mob/living/user) return (only_lethals && !(gun.chambered?.harmful)) || ISINRANGE(GLOB.security_level, min_sec_level, max_sec_level) + +// Explorer Firing Pin- Prevents use on station Z-Level, so it's justifiable to give Explorers guns that don't suck. +/obj/item/firing_pin/explorer + name = "outback firing pin" + desc = "A firing pin used by the austrailian defense force, retrofit to prevent weapon discharge on the station." + icon_state = "firing_pin_explorer" + fail_message = "CANNOT FIRE WHILE ON STATION, MATE!" + +// This checks that the user isn't on the station Z-level. +/obj/item/firing_pin/explorer/pin_auth(mob/living/user) + var/turf/station_check = get_turf(user) + if(!station_check||is_station_level(station_check.z)) + to_chat(user, "You cannot use your weapon while on the station!") + return FALSE + return TRUE diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 71aa78da4b..213bc35b52 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1,6 +1,10 @@ #define MOVES_HITSCAN -1 //Not actually hitscan but close as we get without actual hitscan. #define MUZZLE_EFFECT_PIXEL_INCREMENT 17 //How many pixels to move the muzzle flash up so your character doesn't look like they're shitting out lasers. +/// Minimum projectile pixels to move before it animate()S, below this it's a direct set. +#define MINIMUM_PIXELS_TO_ANIMATE 4 +/// Pixels to instantly travel on firing. +#define PROJECTILE_FIRING_INSTANT_TRAVEL_AMOUNT 16 /obj/item/projectile name = "projectile" @@ -12,7 +16,9 @@ pass_flags = PASSTABLE mouse_opacity = MOUSE_OPACITY_TRANSPARENT movement_type = FLYING + animate_movement = NO_STEPS hitsound = 'sound/weapons/pierce.ogg' + appearance_flags = PIXEL_SCALE var/hitsound_wall = "" resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF @@ -32,14 +38,19 @@ //Fired processing vars var/fired = FALSE //Have we been fired yet var/paused = FALSE //for suspending the projectile midair - var/last_projectile_move = 0 var/time_offset = 0 var/datum/point/vector/trajectory var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location! + /// "leftover" pixels for Range() calculation as pixel_move() was moved to simulated semi-pixel movement and Range() is in tiles. + var/pixels_range_leftover = 0 + /// "leftover" tick pixels and stuff yeah, so we don't round off things and introducing tracing inaccuracy. + var/pixels_tick_leftover = 0 + + /// Pixels moved per second. + var/pixels_per_second = TILES_TO_PIXELS(12.5) + /// The number of pixels we increment by. THIS IS NOT SPEED, DO NOT TOUCH THIS UNLESS YOU KNOW WHAT YOU ARE DOING. In general, lower values means more linetrace accuracy up to a point at cost of performance. + var/pixel_increment_amount - var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel - /// "leftover" ticks and stuff yeah. hey when are we rewriting projectiles for the eighth time to do something smarter like incrementing x pixels until it meets a goal instead of for(var/i in 1 to required_moves)? - var/tick_moves_leftover = 0 var/Angle = 0 var/original_angle = 0 //Angle at firing var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle @@ -75,12 +86,16 @@ //Homing var/homing = FALSE var/atom/homing_target - var/homing_turn_speed = 10 //Angle per tick. + /// How fast the projectile turns towards its homing targets, in angle per second. + var/homing_turn_speed = 100 var/homing_inaccuracy_min = 0 //in pixels for these. offsets are set once when setting target. var/homing_inaccuracy_max = 0 var/homing_offset_x = 0 var/homing_offset_y = 0 + /// How many deciseconds are each hitscan movement considered. Used for homing and other things that use seconds for timing rather than ticks. + var/hitscan_movement_decisecond_equivalency = 0.1 + var/ignore_source_check = FALSE var/damage = 10 @@ -88,7 +103,8 @@ var/nodamage = 0 //Determines if the projectile will skip any damage inflictions var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb var/projectile_type = /obj/item/projectile - var/range = 50 //This will de-increment every step. When 0, it will deletze the projectile. + /// Range of the projectile, de-incrementing every step. The projectile deletes itself at 0. This is in tiles. + var/range = 50 var/decayedRange //stores original range var/reflect_range_decrease = 5 //amount of original range that falls off when reflecting, so it doesn't go forever var/is_reflectable = FALSE // Can it be reflected or not? @@ -120,6 +136,10 @@ permutated = list() decayedRange = range +/** + * Artificially modified to be called at around every world.icon_size pixels of movement. + * WARNING: Range() can only be called once per pixel_increment_amount pixels. + */ /obj/item/projectile/proc/Range() range-- if(range <= 0 && loc) @@ -334,14 +354,15 @@ return TRUE return FALSE +/// one move is a tile. /obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight. if(!trajectory && isnull(forced_angle) && isnull(Angle)) return FALSE var/datum/point/vector/current = trajectory if(!current) var/turf/T = get_turf(src) - current = new(T.x, T.y, T.z, pixel_x, pixel_y, isnull(forced_angle)? Angle : forced_angle, SSprojectiles.global_pixel_speed) - var/datum/point/vector/v = current.return_vector_after_increments(moves * SSprojectiles.global_iterations_per_move) + current = new(T.x, T.y, T.z, pixel_x, pixel_y, isnull(forced_angle)? Angle : forced_angle, pixel_increment_amount || SSprojectiles.global_pixel_increment_amount) + var/datum/point/vector/v = current.return_vector_after_increments(TILES_TO_PIXELS(moves) / (pixel_increment_amount || SSprojectiles.global_pixel_increment_amount)) return v.return_turf() /obj/item/projectile/proc/return_pathing_turfs_in_moves(moves, forced_angle) @@ -358,16 +379,14 @@ return PROCESS_KILL if(paused || !isturf(loc)) return + var/ds = (SSprojectiles.flags & SS_TICKER)? (wait * world.tick_lag) : wait - var/required_moves = ds / speed - var/leftover = MODULUS(required_moves, 1) - tick_moves_leftover += leftover - required_moves = round(required_moves) - if(tick_moves_leftover > 1) - required_moves += round(tick_moves_leftover) - tick_moves_leftover = MODULUS(tick_moves_leftover, 1) - for(var/i in 1 to required_moves) - pixel_move(1, FALSE) + var/required_pixels = (pixels_per_second * ds * 0.1) + pixels_tick_leftover + if(required_pixels >= pixel_increment_amount) + pixels_tick_leftover = MODULUS(required_pixels, pixel_increment_amount) + pixel_move(FLOOR(required_pixels / pixel_increment_amount, 1), FALSE, ds, SSprojectiles.global_projectile_speed_multiplier) + else + pixels_tick_leftover = required_pixels /obj/item/projectile/proc/fire(angle, atom/direct_target) if(fired_from) @@ -390,7 +409,7 @@ qdel(src) return var/turf/target = locate(clamp(starting + xo, 1, world.maxx), clamp(starting + yo, 1, world.maxy), starting.z) - setAngle(Get_Angle(src, target)) + setAngle(get_projectile_angle(src, target)) original_angle = Angle if(!nondirectional_sprite) var/matrix/M = new @@ -399,14 +418,16 @@ trajectory_ignore_forcemove = TRUE forceMove(starting) trajectory_ignore_forcemove = FALSE - trajectory = new(starting.x, starting.y, starting.z, pixel_x, pixel_y, Angle, SSprojectiles.global_pixel_speed) - last_projectile_move = world.time + if(isnull(pixel_increment_amount)) + pixel_increment_amount = SSprojectiles.global_pixel_increment_amount + trajectory = new(starting.x, starting.y, starting.z, pixel_x, pixel_y, Angle, pixel_increment_amount) fired = TRUE if(hitscan) process_hitscan() + return if(!(datum_flags & DF_ISPROCESSING)) START_PROCESSING(SSprojectiles, src) - pixel_move(1, FALSE) //move it now! + pixel_move(round(PROJECTILE_FIRING_INSTANT_TRAVEL_AMOUNT / pixel_increment_amount), FALSE, allow_animation = FALSE) //move it now! /obj/item/projectile/proc/setAngle(new_angle, hitscan_store_segment = TRUE) //wrapper for overrides. Angle = new_angle @@ -451,7 +472,8 @@ else return ..() -/obj/item/projectile/proc/set_pixel_speed(new_speed) +/obj/item/projectile/proc/set_pixel_increment_amount(new_speed) + pixel_increment_amount = new_speed if(trajectory) trajectory.set_speed(new_speed) return TRUE @@ -464,6 +486,7 @@ beam_segments[beam_index] = null //record start. /obj/item/projectile/proc/process_hitscan() + var/ttm = round(world.icon_size / pixel_increment_amount, 1) var/safety = range * 10 record_hitscan_start(RETURN_POINT_VECTOR_INCREMENT(src, Angle, MUZZLE_EFFECT_PIXEL_INCREMENT, 1)) while(loc && !QDELETED(src)) @@ -476,20 +499,33 @@ if(!QDELETED(src)) qdel(src) return //Kill! - pixel_move(1, TRUE) + pixel_move(ttm, TRUE, hitscan_movement_decisecond_equivalency) -/obj/item/projectile/proc/pixel_move(trajectory_multiplier, hitscanning = FALSE) +/** + * The proc to make the projectile go, using a simulated pixel movement line trace. + * Note: deciseconds_equivalent is currently only used for homing, times is the number of times to move pixel_increment_amount. + * Trajectory multiplier directly modifies the factor of pixel_increment_amount to go per time. + * It's complicated, so probably just don'ot mess with this unless you know what you're doing. + */ +/obj/item/projectile/proc/pixel_move(times, hitscanning = FALSE, deciseconds_equivalent = world.tick_lag, trajectory_multiplier = 1, allow_animation = TRUE) if(!loc || !trajectory) return - last_projectile_move = world.time if(!nondirectional_sprite && !hitscanning) var/matrix/M = new M.Turn(Angle) transform = M - if(homing) - process_homing() var/forcemoved = FALSE - for(var/i in 1 to SSprojectiles.global_iterations_per_move) + var/turf/oldloc = loc + var/old_px = pixel_x + var/old_py = pixel_y + for(var/i in 1 to times) + // HOMING START - Too expensive to proccall at this point. + if(homing_target) + // No datum/points, too expensive. + var/angle = closer_angle_difference(Angle, get_projectile_angle(src, homing_target)) + var/max_turn = homing_turn_speed * deciseconds_equivalent * 0.1 + setAngle(Angle + clamp(angle, -max_turn, max_turn)) + // HOMING END trajectory.increment(trajectory_multiplier) var/turf/T = trajectory.return_turf() if(!istype(T)) @@ -509,23 +545,29 @@ pixel_x = trajectory.return_px() pixel_y = trajectory.return_py() else if(T != loc) - step_towards(src, T) + var/safety = CEILING(pixel_increment_amount / world.icon_size, 1) * 2 + 1 + while(T != loc) + if(!--safety) + CRASH("Projectile took more than pixel incrememnt speed times 2 to get to its location, this is probably something seriously scuffed going on.") + step_towards(src, T) + if(QDELETED(src)) + return + pixels_range_leftover += pixel_increment_amount + if(pixels_range_leftover > world.icon_size) + Range() if(QDELETED(src)) return + pixels_range_leftover -= world.icon_size if(!hitscanning && !forcemoved) - pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move - pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move - animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW) - Range() - -/obj/item/projectile/proc/process_homing() //may need speeding up in the future performance wise. - if(!homing_target) - return FALSE - var/datum/point/PT = RETURN_PRECISE_POINT(homing_target) - PT.x += clamp(homing_offset_x, 1, world.maxx) - PT.y += clamp(homing_offset_y, 1, world.maxy) - var/angle = closer_angle_difference(Angle, angle_between_points(RETURN_PRECISE_POINT(src), PT)) - setAngle(Angle + clamp(angle, -homing_turn_speed, homing_turn_speed)) + var/traj_px = round(trajectory.return_px(), 1) + var/traj_py = round(trajectory.return_py(), 1) + if(allow_animation && (pixel_increment_amount * times > MINIMUM_PIXELS_TO_ANIMATE)) + pixel_x = ((oldloc.x - x) * world.icon_size) + old_px + pixel_y = ((oldloc.y - y) * world.icon_size) + old_py + animate(src, pixel_x = traj_px, pixel_y = traj_py, time = 1, flags = ANIMATION_END_NOW) + else + pixel_x = traj_px + pixel_y = traj_py /obj/item/projectile/proc/set_homing_target(atom/A) if(!A || (!isturf(A) && !isturf(A.loc))) @@ -575,7 +617,7 @@ if(targloc || !params) yo = targloc.y - curloc.y xo = targloc.x - curloc.x - setAngle(Get_Angle(src, targloc) + spread) + setAngle(get_projectile_angle(src, targloc) + spread) if(isliving(source) && params) var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params) @@ -586,7 +628,7 @@ else if(targloc) yo = targloc.y - curloc.y xo = targloc.x - curloc.x - setAngle(Get_Angle(src, targloc) + spread) + setAngle(get_projectile_angle(src, targloc) + spread) else stack_trace("WARNING: Projectile [type] fired without either mouse parameters, or a target atom to aim at!") qdel(src) @@ -698,3 +740,7 @@ /proc/is_energy_reflectable_projectile(atom/A) var/obj/item/projectile/P = A return istype(P) && P.is_reflectable + +#undef MOVES_HITSCAN +#undef MINIMUM_PIXELS_TO_ANIMATE +#undef MUZZLE_EFFECT_PIXEL_INCREMENT diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index ee081d57d6..2f12f0f69b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -74,7 +74,7 @@ flag = "energy" hitsound = 'sound/weapons/tap.ogg' eyeblur = 0 - speed = 0.6 + pixels_per_second = TILES_TO_PIXELS(16.667) impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_BLUE tracer_type = /obj/effect/projectile/tracer/disabler diff --git a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm index 2d66e25256..78deff601f 100644 --- a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm +++ b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm @@ -3,7 +3,7 @@ damage = 20 armour_penetration = 20 light_range = 3 - speed = 0.6 + pixels_per_second = TILES_TO_PIXELS(16.667) range = 35 light_color = LIGHT_COLOR_RED @@ -39,7 +39,7 @@ armour_penetration = 20 movement_type = FLYING | UNSTOPPABLE range = 20 - speed = 0.8 + pixels_per_second = TILES_TO_PIXELS(12.5) light_range = 4 light_color = LIGHT_COLOR_RED diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm index 5e3ae53806..f69b62a149 100644 --- a/code/modules/projectiles/projectile/bullets/sniper.dm +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -2,7 +2,7 @@ /obj/item/projectile/bullet/p50 name =".50 bullet" - speed = 0.4 + pixels_per_second = TILES_TO_PIXELS(25) damage = 70 knockdown = 100 dismemberment = 50 @@ -43,5 +43,5 @@ /obj/item/projectile/bullet/p50/penetrator/shuttle //Nukeop Shuttle Variety icon_state = "gaussstrong" damage = 25 - speed = 0.3 + pixels_per_second = TILES_TO_PIXELS(33.33) range = 16 diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm index e08f806fe5..6cbe258560 100644 --- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm +++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm @@ -5,7 +5,7 @@ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE flag = "rad" irradiate = 5000 - speed = 0.4 + pixels_per_second = TILES_TO_PIXELS(25) hitsound = 'sound/weapons/emitter2.ogg' impact_type = /obj/effect/projectile/impact/xray var/static/list/particle_colors = list( diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm index e3449a0c1d..83b753e0a3 100644 --- a/code/modules/projectiles/projectile/energy/stun.dm +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -10,7 +10,7 @@ jitter = 20 hitsound = 'sound/weapons/taserhit.ogg' range = 14 - speed = 0.6 + pixels_per_second = TILES_TO_PIXELS(16.667) tracer_type = /obj/effect/projectile/tracer/stun muzzle_type = /obj/effect/projectile/muzzle/stun impact_type = /obj/effect/projectile/impact/stun diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index dbb1497367..493a02d74c 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -434,7 +434,7 @@ damage = 15 damage_type = BURN nodamage = 0 - speed = 0.3 + pixels_per_second = TILES_TO_PIXELS(33.33) flag = "magic" var/zap_power = 20000 diff --git a/code/modules/projectiles/projectile/special/curse.dm b/code/modules/projectiles/projectile/special/curse.dm index 99aa922622..d967540e6a 100644 --- a/code/modules/projectiles/projectile/special/curse.dm +++ b/code/modules/projectiles/projectile/special/curse.dm @@ -10,7 +10,7 @@ damage_type = BURN damage = 10 knockdown = 20 - speed = 2 + pixels_per_second = TILES_TO_PIXELS(5) range = 16 movement_type = FLYING | UNSTOPPABLE var/datum/beam/arm diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 3b55b0045c..b85d7aefc9 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -23,7 +23,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/chem_dispenser var/obj/item/stock_parts/cell/cell - var/powerefficiency = 0.1 + var/powerefficiency = 0.0666666 var/amount = 30 var/recharge_amount = 10 var/recharge_counter = 0 @@ -387,7 +387,7 @@ /obj/machinery/chem_dispenser/RefreshParts() recharge_amount = initial(recharge_amount) - var/newpowereff = 0.0666666 + var/newpowereff = initial(powerefficiency) for(var/obj/item/stock_parts/cell/P in component_parts) cell = P for(var/obj/item/stock_parts/matter_bin/M in component_parts) @@ -720,3 +720,58 @@ component_parts += new /obj/item/stack/sheet/glass(null) component_parts += new /obj/item/stock_parts/cell/bluespace(null) RefreshParts() + +///An unique, less efficient model found in the medbay apothecary room. +/obj/machinery/chem_dispenser/apothecary + name = "apothecary chem dispenser" + desc = "A cheaper chem dispenser meant for small scale medicine production." + icon_state = "minidispenser" + working_state = "minidispenser_working" + nopower_state = "minidispenser_nopower" + circuit = /obj/item/circuitboard/machine/chem_dispenser/apothecary + powerefficiency = 0.0833333 + dispensable_reagents = list( //radium and stable plasma moved to upgrade tier 1 and 2, they've little to do with most medicines anyway. + /datum/reagent/hydrogen, + /datum/reagent/lithium, + /datum/reagent/carbon, + /datum/reagent/nitrogen, + /datum/reagent/oxygen, + /datum/reagent/fluorine, + /datum/reagent/sodium, + /datum/reagent/aluminium, + /datum/reagent/silicon, + /datum/reagent/phosphorus, + /datum/reagent/sulfur, + /datum/reagent/chlorine, + /datum/reagent/potassium, + /datum/reagent/iron, + /datum/reagent/copper, + /datum/reagent/mercury, + /datum/reagent/water, + /datum/reagent/consumable/ethanol, + /datum/reagent/consumable/sugar, + /datum/reagent/toxin/acid, + /datum/reagent/fuel, + /datum/reagent/silver, + /datum/reagent/iodine, + /datum/reagent/bromine + ) + upgrade_reagents = list( + /datum/reagent/oil, + /datum/reagent/ammonia, + /datum/reagent/radium + ) + upgrade_reagents2 = list( + /datum/reagent/acetone, + /datum/reagent/phenol, + /datum/reagent/stable_plasma + ) + upgrade_reagents3 = list( + /datum/reagent/medicine/mine_salve + ) + + emagged_reagents = list( + /datum/reagent/drug/space_drugs, + /datum/reagent/toxin/carpotoxin, + /datum/reagent/medicine/morphine + ) diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index ef4b7f3a53..f1e45d0717 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -559,3 +559,128 @@ var/mob/living/carbon/C = M if(!C.undergoing_cardiac_arrest()) C.set_heartattack(TRUE) + +//aphrodisiac & anaphrodisiac + +/datum/reagent/drug/aphrodisiac + name = "Crocin" + description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac." + taste_description = "strawberries" + color = "#FFADFF"//PINK, rgb(255, 173, 255) + can_synth = FALSE + +/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) + if((prob(min(current_cycle/2,5)))) + M.emote(pick("moan","blush")) + if(prob(min(current_cycle/4,10))) + var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.") + to_chat(M, "[aroused_message]") + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/list/genits = H.adjust_arousal(current_cycle, aphro = TRUE) // redundant but should still be here + for(var/g in genits) + var/obj/item/organ/genital/G = g + to_chat(M, "[G.arousal_verb]!") + ..() + +/datum/reagent/drug/aphrodisiacplus + name = "Hexacrocin" + description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\ + Addiction withdrawals can cause brain damage and shortness of breath. Overdosage can lead to brain damage and a \ + permanent increase in libido (commonly referred to as 'bimbofication')." + taste_description = "liquid desire" + color = "#FF2BFF"//dark pink + addiction_threshold = 20 + overdose_threshold = 20 + can_synth = FALSE + +/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) + if(prob(5)) + if(prob(current_cycle)) + M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn...")) + else + M.emote(pick("moan","blush")) + if(prob(5)) + var/aroused_message + if(current_cycle>25) + aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!") + else + aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.") + to_chat(M, "[aroused_message]") + REMOVE_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/list/genits = H.adjust_arousal(100, aphro = TRUE) // redundant but should still be here + for(var/g in genits) + var/obj/item/organ/genital/G = g + to_chat(M, "[G.arousal_verb]!") + ..() + +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M) + if(prob(30)) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2) + ..() +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M) + if(prob(30)) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3) + + ..() +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M) + if(prob(30)) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4) + ..() + +/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) + if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO) && prob(33)) + if(prob(5) && ishuman(M) && M.has_dna() && (M.client?.prefs.cit_toggles & BIMBOFICATION)) + if(!HAS_TRAIT(M,TRAIT_PERMABONER)) + to_chat(M, "Your libido is going haywire!") + ADD_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT) + ..() + +/datum/reagent/drug/anaphrodisiac + name = "Camphor" + description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\ + , reducing libido and calming them. Non-habit forming and not addictive." + taste_description = "dull bitterness" + taste_mult = 2 + color = "#D9D9D9"//rgb(217, 217, 217) + reagent_state = SOLID + can_synth = FALSE + +/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable && prob(16)) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/list/genits = H.adjust_arousal(-100, aphro = TRUE) + if(genits.len) + to_chat(M, "You no longer feel aroused.") + ..() + +/datum/reagent/drug/anaphrodisiacplus + name = "Hexacamphor" + description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive." + taste_description = "tranquil celibacy" + color = "#D9D9D9"//rgb(217, 217, 217) + reagent_state = SOLID + overdose_threshold = 20 + can_synth = FALSE + +/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable) + REMOVE_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/list/genits = H.adjust_arousal(-100, aphro = TRUE) + if(genits.len) + to_chat(M, "You no longer feel aroused.") + + ..() + +/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M) + if(M && M.client?.prefs.arousable && prob(5)) + to_chat(M, "You feel like you'll never feel aroused again...") + ADD_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT) + ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5fb27bd074..d3ac8fa506 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1735,6 +1735,22 @@ H.facial_hair_style = "Very Long Beard" H.update_hair() +/datum/reagent/baldium + name = "Baldium" + description = "A major cause of hair loss across the world." + reagent_state = LIQUID + color = "#ecb2cf" + taste_description = "bitterness" + +/datum/reagent/baldium/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(method == TOUCH || method == VAPOR) + if(M && ishuman(M)) + var/mob/living/carbon/human/H = M + to_chat(H, "Your hair is falling out in clumps!") + H.hair_style = "Bald" + H.facial_hair_style = "Shaved" + H.update_hair() + /datum/reagent/saltpetre name = "Saltpetre" description = "Volatile. Controversial. Third Thing." @@ -2178,3 +2194,93 @@ reagent_state = LIQUID color = "#f7685e" metabolization_rate = REAGENTS_METABOLISM * 0.25 + + +//body bluids +/datum/reagent/consumable/semen + name = "Semen" + description = "Sperm from some animal. Useless for anything but insemination, really." + taste_description = "something salty" + taste_mult = 2 //Not very overpowering flavor + data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) + reagent_state = LIQUID + color = "#FFFFFF" // rgb: 255, 255, 255 + can_synth = FALSE + nutriment_factor = 0.5 * REAGENTS_METABOLISM + +/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume) + if(!istype(T)) + return + if(reac_volume < 10) + return + + var/obj/effect/decal/cleanable/semen/S = locate() in T + if(!S) + S = new(T) + if(data["blood_DNA"]) + S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) + +/obj/effect/decal/cleanable/semen + name = "semen" + desc = null + gender = PLURAL + density = 0 + layer = ABOVE_NORMAL_TURF_LAYER + icon = 'icons/obj/genitals/effects.dmi' + icon_state = "semen1" + random_icon_states = list("semen1", "semen2", "semen3", "semen4") + +/obj/effect/decal/cleanable/semen/Initialize(mapload) + . = ..() + dir = GLOB.cardinals + add_blood_DNA(list("Non-human DNA" = "A+")) + +/obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S) + if(S.blood_DNA) + blood_DNA |= S.blood_DNA + return ..() + +/datum/reagent/consumable/femcum + name = "Female Ejaculate" + description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business." + taste_description = "something with a tang" // wew coders who haven't eaten out a girl. + taste_mult = 2 + data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) + reagent_state = LIQUID + color = "#AAAAAA77" + can_synth = FALSE + nutriment_factor = 0.5 * REAGENTS_METABOLISM + +/obj/effect/decal/cleanable/femcum + name = "female ejaculate" + desc = null + gender = PLURAL + density = 0 + layer = ABOVE_NORMAL_TURF_LAYER + icon = 'icons/obj/genitals/effects.dmi' + icon_state = "fem1" + random_icon_states = list("fem1", "fem2", "fem3", "fem4") + blood_state = null + bloodiness = null + +/obj/effect/decal/cleanable/femcum/Initialize(mapload) + . = ..() + dir = GLOB.cardinals + add_blood_DNA(list("Non-human DNA" = "A+")) + +/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F) + if(F.blood_DNA) + blood_DNA |= F.blood_DNA + return ..() + +/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume) + if(!istype(T)) + return + if(reac_volume < 10) + return + + var/obj/effect/decal/cleanable/femcum/S = locate() in T + if(!S) + S = new(T) + if(data["blood_DNA"]) + S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 3ba883a2c7..02e4a89e1d 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -1019,3 +1019,20 @@ to_chat(M, "[tox_message]") . = 1 ..() + +/datum/reagent/toxin/leadacetate + name = "Lead Acetate" + description = "Used hundreds of years ago as a sweetener, before it was realized that it's incredibly poisonous." + reagent_state = SOLID + color = "#2b2b2b" // rgb: 127, 132, 0 + toxpwr = 0.5 + taste_mult = 1.3 + taste_description = "sugary sweetness" + +/datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/M) + M.adjustOrganLoss(ORGAN_SLOT_EARS,1) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN,1) + if(prob(1)) + to_chat(M, "Ah, what was that? You thought you heard something...") + M.confused += 5 + return ..() diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm index 468d29c052..a2b8c27552 100644 --- a/code/modules/reagents/chemistry/recipes/drugs.dm +++ b/code/modules/reagents/chemistry/recipes/drugs.dm @@ -62,3 +62,34 @@ results = list(/datum/reagent/moonsugar = 1, /datum/reagent/medicine/morphine = 2.5) required_temp = 315 //a little above normal body temperature required_reagents = list(/datum/reagent/drug/skooma = 1) +/datum/chemical_reaction/aphro + name = "crocin" + id = /datum/reagent/drug/aphrodisiac + results = list(/datum/reagent/drug/aphrodisiac = 6) + required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/water = 1) + required_temp = 400 + mix_message = "The mixture boils off a pink vapor..."//The water boils off, leaving the crocin + +/datum/chemical_reaction/aphroplus + name = "hexacrocin" + id = /datum/reagent/drug/aphrodisiacplus + results = list(/datum/reagent/drug/aphrodisiacplus = 1) + required_reagents = list(/datum/reagent/drug/aphrodisiac = 6, /datum/reagent/phenol = 1) + required_temp = 400 + mix_message = "The mixture rapidly condenses and darkens in color..." + +/datum/chemical_reaction/anaphro + name = "camphor" + id = /datum/reagent/drug/anaphrodisiac + results = list(/datum/reagent/drug/anaphrodisiac = 6) + required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/sulfur = 1) + required_temp = 400 + mix_message = "The mixture boils off a yellow, smelly vapor..."//Sulfur burns off, leaving the camphor + +/datum/chemical_reaction/anaphroplus + name = "pentacamphor" + id = /datum/reagent/drug/anaphrodisiacplus + results = list(/datum/reagent/drug/anaphrodisiacplus = 1) + required_reagents = list(/datum/reagent/drug/aphrodisiac = 5, /datum/reagent/acetone = 1) + required_temp = 300 + mix_message = "The mixture thickens and heats up slighty..." diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 618ac256e2..df1b57c20b 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -631,6 +631,11 @@ results = list(/datum/reagent/concentrated_barbers_aid = 2) required_reagents = list(/datum/reagent/barbers_aid = 1, /datum/reagent/toxin/mutagen = 1) +/datum/chemical_reaction/baldium + results = list(/datum/reagent/baldium = 1) + required_reagents = list(/datum/reagent/radium = 1, /datum/reagent/toxin/acid = 1, /datum/reagent/lye = 1) + required_temp = 395 + /datum/chemical_reaction/saltpetre name = "saltpetre" id = /datum/reagent/saltpetre diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index b4e954f147..549f4eb48c 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -351,7 +351,7 @@ name = "wooden bucket" desc = "It's a bucket made of wood." icon_state = "bucket_wooden" - custom_materials = null + custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 2) slot_flags = NONE item_flags = NO_MAT_REDEMPTION diff --git a/code/modules/reagents/reagent_containers/maunamug.dm b/code/modules/reagents/reagent_containers/maunamug.dm new file mode 100644 index 0000000000..18e6cfa847 --- /dev/null +++ b/code/modules/reagents/reagent_containers/maunamug.dm @@ -0,0 +1,117 @@ +/obj/item/reagent_containers/glass/maunamug + name = "mauna mug" + desc = "A drink served in a classy mug. Now with built-in heating!" + icon = 'icons/obj/mauna_mug.dmi' + icon_state = "maunamug" + spillable = TRUE + reagent_flags = OPENCONTAINER +// fill_icon_state = "maunafilling" +// fill_icon_thresholds = list(25) + var/obj/item/stock_parts/cell/cell + var/open = FALSE + var/on = FALSE + +/obj/item/reagent_containers/glass/maunamug/Initialize(mapload, vol) + . = ..() + cell = new /obj/item/stock_parts/cell(src) + +/obj/item/reagent_containers/glass/maunamug/examine(mob/user) + . = ..() + . += "The status display reads: Current temperature: [reagents.chem_temp]K Current Charge:[cell ? "[cell.charge / cell.maxcharge * 100]%" : "No cell found"]." + if(open) + . += "The battery case is open." + +/obj/item/reagent_containers/glass/maunamug/update_overlays() + . = ..() + if(reagents.total_volume >= 25) + . += mutable_appearance('icons/obj/reagentfillings.dmi', "maunafilling25", color = mix_color_from_reagents(reagents.reagent_list)) + +/obj/item/reagent_containers/glass/maunamug/process() + ..() + if(on && (!cell || cell.charge <= 0)) //Check if we ran out of power + change_power_status(FALSE) + return FALSE + cell.use(10) //Basic cell goes for like 200 seconds, bluespace for 8000 + if(!reagents.total_volume) + return FALSE + var/max_temp = min(500 + (500 * (0.2 * cell.rating)), 1000) // 373 to 1000 + reagents.adjust_thermal_energy(0.8 * cell.maxcharge * reagents.total_volume, max_temp = max_temp) // 4 kelvin every tick on a basic cell. 160k on bluespace + reagents.handle_reactions() + update_icon() + if(reagents.chem_temp >= max_temp) + change_power_status(FALSE) + audible_message("The Mauna Mug lets out a happy beep and turns off!") + playsound(src, 'sound/machines/chime.ogg', 50) + +/obj/item/reagent_containers/glass/maunamug/Destroy() + if(cell) + QDEL_NULL(cell) + STOP_PROCESSING(SSobj, src) + . = ..() + + +/obj/item/reagent_containers/glass/maunamug/attack_self(mob/user) + if(on) + change_power_status(FALSE) + else + if(!cell || cell.charge <= 0) + return FALSE //No power, so don't turn on + change_power_status(TRUE) + +/obj/item/reagent_containers/glass/maunamug/proc/change_power_status(status) + on = status + if(on) + START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) + update_icon() + +/obj/item/reagent_containers/glass/maunamug/screwdriver_act(mob/living/user, obj/item/I) + . = ..() + open = !open + to_chat(user, "You screw the battery case on [src] [open ? "open" : "closed"] .") + update_icon() + +/obj/item/reagent_containers/glass/maunamug/attackby(obj/item/I, mob/user, params) + add_fingerprint(user) + if(!istype(I, /obj/item/stock_parts/cell)) + return ..() + if(!open) + to_chat(user, "The battery case must be open to insert a power cell!") + return FALSE + if(cell) + to_chat(user, "There is already a power cell inside!") + return FALSE + else if(!user.transferItemToLoc(I, src)) + return + cell = I + user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") + update_icon() + +/obj/item/reagent_containers/glass/maunamug/attack_hand(mob/living/user) + if(cell && open) + cell.update_icon() + user.put_in_hands(cell) + cell = null + to_chat(user, "You remove the power cell from [src].") + on = FALSE + update_icon() + return TRUE + return ..() + +/obj/item/reagent_containers/glass/maunamug/update_icon() + ..() + if(open) + if(cell) + icon_state = "maunamug_bat" + else + icon_state = "maunamug_no_bat" + else if(on) + icon_state = "maunamug_on" + else + icon_state = "maunamug" + if(reagents.total_volume && reagents.chem_temp >= 400) + var/intensity = (reagents.chem_temp - 400) * 1 / 600 //Get the opacity of the incandescent overlay. Ranging from 400 to 1000 + var/mutable_appearance/mug_glow = mutable_appearance(icon, "maunamug_incand") + mug_glow.alpha = 255 * intensity + add_overlay(mug_glow) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 36e3b0d47e..1247a7abc3 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -22,10 +22,17 @@ if(reagents.total_volume && roundstart) name += " ([reagents.total_volume]u)" - /obj/item/reagent_containers/pill/attack_self(mob/user) return +/obj/item/reagent_containers/pill/get_w_volume() + switch(reagents.total_volume) + if(0 to 9.5) + return 1 + if(9.5 to 25) + return DEFAULT_VOLUME_TINY + else + return DEFAULT_VOLUME_SMALL /obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) if(!canconsume(M, user)) @@ -137,14 +144,14 @@ name = "mannitol pill" desc = "Used to treat brain damage." icon_state = "pill17" - list_reagents = list(/datum/reagent/medicine/mannitol = 50) + list_reagents = list(/datum/reagent/medicine/mannitol = 25) roundstart = 1 /obj/item/reagent_containers/pill/mutadone name = "mutadone pill" desc = "Used to treat genetic damage." icon_state = "pill20" - list_reagents = list(/datum/reagent/medicine/mutadone = 50) + list_reagents = list(/datum/reagent/medicine/mutadone = 25) roundstart = 1 /obj/item/reagent_containers/pill/salicyclic @@ -186,14 +193,14 @@ name = "prussian blue pill" desc = "Used to treat heavy radition poisoning." icon_state = "prussian_blue" - list_reagents = list(/datum/reagent/medicine/prussian_blue = 25, /datum/reagent/water = 10) + list_reagents = list(/datum/reagent/medicine/prussian_blue = 25) roundstart = 1 /obj/item/reagent_containers/pill/mutarad name = "radiation treatment deluxe pill" desc = "Used to treat heavy radition poisoning and genetic defects." icon_state = "anit_rad_fixgene" - list_reagents = list(/datum/reagent/medicine/prussian_blue = 15, /datum/reagent/medicine/potass_iodide = 15, /datum/reagent/medicine/mutadone = 15, /datum/reagent/water = 5) + list_reagents = list(/datum/reagent/medicine/prussian_blue = 10, /datum/reagent/medicine/potass_iodide = 10, /datum/reagent/medicine/mutadone = 5) roundstart = 1 ///////////////////////////////////////// this pill is used only in a legion mob drop @@ -216,7 +223,7 @@ /obj/item/reagent_containers/pill/lsd name = "hallucinogen pill" - list_reagents = list(/datum/reagent/drug/mushroomhallucinogen = 15, /datum/reagent/toxin/mindbreaker = 15) + list_reagents = list(/datum/reagent/drug/mushroomhallucinogen = 12.5, /datum/reagent/toxin/mindbreaker = 12.5) /obj/item/reagent_containers/pill/aranesp diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 9ef08590a8..bc4e214161 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -241,12 +241,6 @@ icon_state = "whitekeg" reagent_id = /datum/reagent/consumable/milk -/obj/structure/reagent_dispensers/keg/semen - name = "keg of semen" - desc = "Dear lord, where did this even come from?" - icon_state = "whitekeg" - reagent_id = /datum/reagent/consumable/semen - /obj/structure/reagent_dispensers/keg/gargle name = "keg of pan galactic gargleblaster" desc = "A keg of... wow that's a long name." diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm new file mode 100644 index 0000000000..c6ce45f160 --- /dev/null +++ b/code/modules/research/bepis.dm @@ -0,0 +1,270 @@ +//This system is designed to act as an in-between for cargo and science, and the first major money sink in the game outside of just buying things from cargo (As of 10/9/19, anyway). + +//economics defined values, subject to change should anything be too high or low in practice. + +#define MACHINE_OPERATION 100000 +#define MACHINE_OVERLOAD 500000 +#define MAJOR_THRESHOLD 5500 +#define MINOR_THRESHOLD 3500 +#define STANDARD_DEVIATION 1000 + +/obj/machinery/rnd/bepis + name = "\improper B.E.P.I.S. Chamber" + desc = "A high fidelity testing device which unlocks the secrets of the known universe using the two most powerful substances available to man: excessive amounts of electricity and capital." + icon = 'icons/obj/machines/bepis.dmi' + icon_state = "chamber" + density = TRUE + layer = ABOVE_MOB_LAYER + use_power = IDLE_POWER_USE + active_power_usage = 1500 + circuit = /obj/item/circuitboard/machine/bepis + + var/banking_amount = 100 + var/banked_cash = 0 //stored player cash + var/datum/bank_account/account //payer's account. + var/account_name //name of the payer's account. + var/error_cause = null + //Vars related to probability and chance of success for testing + var/major_threshold = MAJOR_THRESHOLD + var/minor_threshold = MINOR_THRESHOLD + var/std = STANDARD_DEVIATION //That's Standard Deviation, what did you think it was? + //Stock part variables + var/power_saver = 1 + var/inaccuracy_percentage = 1.5 + var/positive_cash_offset = 0 + var/negative_cash_offset = 0 + var/minor_rewards = list(/obj/item/stack/circuit_stack/full, //To add a new minor reward, add it here. + /obj/item/airlock_painter/decal, + /obj/item/pen/survival, + /obj/item/circuitboard/machine/sleeper/party, + /obj/item/toy/sprayoncan) + var/static/list/item_list = list() + +/obj/machinery/rnd/bepis/attackby(obj/item/O, mob/user, params) + if(default_deconstruction_screwdriver(user, "chamber_open", "chamber", O)) + update_icon_state() + return + if(default_deconstruction_crowbar(O)) + return + if(!is_operational()) + to_chat(user, "[src] can't accept money when it's not functioning.") + return + if(istype(O, /obj/item/holochip) || istype(O, /obj/item/stack/spacecash)) + var/deposit_value = O.get_item_credit_value() + banked_cash += deposit_value + qdel(O) + say("Deposited [deposit_value] credits into storage.") + update_icon_state() + return + if(istype(O, /obj/item/card/id)) + var/obj/item/card/id/Card = O + if(Card.registered_account) + account = Card.registered_account + account_name = Card.registered_name + say("New account detected. Console Updated.") + else + say("No account detected on card. Aborting.") + return + return ..() + +/obj/machinery/rnd/bepis/RefreshParts() + var/C = 0 + var/M = 0 + var/L = 0 + var/S = 0 + for(var/obj/item/stock_parts/capacitor/Cap in component_parts) + C += ((Cap.rating - 1) * 0.1) + power_saver = 1 - C + for(var/obj/item/stock_parts/manipulator/Manip in component_parts) + M += ((Manip.rating - 1) * 250) + positive_cash_offset = M + for(var/obj/item/stock_parts/micro_laser/Laser in component_parts) + L += ((Laser.rating - 1) * 250) + negative_cash_offset = L + for(var/obj/item/stock_parts/scanning_module/Scan in component_parts) + S += ((Scan.rating - 1) * 0.25) + inaccuracy_percentage = (1.5 - S) + +/obj/machinery/rnd/bepis/proc/depositcash() + var/deposit_value = 0 + deposit_value = banking_amount + if(deposit_value == 0) + update_icon_state() + say("Attempting to deposit 0 credits. Aborting.") + return + deposit_value = clamp(round(deposit_value, 1), 1, 15000) + if(!account) + say("Cannot find user account. Please swipe a valid ID.") + return + if(!account.has_money(deposit_value)) + say("You do not possess enough credits.") + return + account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts. + SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) + banked_cash += deposit_value + use_power(1000 * power_saver) + say("Cash deposit successful. There is [banked_cash] in the chamber.") + update_icon_state() + return + +/obj/machinery/rnd/bepis/proc/withdrawcash() + var/withdraw_value = 0 + withdraw_value = banking_amount + if(withdraw_value > banked_cash) + say("Cannot withdraw more than stored funds. Aborting.") + else + banked_cash -= withdraw_value + new /obj/item/holochip(src.loc, withdraw_value) + say("Withdrawing [withdraw_value] credits from the chamber.") + update_icon_state() + return + +/obj/machinery/rnd/bepis/proc/calcsuccess() + var/turf/dropturf = null + var/gauss_major = 0 + var/gauss_minor = 0 + var/gauss_real = 0 + var/list/turfs = block(locate(x-1,y-1,z),locate(x+1,y+1,z)) //NO MORE DISCS IN WINDOWS + while(length(turfs)) + var/turf/T = pick_n_take(turfs) + if(is_blocked_turf(T, exclude_mobs=TRUE)) + continue + else + dropturf = T + break + if (!dropturf) + dropturf = drop_location() + gauss_major = (gaussian(major_threshold, std) - negative_cash_offset) //This is the randomized profit value that this experiment has to surpass to unlock a tech. + gauss_minor = (gaussian(minor_threshold, std) - negative_cash_offset) //And this is the threshold to instead get a minor prize. + gauss_real = (gaussian(banked_cash, std*inaccuracy_percentage) + positive_cash_offset) //this is the randomized profit value that your experiment expects to give. + say("Real: [gauss_real]. Minor: [gauss_minor]. Major: [gauss_major].") + flick("chamber_flash",src) + update_icon_state() + banked_cash = 0 + if((gauss_real >= gauss_major) && (SSresearch.techweb_nodes_experimental.len > 0)) //Major Success. + say("Experiment concluded with major success. New technology node discovered on technology disc.") + new /obj/item/disk/tech_disk/major(dropturf,1) + if(SSresearch.techweb_nodes_experimental.len == 0) + say("Expended all available experimental technology nodes. Resorting to minor rewards.") + return + if(gauss_real >= gauss_minor) //Minor Success. + var/reward = pick(minor_rewards) + new reward(dropturf) + say("Experiment concluded with partial success. Dispensing compiled research efforts.") + return + if(gauss_real <= -1) //Critical Failure + say("ERROR: CRITICAL MACHIME MALFUNCTI- ON. CURRENCY IS NOT CRASH. CANNOT COMPUTE COMMAND: 'make bucks'") //not a typo, for once. + new /mob/living/simple_animal/deer(dropturf, 1) + use_power(MACHINE_OVERLOAD * power_saver) //To prevent gambling at low cost and also prevent spamming for infinite deer. + return + //Minor Failure + error_cause = pick("attempted to sell grey products to American dominated market.","attempted to sell gray products to British dominated market.","placed wild assumption that PDAs would go out of style.","simulated product #76 damaged brand reputation mortally.","simulated business model resembled 'pyramid scheme' by 98.7%.","product accidently granted override access to all station doors.") + say("Experiment concluded with zero product viability. Cause of error: [error_cause]") + return + +/obj/machinery/rnd/bepis/update_icon_state() + if(panel_open == TRUE) + icon_state = "chamber_open" + return + if((use_power == ACTIVE_POWER_USE) && (banked_cash > 0) && (is_operational())) + icon_state = "chamber_active_loaded" + return + if (((use_power == IDLE_POWER_USE) && (banked_cash > 0)) || (banked_cash > 0) && (!is_operational())) + icon_state = "chamber_loaded" + return + if(use_power == ACTIVE_POWER_USE && is_operational()) + icon_state = "chamber_active" + return + if(((use_power == IDLE_POWER_USE) && (banked_cash == 0)) || (!is_operational())) + icon_state = "chamber" + return + +/obj/machinery/rnd/bepis/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) + ui = new(user, src, ui_key, "bepis", name, 500, 480, master_ui, state) + ui.open() + RefreshParts() + +/obj/machinery/rnd/bepis/ui_data(mob/user) + var/list/data = list() + var/powered = FALSE + var/zvalue = (banked_cash - (major_threshold - positive_cash_offset - negative_cash_offset))/(std) + var/std_success = 0 + var/prob_success = 0 + //Admittedly this is messy, but not nearly as messy as the alternative, which is jury-rigging an entire Z-table into the code, or making an adaptive z-table. + var/z = abs(zvalue) + if(z > 0 && z <= 0.5) + std_success = 19.1 + else if(z > 0.5 && z <= 1.0) + std_success = 34.1 + else if(z > 1.0 && z <= 1.5) + std_success = 43.3 + else if(z > 1.5 && z <= 2.0) + std_success = 47.7 + else if(z > 2.0 && z <= 2.5) + std_success = 49.4 + else + std_success = 50 + if(zvalue > 0) + prob_success = 50 + std_success + else if(zvalue == 0) + prob_success = 50 + else + prob_success = 50 - std_success + + if(use_power == ACTIVE_POWER_USE) + powered = TRUE + data["account_owner"] = account_name + data["amount"] = banking_amount + data["stored_cash"] = banked_cash + data["mean_value"] = (major_threshold - positive_cash_offset - negative_cash_offset) + data["error_name"] = error_cause + data["power_saver"] = power_saver + data["accuracy_percentage"] = inaccuracy_percentage * 100 + data["positive_cash_offset"] = positive_cash_offset + data["negative_cash_offset"] = negative_cash_offset + data["manual_power"] = powered ? FALSE : TRUE + data["silicon_check"] = issilicon(user) + data["success_estimate"] = prob_success + return data + +/obj/machinery/rnd/bepis/ui_act(action,params) + if(..()) + return + switch(action) + if("deposit_cash") + if(use_power == IDLE_POWER_USE) + return + depositcash() + if("withdraw_cash") + if(use_power == IDLE_POWER_USE) + return + withdrawcash() + if("begin_experiment") + if(use_power == IDLE_POWER_USE) + return + if(banked_cash == 0) + say("Please deposit funds to begin testing.") + return + calcsuccess() + use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful. + use_power = IDLE_POWER_USE //Machine shuts off after use to prevent spam and look better visually. + update_icon_state() + if("amount") + var/input = text2num(params["amount"]) + if(input) + banking_amount = input + if("toggle_power") + if(use_power == ACTIVE_POWER_USE) + use_power = IDLE_POWER_USE + else + use_power = ACTIVE_POWER_USE + update_icon_state() + if("account_reset") + if(use_power == IDLE_POWER_USE) + return + account_name = "" + account = null + say("Account settings reset.") + . = TRUE diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm index 20a5370793..9cbef4abdd 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm @@ -10,6 +10,7 @@ id = "beanbag_slug" build_type = AUTOLATHE materials = list(/datum/material/iron = 250) + materials = list(/datum/material/iron = 1000) build_path = /obj/item/ammo_casing/shotgun/beanbag category = list("initial", "Security") @@ -73,12 +74,12 @@ build_path = /obj/item/restraints/handcuffs category = list("hacked", "Security") -/datum/design/receiver - name = "Modular Receiver" - id = "receiver" - build_type = AUTOLATHE | NO_PUBLIC_LATHE - materials = list(/datum/material/iron = 15000) - build_path = /obj/item/weaponcrafting/receiver +/datum/design/rifle_receiver + name = "Rifle Receiver" + id = "rifle_receiver" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 40000) + build_path = /obj/item/weaponcrafting/improvised_parts/rifle_receiver category = list("hacked", "Security") /datum/design/shotgun_slug @@ -113,6 +114,10 @@ build_path = /obj/item/ammo_casing/shotgun/incendiary category = list("hacked", "Security") +///////////////// +// Bullets // +///////////////// + /datum/design/riot_dart name = "Foam Riot Dart" id = "riot_dart" diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm index eebeec2c78..ea73df568f 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm @@ -271,4 +271,13 @@ build_type = AUTOLATHE materials = list(/datum/material/iron = 5000, /datum/material/glass = 2000) build_path = /obj/item/vending_refill/custom - category = list("initial", "Misc") \ No newline at end of file + category = list("initial", "Misc") + +/datum/design/trigger_assembly + name = "Trigger Assembly" + id = "trigger_assembly" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 6500, /datum/material/glass = 50) + build_path = /obj/item/weaponcrafting/improvised_parts/trigger_assembly + category = list("initial", "Misc") + diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm index 330dfb8f8a..516c91d426 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -157,3 +157,11 @@ materials = list(/datum/material/iron = 150, /datum/material/glass = 150) build_path = /obj/item/geiger_counter category = list("initial", "Tools") + +/datum/design/saw + name = "Hand Saw" + id = "handsaw" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 500) + build_path = /obj/item/hatchet/saw + category = list("initial", "Tools") diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm index 95e5a66099..d12099f7ff 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm @@ -122,3 +122,11 @@ build_path = /obj/item/circuitboard/machine/autolathe/toy departmental_flags = DEPARTMENTAL_FLAG_ALL category = list("Misc. Machinery") + +/datum/design/board/hypnochair + name = "Machine Design (Enhanced Interrogation Chamber)" + desc = "Allows for the construction of circuit boards used to build an Enhanced Interrogation Chamber." + id = "hypnochair" + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + build_path = /obj/item/circuitboard/machine/hypnochair + category = list("Misc. Machinery") diff --git a/code/modules/research/designs/machine_desings/machine_designs_sci.dm b/code/modules/research/designs/machine_desings/machine_designs_sci.dm index 183977b455..59fae9d09b 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_sci.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_sci.dm @@ -66,6 +66,14 @@ category = list("Research Machinery") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE +/datum/design/board/bepis + name = "Machine Design (B.E.P.I.S. Board)" + desc = "The circuit board for a B.E.P.I.S." + id = "bepis" + build_path = /obj/item/circuitboard/machine/bepis + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + /datum/design/board/protolathe name = "Machine Design (Protolathe Board)" desc = "The circuit board for a protolathe." diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index ff60478eb4..81068a1ee0 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -206,6 +206,35 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/bright_helmet + name = "Workplace-Ready Firefighter Helmet" + desc = "By applying state of the art lighting technology to a fire helmet with industry standard photo-chemical hardening methods, this hardhat will protect you from robust workplace hazards." + id = "bright_helmet" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 3000, /datum/material/silver = 500) + build_path = /obj/item/clothing/head/hardhat/red/upgraded + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_CARGO + +/datum/design/mauna_mug + name = "Mauna Mug" + desc = "This awesome mug will ensure your coffee never stays cold!" + id = "mauna_mug" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/glass = 100) + build_path = /obj/item/reagent_containers/glass/maunamug + category = list("Equipment") + +/datum/design/rolling_table + name = "Rolly poly" + desc = "We duct-taped some wheels to the bottom of a table. It's goddamn science alright?" + id = "rolling_table" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 4000) + build_path = /obj/structure/table/rolling + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ALL + /datum/design/portaseeder name = "Portable Seed Extractor" desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." @@ -285,6 +314,25 @@ build_path = /obj/item/vending_refill/donksoft category = list("Equipment") +/datum/design/eng_gloves + name = "Tinkers Gloves" + desc = "Overdesigned engineering gloves that have automated construction subroutines dialed in, allowing for faster construction while worn." + id = "eng_gloves" + build_type = PROTOLATHE + materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000) + build_path = /obj/item/clothing/gloves/color/latex/engineering + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/lavarods + name = "Lava-Resistant Metal Rods" + id = "lava_rods" + build_type = PROTOLATHE + materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000) + build_path = /obj/item/stack/rods/lava + category = list("initial", "Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + ///////////////////////////////////////// ////////////Janitor Designs////////////// ///////////////////////////////////////// diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index 2d938bc38c..e500166e76 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -72,6 +72,16 @@ category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/rld_mini + name = "Mini Rapid Light Device (MRLD)" + desc = "A tool that can portable and standing lighting orbs and glowsticks." + id = "rld_mini" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 20000, /datum/material/glass = 10000, /datum/material/plastic = 8000, /datum/material/gold = 2000) + build_path = /obj/item/construction/rld/mini + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + ///////////////////////////////////////// //////////////Alien Tools//////////////// ///////////////////////////////////////// diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 07679fe1ce..8c934d39a9 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -234,13 +234,13 @@ category = list("Firing Pins") departmental_flags = DEPARTMENTAL_FLAG_SECURITY -/datum/design/pin_away - name = "Station Locked Pin" - desc = "This is a security firing pin which only authorizes users who are off station." - id = "pin_away" +/datum/design/pin_explorer + name = "Outback Firing Pin" + desc = "This firing pin only shoots while ya ain't on station, fair dinkum!" + id = "pin_explorer" build_type = PROTOLATHE - materials = list(/datum/material/iron = 1500, /datum/material/glass = 2000) - build_path = /obj/item/firing_pin/away + materials = list(/datum/material/silver = 1000, /datum/material/gold = 1000, /datum/material/iron = 500) + build_path = /obj/item/firing_pin/explorer category = list("Firing Pins") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -500,3 +500,13 @@ materials = list(MAT_CATEGORY_RIGID = 12000) build_path = /obj/item/melee/cleric_mace category = list("Imported") + +/datum/design/stun_boomerang + name = "OZtek Boomerang" + desc = "Uses reverse flow gravitodynamics to flip its personal gravity back to the thrower mid-flight. Also functions similar to a stun baton." + id = "stun_boomerang" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000) + build_path = /obj/item/melee/baton/boomerang + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm index aa781ca06b..a656093d98 100644 --- a/code/modules/research/research_disk.dm +++ b/code/modules/research/research_disk.dm @@ -21,6 +21,16 @@ . = ..() stored_research = new /datum/techweb/admin +/obj/item/disk/tech_disk/major + name = "Reformatted technology disk" + desc = "A disk containing a new, completed tech from the B.E.P.I.S. Upload the disk to an R&D Console to redeem the tech." + icon_state = "rndmajordisk" + custom_materials = list(/datum/material/iron=300, /datum/material/glass=100) + +/obj/item/disk/tech_disk/major/Initialize() + . = ..() + stored_research = new /datum/techweb/bepis + /obj/item/disk/tech_disk/illegal name = "Illegal technology disk" desc = "A technology disk containing schematics for syndicate inspired equipment." diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index ccfcecf66c..503bd8bae7 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -63,6 +63,19 @@ id = "SCIENCE" organization = "Nanotrasen" +/datum/techweb/bepis //Should contain only 1 BEPIS tech selected at random. + id = "EXPERIMENTAL" + organization = "Nanotrasen R&D" + +/datum/techweb/bepis/New() + . = ..() + var/bepis_id = pick(SSresearch.techweb_nodes_experimental) //To add a new tech to the BEPIS, add the ID to this pick list. + var/datum/techweb_node/BN = (SSresearch.techweb_node_by_id(bepis_id)) + hidden_nodes -= BN.id //Has to be removed from hidden nodes + research_node(BN, TRUE, FALSE, FALSE) + update_node_status(BN) + SSresearch.techweb_nodes_experimental -= bepis_id + /datum/techweb/Destroy() researched_nodes = null researched_designs = null @@ -126,17 +139,17 @@ modify_point_list(l) /datum/techweb/proc/copy_research_to(datum/techweb/receiver, unlock_hidden = TRUE) //Adds any missing research to theirs. + if(unlock_hidden) + for(var/i in receiver.hidden_nodes) + CHECK_TICK + if(!hidden_nodes[i]) + receiver.hidden_nodes -= i //We can see it so let them see it too. for(var/i in researched_nodes) CHECK_TICK receiver.research_node_id(i, TRUE, FALSE) for(var/i in researched_designs) CHECK_TICK receiver.add_design_by_id(i) - if(unlock_hidden) - for(var/i in receiver.hidden_nodes) - CHECK_TICK - if(!hidden_nodes[i]) - receiver.hidden_nodes -= i //We can see it so let them see it too. receiver.recalculate_nodes() /datum/techweb/proc/copy() diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 6750fa5475..40cc322eed 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -7,6 +7,7 @@ var/display_name = "Errored Node" var/description = "Why are you seeing this?" var/hidden = FALSE //Whether it starts off hidden. + var/experimental = FALSE //If the tech can be randomly granted by the BEPIS as a reward. Meant to be fully given in tech disks, not researched. var/starting_node = FALSE //Whether it's available without any research. var/list/prereq_ids = list() var/list/design_ids = list() @@ -102,6 +103,6 @@ description = "NT default research technologies." // Default research tech, prevents bricking design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap", - "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", + "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", "space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal", "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass") diff --git a/code/modules/research/techweb/nodes/bepis_nodes.dm b/code/modules/research/techweb/nodes/bepis_nodes.dm new file mode 100644 index 0000000000..0033564274 --- /dev/null +++ b/code/modules/research/techweb/nodes/bepis_nodes.dm @@ -0,0 +1,82 @@ +////////////////////////B.E.P.I.S. Locked Techs//////////////////////// + +/datum/techweb_node/light_apps + id = "light_apps" + display_name = "Illumination Applications" + description = "Applications of lighting and vision technology not originally thought to be commercially viable." + prereq_ids = list("base") + design_ids = list("bright_helmet", "rld_mini") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/aus_security + id = "aus_security" + display_name = "Australicus Security Protocols" + description = "It is said that security in the Australicus sector is tight, so we took some pointers from their equipment. Thankfully, our sector lacks any signs of these, 'dropbears'." + prereq_ids = list("base") + design_ids = list("pin_explorer", "stun_boomerang") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/spec_eng + id = "spec_eng" + display_name = "Specialized Engineering" + description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone." + prereq_ids = list("base") + design_ids = list("lava_rods", "eng_gloves") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/rolling_table + id = "rolling_table" + display_name = "Advanced Wheel Applications" + description = "Adding wheels to things can lead to extremely beneficial outcomes." + prereq_ids = list("base") + design_ids = list("rolling_table") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/Mauna_Mug + id = "mauna_mug" + display_name = "Mauna Mug" + description = "A bored scientist was thinking to himself for very long...and then realized his coffee got cold! He made this invention to solve this extreme problem." + prereq_ids = list("base") + design_ids = list("mauna_mug") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/nanite_replication_protocols + id = "nanite_replication_protocols" + display_name = "Nanite Replication Protocols" + description = "Advanced behaviours that allow nanites to exploit certain circumstances to replicate faster." + prereq_ids = list("nanite_smart") + design_ids = list("kickstart_nanites","factory_nanites","tinker_nanites","offline_nanites","synergy_nanites") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/interrogation + id = "interrogation" + display_name = "Enhanced Interrogation Technology" + description = "By cross-referencing several declassified documents from past dictatorial regimes, we were able to develop an incredibly effective interrogation device. \ + Ethical concerns about loss of free will may still apply, according to galactic law." + prereq_ids = list("base") + design_ids = list("hypnochair") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/tackle_advanced + id = "tackle_advanced" + display_name = "Advanced Grapple Technology" + description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \ + will no longer be accepted in its academic journals." + design_ids = list("tackle_dolphin", "tackle_rocket") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE diff --git a/code/modules/research/techweb/nodes/nanites_nodes.dm b/code/modules/research/techweb/nodes/nanites_nodes.dm index 5fc707d77a..0a860c8938 100644 --- a/code/modules/research/techweb/nodes/nanites_nodes.dm +++ b/code/modules/research/techweb/nodes/nanites_nodes.dm @@ -74,11 +74,3 @@ prereq_ids = list("nanite_harmonic", "alientech") design_ids = list("spreading_nanites","mindcontrol_nanites","mitosis_nanites") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - -/datum/techweb_node/nanite_replication_protocols - id = "nanite_replication_protocols" - display_name = "Nanite Replication Protocols" - description = "Advanced behaviours that allow nanites to exploit certain circumstances to replicate faster." - prereq_ids = list("nanite_smart") - design_ids = list("kickstart_nanites","factory_nanites","tinker_nanites","offline_nanites","synergy_nanites") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) diff --git a/code/modules/research/techweb/nodes/weaponry_nodes.dm b/code/modules/research/techweb/nodes/weaponry_nodes.dm index 064f88077a..e17d7e1e7b 100644 --- a/code/modules/research/techweb/nodes/weaponry_nodes.dm +++ b/code/modules/research/techweb/nodes/weaponry_nodes.dm @@ -5,7 +5,7 @@ display_name = "Weapon Development Technology" description = "Our researchers have found new to weaponize just about everything now." prereq_ids = list("engineering") - design_ids = list("pin_testing", "tele_shield", "lasercarbine", "pin_away") + design_ids = list("pin_testing", "tele_shield", "lasercarbine") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) /datum/techweb_node/adv_weaponry diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm new file mode 100644 index 0000000000..65530031c0 --- /dev/null +++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm @@ -0,0 +1,247 @@ +//******Decoration objects +//***Bone statues and giant skeleton parts. +/obj/structure/statue/bone + anchored = TRUE + max_integrity = 120 + material_drop_type = /obj/item/stack/sheet/bone + impressiveness = 18 // Carved from the bones of a massive creature, it's going to be a specticle to say the least + layer = ABOVE_ALL_MOB_LAYER + +/obj/structure/statue/bone/rib + name = "collosal rib" + desc = "It's staggering to think that something this big could have lived, let alone died." + oreAmount = 4 + icon = 'icons/obj/statuelarge.dmi' + icon_state = "rib" + +/obj/structure/statue/bone/skull + name = "collosal skull" + desc = "The gaping maw of a dead, titanic monster." + oreAmount = 12 + icon = 'icons/obj/statuelarge.dmi' + icon_state = "skull" + +/obj/structure/statue/bone/skull/half + desc = "The gaping maw of a dead, titanic monster. This one is cracked in half." + oreAmount = 6 + icon = 'icons/obj/statuelarge.dmi' + icon_state = "skull-half" + +//***Wasteland floor and rock turfs here. +/turf/open/floor/plating/asteroid/basalt/wasteland //Like a more fun version of living in Arizona. + name = "cracked earth" + icon = 'icons/turf/floors.dmi' + icon_state = "wasteland" + environment_type = "wasteland" + baseturfs = /turf/open/floor/plating/asteroid/basalt/wasteland + digResult = /obj/item/stack/ore/glass/basalt + initial_gas_mix = LAVALAND_DEFAULT_ATMOS + slowdown = 0.5 + floor_variance = 30 + +/turf/open/floor/plating/asteroid/basalt/wasteland/Initialize() + .=..() + if(prob(floor_variance)) + icon_state = "[environment_type][rand(0,6)]" + +/turf/closed/mineral/strong/wasteland + name = "ancient dry rock" + color = "#B5651D" + environment_type = "wasteland" + turf_type = /turf/open/floor/plating/asteroid/basalt/wasteland + baseturfs = /turf/open/floor/plating/asteroid/basalt/wasteland + smooth_icon = 'icons/turf/walls/rock_wall.dmi' + +/turf/closed/mineral/strong/wasteland/drop_ores() + if(prob(10)) + new /obj/item/stack/ore/iron(src, 1) + new /obj/item/stack/ore/glass(src, 1) + new /obj/effect/decal/remains/human/grave(src, 1) + else + new /obj/item/stack/sheet/bone(src, 1) + +//***Oil well puddles. +/obj/structure/sink/oil_well //You're not going to enjoy bathing in this... + name = "oil well" + desc = "A bubbling pool of oil.This would probably be valuable, had bluespace technology not destroyed the need for fossil fuels 200 years ago." + icon = 'icons/obj/watercloset.dmi' + icon_state = "puddle-oil" + dispensedreagent = /datum/reagent/oil + +/obj/structure/sink/oil_well/Initialize() + .=..() + create_reagents(20) + reagents.add_reagent(dispensedreagent, 20) + +/obj/structure/sink/oil_well/attack_hand(mob/M) + flick("puddle-oil-splash",src) + reagents.reaction(M, TOUCH, 20) //Covers target in 20u of oil. + to_chat(M, "You touch the pool of oil, only to get oil all over yourself. It would be wise to wash this off with water.") + +/obj/structure/sink/oil_well/attackby(obj/item/O, mob/user, params) + flick("puddle-oil-splash",src) + if(O.tool_behaviour == TOOL_SHOVEL && !(flags_1&NODECONSTRUCT_1)) //attempt to deconstruct the puddle with a shovel + to_chat(user, "You fill in the oil well with soil.") + O.play_tool_sound(src) + deconstruct() + return 1 + if(istype(O, /obj/item/reagent_containers)) //Refilling bottles with oil + var/obj/item/reagent_containers/RG = O + if(RG.is_refillable()) + if(!RG.reagents.holder_full()) + RG.reagents.add_reagent(dispensedreagent, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + to_chat(user, "You fill [RG] from [src].") + return TRUE + to_chat(user, "\The [RG] is full.") + return FALSE + if(user.a_intent != INTENT_HARM) + to_chat(user, "You won't have any luck getting \the [O] out if you drop it in the oil.") + return 1 + else + return ..() + +/obj/structure/sink/oil_well/drop_materials() + new /obj/effect/decal/cleanable/oil(loc) + +//***Grave mounds. +/obj/structure/closet/crate/grave + name = "burial mound" + desc = "An marked patch of soil, showing signs of a burial long ago. You wouldn't disturb a grave... right?" + icon = 'icons/obj/crates.dmi' + icon_state = "grave" + dense_when_open = TRUE + material_drop = /obj/item/stack/ore/glass/basalt + material_drop_amount = 5 + anchorable = FALSE + anchored = TRUE + locked = TRUE + breakout_time = 900 + cutting_tool = /obj/item/shovel + var/lead_tomb = FALSE + var/first_open = FALSE + +/obj/structure/closet/crate/grave/PopulateContents() //GRAVEROBBING IS NOW A FEATURE + ..() + new /obj/effect/decal/remains/human/grave(src) + switch(rand(1,8)) + if(1) + new /obj/item/coin/gold(src) + new /obj/item/storage/wallet(src) + if(2) + new /obj/item/clothing/glasses/meson(src) + if(3) + new /obj/item/coin/silver(src) + new /obj/item/shovel/spade(src) + if(4) + new /obj/item/storage/book/bible/booze(src) + if(5) + new /obj/item/clothing/neck/stethoscope(src) + new /obj/item/scalpel(src) + new /obj/item/hemostat(src) + + if(6) + new /obj/item/reagent_containers/glass/beaker(src) + new /obj/item/clothing/glasses/science(src) + if(7) + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/clothing/mask/cigarette/rollie(src) + +/obj/structure/closet/crate/grave/open(mob/living/user, obj/item/S) + if(!opened) + to_chat(user, "The ground here is too hard to dig up with your bare hands. You'll need a shovel.") + else + to_chat(user, "The grave has already been dug up.") + +/obj/structure/closet/crate/grave/tool_interact(obj/item/S, mob/living/carbon/user) + if(user.a_intent == INTENT_HELP) //checks to attempt to dig the grave, must be done on help intent only. + if(!opened) + if(istype(S,cutting_tool) && S.tool_behaviour == TOOL_SHOVEL) + to_chat(user, "You start start to dig open \the [src] with \the [S]...") + if (do_after(user,20, target = src)) + opened = TRUE + locked = TRUE + dump_contents() + update_icon() + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "graverobbing", /datum/mood_event/graverobbing) + if(lead_tomb == TRUE && first_open == TRUE) + user.gain_trauma(/datum/brain_trauma/magic/stalker) + to_chat(user, "Oh no, no no no, THEY'RE EVERYWHERE! EVERY ONE OF THEM IS EVERYWHERE!") + first_open = FALSE + return 1 + return 1 + else + to_chat(user, "You can't dig up a grave with \the [S.name].") + return 1 + else + to_chat(user, "The grave has already been dug up.") + return 1 + + else if((user.a_intent != INTENT_HELP) && opened) //checks to attempt to remove the grave entirely. + if(istype(S,cutting_tool) && S.tool_behaviour == TOOL_SHOVEL) + to_chat(user, "You start to remove \the [src] with \the [S].") + if (do_after(user,15, target = src)) + to_chat(user, "You remove \the [src] completely.") + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "graverobbing", /datum/mood_event/graverobbing) + deconstruct(TRUE) + return 1 + return + +/obj/structure/closet/crate/grave/bust_open() + ..() + opened = TRUE + update_icon() + dump_contents() + return + +/obj/structure/closet/crate/grave/lead_researcher + name = "ominous burial mound" + desc = "Even in a place filled to the brim with graves, this one shows a level of preperation and planning that fills you with dread." + icon = 'icons/obj/crates.dmi' + icon_state = "grave_lead" + lead_tomb = TRUE + first_open = TRUE + +/obj/structure/closet/crate/grave/lead_researcher/PopulateContents() //ADVANCED GRAVEROBBING + ..() + new /obj/effect/decal/cleanable/blood/gibs/old(src) + new /obj/item/book/granter/crafting_recipe/boneyard_notes(src) + +/obj/effect/decal/remains/human/grave + turf_loc_check = FALSE + +/obj/item/book/granter/crafting_recipe/boneyard_notes + name = "The Complete Works of Lavaland Bone Architecture" + desc = "Pried from the lead Archaeologist's cold, dead hands, this seems to explain how ancient bone architecture was erected long ago." + crafting_recipe_types = list(/datum/crafting_recipe/rib, /datum/crafting_recipe/boneshovel, /datum/crafting_recipe/halfskull, /datum/crafting_recipe/skull) + icon = 'icons/obj/library.dmi' + icon_state = "boneworking_learing" + oneuse = FALSE + remarks = list("Who knew you could bend bones that far back?", "I guess that was much easier before the planet heated up...", "So that's how they made those ruins survive the ashstorms. Neat!", "The page is just filled with insane ramblings about some 'legion' thing.", "But why would they need vinegar to polish the bones? And rags too?", "You spend a few moments cleaning dirt and blood off of the page, yeesh.") + + +//***Fluff items for lore/intrigue +/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard + name = "posted warning" + desc = "It seems to be smudged with mud and... oil?" + info = "TO WHOM IT MAY CONCERN

This area is property of the Nanotrasen Mining Division.

Trespassing in this area is illegal, highly dangerous, and subject to several NDAs.

Please turn back now, under intergalactic law section 48-R." + +/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/rnd_notes + name = "Research Findings: Day 26" + desc = "Huh, this one page looks like it was torn out of a full book. How odd." + icon_state = "docs_part" + info = "Researcher name: B--*--* J--*s.

Detailed findings:Today the camp site's cond-tion has wor--ene*. The ashst--ms keep blocking us off from le-ving the sit* for m-re supplies, and it's lo-king like we're out of pl*sma to p-wer the ge-erat*r. Can't rea-*y study c-*bon *ating with no li--ts, ya know? Da-*y's been going -*f again and ag-*n a-*ut h*w the company's left us to *ie here, but I j-s* keep tell-ng him to stop che*-in* out these damn graves. We m-y b* archaeologists, but -e sho*ld have t-e dec-**cy to know these grav-s are *-l NEW.

The rest of the page is just semantics about carbon dating methods." + +/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/mutiny + name = "hastily scribbled note" + desc = "Seems like someone was in a hurry." + info = "Alright, we all know that stuck up son a bitch is just doing this to keep us satisifed. Who the hell does he think he is, taking extra rations? We're OUT OF FOOD, CARL. Tomorrow at noon, we're going to try and take the ship by force. He HAS to be lying about the engine cooling down. He HAS TO BE. I'm tellin ya, with this implant I lifted off that last supply ship, I got the smarts to get us offa this shithole. Keep your knife handy carl." + +/obj/item/paper/fluff/ruins/elephant_graveyard/hypothesis + name = "research document" + desc = "Standard Nanotrasen typeface for important research documents." + info = "Day 9: Tenative Conclusions

While the area appears to be of significant cultural importance to the lizard race, outside of some sparce contact with native wildlife, we're yet to find any exact reasoning for the nature of this phenomenon. It seems that organic life is communally drawn to this planet as though it functions as a final resting place for intelligent life. As per company guidelines, this site shall be given the following classification: 'LZ-0271 - Elephant Graveyard'

Compiled list of Artifact findings (Currently Sent Offsite)
Cultist Blade Fragments: x8
Brass Multiplicative Ore Sample: x105
Syndicate Revolutionary Leader Implant (Broken) x1
Extinct Cortical Borer Tissue Sample x1
Space Carp Fossil x3" + +/obj/item/paper/fluff/ruins/elephant_graveyard/final_message + name = "important looking Note" + desc = "This note is well written, and seems to have been put here so you'd find it." + info = "If you find this... you don't need to know who I am.

You need to leave this place. I dunno what shit they did to me out here, but I don't think I'm going to be making it out of here.

This place... it wears down your psyche. The other researchers out here laughed it off but... They were the first to go.

One by one they started turning on each other. The more they found out, the more they started fighting and arguing...
As I speak now, I had to... I wound up having to put most of my men down. I know what I had to do, and I know there's no way left for me to live with myself.
If anyone ever finds this, just don't touch the graves.

DO NOT. TOUCH. THE GRAVES. Don't be a dumbass, like we all were." diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm index b4c78b5d6e..dd36af9b32 100644 --- a/code/modules/surgery/advanced/revival.dm +++ b/code/modules/surgery/advanced/revival.dm @@ -36,7 +36,7 @@ return FALSE if(istype(tool, /obj/item/melee/baton)) var/obj/item/melee/baton/B = tool - if(!B.status) + if(!B.turned_on) to_chat(user, "[B] needs to be active!") return FALSE if(istype(tool, /obj/item/gun/energy)) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index d9e7012214..f654270df7 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -14,7 +14,6 @@ return FALSE if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return FALSE - var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST) affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] has been violently dismembered!") @@ -44,6 +43,10 @@ throw_at(target_turf, throw_range, throw_speed) return TRUE +/obj/item/bodypart/head/dismember() + if(HAS_TRAIT(owner, TRAIT_NODECAP)) + return FALSE + ..() /obj/item/bodypart/chest/dismember() if(!owner) @@ -53,6 +56,8 @@ return FALSE if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return FALSE + if(HAS_TRAIT(C, TRAIT_NOGUT)) //Just for not allowing gutting + return FALSE . = list() var/organ_spilled = 0 var/turf/T = get_turf(C) diff --git a/code/modules/tgs/LICENSE b/code/modules/tgs/LICENSE new file mode 100644 index 0000000000..221f9e1deb --- /dev/null +++ b/code/modules/tgs/LICENSE @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2017 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/code/modules/tgs/README.md b/code/modules/tgs/README.md new file mode 100644 index 0000000000..445cee41f5 --- /dev/null +++ b/code/modules/tgs/README.md @@ -0,0 +1,13 @@ +# DMAPI Internals + +This folder should be placed on it's own inside a codebase that wishes to use the TGS DMAPI. Warranty void if modified. + +- [includes.dm](./includes.dm) is the file that should be included by DM code, it handles including the rest. +- The [core](./core) folder includes all code not directly part of any API version. +- The other versioned folders contain code for the different DMAPI versions. + - [v3210](./v3210) contains the final TGS3 API. + - [v4](./v4) is the legacy DMAPI 4 (Used in TGS 4.0.X versions). + - [v5](./v5) is the current DMAPI version used by TGS4 >=4.1. +- [LICENSE](./LICENSE) is the MIT license for the DMAPI. + +APIs communicate with TGS in two ways. All versions implement TGS -> DM communication using /world/Topic. DM -> TGS communication, called the bridge method, is different for each version. diff --git a/code/modules/tgs/core/README.md b/code/modules/tgs/core/README.md new file mode 100644 index 0000000000..aa3c7a9c9d --- /dev/null +++ b/code/modules/tgs/core/README.md @@ -0,0 +1,8 @@ +# Core DMAPI functions + +This folder contains all DMAPI code not directly involved in an API. + +- [_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals. +- [core.dm](./core.dm) contains the implementations of the `/world/proc/TgsXXX()` procs. Many map directly to the `/datum/tgs_api` functions. It also contains the /datum selection and setup code. +- [datum.dm](./datum.dm) contains the `/datum/tgs_api` declarations that all APIs must implement. +- [tgs_version.dm](./tgs_version.dm) contains the `/datum/tgs_version` definition \ No newline at end of file diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm index a74c9bbab2..f75e7837af 100644 --- a/code/modules/tgs/core/core.dm +++ b/code/modules/tgs/core/core.dm @@ -154,30 +154,3 @@ var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) if(api) api.SecurityLevel() - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/core/datum.dm b/code/modules/tgs/core/datum.dm index ccc75fe344..ef6d3a4fe5 100644 --- a/code/modules/tgs/core/datum.dm +++ b/code/modules/tgs/core/datum.dm @@ -55,30 +55,3 @@ TGS_PROTECT_DATUM(/datum/tgs_api) /datum/tgs_api/proc/SecurityLevel() return TGS_UNIMPLEMENTED - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/includes.dm b/code/modules/tgs/includes.dm index b3c1728f34..c803cf7ac2 100644 --- a/code/modules/tgs/includes.dm +++ b/code/modules/tgs/includes.dm @@ -15,30 +15,3 @@ #include "v5\api.dm" #include "v5\commands.dm" #include "v5\undef.dm" - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v3210/README.md b/code/modules/tgs/v3210/README.md new file mode 100644 index 0000000000..f96e7cf3b3 --- /dev/null +++ b/code/modules/tgs/v3210/README.md @@ -0,0 +1,6 @@ +# DMAPI V3 + +This DMAPI implements bridge using file output which TGS monitors for. + +- [api.dm](./api.dm) contains the bulk of the API code. +- [commands.dm](./commands.dm) contains functions relating to `/datum/tgs_chat_command`s. diff --git a/code/modules/tgs/v3210/api.dm b/code/modules/tgs/v3210/api.dm index 0fc0076c8b..e0d00ad15d 100644 --- a/code/modules/tgs/v3210/api.dm +++ b/code/modules/tgs/v3210/api.dm @@ -226,30 +226,3 @@ #undef SERVICE_REQUEST_API_VERSION #undef SERVICE_RETURN_SUCCESS - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v3210/commands.dm b/code/modules/tgs/v3210/commands.dm index 5046631981..a1949da444 100644 --- a/code/modules/tgs/v3210/commands.dm +++ b/code/modules/tgs/v3210/commands.dm @@ -19,7 +19,7 @@ TGS_ERROR_LOG("Custom command [command_name] can't be used as it is empty or contains illegal characters!") warned_command_names[command_name] = TRUE continue - + if(command_name_types[command_name]) if(warnings_only) TGS_ERROR_LOG("Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!") @@ -44,35 +44,3 @@ user.friendly_name = sender user.mention = sender return stc.Run(user, params) || TRUE - -/* - -#undef SERVICE_JSON_PARAM_HELPTEXT -#undef SERVICE_JSON_PARAM_ADMINONLY -#undef SERVICE_JSON_PARAM_REQUIREDPARAMETERS - -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v4/README.md b/code/modules/tgs/v4/README.md new file mode 100644 index 0000000000..78191447b2 --- /dev/null +++ b/code/modules/tgs/v4/README.md @@ -0,0 +1,6 @@ +# DMAPI V4 + +This DMAPI implements bridge requests using file output which TGS monitors for. It has a safe mode restriction. + +- [api.dm](./api.dm) contains the bulk of the API code. +- [commands.dm](./commands.dm) contains functions relating to `/datum/tgs_chat_command`s. diff --git a/code/modules/tgs/v4/api.dm b/code/modules/tgs/v4/api.dm index ba18aab688..1dc98f811e 100644 --- a/code/modules/tgs/v4/api.dm +++ b/code/modules/tgs/v4/api.dm @@ -50,6 +50,10 @@ return new /datum/tgs_version("4.0.0.0") /datum/tgs_api/v4/OnWorldNew(minimum_required_security_level) + if(minimum_required_security_level == TGS_SECURITY_ULTRASAFE) + TGS_WARNING_LOG("V4 DMAPI requires safe security!") + minimum_required_security_level = TGS_SECURITY_SAFE + json_path = world.params[TGS4_PARAM_INFO_JSON] if(!json_path) TGS_ERROR_LOG("Missing [TGS4_PARAM_INFO_JSON] world parameter!") @@ -310,30 +314,3 @@ /datum/tgs_api/v4/SecurityLevel() return security_level - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v4/commands.dm b/code/modules/tgs/v4/commands.dm index 1d9951bc04..4ca1500167 100644 --- a/code/modules/tgs/v4/commands.dm +++ b/code/modules/tgs/v4/commands.dm @@ -39,31 +39,3 @@ result = "" return result return "Unknown command: [command]!" - -/* - -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm index 2baf3e12d7..8fd84e19fa 100644 --- a/code/modules/tgs/v5/_defines.dm +++ b/code/modules/tgs/v5/_defines.dm @@ -12,13 +12,14 @@ #define DMAPI5_BRIDGE_COMMAND_CHAT_SEND 5 #define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier" +#define DMAPI5_PARAMETER_CUSTOM_COMMANDS "customCommands" + #define DMAPI5_RESPONSE_ERROR_MESSAGE "errorMessage" #define DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE "commandType" #define DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT "currentPort" #define DMAPI5_BRIDGE_PARAMETER_VERSION "version" #define DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE "chatMessage" -#define DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS "customCommands" #define DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL "minimumSecurityLevel" #define DMAPI5_BRIDGE_RESPONSE_NEW_PORT "newPort" @@ -95,30 +96,3 @@ #define DMAPI5_CUSTOM_CHAT_COMMAND_NAME "name" #define DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT "helpText" #define DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY "adminOnly" - -/* -The MIT License - -Copyright (c) 2020 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm index eedefb2877..8ca85faf05 100644 --- a/code/modules/tgs/v5/api.dm +++ b/code/modules/tgs/v5/api.dm @@ -16,7 +16,7 @@ var/list/chat_channels /datum/tgs_api/v5/ApiVersion() - return new /datum/tgs_version("5.1.1") + return new /datum/tgs_version("5.2.1") /datum/tgs_api/v5/OnWorldNew(minimum_required_security_level) server_port = world.params[DMAPI5_PARAM_SERVER_PORT] @@ -24,7 +24,7 @@ var/datum/tgs_version/api_version = ApiVersion() version = null - var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands())) + var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands())) if(!istype(bridge_response)) TGS_ERROR_LOG("Failed initial bridge request!") return FALSE @@ -201,17 +201,27 @@ if(DMAPI5_TOPIC_COMMAND_HEARTBEAT) return TopicResponse() if(DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH) + var/new_port = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT] + var/error_message = null + if (new_port != null) + if (!isnum(new_port) || !(new_port > 0)) + error_message = "Invalid [DMAPI5_TOPIC_PARAMETER_NEW_PORT]]" + else + server_port = new_port + var/new_version_string = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION] if (!istext(new_version_string)) - return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION]]") + if(error_message != null) + error_message += ", " + error_message += "Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION]]" + else + var/datum/tgs_version/new_version = new(new_version_string) + if (event_handler) + event_handler.HandleEvent(TGS_EVENT_WATCHDOG_REATTACH, new_version) - var/datum/tgs_version/new_version = new(new_version_string) - if (event_handler) - event_handler.HandleEvent(TGS_EVENT_WATCHDOG_REATTACH, new_version) + version = new_version - version = new_version - - return TopicResponse() + return json_encode(list(DMAPI5_RESPONSE_ERROR_MESSAGE = error_message, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands())) return TopicResponse("Unknown command: [command]") @@ -343,30 +353,3 @@ /datum/tgs_api/v5/SecurityLevel() RequireInitialBridgeResponse() return security_level - -/* -The MIT License - -Copyright (c) 2020 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v5/commands.dm b/code/modules/tgs/v5/commands.dm index 2775157656..6d31dd3422 100644 --- a/code/modules/tgs/v5/commands.dm +++ b/code/modules/tgs/v5/commands.dm @@ -38,31 +38,3 @@ topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = text_response return json_encode(topic_response) return TopicResponse("Unknown custom chat command: [command]!") - -/* - -The MIT License - -Copyright (c) 2020 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/tgs/v5/undef.dm b/code/modules/tgs/v5/undef.dm index b27e3abe95..34fc481d36 100644 --- a/code/modules/tgs/v5/undef.dm +++ b/code/modules/tgs/v5/undef.dm @@ -12,13 +12,14 @@ #undef DMAPI5_BRIDGE_COMMAND_CHAT_SEND #undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER +#undef DMAPI5_PARAMETER_CUSTOM_COMMANDS + #undef DMAPI5_RESPONSE_ERROR_MESSAGE #undef DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE #undef DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT #undef DMAPI5_BRIDGE_PARAMETER_VERSION #undef DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE -#undef DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS #undef DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL #undef DMAPI5_BRIDGE_RESPONSE_NEW_PORT @@ -95,30 +96,3 @@ #undef DMAPI5_CUSTOM_CHAT_COMMAND_NAME #undef DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT #undef DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY - -/* -The MIT License - -Copyright (c) 2020 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index efd9aad673..641e52dd13 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -6,7 +6,8 @@ products = list(/obj/item/toy/cards/deck = 5, /obj/item/storage/pill_bottle/dice = 10, /obj/item/toy/cards/deck/cas = 3, - /obj/item/toy/cards/deck/cas/black = 3) + /obj/item/toy/cards/deck/cas/black = 3, + /obj/item/toy/cards/deck/unum = 3) contraband = list(/obj/item/dice/fudge = 9) premium = list(/obj/item/melee/skateboard/pro = 3, /obj/item/melee/skateboard/hoverboard = 1) diff --git a/config/lavaRuinBlacklist.txt b/config/lavaRuinBlacklist.txt index 6d2d2633ce..e86cf42ea0 100644 --- a/config/lavaRuinBlacklist.txt +++ b/config/lavaRuinBlacklist.txt @@ -38,4 +38,5 @@ #_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm -#_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm \ No newline at end of file +#_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm \ No newline at end of file diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 0731583733..0c4784553c 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi index 3860fa4b7e..856fe2149a 100644 Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi index 7902487873..3613488027 100644 Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ diff --git a/icons/mob/inhands/equipment/mining_lefthand.dmi b/icons/mob/inhands/equipment/mining_lefthand.dmi index e902690c37..7496aba625 100644 Binary files a/icons/mob/inhands/equipment/mining_lefthand.dmi and b/icons/mob/inhands/equipment/mining_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/mining_righthand.dmi b/icons/mob/inhands/equipment/mining_righthand.dmi index dacf9be078..de3d11978a 100644 Binary files a/icons/mob/inhands/equipment/mining_righthand.dmi and b/icons/mob/inhands/equipment/mining_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/security_lefthand.dmi b/icons/mob/inhands/equipment/security_lefthand.dmi index d5b32d7c37..47447f80d0 100644 Binary files a/icons/mob/inhands/equipment/security_lefthand.dmi and b/icons/mob/inhands/equipment/security_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/security_righthand.dmi b/icons/mob/inhands/equipment/security_righthand.dmi index 1c8c9b0dfb..79aab1c5cd 100644 Binary files a/icons/mob/inhands/equipment/security_righthand.dmi and b/icons/mob/inhands/equipment/security_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 1cd090a3e9..19738ed490 100644 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 24c9a2d777..9589e338e1 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index e0b02d2adc..a40359cadb 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 1169888b34..95ae326f1e 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 2a6ce77f38..535ae0d241 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a19627b8ea..1768d8a1c6 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 532324fcf4..a1bc443efb 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index f66767292c..c280ee786f 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 2cc3b784f4..f2a8328717 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/guns/gun_parts.dmi b/icons/obj/guns/gun_parts.dmi new file mode 100644 index 0000000000..8e3168769d Binary files /dev/null and b/icons/obj/guns/gun_parts.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 79045ac92b..8b58707615 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 8c61c287ac..9aec5781a9 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index be12ab5f8b..727d69b1e3 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/machines/bepis.dmi b/icons/obj/machines/bepis.dmi new file mode 100644 index 0000000000..f348c2e1b0 Binary files /dev/null and b/icons/obj/machines/bepis.dmi differ diff --git a/icons/obj/mauna_mug.dmi b/icons/obj/mauna_mug.dmi new file mode 100644 index 0000000000..fd576072fd Binary files /dev/null and b/icons/obj/mauna_mug.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index 20ffbdbe06..43bc9c48aa 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 5ad6c1cb3b..03b7a9e44f 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 3d5a825f27..f07928741d 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/icons/obj/smooth_structures/rollingtable.dmi b/icons/obj/smooth_structures/rollingtable.dmi new file mode 100644 index 0000000000..9e559a75d9 Binary files /dev/null and b/icons/obj/smooth_structures/rollingtable.dmi differ diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi index 5b0c05d43d..d327dc8988 100644 Binary files a/icons/obj/stack_objects.dmi and b/icons/obj/stack_objects.dmi differ diff --git a/icons/obj/statuelarge.dmi b/icons/obj/statuelarge.dmi index e45afb8db8..e627a883cb 100644 Binary files a/icons/obj/statuelarge.dmi and b/icons/obj/statuelarge.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 6a2bb343df..0ff7d4a607 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 698c1f7a34..e8106905b7 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi index 5670b9e839..4a299f29dd 100644 Binary files a/icons/obj/watercloset.dmi and b/icons/obj/watercloset.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index d24efa0625..dbd5aaa960 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/modular_citadel/code/_onclick/hud/screen_objects.dm b/modular_citadel/code/_onclick/hud/screen_objects.dm index 2101a6045f..017f7f3485 100644 --- a/modular_citadel/code/_onclick/hud/screen_objects.dm +++ b/modular_citadel/code/_onclick/hud/screen_objects.dm @@ -1,63 +1,22 @@ -/obj/screen/restbutton - name = "rest" - icon = 'modular_citadel/icons/ui/screen_midnight.dmi' - icon_state = "rest" - -/obj/screen/restbutton/Click() - if(isliving(usr)) - var/mob/living/theuser = usr - theuser.lay_down() - -/obj/screen/combattoggle - name = "toggle combat mode" - icon = 'modular_citadel/icons/ui/screen_midnight.dmi' - icon_state = "combat_off" - var/mutable_appearance/flashy - -/obj/screen/combattoggle/Click() - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.user_toggle_intentional_combat_mode() - -/obj/screen/combattoggle/update_icon_state() - var/mob/living/carbon/user = hud?.mymob - if(!istype(user)) - return - if((user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - icon_state = "combat" - else if(HAS_TRAIT(user, TRAIT_COMBAT_MODE_LOCKED)) - icon_state = "combat_locked" - else - icon_state = "combat_off" - -/obj/screen/combattoggle/update_overlays() - . = ..() - var/mob/living/carbon/user = hud?.mymob - if(!istype(user) || !user.client) - return - - if((user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && user.client.prefs.hud_toggle_flash) - if(!flashy) - flashy = mutable_appearance('icons/mob/screen_gen.dmi', "togglefull_flash") - if(flashy.color != user.client.prefs.hud_toggle_color) - flashy.color = user.client.prefs.hud_toggle_color - . += flashy //TODO - beg lummox jr for the ability to force mutable appearances or images to be created rendering from their first frame of animation rather than being based entirely around the client's frame count - /obj/screen/voretoggle name = "toggle vore mode" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "nom_off" /obj/screen/voretoggle/Click() - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.toggle_vore_mode() + if(usr != hud.mymob) + return + var/mob/living/carbon/C = usr + if(SEND_SIGNAL(usr, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) + to_chat(usr, "Disable combat mode first.") + return + C.toggle_vore_mode() /obj/screen/voretoggle/update_icon_state() var/mob/living/carbon/user = hud?.mymob if(!istype(user)) return - if(user.voremode && !(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + if(user.voremode) icon_state = "nom" else icon_state = "nom_off" diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm deleted file mode 100644 index ddac7b5953..0000000000 --- a/modular_citadel/code/modules/admin/chat_commands.dm +++ /dev/null @@ -1,46 +0,0 @@ -/datum/tgs_chat_command/wheelofsalt - name = "wheelofsalt" - help_text = "What are Citadel Station 13 players salting about today? Spin the wheel and find out!" - -/datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) - var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" - var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]" - if(prob(10)) - saltresult += "@here for your salt, all day every day" - if(prob(1)) - saltresult += " @everyone gets some salt this time too" - else - saltresult += "[saltprimarysubject] [saltsecondarysubject]" - return "[saltresult]!" - -/datum/tgs_chat_command/valentine - name = "valentine" - help_text = "Get a random flirt line." - -/datum/tgs_chat_command/valentine/Run(datum/tgs_chat_user/sender, params) - return "[pick(GLOB.flirts)]" - -/datum/tgs_chat_command/despacito - name = "despacito" //someone please high effort this sometime and make it a full on ytdl search - help_text = "This is so sad." - -/datum/tgs_chat_command/despacito/Run() - return "https://www.youtube.com/watch?v=kJQP7kiw5Fk" - -/datum/tgs_chat_command/poly - name = "poly" - help_text = "The Lewder, more applicable Poly speak for Citadel Station 13." - var/list/speech_buffer - -/datum/tgs_chat_command/poly/Run() - LAZYINITLIST(speech_buffer) //I figure this is just safe to do for everything at this point - if(length(speech_buffer)) //Let's not look up the whole json EVERY TIME, just the first time. - return "[pick(speech_buffer)]" - else - var/json_file = file("data/npc_saves/Poly.json") - if(!fexists(json_file)) - return "**BAWWWWWK!** LEAVE THE HEADSET! ***BAWKKKKK!!***" - var/list/json = json_decode(file2text(json_file)) - speech_buffer = json["phrases"] - return "[pick(speech_buffer)]" diff --git a/modular_citadel/code/modules/client/client_defines.dm b/modular_citadel/code/modules/client/client_defines.dm deleted file mode 100644 index d816b15d1d..0000000000 --- a/modular_citadel/code/modules/client/client_defines.dm +++ /dev/null @@ -1,2 +0,0 @@ -/client - var/cryo_warned = -3000//when was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm index 0532f59afa..3a683ca2ff 100644 --- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm +++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm @@ -1,29 +1,16 @@ /mob/living/carbon - var/lastmousedir - var/wrongdirmovedelay - //oh no vore time var/voremode = FALSE /mob/living/carbon/proc/toggle_vore_mode() + if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_TOGGLED)) + return FALSE //let's not override the main draw of the game these days voremode = !voremode var/obj/screen/voretoggle/T = locate() in hud_used?.static_inventory T?.update_icon_state() - if(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) - return FALSE //let's not override the main draw of the game these days - SEND_SIGNAL(src, COMSIG_VORE_TOGGLED, src, voremode) return TRUE -/mob/living/carbon/Move(atom/newloc, direct = 0) - . = ..() - wrongdirmovedelay = FALSE - if((combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && client && lastmousedir) - if(lastmousedir != dir) - wrongdirmovedelay = TRUE - setDir(lastmousedir, ismousemovement = TRUE) - -/mob/living/carbon/onMouseMove(object, location, control, params) - if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) - return - face_atom(object, TRUE) - lastmousedir = dir +/mob/living/carbon/proc/disable_vore_mode() + voremode = FALSE + var/obj/screen/voretoggle/T = locate() in hud_used?.static_inventory + T?.update_icon_state() diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm index 3baab2ad86..01867e9dcc 100644 --- a/modular_citadel/code/modules/mob/living/living.dm +++ b/modular_citadel/code/modules/mob/living/living.dm @@ -37,7 +37,7 @@ if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && total_health >= STAMINA_CRIT && !stat) to_chat(src, "You're too exhausted to keep going...") set_resting(TRUE, FALSE, FALSE) - disable_intentional_combat_mode(TRUE, FALSE) + SEND_SIGNAL(src, COMSIG_DISABLE_COMBAT_MODE) ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_HARD_STAMCRIT) filters += CIT_FILTER_STAMINACRIT update_mobility() diff --git a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm index bcc156a22e..03a124e306 100644 --- a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm +++ b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm @@ -178,7 +178,7 @@ name = "positron blast" damage = 80 range = 14 - speed = 0.6 + pixels_per_second = TILES_TO_PIXELS(16.667) icon_state = "disablerslug" /obj/item/projectile/beam/pump diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm deleted file mode 100644 index 17de8c806d..0000000000 --- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm +++ /dev/null @@ -1,246 +0,0 @@ -//body bluids -/datum/reagent/consumable/semen - name = "Semen" - description = "Sperm from some animal. Useless for anything but insemination, really." - taste_description = "something salty" - taste_mult = 2 //Not very overpowering flavor - data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) - reagent_state = LIQUID - color = "#FFFFFF" // rgb: 255, 255, 255 - can_synth = FALSE - nutriment_factor = 0.5 * REAGENTS_METABOLISM - -/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume) - if(!istype(T)) - return - if(reac_volume < 10) - return - - var/obj/effect/decal/cleanable/semen/S = locate() in T - if(!S) - S = new(T) - if(data["blood_DNA"]) - S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) - -/obj/effect/decal/cleanable/semen - name = "semen" - desc = null - gender = PLURAL - density = 0 - layer = ABOVE_NORMAL_TURF_LAYER - icon = 'icons/obj/genitals/effects.dmi' - icon_state = "semen1" - random_icon_states = list("semen1", "semen2", "semen3", "semen4") - -/obj/effect/decal/cleanable/semen/Initialize(mapload) - . = ..() - dir = GLOB.cardinals - add_blood_DNA(list("Non-human DNA" = "A+")) - -/obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S) - if(S.blood_DNA) - blood_DNA |= S.blood_DNA - return ..() - -/datum/reagent/consumable/femcum - name = "Female Ejaculate" - description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business." - taste_description = "something with a tang" // wew coders who haven't eaten out a girl. - taste_mult = 2 - data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) - reagent_state = LIQUID - color = "#AAAAAA77" - can_synth = FALSE - nutriment_factor = 0.5 * REAGENTS_METABOLISM - -/obj/effect/decal/cleanable/femcum - name = "female ejaculate" - desc = null - gender = PLURAL - density = 0 - layer = ABOVE_NORMAL_TURF_LAYER - icon = 'icons/obj/genitals/effects.dmi' - icon_state = "fem1" - random_icon_states = list("fem1", "fem2", "fem3", "fem4") - blood_state = null - bloodiness = null - -/obj/effect/decal/cleanable/femcum/Initialize(mapload) - . = ..() - dir = GLOB.cardinals - add_blood_DNA(list("Non-human DNA" = "A+")) - -/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F) - if(F.blood_DNA) - blood_DNA |= F.blood_DNA - return ..() - -/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume) - if(!istype(T)) - return - if(reac_volume < 10) - return - - var/obj/effect/decal/cleanable/femcum/S = locate() in T - if(!S) - S = new(T) - if(data["blood_DNA"]) - S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) - -//aphrodisiac & anaphrodisiac - -/datum/reagent/drug/aphrodisiac - name = "Crocin" - description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac." - taste_description = "strawberries" - color = "#FFADFF"//PINK, rgb(255, 173, 255) - can_synth = FALSE - -/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M) - if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) - if((prob(min(current_cycle/2,5)))) - M.emote(pick("moan","blush")) - if(prob(min(current_cycle/4,10))) - var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.") - to_chat(M, "[aroused_message]") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/list/genits = H.adjust_arousal(current_cycle, aphro = TRUE) // redundant but should still be here - for(var/g in genits) - var/obj/item/organ/genital/G = g - to_chat(M, "[G.arousal_verb]!") - ..() - -/datum/reagent/drug/aphrodisiacplus - name = "Hexacrocin" - description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\ - Addiction withdrawals can cause brain damage and shortness of breath. Overdosage can lead to brain damage and a \ - permanent increase in libido (commonly referred to as 'bimbofication')." - taste_description = "liquid desire" - color = "#FF2BFF"//dark pink - addiction_threshold = 20 - overdose_threshold = 20 - can_synth = FALSE - -/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M) - if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) - if(prob(5)) - if(prob(current_cycle)) - M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn...")) - else - M.emote(pick("moan","blush")) - if(prob(5)) - var/aroused_message - if(current_cycle>25) - aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!") - else - aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.") - to_chat(M, "[aroused_message]") - REMOVE_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/list/genits = H.adjust_arousal(100, aphro = TRUE) // redundant but should still be here - for(var/g in genits) - var/obj/item/organ/genital/G = g - to_chat(M, "[G.arousal_verb]!") - ..() - -/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M) - if(prob(30)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2) - ..() -/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M) - if(prob(30)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3) - - ..() -/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M) - if(prob(30)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4) - ..() - -/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) - if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO) && prob(33)) - if(prob(5) && ishuman(M) && M.has_dna() && (M.client?.prefs.cit_toggles & BIMBOFICATION)) - if(!HAS_TRAIT(M,TRAIT_PERMABONER)) - to_chat(M, "Your libido is going haywire!") - ADD_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT) - ..() - -/datum/reagent/drug/anaphrodisiac - name = "Camphor" - description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\ - , reducing libido and calming them. Non-habit forming and not addictive." - taste_description = "dull bitterness" - taste_mult = 2 - color = "#D9D9D9"//rgb(217, 217, 217) - reagent_state = SOLID - can_synth = FALSE - -/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M) - if(M && M.client?.prefs.arousable && prob(16)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/list/genits = H.adjust_arousal(-100, aphro = TRUE) - if(genits.len) - to_chat(M, "You no longer feel aroused.") - ..() - -/datum/reagent/drug/anaphrodisiacplus - name = "Hexacamphor" - description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive." - taste_description = "tranquil celibacy" - color = "#D9D9D9"//rgb(217, 217, 217) - reagent_state = SOLID - overdose_threshold = 20 - can_synth = FALSE - -/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M) - if(M && M.client?.prefs.arousable) - REMOVE_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/list/genits = H.adjust_arousal(-100, aphro = TRUE) - if(genits.len) - to_chat(M, "You no longer feel aroused.") - - ..() - -/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M) - if(M && M.client?.prefs.arousable && prob(5)) - to_chat(M, "You feel like you'll never feel aroused again...") - ADD_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT) - ..() - -//recipes -/datum/chemical_reaction/aphro - name = "crocin" - id = /datum/reagent/drug/aphrodisiac - results = list(/datum/reagent/drug/aphrodisiac = 6) - required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/water = 1) - required_temp = 400 - mix_message = "The mixture boils off a pink vapor..."//The water boils off, leaving the crocin - -/datum/chemical_reaction/aphroplus - name = "hexacrocin" - id = /datum/reagent/drug/aphrodisiacplus - results = list(/datum/reagent/drug/aphrodisiacplus = 1) - required_reagents = list(/datum/reagent/drug/aphrodisiac = 6, /datum/reagent/phenol = 1) - required_temp = 400 - mix_message = "The mixture rapidly condenses and darkens in color..." - -/datum/chemical_reaction/anaphro - name = "camphor" - id = /datum/reagent/drug/anaphrodisiac - results = list(/datum/reagent/drug/anaphrodisiac = 6) - required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/sulfur = 1) - required_temp = 400 - mix_message = "The mixture boils off a yellow, smelly vapor..."//Sulfur burns off, leaving the camphor - -/datum/chemical_reaction/anaphroplus - name = "pentacamphor" - id = /datum/reagent/drug/anaphrodisiacplus - results = list(/datum/reagent/drug/anaphrodisiacplus = 1) - required_reagents = list(/datum/reagent/drug/aphrodisiac = 5, /datum/reagent/acetone = 1) - required_temp = 300 - mix_message = "The mixture thickens and heats up slighty..." diff --git a/modular_citadel/icons/ui/screen_midnight.dmi b/modular_citadel/icons/ui/screen_midnight.dmi index a730c591ba..fc446a411c 100644 Binary files a/modular_citadel/icons/ui/screen_midnight.dmi and b/modular_citadel/icons/ui/screen_midnight.dmi differ diff --git a/modular_citadel/icons/ui/screen_operative.dmi b/modular_citadel/icons/ui/screen_operative.dmi index cb08f08ceb..9383b94718 100644 Binary files a/modular_citadel/icons/ui/screen_operative.dmi and b/modular_citadel/icons/ui/screen_operative.dmi differ diff --git a/modular_citadel/icons/ui/screen_plasmafire.dmi b/modular_citadel/icons/ui/screen_plasmafire.dmi index 5f8cd9d93c..97e577c7bd 100644 Binary files a/modular_citadel/icons/ui/screen_plasmafire.dmi and b/modular_citadel/icons/ui/screen_plasmafire.dmi differ diff --git a/modular_citadel/icons/ui/screen_slimecore.dmi b/modular_citadel/icons/ui/screen_slimecore.dmi index f2f0c88782..8f45ff3f76 100644 Binary files a/modular_citadel/icons/ui/screen_slimecore.dmi and b/modular_citadel/icons/ui/screen_slimecore.dmi differ diff --git a/strings/tips.txt b/strings/tips.txt index 0176420dd3..b135692778 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -37,6 +37,7 @@ As a Medical Doctor, treating plasmamen is not impossible! Salbutamol stops them As a Medical Doctor, you can point your penlight at people to create a medical hologram. This lets them know that you're coming to treat them. As a Medical Doctor, you can extract implants by holding an empty implant case in your offhand while performing the extraction step. As a Medical Doctor, clone scanning people will implant them with a health tracker that displays their vitals in the clone records. Useful to check on crew members that didn't activate suit sensors! +As a Medical Doctor, medical gauze stops bleeding as well as heals 5 brute damage, this even works on the dead! Make sure to always have some gauze on you to stop bleeding before dragging someone. As a Chemist, there are dozens of chemicals that can heal, and even more that can cause harm. Experiment! As a Chemist, some chemicals can only be synthesized by heating up the contents in the chemical heater. As a Chemist, you will be expected to supply crew with certain chemicals. For example, clonexadone and mannitol for the cryo tubes, unstable mutagen and saltpetre for botany as well as healing pills and patches for the front desk. @@ -264,7 +265,12 @@ As a Devil, as long as you control at least one other soul, you will automatical At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. You can swap floor tiles by holding a crowbar in one hand and a stack of tiles in the other. When hacking doors, cutting and mending the "test light wire" will restore power to the door. +When hacking, remote singulars pluse when attached to a wire and pinged. This can allow you to hack things or set traps from far away. When crafting most items, you can either manually combine parts or use the crafting menu. Suit storage units not only remove blood and dirt from clothing, but also radiation! Remote devices will work when used through cameras. For example: Bluespace RPEDs and door remotes. Laser pointers can be upgraded by replacing its micro laser with a better one from RnD! Use a screwdriver on it to remove the old laser. Upgrading the laser pointer gives you better odds of stunning a cyborg, and even blinding people with sunglasses. +Being out of combat mode makes makes you deal less damage to people and objects when attacking. +Resting makes you deal less damage to people and objects when attacking. +You do not regenerate as much stamina while in combat mode. Resting (being on the ground) makes you regenerate stamina faster. +Remember to be in combat mode while in combat, as otherwise you will be penalized by taking more incoming damage and dealing less damage to your adversary. diff --git a/tgstation.dme b/tgstation.dme index 2a13cb472e..56d8b34101 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -137,6 +137,7 @@ #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" +#include "code\__HELPERS\angles.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\AStar.dm" #include "code\__HELPERS\cmp.dm" @@ -380,6 +381,7 @@ #include "code\datums\brain_damage\brain_trauma.dm" #include "code\datums\brain_damage\hypnosis.dm" #include "code\datums\brain_damage\imaginary_friend.dm" +#include "code\datums\brain_damage\magic.dm" #include "code\datums\brain_damage\mild.dm" #include "code\datums\brain_damage\phobia.dm" #include "code\datums\brain_damage\severe.dm" @@ -388,22 +390,20 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\armor_plate.dm" -#include "code\datums\components\art.dm" #include "code\datums\components\bane.dm" #include "code\datums\components\bouncy.dm" #include "code\datums\components\butchering.dm" #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" +#include "code\datums\components\combat_mode.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\decal.dm" #include "code\datums\components\dejavu.dm" #include "code\datums\components\earprotection.dm" #include "code\datums\components\edit_complainer.dm" -#include "code\datums\components\empprotection.dm" #include "code\datums\components\explodable.dm" #include "code\datums\components\field_of_vision.dm" #include "code\datums\components\footstep.dm" -#include "code\datums\components\forced_gravity.dm" #include "code\datums\components\identification.dm" #include "code\datums\components\igniter.dm" #include "code\datums\components\infective.dm" @@ -438,7 +438,6 @@ #include "code\datums\components\summoning.dm" #include "code\datums\components\swarming.dm" #include "code\datums\components\tackle.dm" -#include "code\datums\components\tactical.dm" #include "code\datums\components\thermite.dm" #include "code\datums\components\twohanded.dm" #include "code\datums\components\uplink.dm" @@ -526,13 +525,17 @@ #include "code\datums\diseases\advance\symptoms\weight.dm" #include "code\datums\diseases\advance\symptoms\youth.dm" #include "code\datums\elements\_element.dm" +#include "code\datums\elements\art.dm" +#include "code\datums\elements\beauty.dm" #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" #include "code\datums\elements\dwarfism.dm" #include "code\datums\elements\earhealing.dm" +#include "code\datums\elements\empprotection.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\flavor_text.dm" +#include "code\datums\elements\forced_gravity.dm" #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\mob_holder.dm" #include "code\datums\elements\polychromic.dm" @@ -542,6 +545,7 @@ #include "code\datums\elements\squish.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\sword_point.dm" +#include "code\datums\elements\tactical.dm" #include "code\datums\elements\update_icon_blocker.dm" #include "code\datums\elements\update_icon_updates_onmob.dm" #include "code\datums\elements\wuv.dm" @@ -732,6 +736,7 @@ #include "code\game\machinery\gulag_teleporter.dm" #include "code\game\machinery\harvester.dm" #include "code\game\machinery\hologram.dm" +#include "code\game\machinery\hypnochair.dm" #include "code\game\machinery\igniter.dm" #include "code\game\machinery\iv_drip.dm" #include "code\game\machinery\launch_pad.dm" @@ -1029,6 +1034,7 @@ #include "code\game\objects\items\devices\multitool.dm" #include "code\game\objects\items\devices\paicard.dm" #include "code\game\objects\items\devices\pipe_painter.dm" +#include "code\game\objects\items\devices\polycircuit.dm" #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\pressureplates.dm" #include "code\game\objects\items\devices\quantum_keycard.dm" @@ -1123,6 +1129,7 @@ #include "code\game\objects\items\tanks\tanks.dm" #include "code\game\objects\items\tanks\watertank.dm" #include "code\game\objects\items\tools\crowbar.dm" +#include "code\game\objects\items\tools\saw.dm" #include "code\game\objects\items\tools\screwdriver.dm" #include "code\game\objects\items\tools\weldingtool.dm" #include "code\game\objects\items\tools\wirecutters.dm" @@ -1996,6 +2003,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_soup.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_spaghetti.dm" #include "code\modules\games\cas.dm" +#include "code\modules\games\unum.dm" #include "code\modules\goonchat\browserOutput.dm" #include "code\modules\holiday\easter.dm" #include "code\modules\holiday\holidays.dm" @@ -2312,7 +2320,6 @@ #include "code\modules\mob\living\life.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_block.dm" -#include "code\modules\mob\living\living_combat.dm" #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" #include "code\modules\mob\living\living_mobility.dm" @@ -2335,7 +2342,6 @@ #include "code\modules\mob\living\brain\say.dm" #include "code\modules\mob\living\brain\status_procs.dm" #include "code\modules\mob\living\carbon\carbon.dm" -#include "code\modules\mob\living\carbon\carbon_combat.dm" #include "code\modules\mob\living\carbon\carbon_defense.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\carbon_movement.dm" @@ -2959,6 +2965,7 @@ #include "code\modules\reagents\reagent_containers\glass.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" #include "code\modules\reagents\reagent_containers\hypovial.dm" +#include "code\modules\reagents\reagent_containers\maunamug.dm" #include "code\modules\reagents\reagent_containers\medspray.dm" #include "code\modules\reagents\reagent_containers\patch.dm" #include "code\modules\reagents\reagent_containers\pill.dm" @@ -2976,6 +2983,7 @@ #include "code\modules\recycling\disposal\outlet.dm" #include "code\modules\recycling\disposal\pipe.dm" #include "code\modules\recycling\disposal\pipe_sorting.dm" +#include "code\modules\research\bepis.dm" #include "code\modules\research\designs.dm" #include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\experimentor.dm" @@ -3058,6 +3066,7 @@ #include "code\modules\research\techweb\_techweb.dm" #include "code\modules\research\techweb\_techweb_node.dm" #include "code\modules\research\techweb\nodes\alien_nodes.dm" +#include "code\modules\research\techweb\nodes\bepis_nodes.dm" #include "code\modules\research\techweb\nodes\biotech_nodes.dm" #include "code\modules\research\techweb\nodes\bluespace_nodes.dm" #include "code\modules\research\techweb\nodes\computer_hud_nodes.dm" @@ -3095,6 +3104,7 @@ #include "code\modules\ruins\icemoonruin_code\library.dm" #include "code\modules\ruins\lavalandruin_code\alien_nest.dm" #include "code\modules\ruins\lavalandruin_code\biodome_clown_planet.dm" +#include "code\modules\ruins\lavalandruin_code\elephantgraveyard.dm" #include "code\modules\ruins\lavalandruin_code\pizzaparty.dm" #include "code\modules\ruins\lavalandruin_code\puzzle.dm" #include "code\modules\ruins\lavalandruin_code\sloth.dm" @@ -3360,10 +3370,8 @@ #include "modular_citadel\code\datums\status_effects\chems.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" -#include "modular_citadel\code\modules\admin\chat_commands.dm" #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" -#include "modular_citadel\code\modules\client\client_defines.dm" #include "modular_citadel\code\modules\client\client_procs.dm" #include "modular_citadel\code\modules\client\preferences_savefile.dm" #include "modular_citadel\code\modules\client\preferences_toggles.dm" @@ -3430,5 +3438,4 @@ #include "modular_citadel\code\modules\reagents\chemistry\recipes\fermi.dm" #include "modular_citadel\code\modules\reagents\objects\clothes.dm" #include "modular_citadel\code\modules\reagents\objects\items.dm" -#include "modular_citadel\code\modules\reagents\reagents\cit_reagents.dm" // END_INCLUDE diff --git a/tgui-next/packages/tgui/interfaces/AirlockElectronics.js b/tgui-next/packages/tgui/interfaces/AirlockElectronics.js index 680849e649..f42afd1de2 100644 --- a/tgui-next/packages/tgui/interfaces/AirlockElectronics.js +++ b/tgui-next/packages/tgui/interfaces/AirlockElectronics.js @@ -79,7 +79,7 @@ export const AirlockElectronics = props => { />