diff --git a/README.md b/README.md index 3e123280a2..ed82fb08e6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Based and maintained from /tg/station.
**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/3gJ9pnM).
+**Discord:** [Here](https://discord.gg/E6SQuhz).
## DOWNLOADING diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index 69e618282e..a43e6129b7 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -167,7 +167,7 @@ /obj/item/book/manual/wiki/barman_recipes, /obj/item/book/granter/action/drink_fling, /obj/item/reagent_containers/food/drinks/shaker, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /turf/open/floor/wood, /area/ruin/powered/beach) "aI" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm index a22d1a21e7..60ae409ea2 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm @@ -161,7 +161,7 @@ /turf/open/floor/plasteel/white, /area/ruin/powered/animal_hospital) "av" = ( -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/item/reagent_containers/spray/cleaner, /obj/effect/turf_decal/tile/blue{ dir = 1 diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 738148c948..ed5b07168f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -508,7 +508,9 @@ /obj/structure/stone_tile/cracked{ dir = 4 }, -/obj/item/construction/rcd/loaded, +/obj/item/construction/rcd/loaded/upgraded{ + + }, /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) "bn" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index b330592a8e..8e0d9a523a 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -4728,7 +4728,7 @@ /area/ruin/unpowered/syndicate_lava_base/bar) "lz" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/glass/rag{ +/obj/item/reagent_containers/rag{ pixel_x = -4; pixel_y = 9 }, diff --git a/_maps/RandomRuins/SpaceRuins/advancedlab.dmm b/_maps/RandomRuins/SpaceRuins/advancedlab.dmm new file mode 100644 index 0000000000..39e29018ea --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/advancedlab.dmm @@ -0,0 +1,582 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/closed/wall, +/area/ruin/space/has_grav/powered/advancedlab) +"c" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/external, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"d" = ( +/obj/machinery/vending/assist, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"e" = ( +/obj/machinery/vending/snack/random, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"f" = ( +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"g" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"h" = ( +/obj/structure/table/glass, +/obj/item/crowbar/advanced, +/obj/item/multitool/advanced{ + pixel_x = 4; + pixel_y = -1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"i" = ( +/obj/machinery/computer/rdconsole, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"j" = ( +/obj/structure/chair/comfy/beige, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"k" = ( +/obj/structure/table/glass, +/obj/item/screwdriver/advanced{ + pixel_y = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"l" = ( +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"m" = ( +/obj/structure/table/glass, +/obj/item/gps{ + gpstag = "Abductor Replication Lab"; + pixel_x = -2; + pixel_y = 3 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"n" = ( +/obj/structure/chair/comfy/beige{ + icon_state = "comfychair"; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"o" = ( +/obj/structure/table/glass, +/obj/item/weldingtool/advanced{ + pixel_x = 4; + pixel_y = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"p" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/paper{ + name = "Note to finder"; + pixel_x = -1; + pixel_y = 3; + info = "As of yet, our experiments have seen a fair bit of success. Unfortunately, our business partners have stopped funding us as they realised they utterly hate each other. To whoever finds this place, they are yours. Use them how you will. I leave you with the next generation of greytiding." + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"q" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"r" = ( +/obj/structure/table/glass, +/obj/item/wirecutters/advanced{ + pixel_y = 7 + }, +/obj/item/wrench/advanced{ + pixel_x = -1; + pixel_y = 3 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"s" = ( +/obj/structure/chair/comfy/beige{ + icon_state = "comfychair"; + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"t" = ( +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"u" = ( +/obj/machinery/light/small{ + icon_state = "bulb"; + dir = 4 + }, +/obj/structure/closet, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/item/clothing/shoes/sneakers/brown, +/obj/item/clothing/under/pants/classicjeans, +/obj/item/clothing/neck/scarf, +/obj/item/clothing/neck/stripedgreenscarf, +/obj/item/toy/tennis/rainbow, +/obj/item/toy/tennis, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/item/clothing/shoes/sneakers/brown, +/obj/item/clothing/under/pants/classicjeans, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"v" = ( +/obj/machinery/vending/boozeomat{ + req_access = null; + shut_up = 1 + }, +/turf/closed/wall, +/area/ruin/space/has_grav/powered/advancedlab) +"w" = ( +/obj/machinery/door/airlock/command{ + name = "Dorms" + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"x" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"y" = ( +/obj/machinery/light/small{ + icon_state = "bulb"; + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"z" = ( +/obj/machinery/door/airlock/security{ + name = "Visiting Business Partners" + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"A" = ( +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"B" = ( +/obj/structure/bed, +/obj/item/bedsheet/syndie, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"C" = ( +/obj/structure/closet{ + name = "Clothes" + }, +/obj/item/clothing/head/chameleon, +/obj/item/clothing/gloves/combat, +/obj/item/clothing/suit/chameleon, +/obj/item/clothing/under/chameleon, +/obj/item/clothing/shoes/chameleon, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"D" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"E" = ( +/obj/structure/table/wood, +/obj/item/radio/headset/chameleon, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"F" = ( +/obj/structure/falsewall, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"G" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"H" = ( +/obj/structure/table/wood, +/obj/item/radio/headset/headset_cent/alt{ + keyslot2 = null + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"I" = ( +/obj/structure/closet{ + name = "Official Clothing" + }, +/obj/item/clothing/under/rank/centcom_commander, +/obj/item/clothing/head/centhat, +/obj/item/clothing/gloves/combat, +/obj/item/clothing/suit/armor/vest, +/obj/item/clothing/shoes/sneakers/brown, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"J" = ( +/obj/machinery/door/airlock/command{ + name = "Dorms" + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"K" = ( +/obj/machinery/door/airlock/command{ + name = "Visiting Officials" + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"L" = ( +/obj/structure/bed, +/obj/item/bedsheet/centcom, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) +"M" = ( +/obj/structure/lattice, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/space/basic, +/area/ruin/space/has_grav/powered/advancedlab) +"N" = ( +/obj/structure/extinguisher_cabinet, +/turf/closed/wall, +/area/ruin/space/has_grav/powered/advancedlab) +"O" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"P" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"Q" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"R" = ( +/obj/machinery/light/small{ + icon_state = "bulb"; + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/space/has_grav/powered/advancedlab) +"T" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/wood, +/area/ruin/space/has_grav/powered/advancedlab) + +(1,1,1) = {" +a +b +b +b +b +b +b +b +b +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +b +d +j +l +q +s +O +b +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +b +e +j +m +l +s +f +b +a +a +a +a +a +a +a +a +a +"} +(4,1,1) = {" +a +c +f +j +l +l +s +f +M +M +M +M +M +M +a +a +a +a +"} +(5,1,1) = {" +a +b +f +f +n +n +f +f +w +f +Q +f +f +M +a +a +a +a +"} +(6,1,1) = {" +a +b +f +f +f +f +f +f +M +M +M +M +f +M +a +a +a +a +"} +(7,1,1) = {" +a +b +g +f +f +f +f +f +b +P +P +M +R +M +a +a +a +a +"} +(8,1,1) = {" +a +N +f +f +f +f +f +u +b +P +P +M +f +M +a +a +a +a +"} +(9,1,1) = {" +a +b +f +f +f +f +f +b +b +b +b +M +J +M +b +a +a +a +"} +(10,1,1) = {" +a +b +h +k +o +r +f +b +y +A +A +F +T +A +b +a +a +a +"} +(11,1,1) = {" +a +b +i +f +f +f +t +b +z +v +b +b +b +K +b +a +a +a +"} +(12,1,1) = {" +a +b +p +f +f +f +f +b +A +C +b +G +A +A +b +a +a +a +"} +(13,1,1) = {" +a +b +l +l +x +l +f +b +A +D +b +H +A +D +b +a +a +a +"} +(14,1,1) = {" +a +b +b +b +b +b +b +b +B +E +b +I +A +L +b +a +a +a +"} +(15,1,1) = {" +a +a +a +a +a +a +a +b +b +b +b +b +b +b +b +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index fe624c19bf..c731bcac5e 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -260,7 +260,7 @@ /turf/open/floor/plating/asteroid/airless, /area/ruin/unpowered/no_grav) "aQ" = ( -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /turf/open/floor/plating/asteroid/airless, /area/ruin/unpowered/no_grav) "aR" = ( diff --git a/_maps/RandomRuins/SpaceRuins/gasthelizards.dmm b/_maps/RandomRuins/SpaceRuins/gasthelizards.dmm index 8956267108..e21c3a92f7 100644 --- a/_maps/RandomRuins/SpaceRuins/gasthelizards.dmm +++ b/_maps/RandomRuins/SpaceRuins/gasthelizards.dmm @@ -103,7 +103,7 @@ /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/freezer, /area/ruin/space/has_grav/gasthelizard) "n" = ( /obj/structure/closet/crate/freezer, @@ -117,7 +117,7 @@ }, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/freezer, /area/ruin/space/has_grav/gasthelizard) "o" = ( /obj/structure/closet/crate/freezer, @@ -129,7 +129,7 @@ /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/freezer, /area/ruin/space/has_grav/gasthelizard) "p" = ( /obj/structure/window/reinforced{ @@ -158,7 +158,7 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/gasthelizard) "r" = ( -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "s" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -203,14 +203,14 @@ /area/ruin/space/has_grav/gasthelizard) "x" = ( /obj/structure/kitchenspike, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "y" = ( /obj/structure/table/reinforced, /obj/item/kitchen/knife/butcher, /obj/item/restraints/handcuffs, /obj/item/reagent_containers/spray/pepper, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "z" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -230,14 +230,14 @@ /area/ruin/space/has_grav/gasthelizard) "C" = ( /obj/machinery/gibber, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "D" = ( /obj/structure/table/reinforced, /obj/item/clothing/suit/straight_jacket, /obj/item/reagent_containers/syringe/lethal, /obj/item/reagent_containers/syringe/lethal/choral, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "E" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -258,7 +258,7 @@ /area/ruin/space/has_grav/gasthelizard) "H" = ( /obj/machinery/door/airlock/security, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "I" = ( /obj/item/reagent_containers/glass/bottle/morphine{ @@ -282,7 +282,7 @@ pixel_y = 6 }, /obj/structure/table/reinforced, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "J" = ( /obj/structure/rack, @@ -328,12 +328,12 @@ /obj/item/cautery, /obj/item/circular_saw, /obj/machinery/light, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "Q" = ( /obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "R" = ( /obj/structure/table/reinforced, @@ -342,7 +342,7 @@ /obj/item/reagent_containers/glass/bottle/mutagen, /obj/item/reagent_containers/glass/bottle/mutagen, /obj/item/razor, -/turf/open/floor/plasteel/airless/dark, +/turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/gasthelizard) "S" = ( /obj/machinery/suit_storage_unit/security, diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm index c64a73eada..69b56946f2 100644 --- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm @@ -2010,7 +2010,7 @@ /area/ruin/space/has_grav/hotel/bar) "gd" = ( /obj/structure/table/reinforced, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 diff --git a/_maps/RandomZLevels/VR/syndicate_trainer.dmm b/_maps/RandomZLevels/VR/syndicate_trainer.dmm index f68a799b76..a8c316d770 100644 --- a/_maps/RandomZLevels/VR/syndicate_trainer.dmm +++ b/_maps/RandomZLevels/VR/syndicate_trainer.dmm @@ -1973,7 +1973,7 @@ /turf/open/indestructible, /area/awaymission/centcomAway/thunderdome) "lB" = ( -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /turf/open/indestructible, /area/awaymission/centcomAway/general) "lD" = ( diff --git a/_maps/RandomZLevels/beach.dmm b/_maps/RandomZLevels/beach.dmm index dddeadb0be..7aab25e400 100644 --- a/_maps/RandomZLevels/beach.dmm +++ b/_maps/RandomZLevels/beach.dmm @@ -150,7 +150,7 @@ /area/awaymission/beach) "aB" = ( /obj/structure/table, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /turf/open/floor/wood, /area/awaymission/beach) "aC" = ( diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 61c606dcde..7edc7b4518 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -5383,7 +5383,7 @@ "kn" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, -/obj/item/reagent_containers/glass/rag{ +/obj/item/reagent_containers/rag{ pixel_y = 5 }, /obj/machinery/door/poddoor/shutters{ diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index 39f7d99173..f6d46ef97d 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -3601,7 +3601,7 @@ "hn" = ( /obj/structure/table, /obj/item/stack/packageWrap, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 485666a8ff..62b426d352 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -41,6 +41,21 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/bar) +"aad" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/table, +/obj/item/restraints/handcuffs, +/turf/open/floor/plasteel, +/area/security/prison) "aae" = ( /obj/effect/landmark/carpspawn, /turf/open/space, @@ -577,6 +592,22 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/security/execution/transfer) +"abz" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison) "abA" = ( /obj/machinery/light, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -1849,16 +1880,16 @@ /turf/open/floor/plasteel/dark, /area/security/execution/transfer) "aef" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/red{ dir = 1 }, +/obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/security/prison) "aeg" = ( @@ -2118,6 +2149,31 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"aeD" = ( +/obj/machinery/door/airlock/security{ + name = "Firing Range"; + req_access_txt = "2" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison) +"aeE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating, +/area/security/prison) +"aeF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating, +/area/security/prison) "aeG" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -2193,17 +2249,13 @@ /turf/open/floor/plasteel/dark, /area/security/execution/transfer) "aeM" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable{ - icon_state = "4-8" +/obj/effect/turf_decal/stripes/line{ + dir = 5 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/structure/window/reinforced{ + dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/security/prison) "aeN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -2494,6 +2546,10 @@ }, /turf/open/floor/plasteel, /area/security/main) +"afn" = ( +/obj/structure/table, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "afo" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod Three" @@ -2514,6 +2570,20 @@ }, /turf/open/space/basic, /area/space) +"afq" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel, +/area/security/prison) +"afr" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/prison) +"afs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/security/prison) "aft" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 5 @@ -2570,16 +2640,16 @@ /turf/open/floor/plasteel/dark, /area/security/execution/transfer) "afz" = ( -/obj/structure/table, -/obj/item/restraints/handcuffs, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/effect/turf_decal/stripes/line{ + dir = 4 }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/machinery/door/window/westleft{ + base_state = "right"; + dir = 4; + icon_state = "right"; + name = "Shooting Range" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/security/prison) "afA" = ( /turf/closed/wall/r_wall, @@ -2823,6 +2893,16 @@ /obj/machinery/atmospherics/pipe/manifold4w/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) +"age" = ( +/obj/machinery/door/window/southleft{ + name = "Target Storage" + }, +/obj/item/target/clown, +/obj/item/target/clown, +/obj/item/target, +/obj/item/target, +/turf/open/floor/plating, +/area/security/prison) "agf" = ( /obj/structure/table, /obj/item/stack/sheet/metal, @@ -2976,6 +3056,16 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) +"agv" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "agw" = ( /obj/structure/table, /obj/machinery/syndicatebomb/training, @@ -3100,10 +3190,13 @@ /turf/open/floor/plasteel, /area/security/main) "agH" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/door/window/southright{ + name = "Target Storage" }, -/turf/open/floor/plasteel/dark, +/obj/item/target/alien, +/obj/item/target/alien, +/obj/item/target/syndicate, +/turf/open/floor/plating, /area/security/prison) "agI" = ( /obj/machinery/airalarm{ @@ -3474,6 +3567,15 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) +"ahw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating, +/area/security/prison) "ahx" = ( /obj/structure/cable{ icon_state = "4-8" @@ -4497,26 +4599,18 @@ /turf/open/floor/plasteel, /area/security/processing) "ajt" = ( -/obj/structure/sign/warning/securearea{ - pixel_x = 32 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/table, -/obj/item/storage/box/prisoner, -/obj/machinery/camera{ - c_tag = "Labor Shuttle Dock North" - }, -/turf/open/floor/plasteel, -/area/security/processing) +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/security/prison) "aju" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/stripes/line{ dir = 6 }, -/obj/machinery/computer/security/labor, -/turf/open/floor/plasteel, -/area/security/processing) +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison) "ajv" = ( /obj/machinery/light{ dir = 8 @@ -4830,6 +4924,29 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/maintenance/solars/port/fore) +"ajX" = ( +/obj/structure/table, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/recharger, +/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/practice, +/turf/open/floor/plasteel, +/area/security/prison) +"ajY" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "ajZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external{ @@ -4854,20 +4971,18 @@ /area/security/processing) "akc" = ( /obj/structure/cable{ - icon_state = "4-8" + icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 }, /turf/open/floor/plasteel, -/area/security/processing) +/area/security/prison) "akd" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/security/processing) +/obj/structure/lattice, +/turf/closed/wall, +/area/security/prison) "ake" = ( /obj/structure/cable{ icon_state = "4-8" @@ -5136,6 +5251,44 @@ }, /turf/open/floor/plating, /area/maintenance/solars/port/fore) +"akC" = ( +/obj/machinery/door/airlock/security{ + name = "Labor Shuttle"; + req_access_txt = "2" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/processing) +"akD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/security/prison) +"akE" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/processing) +"akF" = ( +/obj/structure/sign/warning/securearea{ + pixel_x = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Labor Shuttle Dock North" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/processing) "akG" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -5156,11 +5309,12 @@ /turf/open/floor/plasteel, /area/security/processing) "akJ" = ( -/obj/machinery/light_switch{ - pixel_x = 27 +/obj/structure/cable{ + icon_state = "2-4" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, /area/security/processing) @@ -5445,12 +5599,42 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/port/fore) +"alj" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/processing) "alk" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) +"all" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/machinery/computer/security/labor, +/turf/open/floor/plasteel, +/area/security/processing) +"alm" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/processing) "aln" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -5462,6 +5646,12 @@ }, /turf/open/floor/plating, /area/security/processing) +"alo" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/table, +/obj/item/storage/box/prisoner, +/turf/open/floor/plasteel, +/area/security/processing) "alp" = ( /turf/open/floor/plating, /area/security/processing) @@ -5469,13 +5659,10 @@ /turf/open/floor/plasteel, /area/security/processing) "alr" = ( -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/processing) +/obj/structure/target_stake, +/obj/item/target/syndicate, +/turf/open/floor/plating, +/area/security/prison) "als" = ( /obj/structure/cable{ icon_state = "1-2" @@ -5527,6 +5714,18 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"alx" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison) "aly" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -5681,6 +5880,24 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"alM" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/power/apc{ + areastring = "/area/security/main"; + dir = 4; + name = "Firing Range APC"; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison) "alO" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -5736,6 +5953,44 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) +"alY" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Firing Range"; + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"alZ" = ( +/obj/structure/table, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/item/clothing/glasses/sunglasses{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/glasses/sunglasses{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison) "ama" = ( /mob/living/simple_animal/sloth/paperwork, /turf/open/floor/plasteel, @@ -5755,10 +6010,6 @@ }, /turf/open/floor/plasteel, /area/security/processing) -"amd" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/processing) "ame" = ( /obj/structure/cable{ icon_state = "1-2" @@ -6031,26 +6282,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/processing) -"amN" = ( -/obj/structure/table, -/obj/item/clothing/glasses/sunglasses{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/clothing/glasses/sunglasses{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = -3; - pixel_y = -2 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = -3; - pixel_y = -2 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) "amQ" = ( /obj/structure/cable{ icon_state = "0-4" @@ -7412,7 +7643,6 @@ /area/maintenance/fore/secondary) "aqn" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/airalarm{ pixel_y = 23 }, @@ -7426,6 +7656,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "aqo" = ( @@ -8210,7 +8441,6 @@ /area/crew_quarters/fitness) "asu" = ( /obj/structure/bed, -/obj/item/bedsheet/red, /obj/machinery/button/door{ id = "Dorm5"; name = "Cabin Bolt Control"; @@ -8219,6 +8449,7 @@ specialfunctions = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "asv" = ( @@ -8314,7 +8545,6 @@ /area/maintenance/port/fore) "asL" = ( /obj/structure/bed, -/obj/item/bedsheet/red, /obj/machinery/button/door{ id = "Dorm6"; name = "Cabin Bolt Control"; @@ -8323,6 +8553,7 @@ specialfunctions = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "asM" = ( @@ -8933,7 +9164,6 @@ /area/crew_quarters/fitness) "auw" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/airalarm{ pixel_y = 23 }, @@ -8947,6 +9177,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "aux" = ( @@ -10817,7 +11048,6 @@ /area/ai_monitored/storage/eva) "ayV" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/airalarm{ pixel_y = 23 }, @@ -10831,6 +11061,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayW" = ( @@ -20895,7 +21126,7 @@ pixel_x = 32 }, /obj/item/book/manual/wiki/barman_recipes, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -31246,6 +31477,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/keycard_auth{ + pixel_y = 25 + }, /turf/open/floor/plasteel, /area/quartermaster/qm) "bvH" = ( @@ -39365,8 +39599,8 @@ /turf/open/floor/plasteel, /area/tcommsat/computer) "bOm" = ( -/obj/item/bedsheet, /obj/structure/bed, +/obj/item/bedsheet/medical, /turf/open/floor/plasteel/white, /area/medical/virology) "bOn" = ( @@ -42630,11 +42864,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/medical/virology) -"bWk" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/turf/open/floor/plasteel/white, -/area/medical/virology) "bWl" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -56903,6 +57132,12 @@ /obj/item/pen, /turf/open/floor/plasteel/white, /area/science/circuit) +"ium" = ( +/mob/living/simple_animal/bot/cleanbot{ + name = "C.L.E.A.N." + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "izv" = ( /obj/machinery/vending/clothing, /obj/machinery/light/small{ @@ -57137,12 +57372,6 @@ }, /turf/open/floor/plating, /area/construction/mining/aux_base) -"lKX" = ( -/mob/living/simple_animal/bot/cleanbot{ - name = "C.L.E.A.N." - }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/central) "lMg" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -57376,10 +57605,10 @@ /area/construction) "rMN" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/item/tank/internals/anesthetic, /obj/item/clothing/mask/breath, /obj/effect/decal/cleanable/semen, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plating, /area/maintenance/bar) "rNc" = ( @@ -57593,6 +57822,12 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"urE" = ( +/obj/machinery/autolathe{ + name = "public autolathe" + }, +/turf/open/floor/plasteel, +/area/quartermaster/office) "usO" = ( /obj/machinery/vending/snack/random, /obj/machinery/light/small{ @@ -57657,7 +57892,7 @@ /area/ai_monitored/storage/eva) "vjm" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/machinery/light/small{ dir = 1 }, @@ -80531,12 +80766,12 @@ adB aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa +acd +acd +acd +afr +acd +acd aaa aaa aaa @@ -80789,11 +81024,11 @@ abc abc afu abc -aaa -aaa -aaa -aaa -aaa +age +aeE +afs +ahw +acd aaa aaa aaa @@ -81046,11 +81281,11 @@ aea aeH aft abc -aaa -aaa -aaa -aaa -aaa +agH +aeF +alr +ajt +afr aaa aaa aiU @@ -81304,10 +81539,10 @@ aeJ afw abc abc -aaf -aaa -aaf -aaf +aeF +aay +ajt +akd aaf aaf aiU @@ -81561,9 +81796,9 @@ aeI afv agf abc -aaf -aaa -aaa +aeF +aay +ajt aiT aiT aiV @@ -81614,7 +81849,7 @@ cNG cNJ bLF aZK -bbR +urE bbR bqt cBq @@ -81818,9 +82053,9 @@ aeL afy agh abc -aaf -aaa -aaf +aeM +afz +aju aiT ajs akb @@ -82075,9 +82310,9 @@ aeK afx agg abc -aaf -aaa -aaa +ajX +alx +alY aiU ajr aka @@ -82331,13 +82566,13 @@ aeg aeN afA afA -afA -aaf -aaa -aaa -aiU -aju -akd +abc +afq +agv +ajY +akC +akE +akJ akK als ame @@ -82584,20 +82819,20 @@ acd acC ada adF +aad +abz aef -aeM -afz -aai -aai -aai -aai -aai -aai -ajt +aeD +aav akc -akJ -alr -amd +alM +alZ +akD +akF +alj +all +alm +alo amL anu alq @@ -82844,11 +83079,11 @@ adH aei aeO afJ -acd -agL -agK -agK -aiB +aai +aai +aai +aai +aai aai ajw akf @@ -83102,10 +83337,10 @@ aeh aeO afI agl -agH +agL ags ags -aho +aiB acd ajv ake @@ -87727,7 +87962,7 @@ bkA acF aes avB -amN +afn agt awN aHp @@ -94209,7 +94444,7 @@ blm bmL boi bpw -lKX +ium bsx btX bvj @@ -98346,7 +98581,7 @@ bRQ bOr bSQ bWj -bWk +bOm bXc bYe bNd @@ -98860,7 +99095,7 @@ bRQ bOr bSQ bWj -bWk +bOm bXc bYe bNd diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 402633f42b..cefc0eb1a5 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1010,6 +1010,10 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"aez" = ( +/obj/machinery/keycard_auth, +/turf/closed/wall, +/area/quartermaster/qm) "aeB" = ( /obj/machinery/status_display, /turf/closed/wall, @@ -13711,7 +13715,7 @@ /obj/machinery/status_display{ pixel_y = 32 }, -/obj/item/bedsheet/rainbow, +/obj/item/bedsheet/clown, /turf/open/floor/plasteel/grimy, /area/hallway/secondary/service) "aDG" = ( @@ -14428,7 +14432,7 @@ }, /obj/item/book/manual/wiki/barman_recipes, /obj/item/reagent_containers/food/drinks/shaker, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -16873,7 +16877,7 @@ /obj/machinery/status_display{ pixel_y = 32 }, -/obj/item/bedsheet/orange, +/obj/item/bedsheet/mime, /turf/open/floor/wood, /area/hallway/secondary/service) "aIQ" = ( @@ -35021,12 +35025,13 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "blM" = ( -/obj/structure/table, -/obj/item/storage/box/lights/mixed, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/autolathe{ + name = "public autolathe" + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "blN" = ( @@ -35043,6 +35048,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/item/storage/box/lights/mixed, /turf/open/floor/plasteel, /area/hallway/primary/fore) "blO" = ( @@ -78963,10 +78969,10 @@ /obj/machinery/light{ dir = 1 }, -/obj/item/bedsheet/red, /obj/machinery/status_display{ pixel_y = 32 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "cCj" = ( @@ -80988,11 +80994,11 @@ /area/crew_quarters/dorms) "cFx" = ( /obj/structure/bed, -/obj/item/bedsheet/black, /obj/effect/decal/cleanable/dirt{ desc = "A thin layer of dust coating the floor."; name = "dust" }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "cFy" = ( @@ -81001,7 +81007,7 @@ /area/crew_quarters/dorms) "cFz" = ( /obj/structure/bed, -/obj/item/bedsheet/blue, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "cFA" = ( @@ -87800,11 +87806,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cRs" = ( -/obj/structure/bed, -/obj/item/bedsheet/clown, -/turf/open/floor/wood, -/area/crew_quarters/dorms) "cRt" = ( /obj/structure/table/wood, /obj/item/storage/briefcase{ @@ -88880,7 +88881,7 @@ /area/crew_quarters/dorms) "cTc" = ( /obj/structure/bed, -/obj/item/bedsheet/mime, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "cTd" = ( @@ -90082,10 +90083,10 @@ "cUX" = ( /obj/structure/bed, /obj/machinery/light, -/obj/item/bedsheet/brown, /obj/machinery/status_display{ pixel_y = -32 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "cUY" = ( @@ -114275,11 +114276,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 @@ -114287,6 +114283,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Chapel Maintenance"; + req_access_txt = "27" + }, /turf/open/floor/plasteel, /area/maintenance/port/aft) "dKE" = ( @@ -118986,7 +118986,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -119331,7 +119330,6 @@ /turf/closed/wall, /area/chapel/office) "dTx" = ( -/obj/structure/bodycontainer/morgue, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -119342,6 +119340,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/crate/coffin, /turf/open/floor/plasteel/dark, /area/chapel/office) "dTy" = ( @@ -121767,7 +121766,6 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "dYv" = ( -/obj/structure/bodycontainer/morgue, /obj/structure/sign/poster/official/ian{ pixel_y = -32 }, @@ -121781,6 +121779,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/crate/coffin, /turf/open/floor/plasteel/dark, /area/chapel/office) "dYw" = ( @@ -122823,7 +122822,6 @@ /turf/open/floor/plasteel, /area/maintenance/port/aft) "eat" = ( -/obj/effect/decal/cleanable/dirt, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -123560,9 +123558,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -123573,6 +123568,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, /turf/open/floor/plasteel/dark, /area/chapel/office) "ebU" = ( @@ -123815,7 +123813,6 @@ /turf/open/floor/plasteel, /area/maintenance/port/aft) "ecw" = ( -/obj/structure/bodycontainer/morgue, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -126411,6 +126408,13 @@ /obj/machinery/door/airlock/research/glass/incinerator/toxmix_interior, /turf/open/floor/engine, /area/science/mixing) +"fwr" = ( +/obj/machinery/door/poddoor{ + id = "chapelgun"; + name = "Chapel Launcher Door" + }, +/turf/open/floor/plating, +/area/chapel/office) "fFK" = ( /obj/machinery/ore_silo, /obj/effect/turf_decal/tile/neutral{ @@ -126429,6 +126433,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/science/circuit) +"fHS" = ( +/obj/structure/sign/warning/vacuum, +/turf/closed/wall/r_wall, +/area/chapel/office) "fLR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -126461,6 +126469,16 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/science/circuit) +"gJj" = ( +/obj/machinery/door/window/northleft{ + name = "Mass Driver" + }, +/obj/machinery/mass_driver{ + id = "chapelgun"; + name = "Holy Driver" + }, +/turf/open/floor/plating, +/area/chapel/office) "gKr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -126478,6 +126496,22 @@ }, /turf/open/floor/plasteel/white, /area/science/misc_lab) +"gNJ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/chapel/office) "gNS" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/tile/neutral{ @@ -126542,6 +126576,10 @@ }, /turf/open/floor/plating, /area/quartermaster/storage) +"hei" = ( +/obj/effect/decal/cleanable/dirt, +/turf/closed/wall/r_wall, +/area/chapel/office) "hic" = ( /obj/structure/table/reinforced, /obj/item/integrated_electronics/analyzer, @@ -126603,6 +126641,22 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"hLO" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/closet, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "hNZ" = ( /obj/structure/chair/office/light{ dir = 8 @@ -126649,6 +126703,9 @@ }, /turf/open/floor/engine/vacuum, /area/science/mixing) +"iyd" = ( +/turf/open/space, +/area/space) "iQh" = ( /obj/structure/bodycontainer/morgue{ dir = 1 @@ -126713,6 +126770,9 @@ }, /turf/open/floor/plasteel, /area/science/research/abandoned) +"jhK" = ( +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "jjN" = ( /obj/structure/table/reinforced, /obj/machinery/camera{ @@ -126810,6 +126870,28 @@ /obj/machinery/chem_master, /turf/open/floor/plasteel/dark, /area/medical/medbay/central) +"jPA" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/computer/pod/old{ + density = 0; + icon = 'icons/obj/airlock_machines.dmi'; + icon_state = "airlock_control_standby"; + id = "chapelgun"; + name = "Mass Driver Controller"; + pixel_x = 0; + pixel_y = -24 + }, +/turf/open/floor/plasteel/dark, +/area/chapel/office) "jRy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -127094,6 +127176,33 @@ }, /turf/open/floor/engine, /area/science/mixing) +"mXJ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark, +/area/chapel/office) +"nht" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/chapel/office) "nyN" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, @@ -127102,6 +127211,19 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"owr" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark, +/area/chapel/office) "oIl" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -127212,9 +127334,9 @@ /area/science/circuit) "poI" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/item/tank/internals/anesthetic, /obj/item/clothing/mask/breath, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) "psi" = ( @@ -127280,6 +127402,12 @@ /obj/effect/spawner/lootdrop/keg, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"qMR" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/turf/open/floor/plating, +/area/chapel/office) "rhO" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -127429,6 +127557,14 @@ }, /turf/open/floor/engine, /area/engine/supermatter) +"uZN" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "vhA" = ( /obj/item/clothing/under/color/grey, /turf/open/floor/plating, @@ -127566,6 +127702,25 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/research) +"xWZ" = ( +/obj/structure/bodycontainer/morgue{ + dir = 2 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/chapel/office) "xXn" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxins_mixing_output, /turf/open/floor/engine/vacuum, @@ -159674,12 +159829,12 @@ dWI dZf dZM eat -dLY -dLY -dLY -dLY -dLY -dLY +dZN +dZN +dZN +dZN +fHS +dZN dLY dLY aad @@ -159929,20 +160084,20 @@ dWJ dLW dYu dZg -dYu -dYu -dZg -ebR -dLW -ecQ -edl -aad +jhK +jhK +dZN +owr +mXJ +gJj +qMR +fwr aaa aaa -aad +iyd aaa aaa -aad +iyd aaa aaa aaa @@ -160186,14 +160341,14 @@ dTw dTw dTw dTw -dLX -dLW -dLW -dLW -ecv -dNt -edl -aad +hLO +uZN +hei +gNJ +jPA +dTw +dTw +dTw aad aad aad @@ -160446,8 +160601,8 @@ dTw dZN dZN dZN -dZN -dZN +xWZ +nht dTw dTw dTw @@ -174468,7 +174623,7 @@ aaa aaa aad aQQ -aQQ +aez aUp aVY aXE @@ -178385,7 +178540,7 @@ cLa cMx cIi cPR -cRs +cFz cDG cUW cAw diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index efd4d0f56e..75d7466371 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -10143,7 +10143,6 @@ /area/crew_quarters/dorms) "asV" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/button/door{ id = "Cabin3"; name = "Cabin Bolt Control"; @@ -10155,6 +10154,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "asW" = ( @@ -10209,7 +10209,7 @@ }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/structure/bed, -/obj/item/bedsheet, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "atb" = ( @@ -11894,7 +11894,6 @@ /area/crew_quarters/dorms) "awE" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/button/door{ id = "Cabin2"; name = "Cabin Bolt Control"; @@ -11905,6 +11904,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "awF" = ( @@ -11922,7 +11922,6 @@ /area/crew_quarters/dorms) "awG" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/button/door{ id = "Cabin5"; name = "Dorm Bolt Control"; @@ -11931,6 +11930,7 @@ specialfunctions = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "awH" = ( @@ -14985,7 +14985,6 @@ /area/crew_quarters/dorms) "aCJ" = ( /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/button/door{ id = "Cabin6"; name = "Dorm Bolt Control"; @@ -14997,6 +14996,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "aCK" = ( @@ -17584,10 +17584,10 @@ specialfunctions = 4 }, /obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "aHT" = ( @@ -20373,6 +20373,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/keycard_auth{ + pixel_y = 23 + }, /turf/open/floor/plasteel, /area/quartermaster/qm) "aNS" = ( @@ -31534,6 +31537,10 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plasteel, /area/hallway/primary/port) "biO" = ( @@ -32410,10 +32417,6 @@ /turf/open/floor/plasteel, /area/quartermaster/office) "bks" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/effect/spawner/lootdrop/maintenance, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -32421,6 +32424,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/autolathe{ + name = "public autolathe" + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "bkt" = ( @@ -38982,7 +38988,7 @@ pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/shaker, -/obj/item/reagent_containers/glass/rag{ +/obj/item/reagent_containers/rag{ pixel_y = 5 }, /obj/effect/turf_decal/tile/bar, @@ -59278,7 +59284,7 @@ }, /area/maintenance/port/aft) "ckR" = ( -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/structure/table/wood, /turf/open/floor/wood{ icon_state = "wood-broken4" diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index cef0aefc50..0c55f05fcb 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -13484,7 +13484,7 @@ /obj/structure/table/wood, /obj/item/book/manual/wiki/barman_recipes, /obj/item/reagent_containers/food/drinks/shaker, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 9efbb28e2b..ee97af14fc 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -17,6 +17,13 @@ /obj/structure/grille, /turf/open/space, /area/space/nearstation) +"abD" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "abI" = ( /obj/structure/lattice, /turf/open/space, @@ -8607,12 +8614,12 @@ /area/crew_quarters/dorms) "ave" = ( /obj/structure/bed, -/obj/item/bedsheet/nanotrasen, /obj/machinery/button/door{ id = "Dorm3Shutters"; name = "Privacy Shutters Control"; pixel_y = 26 }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/wood, /area/crew_quarters/dorms) "avf" = ( @@ -10060,13 +10067,13 @@ /area/crew_quarters/dorms) "ayj" = ( /obj/structure/bed, -/obj/item/bedsheet/nanotrasen, /obj/machinery/button/door{ id = "Dorm2Shutters"; name = "Privacy Shutters Control"; pixel_y = 26; req_access_txt = "0" }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayk" = ( @@ -11518,13 +11525,13 @@ /area/crew_quarters/dorms) "aBM" = ( /obj/structure/bed, -/obj/item/bedsheet/nanotrasen, /obj/machinery/button/door{ id = "Dorm1Shutters"; name = "Privacy Shutters Control"; pixel_y = 26; req_access_txt = "0" }, +/obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "aBN" = ( @@ -14549,6 +14556,18 @@ }, /turf/open/space, /area/solar/port) +"aIA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "aIC" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -15277,13 +15296,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"aKm" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/engineering) "aKn" = ( /obj/structure/cable{ icon_state = "1-2" @@ -16688,9 +16700,22 @@ /turf/open/floor/plating, /area/maintenance/disposal) "aNV" = ( +/obj/machinery/mineral/stacking_unit_console{ + dir = 2; + machinedir = 8; + pixel_x = -32; + pixel_y = 32 + }, /obj/machinery/conveyor{ - dir = 8; - id = "EngLoad" + dir = 4; + id = "garbagestacked" + }, +/turf/open/floor/plating, +/area/maintenance/disposal) +"aNW" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "garbagestacked" }, /turf/open/floor/plating, /area/maintenance/disposal) @@ -17182,7 +17207,7 @@ /area/maintenance/department/cargo) "aPg" = ( /obj/machinery/conveyor{ - dir = 8; + dir = 4; id = "garbage" }, /obj/structure/disposaloutlet{ @@ -17294,7 +17319,7 @@ lootcount = 2; name = "2maintenance loot spawner" }, -/obj/item/clothing/gloves/color/random, +/obj/effect/spawner/lootdrop/gloves, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/bar) "aPD" = ( @@ -17566,7 +17591,7 @@ dir = 8 }, /obj/machinery/conveyor{ - dir = 2; + dir = 1; id = "garbage" }, /turf/open/floor/plating, @@ -21118,7 +21143,7 @@ "aYf" = ( /obj/structure/table/reinforced, /obj/item/book/manual/wiki/barman_recipes, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -24110,6 +24135,10 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/keycard_auth{ + pixel_x = -23; + pixel_y = 0 + }, /turf/open/floor/plasteel, /area/quartermaster/qm) "beK" = ( @@ -24169,6 +24198,17 @@ /obj/item/caution, /turf/open/floor/plating, /area/maintenance/department/cargo) +"beT" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/public/glass{ + name = "Monastery Transit" + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/chapel/dock) "beU" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -29401,6 +29441,13 @@ dir = 1 }, /obj/effect/landmark/start/chemist, +/obj/machinery/button/door{ + id = "chemistry_shutters"; + name = "Shutters Control"; + pixel_x = 26; + pixel_y = 4; + req_access_txt = "5; 33" + }, /obj/effect/turf_decal/tile/yellow{ dir = 1 }, @@ -29442,6 +29489,15 @@ }, /turf/open/floor/plasteel/white, /area/medical/chemistry) +"brp" = ( +/obj/item/twohanded/required/kirbyplants{ + icon_state = "plant-03" + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -24 + }, +/turf/open/floor/plasteel/dark, +/area/science/lab) "brq" = ( /obj/structure/sink/kitchen{ desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; @@ -31924,27 +31980,13 @@ /turf/open/floor/plasteel/white, /area/medical/chemistry) "bwW" = ( -/obj/structure/rack, -/obj/item/stack/packageWrap, -/obj/item/hand_labeler, -/obj/item/clothing/glasses/science, -/obj/item/clothing/glasses/science, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/medical/chemistry) -"bxa" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/research_and_development, -/obj/item/disk/tech_disk, -/obj/item/disk/design_disk, -/turf/open/floor/plasteel/dark, -/area/science/lab) "bxc" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -32453,17 +32495,19 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bxY" = ( -/obj/structure/closet/emcloset, /obj/machinery/light/small{ dir = 1 }, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "bxZ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "bya" = ( /obj/structure/extinguisher_cabinet{ @@ -32472,7 +32516,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "byb" = ( /obj/structure/table, @@ -33186,17 +33230,14 @@ /area/space/nearstation) "bzz" = ( /obj/effect/turf_decal/stripes/line, -/obj/structure/chair{ - dir = 4 - }, -/obj/structure/sign/departments/holy{ - pixel_x = -32 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "bzA" = ( /obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "bzB" = ( /obj/effect/turf_decal/stripes/line, @@ -33207,7 +33248,7 @@ network = list("monastery"); pixel_x = 28 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/hallway/secondary/entry) "bzC" = ( /obj/structure/table, @@ -33740,8 +33781,9 @@ /obj/structure/transit_tube/curved/flipped{ dir = 4 }, -/turf/open/space/basic, -/area/space/nearstation) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/hallway/secondary/entry) "bAJ" = ( /obj/structure/transit_tube/horizontal, /obj/structure/window/reinforced/fulltile, @@ -37152,6 +37194,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/purple{ dir = 1 }, @@ -37276,19 +37319,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"bHp" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "bHq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -37478,6 +37508,7 @@ dir = 8; layer = 2.9 }, +/obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) "bHP" = ( @@ -38059,14 +38090,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/dock) -"bIY" = ( -/obj/structure/lattice, -/obj/structure/window/reinforced{ - dir = 8; - layer = 2.9 - }, -/turf/open/space/basic, -/area/space/nearstation) "bIZ" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -38622,15 +38645,15 @@ /area/chapel/dock) "bKe" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/dark, +/obj/structure/closet/emcloset, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, /area/chapel/dock) "bKf" = ( -/obj/structure/chair, -/turf/open/floor/plasteel/dark, -/area/chapel/dock) -"bKg" = ( -/obj/structure/closet/emcloset, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, /area/chapel/dock) "bKh" = ( /obj/machinery/door/window/eastright{ @@ -39144,19 +39167,11 @@ /turf/open/floor/plasteel/dark, /area/chapel/dock) "bLr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 }, -/turf/open/floor/plasteel/dark, /area/chapel/dock) -"bLs" = ( -/obj/structure/lattice, -/obj/structure/window/reinforced{ - dir = 8; - layer = 2.9 - }, -/turf/open/space, -/area/space/nearstation) "bLt" = ( /obj/effect/decal/cleanable/oil{ icon_state = "floor6" @@ -39647,7 +39662,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, /area/chapel/dock) "bMx" = ( /obj/effect/turf_decal/stripes/line, @@ -39657,16 +39674,13 @@ /obj/machinery/light/small{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/chapel/dock) -"bMy" = ( -/obj/structure/window/reinforced{ - dir = 8; - layer = 2.9 +/obj/structure/chair{ + dir = 1 }, -/obj/structure/lattice, -/turf/open/space, -/area/space/nearstation) +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/chapel/dock) "bMA" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/engine, @@ -40518,19 +40532,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/dock) -"bOy" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/chapel/dock) "bOz" = ( /obj/structure/chair/comfy/black{ dir = 1 @@ -42241,12 +42242,6 @@ /obj/structure/flora/ausbushes, /turf/open/floor/plating/asteroid, /area/chapel/asteroid/monastery) -"bSn" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/open/space, -/area/space/nearstation) "bSo" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -44059,7 +44054,8 @@ /turf/open/floor/engine/co2, /area/engine/atmos) "bWh" = ( -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand, +/turf/open/floor/plasteel, /area/chapel/office) "bWi" = ( /obj/structure/flora/ausbushes/leafybush, @@ -44780,12 +44776,6 @@ }, /turf/closed/wall/r_wall, /area/engine/atmos) -"bXI" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, -/area/chapel/main/monastery) "bXJ" = ( /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) @@ -45107,6 +45097,24 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) +"bYM" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "bYN" = ( /obj/structure/cable{ icon_state = "4-8" @@ -45179,15 +45187,15 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/yellow{ dir = 1 }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "bYR" = ( @@ -46450,13 +46458,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) -"ccL" = ( -/obj/item/flashlight/lantern{ - icon_state = "lantern-on" - }, -/obj/effect/turf_decal/sand, -/turf/open/floor/plasteel, -/area/chapel/asteroid/monastery) "ccM" = ( /obj/structure/chair, /turf/open/floor/plating/asteroid, @@ -46689,6 +46690,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plasteel, /area/engine/engineering) "cdK" = ( @@ -46857,6 +46859,15 @@ }, /turf/open/floor/plating/asteroid, /area/chapel/asteroid/monastery) +"cep" = ( +/obj/structure/sign/poster/official/random{ + pixel_x = -32 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "ceq" = ( /obj/machinery/power/emitter, /turf/open/floor/plating, @@ -47117,22 +47128,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) -"cfp" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/chapel/main/monastery) "cfr" = ( /obj/structure/transit_tube_pod, /obj/structure/transit_tube/station/reverse{ @@ -47240,7 +47235,6 @@ /turf/open/floor/plating, /area/chapel/main/monastery) "cfL" = ( -/obj/structure/flora/ausbushes/fernybush, /obj/machinery/camera{ c_tag = "Monastery Asteroid Starboard Aft"; dir = 1; @@ -47249,11 +47243,6 @@ /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, /area/chapel/asteroid/monastery) -"cfM" = ( -/obj/structure/flora/ausbushes, -/obj/effect/turf_decal/sand, -/turf/open/floor/plasteel, -/area/chapel/asteroid/monastery) "cfN" = ( /turf/closed/mineral, /area/chapel/asteroid/monastery) @@ -47426,6 +47415,13 @@ }, /turf/open/floor/plating, /area/engine/engineering) +"cgt" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/turf/open/floor/plating, +/area/engine/engineering) "cgu" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -50161,6 +50157,19 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/dock) +"cqI" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/chapel/dock) "cqS" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -50902,6 +50911,22 @@ /obj/machinery/vending/wardrobe/chap_wardrobe, /turf/open/floor/carpet, /area/chapel/office) +"cua" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/chapel/main/monastery) "cuc" = ( /obj/machinery/light, /obj/machinery/camera{ @@ -50922,13 +50947,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) -"cui" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/space, -/area/space/nearstation) "cuk" = ( /obj/structure/closet{ name = "beekeeping wardrobe" @@ -51264,11 +51282,11 @@ /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) "cvf" = ( +/obj/machinery/recycler, /obj/machinery/conveyor{ - dir = 8; + dir = 4; id = "garbage" }, -/obj/machinery/recycler, /turf/open/floor/plating, /area/maintenance/disposal) "cvg" = ( @@ -51544,15 +51562,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) -"cvM" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-10" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel/dark, -/area/chapel/main/monastery) "cvR" = ( /obj/machinery/light/small{ dir = 8 @@ -51850,6 +51859,22 @@ }, /turf/open/space/basic, /area/space/nearstation) +"cxj" = ( +/obj/structure/table, +/obj/item/clothing/glasses/meson/engine, +/obj/item/clothing/glasses/meson/engine, +/obj/item/clothing/glasses/meson/engine, +/obj/item/pipe_dispenser, +/obj/item/pipe_dispenser, +/obj/item/pipe_dispenser, +/obj/machinery/light, +/obj/effect/turf_decal/delivery, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) "cxk" = ( /obj/structure/window/reinforced{ dir = 1; @@ -52395,6 +52420,12 @@ }, /turf/open/floor/plasteel/dark, /area/library) +"cAp" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "cAr" = ( /obj/machinery/light/small{ dir = 8 @@ -52546,15 +52577,6 @@ }, /turf/open/floor/plasteel/dark, /area/library) -"cAQ" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/engine/engineering) "cAS" = ( /obj/machinery/vending/wardrobe/curator_wardrobe, /turf/open/floor/plasteel/dark, @@ -52870,23 +52892,6 @@ }, /turf/open/floor/plasteel, /area/science/explab) -"cKV" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"cLw" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plating, -/area/engine/engineering) "cOp" = ( /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, @@ -52896,6 +52901,13 @@ /obj/structure/table, /turf/open/floor/plasteel, /area/science/xenobiology) +"cOA" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) "cPy" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 2 @@ -52930,6 +52942,14 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"cQZ" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plating, +/area/maintenance/department/engine) +"cRJ" = ( +/obj/machinery/status_display/supply, +/turf/closed/wall, +/area/quartermaster/warehouse) "cSJ" = ( /obj/item/reagent_containers/glass/beaker/cryoxadone{ pixel_x = -2; @@ -52985,6 +53005,15 @@ }, /turf/open/floor/plasteel/dark, /area/science/lab) +"cUT" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 9 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "cXW" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -53037,13 +53066,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"dgj" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 6 - }, -/obj/machinery/meter, -/turf/closed/wall/r_wall, -/area/engine/supermatter) "dgz" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -53065,6 +53087,13 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"dhu" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) "dhz" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -53109,6 +53138,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/explab) +"dlI" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "dmP" = ( /obj/structure/chair{ dir = 8 @@ -53180,10 +53215,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/office) -"dps" = ( -/obj/machinery/status_display/ai, -/turf/closed/wall, -/area/quartermaster/qm) "dqw" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "0"; @@ -53219,13 +53250,6 @@ /obj/machinery/reagentgrinder, /turf/open/floor/plating, /area/maintenance/department/cargo) -"dsz" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 5 - }, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) "dtm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53291,6 +53315,24 @@ /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plating, /area/maintenance/department/engine) +"dzA" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) +"dAa" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) "dAF" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external, @@ -53305,54 +53347,30 @@ icon_state = "platingdmg1" }, /area/maintenance/department/engine) -"dEy" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) -"dFJ" = ( -/turf/open/floor/engine, +"dFF" = ( +/turf/closed/wall/r_wall, /area/engine/supermatter) -"dHr" = ( +"dGd" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/machinery/button/door{ - id = "engsm"; - name = "Radiation Shutters Control"; - pixel_y = 24; - req_access_txt = "10" - }, +/obj/machinery/meter, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/engine, /area/engine/engineering) -"dHZ" = ( -/obj/structure/chair/office/light{ - dir = 1 - }, -/obj/effect/landmark/start/chemist, -/obj/machinery/button/door{ - id = "chemistry_shutters"; - name = "Shutters Control"; - pixel_x = 26; - pixel_y = 4; - req_access_txt = "5; 33" - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ +"dGp" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ dir = 4 }, -/turf/open/floor/plasteel/white, -/area/medical/chemistry) -"dJk" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/turf/open/floor/plating, -/area/engine/atmos) +/turf/closed/wall/r_wall, +/area/engine/engineering) +"dHF" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) "dJm" = ( /obj/structure/cable{ icon_state = "4-8" @@ -53412,12 +53430,18 @@ /obj/machinery/shieldwallgen/xenobiologyaccess, /turf/open/floor/plating, /area/maintenance/department/engine) -"dSp" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ - dir = 1 +"dPZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, -/turf/open/floor/plating/airless, +/turf/open/floor/plasteel, /area/engine/engineering) +"dRs" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space) "dSr" = ( /obj/item/chair, /turf/open/floor/wood, @@ -53428,6 +53452,25 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"dUk" = ( +/obj/machinery/cryopod{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"dVt" = ( +/obj/structure/chair/office/light{ + dir = 1 + }, +/obj/effect/landmark/start/chemist, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) "dVI" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 4; @@ -53494,10 +53537,6 @@ /obj/structure/chair/office/light, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"eex" = ( -/obj/machinery/status_display/supply, -/turf/closed/wall, -/area/quartermaster/office) "eeQ" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -53533,13 +53572,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"eiV" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 4 - }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) "ekU" = ( /obj/effect/decal/cleanable/cobweb{ icon_state = "cobweb2" @@ -53550,23 +53582,12 @@ /obj/structure/chair/office/dark, /turf/open/floor/wood, /area/lawoffice) -"epj" = ( -/obj/machinery/cryopod{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/dorms) "epJ" = ( /obj/structure/sign/poster/contraband/random{ pixel_y = 32 }, /turf/open/floor/carpet, /area/maintenance/department/crew_quarters/dorms) -"epV" = ( -/obj/structure/chair, -/obj/effect/turf_decal/stripes/corner, -/turf/open/floor/plasteel, -/area/engine/engineering) "eqD" = ( /obj/structure/sign/poster/contraband/random{ pixel_x = -32 @@ -53576,6 +53597,20 @@ icon_state = "wood-broken" }, /area/maintenance/department/crew_quarters/dorms) +"eqM" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"erV" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "eta" = ( /obj/machinery/door/airlock/engineering{ name = "Engineering Supplies"; @@ -53594,6 +53629,40 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"eue" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eux" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) +"euN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/item/twohanded/required/kirbyplants{ + icon_state = "plant-10" + }, +/turf/open/floor/plasteel/dark, +/area/chapel/main/monastery) "euQ" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -53603,10 +53672,20 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) -"eyj" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/turf/open/floor/plating, -/area/engine/engineering) +"eyT" = ( +/obj/machinery/jukebox, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/bar) +"ezo" = ( +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/structure/rack, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) "ezF" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -53638,23 +53717,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) -"eAH" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"eAZ" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/space, -/area/space/nearstation) "eCw" = ( /obj/structure/cable{ icon_state = "1-2" @@ -53693,19 +53755,6 @@ }, /turf/open/floor/plasteel/white, /area/medical/sleeper) -"eFG" = ( -/obj/machinery/mineral/stacking_unit_console{ - dir = 2; - machinedir = 8; - pixel_x = -32; - pixel_y = 32 - }, -/obj/machinery/conveyor{ - dir = 8; - id = "EngLoad" - }, -/turf/open/floor/plating, -/area/maintenance/disposal) "eHI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, @@ -53730,6 +53779,17 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"eMz" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine"; + req_access_txt = "10" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "eMC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -53749,6 +53809,15 @@ /obj/structure/lattice, /turf/closed/wall, /area/space/nearstation) +"eOA" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/lattice, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "eOZ" = ( /obj/structure/closet, /obj/item/clothing/suit/judgerobe, @@ -53756,6 +53825,19 @@ /obj/item/gavelhammer, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"ePS" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -28 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "ePU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53783,18 +53865,6 @@ icon_state = "platingdmg3" }, /area/maintenance/department/security/brig) -"eRp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"eSB" = ( -/obj/machinery/computer/cryopod{ - dir = 1; - pixel_y = -26 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) "eSL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/beacon, @@ -53816,6 +53886,10 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"eVW" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/turf/open/floor/plating, +/area/engine/engineering) "eWi" = ( /obj/structure/cable{ icon_state = "0-4" @@ -53845,6 +53919,12 @@ /obj/item/stack/cable_coil/cut/random, /turf/open/floor/plating, /area/maintenance/department/cargo) +"fbu" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) "fdQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -53929,12 +54009,6 @@ }, /turf/open/floor/plasteel/white, /area/science/explab) -"fjD" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, -/turf/closed/wall/r_wall, -/area/engine/supermatter) "fkH" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -53947,16 +54021,20 @@ }, /turf/open/floor/plasteel, /area/science/explab) +"flP" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "fmh" = ( /turf/open/floor/wood, /area/maintenance/department/engine) -"fmL" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/light{ - dir = 8; - light_color = "#e8eaff" +"fml" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 9 }, -/turf/open/floor/plasteel/dark, +/turf/closed/wall/r_wall, /area/engine/engineering) "fmU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -53997,12 +54075,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) -"frj" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 6 - }, -/turf/closed/wall/r_wall, -/area/engine/engineering) "ftp" = ( /turf/open/floor/plating{ icon_state = "platingdmg1" @@ -54052,6 +54124,10 @@ }, /turf/open/floor/plasteel, /area/quartermaster/sorting) +"fwo" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plating, +/area/chapel/main/monastery) "fwr" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -54065,21 +54141,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"fxC" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/turf/closed/wall/r_wall, -/area/engine/supermatter) -"fym" = ( -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber"; - req_access_txt = "10" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/supermatter) "fyF" = ( /obj/structure/cable/yellow{ icon_state = "0-4" @@ -54148,12 +54209,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) -"fBZ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/supermatter) "fFv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/firealarm{ @@ -54162,6 +54217,14 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"fGt" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/station_engineer, +/turf/open/floor/plasteel, +/area/engine/engineering) "fIu" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -54234,19 +54297,9 @@ /obj/structure/bookcase/random/religion, /turf/open/floor/plasteel/dark, /area/library/lounge) -"fZK" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 4 - }, -/obj/machinery/light{ - dir = 4; - light_color = "#e8eaff" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, +"fWE" = ( /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "gam" = ( /obj/machinery/door/airlock/medical/glass{ name = "Service Door"; @@ -54259,6 +54312,18 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) +"gaJ" = ( +/obj/machinery/status_display/ai, +/turf/closed/wall, +/area/quartermaster/qm) +"gaQ" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "gcj" = ( /obj/machinery/vending/kink, /obj/effect/turf_decal/tile/blue{ @@ -54306,6 +54371,13 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"gfh" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "gfi" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -54315,11 +54387,18 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"ggg" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 6 +"gih" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 }, -/turf/open/floor/plasteel/dark, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, /area/engine/engineering) "giI" = ( /obj/machinery/light/small{ @@ -54364,6 +54443,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"gkN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engine/engineering) "gkR" = ( /obj/item/twohanded/required/kirbyplants/random, /obj/structure/extinguisher_cabinet{ @@ -54493,6 +54578,14 @@ heat_capacity = 1e+006 }, /area/hallway/secondary/exit/departure_lounge) +"gvO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/chapel/dock) "gwn" = ( /obj/structure/sign/warning{ pixel_y = 32 @@ -54545,24 +54638,6 @@ /obj/item/flashlight/lamp/green, /turf/open/floor/carpet, /area/lawoffice) -"gBb" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/heat_exchanging/simple, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) -"gDR" = ( -/obj/machinery/camera{ - c_tag = "Central Primary Hallway Escape"; - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "gDZ" = ( /obj/effect/turf_decal/box/corners{ dir = 1 @@ -54582,11 +54657,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/explab) -"gEo" = ( -/obj/machinery/atmospherics/pipe/manifold4w/general/visible, -/obj/machinery/meter, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "gFo" = ( /obj/structure/window/reinforced, /obj/structure/table/glass, @@ -54620,17 +54690,39 @@ /turf/open/floor/plating, /area/maintenance/department/security/brig) "gGA" = ( -/obj/structure/table/glass, -/obj/machinery/reagentgrinder, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" }, -/turf/open/floor/plasteel/white, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/medical/chemistry) +"gHp" = ( +/obj/machinery/atmospherics/pipe/manifold/orange/visible{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"gHy" = ( +/obj/machinery/computer/cryopod{ + dir = 1; + pixel_y = -26 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "gHZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -54681,6 +54773,13 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"gLn" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "gLF" = ( /obj/machinery/vending/snack/random, /obj/effect/turf_decal/tile/neutral{ @@ -54732,12 +54831,6 @@ }, /turf/open/floor/wood, /area/lawoffice) -"gQf" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/engine, -/area/engine/engineering) "gSH" = ( /turf/closed/wall, /area/lawoffice) @@ -54755,6 +54848,21 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"gUS" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/camera{ + c_tag = "Engineering Supermatter Fore"; + dir = 1; + network = list("ss13","engine") + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engine/engineering) "gVc" = ( /turf/open/floor/wood{ icon_state = "wood-broken4" @@ -54767,31 +54875,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) -"gXZ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Engineering Supermatter Fore"; - dir = 4; - network = list("ss13","engine") - }, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "gYo" = ( /obj/structure/grille, /turf/open/space/basic, /area/space/nearstation) -"haA" = ( -/obj/structure/table, -/obj/item/stack/sheet/metal/fifty, -/obj/item/stack/rods/fifty, -/obj/item/clothing/glasses/welding, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) "heC" = ( /obj/machinery/power/apc/highcap/five_k{ dir = 8; @@ -54838,24 +54925,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"hjk" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) -"hjD" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) "hkQ" = ( /obj/machinery/light{ dir = 4 @@ -54878,26 +54947,6 @@ }, /turf/open/floor/wood, /area/lawoffice) -"hon" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 4; - name = "Gas to Filter" - }, -/turf/open/floor/engine, -/area/engine/engineering) -"hoS" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, -/obj/effect/turf_decal/stripes/corner, -/turf/open/floor/engine, -/area/engine/engineering) "hqo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54913,6 +54962,13 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"hrx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "hvW" = ( /obj/machinery/door/poddoor/preopen{ id = "xenobio4"; @@ -54948,18 +55004,18 @@ /obj/machinery/portable_atmospherics/canister/toxins, /turf/open/floor/plating, /area/security/execution/transfer) +"hxh" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "hxn" = ( /obj/structure/chair, /obj/item/clothing/glasses/regular, /turf/open/floor/plating, /area/maintenance/department/science) -"hyh" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 9 - }, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) "hzc" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -54989,6 +55045,21 @@ }, /turf/open/floor/plating, /area/maintenance/solars/port) +"hCg" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "garbage" + }, +/turf/open/floor/plating, +/area/maintenance/disposal) +"hDy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/engine/engineering) "hDG" = ( /obj/machinery/door/airlock/engineering{ name = "Auxillary Base Construction"; @@ -55021,43 +55092,20 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) -"hGB" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) "hHr" = ( /obj/structure/chair/comfy/black{ dir = 4 }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"hIZ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"hKp" = ( -/obj/structure/cable/yellow{ - icon_state = "0-8" - }, -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/structure/window/plasma/reinforced{ +"hJO" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 }, -/obj/machinery/power/rad_collector/anchored, -/turf/open/floor/engine, -/area/engine/supermatter) +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "hOx" = ( /obj/structure/cable{ icon_state = "2-4" @@ -55095,17 +55143,6 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) -"hQy" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "engsm"; - name = "Radiation Chamber Shutters" - }, -/obj/item/tank/internals/plasma, -/turf/open/floor/plating, -/area/engine/supermatter) "hQz" = ( /obj/structure/closet/emcloset/anchored, /obj/structure/cable/yellow{ @@ -55117,29 +55154,14 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/engine/engineering) -"hSt" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 4; - name = "Gas to Cooling Loop" +"hRQ" = ( +/obj/structure/window/reinforced{ + dir = 8; + layer = 2.9 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"hSC" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) "hSM" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -55164,18 +55186,23 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"hUf" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"hUi" = ( +/obj/machinery/atmospherics/pipe/manifold4w/general/visible, +/obj/machinery/meter, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "hUt" = ( /obj/structure/closet/crate{ icon_state = "crateopen" }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"hUw" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 9 - }, -/turf/closed/wall/r_wall, -/area/engine/engineering) "hUJ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55191,17 +55218,25 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"hWa" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) +"hXm" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "hXt" = ( /obj/structure/girder, /turf/open/floor/plating, /area/maintenance/department/science) -"hXK" = ( -/obj/structure/chair/office/dark{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/engine/engineering) "hYe" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/red{ @@ -55243,20 +55278,15 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"iaZ" = ( +/turf/open/space/basic, +/area/hallway/secondary/entry) "ick" = ( /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel/dark, /area/library) -"iej" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/engine, -/area/engine/engineering) "igE" = ( /obj/structure/table/reinforced, /obj/machinery/button/door{ @@ -55305,30 +55335,24 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) +"ikm" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Mix to Gas" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/engineering) "ikB" = ( /obj/structure/closet/secure_closet/medical2, /turf/open/floor/plating, /area/maintenance/department/science) -"ikO" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 9 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) "ilD" = ( /obj/machinery/processor/slime, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"imE" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "ioj" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -55345,40 +55369,13 @@ }, /turf/open/floor/plasteel/white, /area/medical/sleeper) -"iop" = ( -/obj/machinery/atmospherics/pipe/manifold/orange/visible{ - dir = 8 - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/light{ - dir = 8; - light_color = "#e8eaff" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"ioF" = ( -/obj/structure/closet/secure_closet/engineering_electrical, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) "iqc" = ( /turf/open/floor/plasteel/stairs/right, /area/maintenance/department/crew_quarters/dorms) -"irM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) +"irs" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) "itl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -55411,13 +55408,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) -"iwe" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "iyg" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55434,11 +55424,6 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) -"izm" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/engine/engineering) "izB" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod" @@ -55521,6 +55506,20 @@ }, /turf/open/floor/plasteel/white, /area/storage/emergency/port) +"iHe" = ( +/obj/machinery/camera{ + c_tag = "Central Primary Hallway Escape"; + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) +"iHI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "iJi" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -55534,13 +55533,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/quartermaster/sorting) -"iLh" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/engine, -/area/engine/engineering) "iLl" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -55602,6 +55594,22 @@ }, /turf/open/floor/plating, /area/security/execution/transfer) +"iSi" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Cooling Loop Bypass" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/engineering) "iSz" = ( /obj/structure/cable{ icon_state = "2-8" @@ -55614,9 +55622,14 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"iTF" = ( -/obj/structure/sign/warning/electricshock, -/turf/closed/wall/r_wall, +"iSL" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/plating, +/area/engine/atmos) +"iTE" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/engine, /area/engine/supermatter) "iVJ" = ( /obj/effect/spawner/lootdrop/organ_spawner, @@ -55683,6 +55696,16 @@ icon_state = "platingdmg3" }, /area/maintenance/department/crew_quarters/dorms) +"jjA" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 4; + name = "Gas to Cooling Loop" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "jjC" = ( /obj/structure/rack, /obj/item/storage/briefcase{ @@ -55695,6 +55718,18 @@ }, /turf/open/floor/wood, /area/lawoffice) +"jkm" = ( +/obj/structure/closet/emcloset, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) +"jrb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "jrG" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -55750,6 +55785,17 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"jtv" = ( +/obj/machinery/camera{ + c_tag = "Engineering Supermatter Starboard"; + dir = 8; + network = list("ss13","engine") + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "jvi" = ( /obj/structure/cable{ icon_state = "4-8" @@ -55795,17 +55841,6 @@ /obj/structure/sign/warning/vacuum/external, /turf/open/floor/plating, /area/hallway/secondary/entry) -"jzE" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering/glass{ - name = "Supermatter Engine"; - req_access_txt = "10" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "jAy" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -55884,15 +55919,39 @@ /obj/machinery/atmospherics/pipe/simple/purple/visible, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"jOw" = ( +/obj/structure/closet/secure_closet/engineering_electrical, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "jOB" = ( /turf/open/floor/plating, /area/storage/emergency/starboard) +"jOX" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Monastery Transit" + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/chapel/dock) "jPf" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/maintenance, /obj/item/kitchen/knife, /turf/open/floor/plasteel, /area/maintenance/department/engine) +"jPC" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/space, +/area/space/nearstation) "jQh" = ( /obj/item/stack/sheet/animalhide/xeno, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -55902,6 +55961,15 @@ icon_state = "platingdmg1" }, /area/maintenance/department/science) +"jQn" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) "jRG" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -55912,6 +55980,13 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"jTc" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 4; + name = "Gas to Filter" + }, +/turf/open/floor/engine, +/area/engine/engineering) "jTh" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55933,16 +56008,6 @@ }, /turf/open/floor/carpet, /area/lawoffice) -"jTU" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) "jUV" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -55963,12 +56028,6 @@ /obj/item/stack/ore/iron, /turf/open/floor/plating, /area/maintenance/department/science) -"jXF" = ( -/obj/machinery/cryopod{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) "jXV" = ( /obj/machinery/light/small{ dir = 1 @@ -55993,20 +56052,14 @@ icon_state = "platingdmg3" }, /area/maintenance/department/engine) -"jZG" = ( -/obj/machinery/door/poddoor/shutters/preopen{ - id = "chemistry_shutters"; - name = "chemistry shutters" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/medical/chemistry) -"kaR" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - dir = 8 +"kec" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" }, /obj/effect/turf_decal/stripes/line{ - dir = 1 + dir = 8 }, /turf/open/floor/engine, /area/engine/engineering) @@ -56064,10 +56117,6 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) -"klb" = ( -/obj/machinery/status_display/supply, -/turf/closed/wall, -/area/quartermaster/sorting) "klo" = ( /obj/structure/dresser, /obj/structure/mirror{ @@ -56086,22 +56135,10 @@ /obj/item/clothing/under/rank/clown/sexy, /turf/open/floor/plasteel/dark, /area/maintenance/department/crew_quarters/dorms) -"kmd" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "kmn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/mixing) -"koz" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "kpK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -56121,6 +56158,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"ksC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "kvj" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -56134,6 +56177,20 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"kvu" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"kvx" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "kwm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -56194,12 +56251,22 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"kBe" = ( +/obj/structure/reflector/double/anchored{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "kDf" = ( /obj/machinery/light/small{ dir = 2 }, /turf/open/floor/carpet/black, /area/chapel/office) +"kDI" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/supermatter) "kDJ" = ( /obj/machinery/light{ dir = 8 @@ -56332,6 +56399,11 @@ }, /turf/open/floor/engine, /area/science/xenobiology) +"kNK" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/engine/engineering) "kPi" = ( /obj/structure/table, /obj/machinery/microwave, @@ -56405,20 +56477,10 @@ }, /turf/open/floor/plating, /area/storage/emergency/port) -"kTj" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) -"kTR" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) +"kVA" = ( +/obj/machinery/status_display/supply, +/turf/closed/wall, +/area/quartermaster/sorting) "kWQ" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/structure/cable/yellow{ @@ -56432,16 +56494,15 @@ }, /turf/open/floor/engine, /area/engine/engineering) -"kYM" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 27 +"kYR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 +/obj/machinery/light, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) +/area/hallway/secondary/entry) "lcU" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -56469,29 +56530,14 @@ }, /turf/open/floor/plating, /area/security/execution/transfer) -"lfx" = ( -/obj/structure/table, -/obj/item/clothing/suit/hooded/wintercoat/engineering, -/obj/item/clothing/glasses/meson, -/obj/item/clothing/glasses/meson, -/obj/item/clothing/glasses/meson, -/obj/effect/turf_decal/delivery, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) +"lfZ" = ( +/obj/machinery/status_display/supply, +/turf/closed/wall, +/area/quartermaster/office) "lhA" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible, /turf/open/floor/plasteel/dark, /area/science/xenobiology) -"lhP" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "liR" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -56506,18 +56552,30 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/open/floor/plating, /area/maintenance/department/cargo) -"ljG" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 6 +"llS" = ( +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 }, -/turf/open/floor/plasteel, -/area/engine/atmos) +/area/hallway/secondary/entry) "lms" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, /turf/closed/wall, /area/maintenance/department/engine) +"lmv" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) "lnn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral, @@ -56526,32 +56584,17 @@ }, /turf/open/floor/plasteel, /area/storage/primary) -"lnr" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"loz" = ( -/obj/structure/closet/radiation, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) "lqc" = ( /obj/item/toy/gun, /obj/effect/decal/cleanable/oil, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"lqo" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "lqy" = ( /obj/machinery/door/airlock/grunge{ name = "Library" @@ -56561,13 +56604,13 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/library/lounge) -"lrM" = ( -/obj/structure/cable{ - icon_state = "2-8" +"lxh" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) +/turf/open/space, +/area/space/nearstation) "lzJ" = ( /obj/structure/closet/crate/bin, /turf/open/floor/carpet, @@ -56601,6 +56644,24 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"lCR" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"lCY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) +"lDW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, +/area/engine/engineering) "lEn" = ( /obj/structure/window/reinforced{ dir = 1 @@ -56671,12 +56732,6 @@ /obj/item/wrench, /turf/open/floor/plating, /area/maintenance/department/science) -"lJI" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "lKL" = ( /obj/machinery/door/airlock/abandoned{ name = "Starboard Emergency Storage"; @@ -56711,6 +56766,13 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"lQy" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 9 + }, +/turf/open/space, +/area/space/nearstation) "lQQ" = ( /obj/machinery/door/poddoor/preopen{ id = "bridgespace"; @@ -56736,13 +56798,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"lRX" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 9 - }, -/turf/open/floor/plating, -/area/engine/engineering) "lTC" = ( /obj/item/shard, /obj/effect/turf_decal/stripes/line{ @@ -56753,10 +56808,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"lUO" = ( -/obj/structure/sign/warning/radiation, -/turf/closed/wall/r_wall, -/area/engine/supermatter) "lWy" = ( /turf/open/floor/plating, /area/maintenance/department/science) @@ -56778,28 +56829,11 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) -"lXb" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Gas to Mix" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) "lXc" = ( /obj/structure/table, /obj/item/clothing/head/beret, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"lXJ" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 - }, -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "mal" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -56840,10 +56874,32 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) -"mci" = ( -/obj/machinery/portable_atmospherics/canister/toxins, +"mbD" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plating, /area/engine/engineering) +"mcf" = ( +/obj/structure/table/glass, +/obj/machinery/reagentgrinder, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"mdi" = ( +/obj/machinery/rnd/production/circuit_imprinter, +/obj/machinery/camera{ + c_tag = "Engineering Starboard Aft"; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "mdL" = ( /obj/structure/table, /obj/item/paper_bin, @@ -56860,19 +56916,19 @@ /obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/engine/supermatter) -"mfC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +"mfg" = ( +/obj/structure/window/reinforced{ + dir = 8 }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"mgz" = ( -/obj/structure/cable{ - icon_state = "4-8" +/turf/open/space, +/area/space/nearstation) +"mfx" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "mhl" = ( /obj/machinery/power/emitter, /obj/machinery/light{ @@ -56880,39 +56936,14 @@ }, /turf/open/floor/plating, /area/engine/engineering) -"mhn" = ( -/obj/machinery/door/firedoor, -/obj/structure/sign/poster/random{ - pixel_x = 32 +"mlb" = ( +/obj/structure/cable{ + icon_state = "1-8" }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"miw" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/camera{ - c_tag = "Engineering Supermatter Fore"; - dir = 1; - network = list("ss13","engine") - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"mjn" = ( -/obj/machinery/jukebox, -/turf/open/floor/plasteel/dark, -/area/crew_quarters/bar) -"mjK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/turf/closed/wall/r_wall, +/turf/open/floor/plating, /area/engine/engineering) "mlr" = ( /obj/structure/lattice, @@ -56921,6 +56952,26 @@ }, /turf/open/space/basic, /area/space/nearstation) +"mlx" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"mlS" = ( +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber"; + req_access_txt = "10" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/supermatter) "mmv" = ( /obj/machinery/door/airlock/engineering{ name = "Engineering Supplies"; @@ -56968,19 +57019,6 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"mqp" = ( -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -28 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "msX" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -57019,6 +57057,21 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) +"mvA" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"mvY" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 2; + name = "Gas to Filter" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/engine, +/area/engine/supermatter) "mwg" = ( /obj/structure/closet/crate{ icon_state = "crateopen" @@ -57086,6 +57139,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/maintenance/department/engine) +"mAi" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "mCe" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -57094,6 +57153,27 @@ }, /turf/open/floor/plating, /area/security/checkpoint/engineering) +"mCP" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"mCU" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/rods/fifty, +/obj/item/clothing/glasses/welding, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) "mDW" = ( /obj/machinery/power/smes{ charge = 5e+006 @@ -57101,16 +57181,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/tcommsat/computer) -"mEu" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) "mES" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Surgical Room" @@ -57140,6 +57210,10 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) +"mLc" = ( +/obj/structure/sign/warning/electricshock, +/turf/closed/wall/r_wall, +/area/engine/supermatter) "mLB" = ( /obj/structure/cable{ icon_state = "1-4" @@ -57179,6 +57253,16 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"mVj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "mVM" = ( /turf/open/floor/plating/airless, /area/space/nearstation) @@ -57191,6 +57275,20 @@ "mZE" = ( /turf/open/space/basic, /area/space/nearstation) +"mZK" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"mZV" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/turf/closed/wall/r_wall, +/area/engine/supermatter) "naq" = ( /obj/structure/disposaloutlet{ dir = 4 @@ -57200,14 +57298,14 @@ }, /turf/open/floor/engine, /area/science/xenobiology) -"ncm" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 +"ndf" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Gas to Mix" }, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, -/obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/engine/engineering) "ndI" = ( @@ -57252,10 +57350,37 @@ /obj/structure/lattice, /turf/open/space, /area/space/nearstation) +"ngg" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/engineering) "ngp" = ( /obj/item/chair/stool, /turf/open/floor/carpet, /area/maintenance/department/crew_quarters/dorms) +"nhW" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) +"nif" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/engineering_hacking{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/book/manual/wiki/engineering_construction, +/turf/open/floor/plasteel, +/area/engine/engineering) "nih" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/costume, @@ -57279,6 +57404,30 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"nkk" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/chair{ + dir = 8; + name = "Defense" + }, +/obj/machinery/camera{ + c_tag = "Atmospherics Starboard"; + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "nku" = ( /obj/machinery/door/airlock/centcom{ name = "Crematorium"; @@ -57288,6 +57437,21 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/chapel/office) +"nnf" = ( +/obj/structure/rack, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/obj/item/clothing/glasses/science, +/obj/item/clothing/glasses/science, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) "nnh" = ( /obj/structure/chair{ dir = 8 @@ -57309,13 +57473,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) -"nqu" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 10 - }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) "nqV" = ( /obj/structure/cable{ icon_state = "1-2" @@ -57326,6 +57483,19 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"nqW" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "nsy" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -57355,14 +57525,6 @@ }, /turf/closed/wall/r_wall, /area/science/mixing) -"nsJ" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/heat_exchanging/simple, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) "ntj" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57399,6 +57561,10 @@ }, /turf/open/floor/plasteel/white/corner, /area/hallway/primary/central) +"nyN" = ( +/obj/machinery/power/supermatter_crystal/engine, +/turf/open/floor/engine, +/area/engine/supermatter) "nyO" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" @@ -57425,12 +57591,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/engine/engineering) -"nAY" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/landmark/start/station_engineer, -/turf/open/floor/plasteel, -/area/engine/engineering) "nBw" = ( /obj/machinery/computer/crew{ dir = 1 @@ -57503,6 +57663,15 @@ /obj/structure/table/reinforced, /turf/open/floor/plasteel, /area/science/xenobiology) +"nIq" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Engineering Supermatter Fore"; + dir = 4; + network = list("ss13","engine") + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "nIU" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -57526,6 +57695,17 @@ }, /turf/open/floor/engine, /area/science/explab) +"nKF" = ( +/obj/machinery/door/firedoor, +/obj/structure/sign/poster/random{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "nLl" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -57561,6 +57741,17 @@ }, /turf/open/floor/plasteel, /area/tcommsat/computer) +"nNn" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) "nNJ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57595,6 +57786,13 @@ /obj/item/chair, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"nPW" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, +/obj/machinery/meter, +/turf/closed/wall/r_wall, +/area/engine/supermatter) "nQc" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -57605,13 +57803,9 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"nRM" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/landmark/start/station_engineer, -/turf/open/floor/plasteel, +"nQf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/closed/wall/r_wall, /area/engine/engineering) "nSj" = ( /obj/structure/grille/broken, @@ -57625,16 +57819,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/lawoffice) -"nTr" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"nUQ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/engine, -/area/engine/supermatter) "nVU" = ( /obj/item/twohanded/spear, /turf/open/floor/plating, @@ -57647,6 +57831,13 @@ /obj/structure/table_frame/wood, /turf/open/floor/wood, /area/maintenance/department/engine) +"nYe" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Mix to Engine" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "nYn" = ( /obj/structure/sign/warning/docking, /obj/effect/spawner/structure/window/reinforced, @@ -57673,6 +57864,23 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"obl" = ( +/obj/structure/sign/warning/radiation, +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"obG" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/machinery/button/door{ + id = "engsm"; + name = "Radiation Shutters Control"; + pixel_y = 24; + req_access_txt = "10" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) "obP" = ( /obj/structure/table, /obj/item/paper_bin, @@ -57682,6 +57890,11 @@ initial_gas_mix = "o2=0.01;n2=0.01" }, /area/maintenance/department/science) +"ocy" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/engine/engineering) "oep" = ( /obj/structure/table/glass, /obj/item/paper_bin, @@ -57714,6 +57927,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"oge" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) "ohR" = ( /obj/item/chair, /turf/open/floor/plating, @@ -57728,6 +57945,18 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"ona" = ( +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/engineering) "onX" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -57785,6 +58014,12 @@ /obj/structure/window/reinforced, /turf/open/floor/plasteel, /area/science/xenobiology) +"oto" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "ous" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/button/door{ @@ -57807,6 +58042,14 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) +"ovE" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) "ovM" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 @@ -57832,11 +58075,17 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/office) -"oxw" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +"oxt" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/research_and_development, +/obj/item/disk/tech_disk, +/obj/item/disk/design_disk, +/turf/open/floor/plasteel/dark, +/area/science/lab) +"oyE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 }, -/obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/engine/engineering) "oyF" = ( @@ -57864,6 +58113,19 @@ }, /turf/closed/wall/r_wall, /area/science/xenobiology) +"oBY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/meter, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/engine, +/area/engine/engineering) "oCn" = ( /obj/structure/chair/office/dark{ dir = 1 @@ -57934,6 +58196,15 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"oFi" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/engine, +/area/engine/engineering) "oFo" = ( /obj/structure/closet/emcloset/anchored, /obj/structure/sign/warning/vacuum/external{ @@ -57950,23 +58221,6 @@ /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plasteel, /area/maintenance/department/engine) -"oHa" = ( -/obj/machinery/power/emitter/anchored{ - dir = 8; - state = 2 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/engine/engineering) -"oJr" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plating, -/area/engine/engineering) "oKa" = ( /obj/structure/rack, /obj/effect/spawner/lootdrop/maintenance{ @@ -57982,18 +58236,6 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) -"oKv" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/machinery/portable_atmospherics/canister/nitrogen, -/obj/effect/turf_decal/bot, -/turf/open/floor/engine, -/area/engine/engineering) -"oKJ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/engine, -/area/engine/engineering) "oLR" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -58100,6 +58342,12 @@ icon_state = "platingdmg3" }, /area/maintenance/department/security/brig) +"oTD" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/turf/open/floor/engine, +/area/engine/engineering) "oUa" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -58115,14 +58363,6 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) -"oWu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/holopad, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/engine/engineering) "oWw" = ( /obj/item/flashlight, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -58143,22 +58383,6 @@ }, /turf/open/floor/plasteel/white, /area/security/execution/transfer) -"oXq" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Cooling Loop Bypass" - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) "oYj" = ( /obj/effect/turf_decal/loading_area{ dir = 4 @@ -58171,12 +58395,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"paU" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, -/turf/open/floor/plating/airless, -/area/engine/engineering) "pbm" = ( /obj/machinery/door/airlock/external{ name = "Pod Docking Bay" @@ -58212,6 +58430,19 @@ }, /turf/open/floor/plating, /area/science/explab) +"peb" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 8 + }, +/obj/structure/window/plasma/reinforced{ + dir = 4 + }, +/obj/machinery/power/rad_collector/anchored, +/turf/open/floor/engine, +/area/engine/supermatter) "pfz" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -58232,13 +58463,12 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) -"pgH" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +"pga" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 }, -/turf/open/floor/engine, -/area/engine/engineering) +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "phJ" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -58260,13 +58490,6 @@ /obj/structure/piano, /turf/open/floor/plasteel/dark, /area/maintenance/department/crew_quarters/dorms) -"pmB" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) "pnU" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ dir = 4; @@ -58275,14 +58498,16 @@ }, /turf/open/floor/circuit/telecomms, /area/science/xenobiology) -"poP" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ +"ppi" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = 29 + }, +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/turf/open/space, -/area/space/nearstation) +/turf/open/floor/engine, +/area/engine/engineering) "pps" = ( /turf/closed/wall, /area/engine/break_room) @@ -58301,18 +58526,20 @@ }, /turf/open/floor/engine, /area/engine/supermatter) -"psd" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 2; - name = "Gas to Filter" +"ptk" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" }, -/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, -/area/engine/supermatter) -"puw" = ( -/obj/structure/sign/warning/fire, -/turf/closed/wall/r_wall, -/area/engine/supermatter) +/area/engine/engineering) +"puO" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) "pvK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -58347,17 +58574,13 @@ }, /turf/open/space/basic, /area/space/nearstation) -"pxD" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +"pBs" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "chemistry_shutters"; - name = "chemistry shutters" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/medical/chemistry) +/turf/open/floor/engine, +/area/engine/engineering) "pBD" = ( /obj/structure/cable{ icon_state = "0-8" @@ -58368,22 +58591,6 @@ /obj/machinery/shieldwallgen/xenobiologyaccess, /turf/open/floor/plating, /area/maintenance/department/engine) -"pBJ" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 10 - }, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) -"pCo" = ( -/obj/structure/reflector/single/anchored{ - dir = 6 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating, -/area/engine/engineering) "pDP" = ( /obj/machinery/vending/assist, /obj/effect/turf_decal/tile/neutral{ @@ -58440,6 +58647,29 @@ }, /turf/open/floor/wood, /area/crew_quarters/heads/hop) +"pIk" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/engine, +/area/engine/engineering) +"pJx" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/engine, +/area/engine/engineering) "pKd" = ( /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; @@ -58499,6 +58729,12 @@ dir = 1 }, /area/hallway/secondary/exit/departure_lounge) +"pPu" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/engine/engineering) "pQw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -58579,19 +58815,6 @@ /obj/structure/cable, /turf/open/floor/wood, /area/lawoffice) -"pYh" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/turf/closed/wall/r_wall, -/area/engine/engineering) -"pYw" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-03" - }, -/obj/structure/extinguisher_cabinet{ - pixel_x = -24 - }, -/turf/open/floor/plasteel/dark, -/area/science/lab) "pYC" = ( /obj/structure/sign/warning{ pixel_y = -32 @@ -58606,12 +58829,25 @@ }, /turf/open/floor/plasteel/white, /area/medical/virology) +"qbm" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "qbp" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible{ dir = 8 }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"qbV" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space) "qbZ" = ( /obj/structure/rack, /obj/item/clothing/mask/gas, @@ -58666,18 +58902,6 @@ /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plating, /area/maintenance/department/engine) -"qeY" = ( -/turf/closed/wall/r_wall, -/area/engine/supermatter) -"qhE" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) "qjx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line, @@ -58687,38 +58911,10 @@ }, /turf/open/floor/plasteel, /area/construction/mining/aux_base) -"qkM" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/engine, -/area/engine/engineering) "qnT" = ( /obj/machinery/iv_drip, /turf/open/floor/plating, /area/maintenance/department/science) -"qpd" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 8 - }, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"qpS" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) "qtA" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 @@ -58859,21 +59055,6 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/maintenance/department/science) -"qLI" = ( -/obj/structure/table, -/obj/item/stack/sheet/glass/fifty{ - layer = 4 - }, -/obj/item/stack/cable_coil, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) "qMi" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/general/visible, @@ -58910,10 +59091,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"qOS" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, +"qPh" = ( +/obj/structure/chair, +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, /area/engine/engineering) "qPB" = ( /obj/structure/chair/stool, @@ -58922,22 +59103,8 @@ }, /turf/open/floor/plasteel/dark, /area/maintenance/department/crew_quarters/dorms) -"qRl" = ( -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_x = 29 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"qTV" = ( -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_x = -27 - }, -/obj/effect/turf_decal/tile/blue{ +"qUe" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, /turf/open/floor/plasteel, @@ -58967,6 +59134,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"qWB" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "qWG" = ( /obj/structure/closet/emcloset/anchored, /turf/open/floor/plating, @@ -59045,9 +59218,8 @@ /area/medical/sleeper) "rax" = ( /obj/machinery/conveyor{ - icon_state = "conveyor_map"; dir = 1; - id = "EngLoad" + id = "garbage" }, /turf/open/floor/plating, /area/maintenance/disposal) @@ -59206,6 +59378,23 @@ }, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) +"rwf" = ( +/obj/machinery/power/emitter/anchored{ + dir = 8; + state = 2 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"rwt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/engine, +/area/engine/engineering) "rxa" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -59240,6 +59429,13 @@ icon_state = "panelscorched" }, /area/maintenance/department/engine) +"rAZ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) "rBh" = ( /obj/structure/mopbucket, /obj/item/mop, @@ -59254,6 +59450,19 @@ /obj/item/reagent_containers/blood/random, /turf/open/floor/plating, /area/maintenance/department/science) +"rEt" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "rFq" = ( /obj/structure/chair, /obj/item/reagent_containers/food/snacks/donkpocket, @@ -59261,6 +59470,24 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) +"rGz" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) +"rHv" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Monastery Transit" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/hallway/secondary/entry) "rHA" = ( /turf/open/floor/plasteel, /area/construction/mining/aux_base) @@ -59319,6 +59546,16 @@ /obj/item/ammo_casing/shotgun/improvised, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"rMt" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 27 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "rMV" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -59330,6 +59567,16 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/department/science) +"rPd" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = -27 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "rPg" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer{ dir = 8 @@ -59344,13 +59591,12 @@ /obj/item/trash/can, /turf/open/floor/wood, /area/maintenance/department/engine) -"rTd" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/yellow{ - icon_state = "4-8" +"rTZ" = ( +/obj/machinery/cryopod{ + dir = 8 }, /turf/open/floor/plasteel, -/area/engine/engineering) +/area/crew_quarters/dorms) "rWE" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -59377,6 +59623,14 @@ }, /turf/open/floor/plating, /area/storage/emergency/starboard) +"saW" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Monastery Transit" + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/hallway/secondary/entry) "sbk" = ( /obj/structure/girder, /turf/open/floor/plating, @@ -59419,6 +59673,17 @@ }, /turf/open/space, /area/space/nearstation) +"sdZ" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sfr" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible, +/turf/closed/wall/r_wall, +/area/engine/supermatter) "sgc" = ( /obj/machinery/vending/cigarette, /obj/effect/turf_decal/tile/neutral{ @@ -59433,51 +59698,23 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) -"shH" = ( -/turf/closed/wall/r_wall, -/area/space/nearstation) +"sho" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white{ + heat_capacity = 1e+006 + }, +/area/hallway/secondary/entry) "sij" = ( /obj/structure/closet, /obj/item/reagent_containers/food/snacks/meat/slab/monkey, /turf/open/floor/plating, /area/maintenance/department/engine) -"sjC" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/machinery/power/port_gen/pacman, -/turf/open/floor/plasteel, -/area/engine/engineering) "skw" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/closed/wall, /area/maintenance/department/security/brig) -"slJ" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/light{ - dir = 1; - light_color = "#d1dfff" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"smv" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "Cooling Loop to Gas" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) "spz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, @@ -59523,12 +59760,6 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard) -"svA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, -/turf/closed/wall/r_wall, -/area/engine/engineering) "svN" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/structure/sign/departments/restroom{ @@ -59536,11 +59767,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) -"swg" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) "sww" = ( /obj/effect/decal/cleanable/blood/old, /obj/item/reagent_containers/food/snacks/meat/slab/monkey, @@ -59575,6 +59801,12 @@ }, /turf/open/floor/plating, /area/security/execution/transfer) +"sAF" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/landmark/start/station_engineer, +/turf/open/floor/plasteel, +/area/engine/engineering) "sAK" = ( /obj/item/clothing/mask/gas/plaguedoctor, /turf/open/floor/plating, @@ -59612,6 +59844,17 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"sHX" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Cooling Loop to Gas" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engine/engineering) "sJp" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/effect/turf_decal/stripes/line, @@ -59633,6 +59876,21 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) +"sKw" = ( +/obj/structure/table, +/obj/item/stack/sheet/glass/fifty{ + layer = 4 + }, +/obj/item/stack/cable_coil, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "sNz" = ( /obj/structure/cable{ icon_state = "1-2" @@ -59646,6 +59904,12 @@ }, /turf/open/floor/plating, /area/security/execution/transfer) +"sOQ" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space/basic, +/area/space) "sQt" = ( /obj/machinery/door/airlock/external{ name = "Supply Dock Airlock"; @@ -59656,6 +59920,37 @@ }, /turf/open/floor/plating, /area/quartermaster/storage) +"sQG" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"sQV" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/engine, +/area/engine/engineering) +"sRH" = ( +/obj/structure/lattice, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced, +/turf/open/space, +/area/space/nearstation) +"sTg" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/lattice, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "sUP" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 @@ -59682,19 +59977,6 @@ }, /turf/open/floor/engine, /area/engine/engineering) -"sWW" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/meter, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/engine, -/area/engine/engineering) "sXi" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -59709,16 +59991,6 @@ /obj/structure/disposalpipe/segment, /turf/closed/wall/r_wall, /area/science/xenobiology) -"sYQ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "sZh" = ( /obj/structure/closet/crate, /turf/open/floor/plating, @@ -59756,13 +60028,16 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) -"tbw" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 9 +"tcC" = ( +/obj/machinery/door/firedoor, +/obj/structure/sign/poster/official/random{ + pixel_x = -32 }, -/turf/open/space, -/area/space/nearstation) +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "tcY" = ( /obj/structure/cable{ icon_state = "4-8" @@ -59810,10 +60085,6 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"tdL" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/turf/closed/wall/r_wall, -/area/engine/supermatter) "tfw" = ( /obj/structure/cable{ icon_state = "0-2"; @@ -59859,17 +60130,6 @@ }, /turf/open/floor/plasteel/white, /area/medical/sleeper) -"tkL" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/light{ - dir = 8; - light_color = "#e8eaff" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) "tlc" = ( /obj/machinery/recharger, /obj/structure/table, @@ -59888,12 +60148,14 @@ }, /turf/open/floor/engine, /area/engine/engineering) -"tlV" = ( -/obj/structure/reflector/double/anchored{ - dir = 9 +"tmi" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/engine/engineering) +/turf/open/space, +/area/space/nearstation) "tnY" = ( /obj/machinery/button/door{ id = "aux_base_shutters"; @@ -59915,15 +60177,13 @@ icon_state = "panelscorched" }, /area/maintenance/department/security/brig) -"tqO" = ( -/obj/structure/sign/poster/official/random{ - pixel_x = -32 - }, -/obj/effect/turf_decal/tile/blue{ +"tpX" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "tqX" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -59935,6 +60195,13 @@ }, /turf/open/floor/plating, /area/science/xenobiology) +"ttX" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 9 + }, +/turf/open/floor/plating, +/area/engine/engineering) "tue" = ( /obj/structure/cable{ icon_state = "2-4" @@ -59991,14 +60258,19 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"tzH" = ( -/obj/machinery/door/poddoor/shutters/preopen{ - id = "research_shutters_2"; - name = "research shutters" +"tzh" = ( +/obj/structure/chair/office/dark{ + dir = 4 }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/science/lab) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tAv" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 + }, +/turf/open/floor/plating/airless, +/area/engine/engineering) "tAK" = ( /obj/structure/table, /obj/structure/window/reinforced{ @@ -60016,13 +60288,6 @@ /obj/item/wrench, /turf/open/floor/plating, /area/maintenance/department/cargo) -"tDE" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Mix to Engine" - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "tHk" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -60038,33 +60303,13 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) -"tJr" = ( -/obj/structure/plasticflaps/opaque, -/obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "research_shutters_2"; - name = "research shutters" +"tMA" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 }, -/turf/open/floor/plasteel, -/area/science/lab) -"tLP" = ( -/obj/machinery/status_display/supply, -/turf/closed/wall, -/area/quartermaster/warehouse) -"tOD" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"tQT" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/engineering) +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "tRc" = ( /obj/structure/ore_box, /turf/open/floor/plating{ @@ -60097,6 +60342,11 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"uaa" = ( +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) "uaC" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -60109,13 +60359,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"uaO" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 6 - }, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) "uaP" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -60129,14 +60372,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/science/mixing) -"udl" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/space, -/area/space/nearstation) "uek" = ( /obj/structure/rack, /obj/effect/spawner/lootdrop/maintenance{ @@ -60165,21 +60400,27 @@ icon_state = "panelscorched" }, /area/maintenance/department/science) -"ueX" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/engineering_hacking{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/book/manual/wiki/engineering_construction, -/turf/open/floor/plasteel, -/area/engine/engineering) "ufa" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"ufr" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/plasteel, +/area/engine/atmos) +"ufx" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "research_shutters_2"; + name = "research shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/lab) "ugC" = ( /obj/structure/chair/office/light{ icon_state = "officechair_white"; @@ -60212,16 +60453,6 @@ }, /turf/closed/wall, /area/maintenance/department/engine) -"ukp" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "Mix to Gas" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/engine, -/area/engine/engineering) "ulu" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -60284,13 +60515,12 @@ "uoS" = ( /turf/open/floor/plating, /area/construction/mining/aux_base) -"upc" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ +"upg" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 6 }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "uqJ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -60359,44 +60589,17 @@ }, /turf/open/floor/circuit/telecomms, /area/science/xenobiology) +"uwT" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "uwX" = ( /obj/machinery/field/generator, /turf/open/floor/plating, /area/maintenance/department/engine) -"uxP" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/obj/structure/chair{ - dir = 8; - name = "Defense" - }, -/obj/machinery/camera{ - c_tag = "Atmospherics Starboard"; - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"uzh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber"; - req_access_txt = "10" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/engine, -/area/engine/supermatter) "uzn" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable{ @@ -60410,6 +60613,10 @@ }, /turf/open/floor/plasteel, /area/tcommsat/computer) +"uAL" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "uAU" = ( /obj/structure/table/wood, /obj/item/folder/blue, @@ -60431,6 +60638,11 @@ }, /turf/open/floor/engine, /area/science/explab) +"uBu" = ( +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/chapel/monastery) "uCS" = ( /obj/machinery/door/poddoor/shutters{ id = "aux_base_shutters"; @@ -60439,6 +60651,16 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"uDr" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"uER" = ( +/turf/closed/wall/r_wall, +/area/space/nearstation) "uHG" = ( /obj/structure/cable{ icon_state = "1-4" @@ -60451,12 +60673,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"uIB" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/engine/engineering) "uLF" = ( /obj/structure/cable{ icon_state = "1-4" @@ -60493,6 +60709,12 @@ /obj/effect/turf_decal/plaque, /turf/open/floor/plating, /area/maintenance/department/engine) +"uQa" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engine/supermatter) "uQR" = ( /obj/item/ammo_casing/shotgun/beanbag, /turf/open/floor/plating, @@ -60532,6 +60754,14 @@ /obj/item/stamp/law, /turf/open/floor/carpet, /area/lawoffice) +"uWe" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 2; + name = "External Gas to Loop" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/engine, +/area/engine/engineering) "uXG" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -60554,12 +60784,28 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard) +"uZs" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "vay" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plating, /area/maintenance/department/engine) +"vbQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) +"vdb" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "veM" = ( /obj/machinery/suit_storage_unit/rd, /obj/machinery/light{ @@ -60577,6 +60823,15 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"vfn" = ( +/obj/structure/plasticflaps/opaque, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "research_shutters_2"; + name = "research shutters" + }, +/turf/open/floor/plasteel, +/area/science/lab) "vgp" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -60594,6 +60849,14 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) +"vgX" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/space, +/area/space/nearstation) "vhk" = ( /obj/structure/chair, /turf/open/floor/carpet, @@ -60607,31 +60870,6 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) -"vli" = ( -/obj/structure/table, -/obj/item/clothing/glasses/meson/engine, -/obj/item/clothing/glasses/meson/engine, -/obj/item/clothing/glasses/meson/engine, -/obj/item/pipe_dispenser, -/obj/item/pipe_dispenser, -/obj/item/pipe_dispenser, -/obj/machinery/light, -/obj/effect/turf_decal/delivery, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/engineering) -"vlC" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/engineering) "vlF" = ( /obj/item/coin/silver, /obj/effect/decal/cleanable/oil{ @@ -60666,20 +60904,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"voh" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ - dir = 5 - }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"vor" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/engine/engineering) "vpz" = ( /obj/structure/girder, /turf/open/floor/plating{ @@ -60697,31 +60921,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"vsw" = ( -/obj/machinery/camera{ - c_tag = "Engineering Supermatter Starboard"; - dir = 8; - network = list("ss13","engine") - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) -"vsG" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance{ - name = "Research Lab Maintenance"; - req_access_txt = "0"; - req_one_access_txt = "7;29" - }, -/turf/open/floor/plating, -/area/maintenance/department/engine) "vsJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ @@ -60755,6 +60954,13 @@ /obj/item/clothing/mask/gas, /turf/open/floor/plating, /area/maintenance/department/science) +"vvr" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) "vxp" = ( /obj/machinery/door/window/eastright{ base_state = "left"; @@ -60768,17 +60974,12 @@ /obj/item/assembly/mousetrap, /turf/open/floor/engine, /area/science/explab) -"vxr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/light{ - dir = 4; - light_color = "#e8eaff" - }, -/obj/effect/turf_decal/stripes/line{ +"vyN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel, -/area/engine/engineering) +/turf/closed/wall/r_wall, +/area/crew_quarters/heads/hor) "vzz" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -60789,15 +60990,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) -"vzA" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "vzP" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, @@ -60828,19 +61020,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"vBE" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/light{ - dir = 1; - light_color = "#d1dfff" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/engineering) "vCC" = ( /obj/structure/cable{ icon_state = "4-8" @@ -60866,16 +61045,36 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"vKq" = ( -/obj/machinery/door/firedoor, -/obj/structure/sign/poster/official/random{ +"vIn" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"vIU" = ( +/obj/structure/transit_tube/horizontal, +/obj/structure/sign/departments/holy{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/blue{ +/turf/open/floor/plating, +/area/hallway/secondary/entry) +"vJS" = ( +/obj/structure/closet/radiation, +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, /turf/open/floor/plasteel, -/area/hallway/primary/aft) +/area/engine/engineering) +"vMv" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/chapel/main/monastery) "vMx" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -60885,6 +61084,19 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"vMH" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"vMQ" = ( +/obj/structure/sign/warning/fire, +/turf/closed/wall/r_wall, +/area/engine/supermatter) "vOw" = ( /obj/machinery/door/airlock/grunge{ name = "Library" @@ -60899,6 +61111,13 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/library) +"vPU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "vRi" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -60967,16 +61186,20 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) -"vVO" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/obj/structure/cable/yellow{ - icon_state = "2-8" +"vYi" = ( +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, -/turf/open/floor/engine, -/area/engine/engineering) +/obj/machinery/door/airlock/maintenance{ + name = "Research Lab Maintenance"; + req_access_txt = "0"; + req_one_access_txt = "7;29" + }, +/turf/open/floor/plating, +/area/maintenance/department/engine) "vYN" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8; @@ -60986,22 +61209,16 @@ }, /turf/open/floor/circuit/telecomms, /area/science/xenobiology) -"wbB" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 2; - name = "External Gas to Loop" +"waN" = ( +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/engine, -/area/engine/engineering) -"wbF" = ( -/obj/machinery/rnd/production/circuit_imprinter, -/obj/machinery/camera{ - c_tag = "Engineering Starboard Aft"; - dir = 8 +/obj/structure/rack, +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/turf/open/floor/plasteel, -/area/engine/engineering) +/area/maintenance/department/chapel/monastery) "wcs" = ( /turf/open/floor/plasteel/dark, /area/engine/engineering) @@ -61038,24 +61255,10 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) -"wfG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/crew_quarters/heads/hor) "wfO" = ( /mob/living/simple_animal/hostile/retaliate/poison/snake, /turf/open/floor/plating, /area/maintenance/department/engine) -"wfP" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/machinery/meter, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/engineering) "wig" = ( /obj/machinery/vending/cigarette, /turf/open/floor/plating{ @@ -61070,22 +61273,14 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "wjm" = ( -/obj/structure/cable{ +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/effect/turf_decal/stripes/line{ + dir = 6 }, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/engine, /area/engine/engineering) "wkZ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -61114,6 +61309,27 @@ }, /turf/open/floor/plasteel/white, /area/science/explab) +"wlZ" = ( +/obj/machinery/light/small, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) +"wmA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) +"wnw" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "wnJ" = ( /obj/structure/sign/warning, /turf/closed/wall, @@ -61147,6 +61363,17 @@ }, /turf/open/floor/wood, /area/lawoffice) +"wsx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "wun" = ( /obj/structure/cable{ icon_state = "1-2" @@ -61174,6 +61401,9 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"wwK" = ( +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "wxb" = ( /obj/structure/cable{ icon_state = "4-8" @@ -61221,15 +61451,21 @@ }, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/bar) -"wDl" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/corner, -/turf/open/floor/plasteel, -/area/engine/engineering) "wDm" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"wDH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/obj/item/tank/internals/plasma, +/turf/open/floor/plating, +/area/engine/supermatter) "wDZ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 @@ -61257,18 +61493,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) -"wHI" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, -/turf/open/floor/plating, -/area/engine/engineering) -"wIo" = ( -/obj/machinery/atmospherics/pipe/heat_exchanging/simple, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) "wIv" = ( /obj/machinery/power/apc/highcap/five_k{ dir = 8; @@ -61303,12 +61527,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/heads/cmo) -"wLK" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "wMF" = ( /obj/effect/spawner/lootdrop/three_course_meal, /obj/effect/spawner/lootdrop/three_course_meal, @@ -61324,10 +61542,6 @@ /obj/structure/grille, /turf/open/floor/plating, /area/maintenance/department/engine) -"wMX" = ( -/obj/effect/spawner/structure/window/plasma/reinforced, -/turf/open/floor/plating, -/area/engine/supermatter) "wNq" = ( /obj/structure/cable{ icon_state = "1-4" @@ -61398,6 +61612,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"wSU" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/hallway/secondary/entry) "wTD" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -61440,6 +61660,16 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"wXe" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber"; + req_access_txt = "10" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/engine, +/area/engine/supermatter) "wXu" = ( /obj/machinery/disposal/bin, /obj/structure/window/reinforced{ @@ -61457,10 +61687,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"wYK" = ( -/obj/machinery/power/supermatter_crystal/engine, -/turf/open/floor/engine, -/area/engine/supermatter) "xah" = ( /obj/structure/cable{ icon_state = "1-2" @@ -61508,18 +61734,15 @@ /obj/structure/sign/warning/vacuum/external, /turf/open/floor/plating, /area/hallway/secondary/exit/departure_lounge) -"xer" = ( -/obj/machinery/conveyor{ - dir = 2; - id = "garbage" - }, -/turf/open/floor/plating, -/area/maintenance/disposal) "xeB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/lawoffice) +"xgB" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/closed/wall/r_wall, +/area/engine/engineering) "xgG" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -61544,12 +61767,11 @@ dir = 1 }, /area/hallway/secondary/exit/departure_lounge) -"xhI" = ( -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/engine/engineering) +"xiY" = ( +/obj/structure/lattice, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "xja" = ( /obj/machinery/light/small{ dir = 4 @@ -61597,10 +61819,34 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"xkf" = ( +/obj/effect/landmark/carpspawn, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) +"xkL" = ( +/obj/structure/table, +/obj/item/clothing/suit/hooded/wintercoat/engineering, +/obj/item/clothing/glasses/meson, +/obj/item/clothing/glasses/meson, +/obj/item/clothing/glasses/meson, +/obj/effect/turf_decal/delivery, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) "xlA" = ( /obj/machinery/door/airlock/maintenance/abandoned, /turf/open/floor/plating, /area/maintenance/department/science) +"xlY" = ( +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/maintenance/department/chapel/monastery) "xmp" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -61655,6 +61901,20 @@ /obj/item/broken_bottle, /turf/open/floor/plating, /area/maintenance/solars/port) +"xuW" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"xvK" = ( +/obj/structure/reflector/single/anchored{ + dir = 6 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/engine/engineering) "xvO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -61712,6 +61972,10 @@ icon_state = "panelscorched" }, /area/maintenance/department/security/brig) +"xyT" = ( +/obj/machinery/light/small, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "xzp" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -61719,13 +61983,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) -"xzR" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/engine/engineering) "xCV" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -61779,6 +62036,7 @@ dir = 1; light_color = "#ffc1c1" }, +/obj/effect/landmark/start/lawyer, /turf/open/floor/wood, /area/lawoffice) "xKc" = ( @@ -61809,13 +62067,6 @@ /obj/structure/disposalpipe/junction/flip, /turf/open/space/basic, /area/space/nearstation) -"xNy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engine/engineering) "xOC" = ( /obj/machinery/door/airlock/external{ name = "Construction Zone"; @@ -61858,6 +62109,12 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"xVT" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "xWl" = ( /obj/item/pen, /obj/item/paper_bin{ @@ -61869,6 +62126,10 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) +"xXh" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "ybX" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance, @@ -61906,6 +62167,21 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"yjy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) +"ykV" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/plasteel, +/area/engine/atmos) "ymb" = ( /obj/machinery/camera{ c_tag = "Engineering Telecomms Access"; @@ -75967,7 +76243,7 @@ cfN bOw bOw bOw -bOw +bQg bOw ccu cbG @@ -76224,7 +76500,7 @@ bOw bOw bOw bOw -bOw +bQg bUC bOw cbG @@ -76476,12 +76752,12 @@ bOv bNs bNs bWh -bOw -bOw -bOw -bOw -bOw -bOw +bQg +bQg +bQg +bQg +bQg +bQg bOw bOw cbG @@ -76732,7 +77008,7 @@ bQQ bNs bNs bQe -bOw +bQg bOw bOw bOw @@ -76989,7 +77265,7 @@ bNs bNs bOw bOw -bOw +bQg bOw bOw bOw @@ -77246,7 +77522,7 @@ bOw bOw bOw bOw -bOw +bQg bOw bOw bOw @@ -77503,7 +77779,7 @@ bOw bOw bOw bOw -bOw +bQg bOw bOw bUC @@ -77520,7 +77796,7 @@ ctL cgg cfE cfE -cfp +cua cfE cuW cfE @@ -77759,8 +78035,8 @@ bOw bOw bOw bOw -bOw -bOw +bQg +bQg bOw bWV bWV @@ -78016,7 +78292,7 @@ bOw bOw bOw bOw -bOw +bQg bOw bOw bWV @@ -78273,7 +78549,7 @@ bOw bQd bOw bQd -bOw +bQg bQd bWV bWV @@ -78530,7 +78806,7 @@ bOw bQe bOw bOw -bOw +bQg bQe bWV bXJ @@ -78790,7 +79066,7 @@ bQf bQf bQf bWW -bXI +vMv bZn bZn bZn @@ -79032,10 +79308,10 @@ bGG bHL bIW bKc -bOy +cqI bMt bLn -bOy +cqI bPo bQg bQg @@ -79301,7 +79577,7 @@ bOw bQe bOw bOw -bOw +bQg bQe bWV bXJ @@ -79558,7 +79834,7 @@ bOw bQd bOw bQd -bOw +bQg bWi bWV bWV @@ -79785,7 +80061,7 @@ aaa aaa aaa aaa -aaa +btK aaa aaa aaa @@ -79815,7 +80091,7 @@ bOw bOw bOw bOw -bOw +bQg bOw bOw bWV @@ -80040,9 +80316,9 @@ aaa aaa aaa aaa -aZx -aZx -aZx +iaZ +bsl +btL aZx aaa aaa @@ -80056,11 +80332,11 @@ aaa aaa aaa aaa -aaa -bGI +irs +aqG bGE bKf -bLn +gvO bMw bNy bNw @@ -80072,7 +80348,7 @@ bOw bSm bOw bOw -bOw +bQg bOw bOw bWV @@ -80297,9 +80573,9 @@ aaa aaa aaa aaa +iaZ aZx -baJ -bon +bcX aZx aaa aaa @@ -80312,12 +80588,12 @@ aaa aaa aaa aaa -aaa -aaa -bGI +irs +irs +aqG bGE -bKg -bLn +bKf +gvO bMx bNz bHM @@ -80329,7 +80605,7 @@ bOw bOw bOw bOw -bOw +bQg bOw bOw bOw @@ -80344,7 +80620,7 @@ ccJ cdw cel ceM -cfp +cua cfE cfE chn @@ -80555,8 +80831,8 @@ aaa jzz aZx jzz -baK -bon +bsl +btM aZx aaa aaa @@ -80568,17 +80844,17 @@ aaa aaa aaa aaa -aaa -aaa -aaa -bGI -bHM -bGE +irs +irs +irs +aqG bGE +jOX +beT bHM bNA bHM -abI +bSZ bQi bQR bNs @@ -80586,7 +80862,7 @@ bNs bOw bOw bOw -bOw +bQg bOw bOw bOw @@ -80611,8 +80887,8 @@ cvc cho cvk cdx -cvc -cvM +euN +csS cfm cwe fWv @@ -80818,23 +81094,23 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -bIY -bIY -bLs -bMy +mZE +bVp +bVp +bVp +bVp +bVp +gLn +sTg +gLn +gLn +eOA +aZx +llS +kYR +aZx bNB -bMy +hRQ abI aby abI @@ -80843,15 +81119,15 @@ bNs bNs bNs bOw -bOw -bOw -bOw -bOw -bOw -bOw -bOw -bOw -bOw +bQg +bQg +bQg +bQg +bQg +bQg +bQg +bQg +bQg bQg cbR bXJ @@ -80869,7 +81145,7 @@ ciF cuQ cfm cfm -cfm +fwo cfm cwe ckp @@ -81075,29 +81351,29 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aby -aby -aaa -aaa +bGI +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +llS +sho +aZx amC aaa aht aby aby abI -bSn -bSZ +mfg +sRH cqS bNs bQe @@ -81108,8 +81384,8 @@ bQg bQg bQg bOw -bOw -ccL +bQe +bQg bWV csT cen @@ -81126,7 +81402,7 @@ chq ciX cfm cfN -cfN +cwA cfN cwe cwe @@ -81332,21 +81608,21 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +bGI +aZx +jkm +tpX +iHI +iHI +iHI +tpX +iHI +hWa +wwK +wSU +llS +wmA +aZx amB aht aht @@ -81355,7 +81631,7 @@ aaa abI abI abI -abI +sRH bNs bNs bNs @@ -81366,7 +81642,7 @@ bXL bNs bOw bOw -bOw +bQg bWV csU bWV @@ -81383,7 +81659,7 @@ chr chL cfm cfN -cfN +xyT cfN cfN cfN @@ -81589,21 +81865,21 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +bGI +aZx +oto +wwK +wwK +wwK +uAL +vbQ +vbQ +vbQ +vbQ +vbQ +vbQ +pga +aZx amC aaa aht @@ -81613,7 +81889,7 @@ aaa aaa abI aaa -aaa +sOQ bQR bNs bNs @@ -81623,7 +81899,7 @@ bXM bNs bOw bOw -bOw +bQg bOw ccM cdD @@ -81640,7 +81916,7 @@ chs ciY cfm cfN -cfN +cwA cfN cfN cfN @@ -81846,21 +82122,21 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +bGI +aZx +oto +wwK +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx +aZx amB aht aht @@ -81880,12 +82156,12 @@ bXN bNs bOw bOw -bOw -bOw -bOw -bQe -bOw -bOw +bQg +bQg +bQg +bQg +bQg +bQg cfL cfm cfm @@ -81897,7 +82173,7 @@ cht cfm cfm cfN -cfN +cwA cfN cfN cfN @@ -82103,21 +82379,21 @@ aZx aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aqG +aZx +oto +wwK +aZx +irs +irs +irs +irs +irs +irs +irs +irs +irs +irs amD aaa aht @@ -82140,10 +82416,10 @@ bOw bUC bOw bOw -bOw +bQe bOw bUC -cfM +bQg cfm cgO chu @@ -82154,7 +82430,7 @@ chu ciZ cfm cfN -cfN +cwA cfN cfN cfN @@ -82359,12 +82635,12 @@ bon aZx aaa aaa -btK -aaa -aaa -aaa -aaa -aaa +irs +aqG +aZx +oto +wwK +aZx bBV bDf bDf @@ -82411,8 +82687,8 @@ cfm cfm cfm cfN -cfN -cfN +cwA +cjm cfN cfN cfN @@ -82615,16 +82891,16 @@ bnp bon aZx aZx -bsl -btL aZx -aaa -aaa -aaa +aZx +aZx +aZx +oto +kvx bAI -bBW +qbV abI -aaa +irs abI aaa bva @@ -82650,11 +82926,11 @@ abI ahi bSZ crO -crO -crO -crO -crO -crO +arF +arF +arF +arF +arF crO crO crO @@ -82668,8 +82944,8 @@ cfN cfN cfN cfN -cfN -cfN +wlZ +cjm cfN cfN aaa @@ -82802,7 +83078,7 @@ aeU afo afG aeU -eSB +gHy agy agL agZ @@ -82872,12 +83148,12 @@ bnp baK bbR bbR +bbR +bbR +bbR aZx -bcX -aZx -aYG -aZx -aYG +rHv +saW bAJ bBX bBX @@ -82925,9 +83201,9 @@ cfN cfN cfN cfN -cfN -cfN -aaa +uaa +cjm +irs aaa aaa aaa @@ -83129,13 +83405,13 @@ bnq baM baK baK -bsl -btM +baK +baK +baK aZx -aYG bxY bzz -bAK +vIU bBX bDg bEj @@ -83169,23 +83445,23 @@ caZ cbS ccN bIZ -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cjm +cjm +cjm +cjm +cjm +cjm +cjm +cjm +cjm cfN cfN cfN cfN -aaa -aaa -aaa -aaa +uBu +cjm +cjm +irs aaa aaa aaa @@ -83316,7 +83592,7 @@ lGp aeU afI aeU -jXF +dUk agy agN agY @@ -83425,24 +83701,24 @@ bIZ cba cbT bDi -bIZ -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cQZ +cwA +cwA +cwA +cwA +lqo +cwA +cwA +cwA +cwA +uaa +ovE +uaa +uBu +xlY +ezo +cjm +aht aaa aaa aaa @@ -83683,23 +83959,23 @@ cbb bDi ccO bIZ -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cjm +cjm +xXh +xXh +cjm +cjm +cjm +xXh +xXh +cjm +cjm +cjm +cjm +waN +dzA +cjm +aht aaa aaa aaa @@ -83940,23 +84216,23 @@ bva bNK bva bva -aaa -cFB -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +irs +xkf +dRs +dRs +aht +aht +mau +fon +fon +aht +aht +aht +cjm +cjm +cjm +cjm +aht aaa aaa aaa @@ -84209,11 +84485,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +dRs +dRs +irs +irs +xiY aaa aaa aaa @@ -88820,9 +89096,9 @@ eQN tcY cam cam -sjC +cdI bXk -mci +eVW cbX ceq mhl @@ -89077,7 +89353,7 @@ bpL fQf cbW cbd -cdI +gaQ cri cbX cbX @@ -90615,9 +90891,9 @@ bXh bXZ bYK bZz -nAY +sAF cbd -nRM +fGt cam cdM bXq @@ -90627,8 +90903,8 @@ cfQ bXk qWG bXk -paU -dSp +tAv +pPu cdm aaa aht @@ -90880,22 +91156,22 @@ qtO bXk bXk bXk -svA -mjK -mjK -mjK -wHI -eyj -eyj +fbu +nQf +nQf +nQf +cgt +oge +oge bXk -shH -shH -shH -shH -shH -shH -shH -shH +uER +uER +uER +uER +uER +uER +uER +uER fon fon mau @@ -91127,23 +91403,23 @@ bVH bWr bXj qGZ -bYQ +bYM bZD caj cbf ccb cah cdO -ioF +jOw ceX -qOS +ocy cfS fFv -fmL -gXZ -kmd -lXJ -lXJ +yjy +nIq +mAi +abD +abD bXk aaa aht @@ -91396,10 +91672,10 @@ mwG nAs cfT wcs -ggg +upg qbp qbp -gEo +hUi dMG bXk aaa @@ -91643,14 +91919,14 @@ bXk bYc bYO bZA -xhI +dlI cbh cbh cbh cbh cbh -hjD -vor +nNn +mvA cfU tIS iCs @@ -91900,21 +92176,21 @@ bXk bYd bYP bZF -rTd -wDl -vxr -irM -irM +uZs +lDW +wsx +uwT +uwT qFu cet ulY cfV cgu cgU -izm +kNK chw -eyj -jzE +oge +eMz bXk bXk bXk @@ -92155,31 +92431,31 @@ bVK bWu bXk bYe -bYQ +bYM bZA can cbi ccc -eyj +oge cdR -tQT +vvr bXk bXk -sWW +oBY cgv -lXb +ndf cgv uaP cgv -ukp +ikm cgV cgv cgv -gQf +gkN bXk aht fon -shH +uER fon aaa aaa @@ -92416,27 +92692,27 @@ bYR bZA can cbj -eyj +oge cbX wcs iyJ cfa -eyj +oge twv -hoS +pJx sWj dnS -hSC -jTU -fZK -pgH -pgH +rEt +mZK +nqW +pBs +pBs uRk ciG bXk aaa fon -shH +uER fon aaa aaa @@ -92672,7 +92948,7 @@ bYf bYS bZA can -qpS +eue ccd ccX ccX @@ -92680,20 +92956,20 @@ ceu cbX cfu tlN -ncm +pIk cCI uoq -hQy +wDH chA meF -oKv -wbB -xzR +oTD +uWe +dHF hQC bXk aht fon -shH +uER fon aht aaa @@ -92894,7 +93170,7 @@ bmz bnG boN bpW -dHZ +brk bsK buk bvs @@ -92930,27 +93206,27 @@ bYT bZB caq cbk -eyj +oge ccY cdT ccY cbX -eyj -vlC -iej -qeY +oge +jQn +sQV +dFF fyO fyO fyO -qeY -oKv -wbB -wfP +dFF +oTD +uWe +dGd hQC bXk aaa fon -shH +uER fon aaa aaa @@ -93186,28 +93462,28 @@ bYh bYU bZE car -mgz -eyj +sdZ +oge cbX wcs wcs cfd bXk tlN -ncm -lUO +pIk +obl mpd -hKp -hKp +peb +peb cit -qeY -puw -vBE +dFF +vMQ +gih hQC bXk aht fon -shH +uER fon aaa aaa @@ -93408,7 +93684,7 @@ bkh bkh boN bpW -brk +dVt bsM bum bvt @@ -93449,22 +93725,22 @@ cda wcs wcs wcs -eyj -eAH -lnr -qeY -fBZ -fBZ -fBZ +oge +oFi +wjm +dFF +uQa +uQa +uQa cgY ciI -tdL -dHr +mZV +obG hQC bXk aaa fon -shH +uER fon aaa aaa @@ -93645,7 +93921,7 @@ aSS aUg aVf aWi -mjn +eyT aYe aZb bag @@ -93668,8 +93944,8 @@ bpV brm bsN bun -gGA -bwW +mcf +nnf byA bAi bpY @@ -93698,30 +93974,30 @@ bWz bVN bYf bYW -oWu +hDy cam -vli +cxj ckJ cey cdW wcs cdW -eyj -kTR -mEu -wMX -dFJ -wYK -dFJ -uzh -nUQ -fym -hon +oge +vPU +eux +kDI +fWE +nyN +fWE +wXe +iTE +mlS +jTc hQC bXk aht fon -shH +uER fon aaa aaa @@ -93925,12 +94201,12 @@ bpY bpY bpY bpY -pxD -jZG +gGA +bwW bpY bpY bpY -vsG +vYi bva bva bva @@ -93957,28 +94233,28 @@ bUT bYX bZA cam -lfx +xkL bXk -pCo +xvK wcs wcs -tlV -eyj -qkM -miw -qeY +kBe +oge +mlx +gUS +dFF prQ prQ prQ -dgj -psd -fxC +nPW +mvY +sfr dZj hQC bXk aaa fon -shH +uER fon aaa aaa @@ -94178,17 +94454,17 @@ bls aBI aBI bmB -vKq -nTr -gDR -vzA +tcC +qWB +iHe +qbm bvu -hIZ -tqO -mqp -cKV -iwe -qTV +wnw +cep +ePS +nhW +rGz +rPd xDj blt jCv @@ -94211,31 +94487,31 @@ bVO bWA mCe bYj -bYQ +bYM bZA cam -mgz -eyj +sdZ +oge cbX wcs wcs -dEy +hxh bXk tlN -ncm -puw +pIk +vMQ fyF cZt cZt -fjD -qeY -iTF -slJ +hUf +dFF +mLc +lmv hQC bXk aht fon -shH +uER fon aaa aaa @@ -94443,11 +94719,11 @@ gkS tTl tTl tTl -koz +qUe dgg phJ phJ -lJI +lCY bAk bIt bJB @@ -94468,31 +94744,31 @@ bVP bWB mCe bYk -wjm +bYQ bZF cbm -mgz -eyj -oHa -oHa +sdZ +oge +rwf +rwf eWi cbX -eyj -vlC +oge +jQn cgx -qeY +dFF fyO fyO fyO -qeY +dFF cBS cjt -kaR +mCP hQC bXk aaa fon -shH +uER fon aht aaa @@ -94692,19 +94968,19 @@ blu aDZ aDZ bjm -mhn +nKF cqi cqi cqi cqi cqi -imE -kYM -mfC +erV +rMt +ksC fdQ bmD bmD -eRp +jrb bAl bIu bJC @@ -94728,28 +95004,28 @@ bYl bYO bZA cam -lrM +lCR ccd -cAQ -cAQ -cLw +mlb +mlb +mbD cbX cfu jBn -oxw +ptk meF chA chA woh cCI cBS -iLh +rwt liR hQC bXk aht fon -shH +uER fon aaa aaa @@ -94952,18 +95228,18 @@ bKM cCl cCl cCl -tJr -tzH -tzH +vfn +ufx +ufx byD bAm dhz -uxP +nkk bDA bEQ bGa -bHp -sYQ +bHg +mVj bJD bBo bBo @@ -94986,27 +95262,27 @@ bYY bZA cam cbn -eyj +oge cbX wcs cfP cff -eyj +oge cfX -vVO -iop +kvu +gHp kWQ -oXq -qpd -tkL -tOD -tOD -ikO +iSi +ona +kec +ngg +ngg +cUT hQC bXk aaa fon -shH +uER fon aaa aaa @@ -95207,14 +95483,14 @@ bmC cqi boP bqb -pYw +brp gFo cSK duF -bxa +oxt byE bBp -wfG +vyN bBp bBp bBp @@ -95244,22 +95520,22 @@ bZG cax cbo ccc -eyj +oge cdR -oJr +uDr bXq bXq cfY -xNy -smv -xNy -hGB -hSt +hrx +sHX +hrx +hXm +jjA civ civ -vsw -qRl -oKJ +jtv +ppi +oyE bXk aht fon @@ -95501,19 +95777,19 @@ bZF cal cbp cci -kTj -kTj -qhE -loz -frj -lRX -eyj -uIB -eyj -eyj -uIB -eyj -eyj +dPZ +dPZ +vMH +vJS +vIn +ttX +oge +dGp +oge +oge +dGp +oge +oge bXk bXk bXk @@ -95753,24 +96029,24 @@ bVU bWG bXq bYo -hXK +tzh bZI -hXK +tzh cbq cbd cam cam cam -haA -aKm -upc -wIo -hyh -upc -voh -pBJ -wIo -voh +mCU +cOA +gfh +vdb +rAZ +gfh +tMA +puO +vdb +tMA cdm aaa aaa @@ -96011,23 +96287,23 @@ bWH bXk bTE bZc -ueX +nif cCU bZJ -wbF +mdi cCV ceb -epV -qLI -aKm -eiV -upc -dsz -eiV -eiV -uaO -voh -eiV +qPh +sKw +cOA +sQG +gfh +eqM +sQG +sQG +dhu +tMA +sQG cdm aaa aaa @@ -96267,29 +96543,29 @@ bJN bJN bJN bJN -frj -pYh -pYh -pYh -pYh -pYh -pYh -pYh -pYh -hUw -nqu -nsJ -gBb -nsJ -nsJ -gBb -nsJ -nsJ -dsz +vIn +xgB +xgB +xgB +xgB +xgB +xgB +xgB +xgB +fml +mfx +hJO +dAa +hJO +hJO +dAa +hJO +hJO +eqM aht aht fon -shH +uER fon aaa aaa @@ -96524,7 +96800,7 @@ bVV bWI bXr bKQ -udl +vgX bZK abI abI @@ -96533,20 +96809,20 @@ abI aaa aaa aaa -uaO -wIo -nsJ -gBb -nsJ -nsJ -gBb -nsJ -nsJ -hyh +dhu +vdb +hJO +dAa +hJO +hJO +dAa +hJO +hJO +rAZ aaa aaa fon -shH +uER fon aaa aaa @@ -96781,7 +97057,7 @@ bQI bWJ bXs bJN -cui +lxh bJP bJP bJP @@ -96790,20 +97066,20 @@ bJP abI abI aht -pBJ -wIo -nsJ -gBb -nsJ -nsJ -gBb -nsJ -nsJ -dsz +puO +vdb +hJO +dAa +hJO +hJO +dAa +hJO +hJO +eqM aht aht fon -shH +uER fon aaa aaa @@ -97018,7 +97294,7 @@ bCK bDG bEW bAt -bHg +aIA cqw cqD bKO @@ -97038,7 +97314,7 @@ bMf fuR bXt bYp -eAZ +jPC bZL caz cbs @@ -97047,20 +97323,20 @@ bJP aaa aaa aaa -uaO -wIo -nsJ -gBb -nsJ -nsJ -gBb -nsJ -nsJ -hyh +dhu +vdb +hJO +dAa +hJO +hJO +dAa +hJO +hJO +rAZ aaa aaa fon -shH +uER fon aaa aaa @@ -97295,7 +97571,7 @@ bVW bWL bXu bLW -cui +lxh bMi caA cbt @@ -97304,20 +97580,20 @@ bJP aaa aaa aaa -pBJ -swg -hyh -pBJ -hyh -pBJ -hyh -pBJ -hyh +puO +xuW +rAZ +puO +rAZ +puO +rAZ +puO +rAZ cdm aht aht fon -shH +uER fon aaa aaa @@ -97552,7 +97828,7 @@ bVX bWM bXv bWc -poP +tmi bZL caB cbs @@ -97789,7 +98065,7 @@ bAt bAt bAu bAu -bHp +bHg cqx bJJ bKQ @@ -97804,12 +98080,12 @@ bQI bQI bTM bUs -ljG -hjk -pmB +cAp +ykV +ufr bXw -dJk -tbw +iSL +lQy bJP bJP bJP @@ -98061,7 +98337,7 @@ bMf bMf bTN bUt -wLK +flP bOk bWK bXt @@ -98317,8 +98593,8 @@ bRx bQJ bPQ bTO -ljG -lhP +cAp +xVT bOk bWL bXx @@ -98332,21 +98608,21 @@ bJP aaa aaa fon -shH -shH -shH -shH -shH -shH -shH -shH -shH -shH +uER +uER +uER +uER +uER +uER +uER +uER +uER +uER fon aaa aht -shH -shH +uER +uER fon aaa aaa @@ -98574,7 +98850,7 @@ bPQ bPQ bPQ bTP -wLK +flP bVh bVY bWM @@ -98602,7 +98878,7 @@ fon fon aaa aht -shH +uER fon fon aaa @@ -98831,7 +99107,7 @@ bQK bQK bPQ bTQ -wLK +flP bKX bOk bWN @@ -99088,7 +99364,7 @@ bRy bSf bSR bTM -wLK +flP bKX bVZ bWO @@ -99345,7 +99621,7 @@ bRz bMf bSS bTR -tDE +nYe bKX bWa bMf @@ -99802,7 +100078,7 @@ aHn aIi aJi aKe -klb +kVA aMi aNJ fwl @@ -100840,7 +101116,7 @@ lAs eeQ aUs aLf -eex +lfZ aLf aLf aUl @@ -101105,7 +101381,7 @@ aTm bbE bbE bbE -dps +bbE bbE bbE aEj @@ -101364,7 +101640,7 @@ bcA bdF beJ bfB -bbE +gaJ aZv aUC biz @@ -102101,7 +102377,7 @@ apX apX avl fIu -epj +rTZ aIh azA dbi @@ -102635,7 +102911,7 @@ aNP aPb aNO aNP -tLP +cRJ aTq aSk aTm @@ -107513,7 +107789,7 @@ aaa aaa aLn aNT -xer +rax aQo aPg aRu @@ -107771,7 +108047,7 @@ aaa aLm aLm aNU -aNV +hCg dqY aRv sZh @@ -108027,8 +108303,8 @@ aaa aaa aLm aME -eFG aNV +hCg dqY aRw sqQ @@ -108284,8 +108560,8 @@ aaa aaa aLo aMF -aNV -aNV +aNW +hCg cvf aQn sqQ @@ -108542,7 +108818,7 @@ aaa aLo aMG aNX -aNV +hCg rax aRy aSn diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 7a591a48fa..3bdf64ac27 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -41,7 +41,7 @@ /area/engine/gravity_generator) "am" = ( /obj/machinery/atmospherics/components/unary/tank/air, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "an" = ( /obj/structure/lattice/catwalk, @@ -124,6 +124,8 @@ dir = 5 }, /obj/structure/cable, +/obj/machinery/power/port_gen/pacman/super, +/obj/item/stack/sheet/mineral/uranium, /turf/open/floor/plasteel, /area/engine/gravity_generator) "au" = ( @@ -351,7 +353,7 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aY" = ( /obj/machinery/light{ @@ -431,7 +433,7 @@ icon_state = "1-2" }, /obj/machinery/door/airlock, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "bl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -447,9 +449,9 @@ /turf/open/floor/plating, /area/engine/atmos) "bo" = ( -/obj/structure/table, -/obj/item/screwdriver/power, -/obj/item/wirecutters/power, +/obj/structure/closet/secure_closet/atmospherics{ + locked = 0 + }, /turf/open/floor/plasteel, /area/engine/engineering) "bp" = ( @@ -508,7 +510,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/engineering) "by" = ( /turf/closed/wall/r_wall, @@ -658,13 +660,13 @@ /obj/structure/cable{ icon_state = "0-2" }, -/mob/living/carbon/human, /obj/effect/turf_decal/tile/blue{ dir = 4 }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/mob/living/carbon/human, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -673,20 +675,20 @@ /obj/machinery/light{ dir = 1 }, -/mob/living/carbon/human, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/mob/living/carbon/human, /turf/open/floor/plasteel/white/corner{ dir = 1 }, /area/medical/medbay) "bW" = ( /obj/machinery/camera/autoname, -/mob/living/carbon/human, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/mob/living/carbon/human, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -730,7 +732,7 @@ icon_state = "4-8" }, /obj/machinery/door/airlock, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/bridge) "ce" = ( /obj/structure/cable{ @@ -895,7 +897,7 @@ /area/medical/medbay) "cz" = ( /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/medical/medbay) "cA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -1280,7 +1282,7 @@ /area/storage/primary) "dH" = ( /obj/machinery/door/airlock, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/maintenance/department/bridge) "dI" = ( /obj/effect/landmark/start, @@ -1309,6 +1311,8 @@ /area/construction) "dN" = ( /obj/structure/table, +/obj/item/warpwhistle, +/obj/item/voodoo, /turf/open/floor/plasteel, /area/storage/primary) "dO" = ( @@ -1337,7 +1341,7 @@ "dS" = ( /obj/machinery/atmospherics/components/unary/tank/air, /obj/machinery/camera/autoname, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "dT" = ( /obj/machinery/camera/autoname, @@ -1429,7 +1433,7 @@ name = "Mining Dock Airlock" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/quartermaster/miningoffice) "ef" = ( /obj/machinery/door/airlock, @@ -1484,7 +1488,7 @@ name = "Arrival Airlock" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/hallway/secondary/entry) "ep" = ( /obj/structure/cable{ @@ -1543,7 +1547,7 @@ name = "Escape Pod One" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/hallway/secondary/entry) "ey" = ( /obj/machinery/status_display/supply, @@ -1576,6 +1580,9 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "eC" = ( @@ -1659,6 +1666,9 @@ /area/storage/primary) "eL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "eM" = ( @@ -1800,6 +1810,9 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "fe" = ( @@ -1822,6 +1835,7 @@ dir = 8 }, /obj/effect/turf_decal/bot, +/obj/item/export_scanner, /turf/open/floor/plasteel, /area/quartermaster/storage) "ff" = ( @@ -1911,6 +1925,7 @@ /obj/machinery/computer/cargo/express{ dir = 4 }, +/obj/item/disk/cargo/bluespace_pod, /turf/open/floor/plasteel, /area/quartermaster/storage) "fs" = ( @@ -1918,7 +1933,7 @@ name = "Transport Airlock" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/hallway/secondary/entry) "ft" = ( /obj/machinery/door/airlock, @@ -1928,7 +1943,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/hallway/primary/central) "fu" = ( /obj/structure/cable{ @@ -2135,7 +2150,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/storage/primary) "fO" = ( /turf/open/floor/plasteel, @@ -2236,12 +2251,6 @@ }, /turf/open/floor/plasteel, /area/quartermaster/storage) -"fZ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/hallway/secondary/entry) "ga" = ( /turf/closed/wall/r_wall, /area/hallway/secondary/exit/departure_lounge) @@ -2256,7 +2265,7 @@ name = "Auxiliary Airlock" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/hallway/secondary/entry) "gd" = ( /obj/effect/spawner/structure/window/reinforced, @@ -2513,6 +2522,26 @@ /obj/item/paper/guides/jobs/security/labor_camp, /turf/open/floor/plasteel, /area/security/brig) +"gM" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) +"gR" = ( +/obj/machinery/power/apc{ + dir = 1; + pixel_y = 25 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hydroponics) "gY" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -2539,6 +2568,15 @@ }, /turf/open/floor/plasteel, /area/science) +"jt" = ( +/obj/machinery/smartfridge, +/turf/open/floor/grass, +/area/hydroponics) +"jw" = ( +/obj/machinery/power/rtg/abductor, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/space/nearstation) "jE" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -2550,6 +2588,26 @@ /obj/item/melee/transforming/energy/axe, /turf/open/floor/plasteel, /area/storage/primary) +"kf" = ( +/obj/machinery/vending/hydroseeds, +/turf/open/floor/grass, +/area/hydroponics) +"kk" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/space, +/area/space/nearstation) "kn" = ( /obj/machinery/light{ dir = 1 @@ -2559,6 +2617,14 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"kG" = ( +/obj/machinery/vending/hydronutrients, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/grass, +/area/hydroponics) "kQ" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -2575,6 +2641,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"kT" = ( +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) "lg" = ( /obj/structure/cable{ icon_state = "4-8" @@ -2590,6 +2660,14 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"mI" = ( +/obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, +/area/hydroponics) +"nb" = ( +/obj/structure/filingcabinet/chestdrawer/wheeled, +/turf/open/floor/plasteel, +/area/quartermaster/storage) "ny" = ( /obj/structure/table, /obj/item/storage/toolbox/syndicate, @@ -2597,7 +2675,7 @@ /area/storage/primary) "ou" = ( /obj/machinery/airalarm/directional/west, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "oV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -2610,12 +2688,20 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/science) +"pF" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/reagentgrinder/constructed, +/obj/structure/table/reinforced, +/turf/open/floor/grass, +/area/hydroponics) "pI" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, /obj/machinery/door/airlock/external/glass, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/medical/medbay) "pQ" = ( /obj/structure/cable{ @@ -2625,7 +2711,7 @@ /area/medical/chemistry) "qb" = ( /obj/machinery/door/airlock, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "qn" = ( /obj/structure/cable{ @@ -2633,11 +2719,55 @@ }, /turf/open/floor/plating, /area/maintenance/department/bridge) +"qZ" = ( +/obj/structure/lattice, +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/space, +/area/space/nearstation) +"rN" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) +"sD" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/closet/secure_closet/warden{ + locked = 0 + }, +/turf/open/floor/plasteel, +/area/bridge) "sE" = ( /obj/machinery/power/rtg/advanced, /obj/structure/cable, /turf/open/floor/plating/airless, /area/space/nearstation) +"sN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"sP" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"up" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "ut" = ( /obj/structure/closet/secure_closet/atmospherics{ locked = 0 @@ -2645,15 +2775,40 @@ /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "vm" = ( /turf/closed/wall/r_wall, /area/maintenance/aft) +"vs" = ( +/obj/machinery/door/airlock, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) "vv" = ( /obj/machinery/door/airlock, /turf/open/floor/plating, /area/storage/primary) +"vG" = ( +/obj/machinery/biogenerator, +/turf/open/floor/grass, +/area/hydroponics) +"vH" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"vN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) "vP" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2676,6 +2831,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"wf" = ( +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) "wS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2685,6 +2844,48 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"wT" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"wX" = ( +/obj/structure/chair/stool/bar, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) +"xh" = ( +/obj/structure/closet/secure_closet/hydroponics, +/turf/open/floor/grass, +/area/hydroponics) +"xj" = ( +/turf/open/floor/plasteel, +/area/hydroponics) +"yl" = ( +/obj/structure/chair/stool/bar, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) +"yt" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/crew_quarters/bar) +"yM" = ( +/obj/machinery/vending/wallmed, +/turf/closed/wall/r_wall, +/area/hallway/secondary/entry) +"yO" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "zo" = ( /obj/machinery/power/apc/auto_name/south, /obj/structure/cable{ @@ -2732,6 +2933,10 @@ "Ce" = ( /turf/open/floor/plasteel, /area/medical/chemistry) +"Cr" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/crew_quarters/cafeteria) "Ct" = ( /obj/structure/closet/syndicate/resources/everything, /turf/open/floor/plasteel, @@ -2743,6 +2948,30 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/medical/chemistry) +"Dh" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"DH" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/hydroponics) +"DJ" = ( +/obj/structure/kitchenspike, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) +"Em" = ( +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) "EI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -2751,6 +2980,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/closet/secure_closet/quartermaster{ + locked = 0 + }, /turf/open/floor/plasteel, /area/bridge) "ES" = ( @@ -2762,6 +2994,37 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"Fg" = ( +/turf/open/floor/plasteel, +/area/engine/atmos) +"Fy" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/grass, +/area/hydroponics) +"Ga" = ( +/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"Gc" = ( +/obj/structure/closet/secure_closet/miner/unlocked, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"Go" = ( +/obj/structure/closet/wardrobe/cargotech, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"Hn" = ( +/obj/structure/beebox, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/queen_bee/bought, +/turf/open/floor/grass, +/area/hydroponics) "If" = ( /obj/machinery/rnd/production/techfab/department, /turf/open/floor/plasteel, @@ -2776,12 +3039,35 @@ }, /turf/open/floor/plasteel, /area/bridge) +"IB" = ( +/obj/structure/chair/stool/bar, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) "JF" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel, /area/medical/chemistry) +"JJ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hydroponics) +"JV" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) "Kx" = ( /obj/structure/table, /obj/item/analyzer, @@ -2789,10 +3075,55 @@ /obj/machinery/light, /turf/open/floor/plating, /area/engine/atmos) +"Lg" = ( +/obj/machinery/door/airlock/external{ + name = "Labor Camp Shuttle Airlock" + }, +/obj/structure/fans/tiny, +/turf/open/floor/plasteel, +/area/security/brig) +"Lo" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) "Ly" = ( /obj/machinery/chem_dispenser/chem_synthesizer, /turf/open/floor/plasteel/dark, /area/medical/chemistry) +"Mk" = ( +/obj/structure/table, +/obj/item/book_of_babel, +/obj/item/book/granter/action/origami, +/obj/item/book/granter/action/drink_fling, +/turf/open/floor/plasteel, +/area/storage/primary) +"MH" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + dir = 1; + pixel_y = 25 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/bar) +"MQ" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) +"MS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hydroponics) "MY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -2800,6 +3131,27 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) +"Nw" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "0-2"; + pixel_y = 1 + }, +/obj/machinery/power/apc{ + dir = 1; + pixel_y = 25 + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) +"NC" = ( +/turf/closed/wall/r_wall, +/area/crew_quarters/cafeteria) +"NL" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/mining, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "NZ" = ( /obj/machinery/rnd/production/protolathe/department, /turf/open/floor/plasteel, @@ -2808,16 +3160,26 @@ /obj/item/disk/tech_disk/debug, /turf/open/floor/plasteel, /area/science) +"PD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "PI" = ( /obj/structure/fans/tiny/invisible, /turf/open/space/basic, /area/space) +"PV" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "Qt" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, /obj/machinery/door/airlock/external/glass, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/medical/medbay) "Rb" = ( /obj/effect/spawner/structure/window/reinforced, @@ -2830,6 +3192,9 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) +"Si" = ( +/turf/open/floor/plasteel, +/area/crew_quarters/bar) "Sj" = ( /obj/structure/table/optable, /obj/effect/turf_decal/tile/blue{ @@ -2837,9 +3202,37 @@ }, /turf/open/floor/plasteel/white/corner, /area/medical/medbay) +"Sv" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/plantgenes/seedvault, +/turf/open/floor/grass, +/area/hydroponics) +"SC" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) +"SF" = ( +/obj/machinery/chem_dispenser/mutagensaltpeter, +/obj/item/reagent_containers/glass/beaker/bluespace, +/obj/item/reagent_containers/glass/beaker/bluespace, +/obj/item/reagent_containers/glass/beaker/bluespace, +/turf/open/floor/grass, +/area/hydroponics) +"Tp" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/power/rtg/abductor, +/turf/open/floor/plating/airless, +/area/space/nearstation) "Tt" = ( /turf/open/floor/plating, /area/maintenance/aft) +"TZ" = ( +/turf/closed/wall/r_wall, +/area/crew_quarters/bar) "Ut" = ( /obj/structure/closet/secure_closet/medical3{ locked = 0 @@ -2911,7 +3304,7 @@ /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "Yy" = ( /obj/machinery/light{ @@ -2924,10 +3317,26 @@ }, /turf/open/floor/plasteel, /area/science) +"YB" = ( +/turf/open/floor/plasteel/freezer, +/area/crew_quarters/cafeteria) "ZD" = ( /obj/machinery/suit_storage_unit/ce, /turf/open/floor/plasteel, /area/engine/atmos) +"ZO" = ( +/turf/closed/wall/r_wall, +/area/hydroponics) +"ZR" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/space/basic, +/turf/open/floor/carpet/blackred, +/area/crew_quarters/bar) (1,1,1) = {" aa @@ -5368,13 +5777,13 @@ en ek eh dY -aa -aa -aa -aa -aa -aa -aa +DH +DH +DH +DH +DH +DH +ZO aa aa aa @@ -5460,13 +5869,13 @@ en ek eh en -aa -aa -aa -aa -aa -aa -aa +Hn +mI +mI +mI +mI +xh +DH aa aa aa @@ -5552,13 +5961,13 @@ en ek eh dY -aa -aa -aa -aa -aa -aa -aa +gR +JJ +xj +xj +xj +xj +DH aa aa aa @@ -5644,13 +6053,13 @@ dY gC eh dY -aa -aa -aa -aa -aa -aa -aa +pF +MS +vG +SF +xj +kf +DH aa aa aa @@ -5736,13 +6145,13 @@ en ek eh dY -aa -aa -aa -aa -aa -aa -aa +Sv +MS +Fy +jt +xj +kG +ZO aa aa aa @@ -5801,7 +6210,7 @@ di bw ag bw -di +Lg bw ag ag @@ -5827,14 +6236,14 @@ dY dY ek eh -dY -aa -aa -aa -aa -aa -aa -aa +yM +vH +sN +Si +Si +Si +kT +TZ aa aa aa @@ -5920,13 +6329,13 @@ eh ek eh dY -aa -aa -aa -aa -aa -aa -aa +vH +vN +wf +wf +wf +Si +yt aa aa aa @@ -6009,16 +6418,16 @@ eL eL eL eL -fZ -eh -dY -aa -aa -aa -aa -aa -aa -aa +fd +eL +vs +JV +ZR +MQ +Lo +gM +Si +yt aa aa aa @@ -6104,13 +6513,13 @@ eh eh eh ge -aa -aa -aa -aa -aa -aa -aa +MH +IB +yl +wX +IB +Si +yt aa aa aa @@ -6196,13 +6605,13 @@ fI dY dY ge -aa -aa -aa -aa -aa -aa -aa +Ga +Dh +sP +Em +wT +kT +TZ aa aa aa @@ -6256,10 +6665,10 @@ aa aa ah ut -aw +Fg ou -aw -aw +Fg +Fg Kx ah bs @@ -6287,14 +6696,14 @@ cN Tt vm fg -aa -aa -aa -aa -aa -aa -aa -aa +NC +NC +YB +PD +up +YB +YB +NC aa aa aa @@ -6380,13 +6789,13 @@ Tt vm fg aa -aa -aa -aa -aa -aa -aa -aa +NC +Nw +rN +yO +YB +YB +NC aa aa aa @@ -6472,13 +6881,13 @@ Tt vm fg aa -aa -aa -aa -aa -aa -aa -aa +NC +PV +NL +SC +SC +DJ +NC aa aa aa @@ -6564,13 +6973,13 @@ Tt vm fg aa -aa -aa -aa -aa -aa -aa -aa +NC +NC +Cr +NC +Cr +NC +NC aa aa aa @@ -7084,11 +7493,11 @@ aa aa ae ab -ab -ab -aB -ab -ab +Tp +qZ +kk +qZ +jw ab bv bJ @@ -7175,13 +7584,13 @@ aa aa aa ae -ac -ac +ab +ab ab aB ab -ac -ac +ab +ab bv bK cf @@ -7277,7 +7686,7 @@ ac bv bL cf -cq +sD bv cD bE @@ -8306,7 +8715,7 @@ dJ dJ dJ dJ -dN +Mk cS gH fO @@ -8669,7 +9078,7 @@ cS cS cS fN -vv +dG cS cS cS @@ -8764,9 +9173,9 @@ eZ eu fq fr -eu -eu -eu +nb +Go +Gc et aa aa diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index d005f1eb40..f2e0599ae6 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -8394,6 +8394,9 @@ /turf/open/floor/plating, /area/syndicate_mothership) "tg" = ( +/obj/machinery/shower{ + dir = 4 + }, /obj/item/soap/syndie, /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) @@ -9837,7 +9840,7 @@ id = "XCCFerry"; name = "Hanger Bay Shutters"; pixel_y = 24; - req_access_txt = "2" + req_access_txt = "101" }, /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -11383,6 +11386,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/item/paicard, /turf/open/floor/plasteel/dark, /area/centcom/ferry) "AM" = ( @@ -11581,6 +11585,11 @@ }, /turf/open/floor/plasteel/white, /area/centcom/holding) +"Bp" = ( +/obj/item/paicard, +/obj/structure/table/wood, +/turf/open/floor/engine/cult, +/area/wizard_station) "Bs" = ( /obj/structure/table/wood, /obj/machinery/computer/libraryconsole/bookmanagement, @@ -15116,7 +15125,7 @@ /obj/structure/table/wood, /obj/item/book/manual/wiki/barman_recipes, /obj/item/reagent_containers/food/drinks/shaker, -/obj/item/reagent_containers/glass/rag, +/obj/item/reagent_containers/rag, /obj/machinery/newscaster{ pixel_y = -32 }, @@ -17428,6 +17437,8 @@ /obj/structure/mirror{ pixel_x = -28 }, +/obj/structure/table, +/obj/item/reagent_containers/rag/towel/syndicate, /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) "Rm" = ( @@ -25222,7 +25233,7 @@ lI lI lI Ax -qZ +EW qZ qZ Ax @@ -25480,7 +25491,7 @@ lI lI Ax ra -qZ +Bf qZ tX qZ @@ -25736,7 +25747,7 @@ lI lI lI Ax -qZ +Bp qZ qZ Ax diff --git a/_maps/shuttles/pirate_default.dmm b/_maps/shuttles/pirate_default.dmm index 445c29241c..1c8670d5b6 100644 --- a/_maps/shuttles/pirate_default.dmm +++ b/_maps/shuttles/pirate_default.dmm @@ -239,6 +239,23 @@ }, /turf/open/floor/plasteel, /area/shuttle/pirate) +"as" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel, +/area/shuttle/pirate) +"at" = ( +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel, +/area/shuttle/pirate) "au" = ( /obj/machinery/door/airlock/hatch{ id_tag = "piratebridgebolt"; @@ -314,6 +331,13 @@ }, /turf/open/floor/plasteel, /area/shuttle/pirate) +"aA" = ( +/obj/structure/closet/secure_closet/personal, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, +/obj/item/bedsheet/pirate, +/turf/open/floor/wood, +/area/shuttle/pirate) "aB" = ( /obj/machinery/light/small{ dir = 4 @@ -408,12 +432,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/shuttle/pirate) -"aM" = ( -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/wood, -/area/shuttle/pirate) "aN" = ( /obj/machinery/light/small, /obj/machinery/button/door{ @@ -1022,12 +1040,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/shuttle/pirate) -"mD" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, -/area/shuttle/pirate) "mU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/engineering{ @@ -1172,15 +1184,6 @@ }, /turf/open/floor/wood, /area/shuttle/pirate) -"Ur" = ( -/obj/structure/closet/secure_closet/personal, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/shuttle/pirate) (1,1,1) = {" af @@ -1231,7 +1234,7 @@ aq ar aj RY -aM +aA ep aH af @@ -1406,9 +1409,9 @@ af af af aj -mD +as bB -Ur +at aj aj aj diff --git a/_maps/shuttles/ruin_pirate_cutter.dmm b/_maps/shuttles/ruin_pirate_cutter.dmm index 4e36ea9edf..424436f1b3 100644 --- a/_maps/shuttles/ruin_pirate_cutter.dmm +++ b/_maps/shuttles/ruin_pirate_cutter.dmm @@ -1,7 +1,81 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/obj/structure/bed, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -26 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark/side{ + dir = 6 + }, +/area/shuttle/caravan/pirate) +"ab" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/machinery/turretid{ + icon_state = "control_kill"; + lethal = 1; + locked = 0; + pixel_y = -30; + req_access = null + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/mob/living/simple_animal/hostile/pirate/ranged{ + environment_smash = 0 + }, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) +"ac" = ( +/obj/structure/bed, +/obj/machinery/airalarm/all_access{ + dir = 4; + pixel_x = -24 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) +"ad" = ( +/obj/effect/decal/cleanable/dirt, +/mob/living/simple_animal/hostile/pirate/ranged{ + environment_smash = 0 + }, +/turf/open/floor/plasteel, +/area/shuttle/caravan/pirate) +"ae" = ( +/obj/structure/rack, +/obj/item/storage/bag/money/vault, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/mob/living/simple_animal/parrot{ + faction = list("pirate"); + name = "Pegwing" + }, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) "af" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/caravan/pirate) +"ag" = ( +/obj/machinery/light/small, +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/turf/open/floor/plasteel/dark, +/area/shuttle/caravan/pirate) "aE" = ( /obj/structure/closet{ name = "pirate outfits" @@ -89,18 +163,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"fS" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/obj/machinery/airalarm/all_access{ - dir = 4; - pixel_x = -24 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "fU" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/red, @@ -223,18 +285,6 @@ dir = 1 }, /area/shuttle/caravan/pirate) -"ku" = ( -/obj/structure/rack, -/obj/item/storage/bag/money/vault, -/mob/living/simple_animal/parrot{ - faction = list("pirate"); - name = "Pegwing" - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "kY" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -502,13 +552,6 @@ /obj/item/reagent_containers/food/drinks/bottle/rum, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"tM" = ( -/mob/living/simple_animal/hostile/pirate/ranged{ - environment_smash = 0 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, -/area/shuttle/caravan/pirate) "ul" = ( /obj/structure/table, /obj/item/retractor, @@ -535,17 +578,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, /area/shuttle/caravan/pirate) -"vq" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -26 - }, -/turf/open/floor/plasteel/dark/side{ - dir = 6 - }, -/area/shuttle/caravan/pirate) "vW" = ( /obj/machinery/light/small{ dir = 4 @@ -734,32 +766,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"EB" = ( -/obj/structure/chair/office/dark{ - dir = 4 - }, -/obj/machinery/turretid{ - icon_state = "control_kill"; - lethal = 1; - locked = 0; - pixel_y = -30; - req_access = null - }, -/mob/living/simple_animal/hostile/pirate/ranged{ - environment_smash = 0 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "EK" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -1018,12 +1024,6 @@ }, /turf/open/floor/plasteel/dark, /area/shuttle/caravan/pirate) -"Wb" = ( -/obj/machinery/light/small, -/obj/structure/bed, -/obj/item/bedsheet/brown, -/turf/open/floor/plasteel/dark, -/area/shuttle/caravan/pirate) "Xq" = ( /obj/structure/table/reinforced, /obj/machinery/recharger, @@ -1181,7 +1181,7 @@ su Ag af jo -tM +ad sr af af @@ -1253,9 +1253,9 @@ Jv af aE SF -vq +aa NM -fS +ac RC oF af @@ -1272,7 +1272,7 @@ hZ wZ de iF -Wb +ag af Jv Jv @@ -1286,7 +1286,7 @@ xg qC pK Sk -ku +ae af qo Jv @@ -1374,7 +1374,7 @@ Jv Jv Bi oO -EB +ab bd Bi Jv diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index e35defd485..b2f05fd5f8 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -38,5 +38,5 @@ //Gangshit #define NOT_DOMINATING -1 -#define MAX_LEADERS_GANG 3 +#define MAX_LEADERS_GANG 4 #define INITIAL_DOM_ATTEMPTS 3 diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 2abe0db04e..da5981ff8a 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -12,7 +12,7 @@ #define ui_boxcraft "EAST-4:22,SOUTH+1:6" #define ui_boxarea "EAST-4:6,SOUTH+1:6" #define ui_boxlang "EAST-5:22,SOUTH+1:6" -#define ui_boxvore "EAST-4:22,SOUTH+1:6" +#define ui_boxvore "EAST-5:22,SOUTH+1:6" //Filters #define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, border=0, color="#04080F") @@ -40,7 +40,7 @@ #define BALLS_SACK_SIZE_DEF 8 #define BALLS_SACK_SIZE_MAX 40 -#define CUM_RATE 5 +#define CUM_RATE 0.035 #define CUM_RATE_MULT 1 #define CUM_EFFICIENCY 1//amount of nutrition required per life() @@ -115,22 +115,21 @@ //xenobio console upgrade stuff #define XENOBIO_UPGRADE_MONKEYS 1 -#define XENOBIO_UPGRADE_SLIMEBASIC 2 +#define XENOBIO_UPGRADE_SLIMEBASIC 2 #define XENOBIO_UPGRADE_SLIMEADV 4 //stamina stuff -#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement -#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit -#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations +#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement +#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit +#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations #define STAMINA_CRIT_TRADITIONAL -40 //ditto, but for STAMINA_CRIT -#define MIN_MELEE_STAMCOST 1.25 //Minimum cost for swinging items around. Will be extra useful when stats and skills are introduced. #define CRAWLUNDER_DELAY 30 //Delay for crawling under a standing mob //Citadel toggles because bitflag memes -#define MEDIHOUND_SLEEPER 1 -#define EATING_NOISES 2 -#define DIGESTION_NOISES 4 +#define MEDIHOUND_SLEEPER (1<<0) +#define EATING_NOISES (1<<1) +#define DIGESTION_NOISES (1<<2) #define TOGGLES_CITADEL (EATING_NOISES|DIGESTION_NOISES) diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index de9c7af221..06c3c352ca 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -3,26 +3,35 @@ #define COLOR_INPUT_DISABLED "#F0F0F0" #define COLOR_INPUT_ENABLED "#D3B5B5" -//#define COLOR_WHITE "#EEEEEE" -//#define COLOR_SILVER "#C0C0C0" -//#define COLOR_GRAY "#808080" +#define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A" +#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#ce4242" +#define COLOR_DARKMODE_BACKGROUND "#202020" +#define COLOR_DARKMODE_DARKBACKGROUND "#171717" +#define COLOR_DARKMODE_TEXT "#f0f0f0" + +#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90b3dd" +#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#ef7f7f" +#define COLOR_WHITEMODE_BACKGROUND "#ffffff" +#define COLOR_WHITEMODE_DARKBACKGROUND "#eeeeee" +#define COLOR_WHITEMODE_TEXT "#000000" + #define COLOR_FLOORTILE_GRAY "#8D8B8B" #define COLOR_ALMOST_BLACK "#333333" -//#define COLOR_BLACK "#000000" +#define COLOR_BLACK "#000000" #define COLOR_RED "#FF0000" -//#define COLOR_RED_LIGHT "#FF3333" -//#define COLOR_MAROON "#800000" +#define COLOR_RED_LIGHT "#FF3333" +#define COLOR_MAROON "#800000" #define COLOR_YELLOW "#FFFF00" -//#define COLOR_OLIVE "#808000" -//#define COLOR_LIME "#32CD32" +#define COLOR_OLIVE "#808000" +#define COLOR_LIME "#32CD32" #define COLOR_GREEN "#008000" #define COLOR_CYAN "#00FFFF" -//#define COLOR_TEAL "#008080" +#define COLOR_TEAL "#008080" #define COLOR_BLUE "#0000FF" -//#define COLOR_BLUE_LIGHT "#33CCFF" -//#define COLOR_NAVY "#000080" +#define COLOR_BLUE_LIGHT "#33CCFF" +#define COLOR_NAVY "#000080" #define COLOR_PINK "#FFC0CB" -//#define COLOR_MAGENTA "#FF00FF" +#define COLOR_MAGENTA "#FF00FF" #define COLOR_PURPLE "#800080" #define COLOR_ORANGE "#FF9900" #define COLOR_BEIGE "#CEB689" diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 7cab82149d..e31d2a278e 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -183,4 +183,16 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BODY_ZONE_PRECISE_R_FOOT "r_foot" //We will round to this value in damage calculations. -#define DAMAGE_PRECISION 0.1 \ No newline at end of file +#define DAMAGE_PRECISION 0.1 + +//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25) +#define TOTAL_MASS_TINY_ITEM 1.25 +#define TOTAL_MASS_SMALL_ITEM 2.5 +#define TOTAL_MASS_NORMAL_ITEM 3.75 +#define TOTAL_MASS_BULKY_ITEM 5 +#define TOTAL_MASS_HUGE_ITEM 6.25 +#define TOTAL_MASS_GIGANTIC_ITEM 7.5 + +#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway. +#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds. +#define TOTAL_MASS_TOY_SWORD 1.5 diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 210bdf57a6..40aea24105 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -24,7 +24,7 @@ // start global signals with "!", this used to be necessary but now it's just a formatting choice #define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) #define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) - +#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) ////////////////////////////////////////////////////////////////// // /datum signals @@ -73,6 +73,8 @@ #define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) #define COMPONENT_BLOCK_REACH 1 #define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) +#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin) + #define COMPONENT_BLOCK_TELEPORT 1 ///////////////// #define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost) #define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user) @@ -131,6 +133,16 @@ #define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) #define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) #define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () +#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) + #define COMPONENT_UPPERCASE_SPEECH 1 + // used to access COMSIG_MOB_SAY argslist + #define SPEECH_MESSAGE 1 + // #define SPEECH_BUBBLE_TYPE 2 + #define SPEECH_SPANS 3 + /* #define SPEECH_SANITIZE 4 + #define SPEECH_LANGUAGE 5 + #define SPEECH_IGNORE_SPAM 6 + #define SPEECH_FORCED 7 */ // /mob/living signals #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) @@ -147,6 +159,7 @@ #define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) #define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) + // /obj/item signals #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index ee51fb6909..c394d003d8 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -109,3 +109,5 @@ #define RCD_AIRLOCK 2 #define RCD_DECONSTRUCT 3 #define RCD_WINDOWGRILLE 4 +#define RCD_MACHINE 8 +#define RCD_COMPUTER 16 \ No newline at end of file diff --git a/code/__DEFINES/donator_groupings.dm b/code/__DEFINES/donator_groupings.dm new file mode 100644 index 0000000000..4b210609f2 --- /dev/null +++ b/code/__DEFINES/donator_groupings.dm @@ -0,0 +1,18 @@ +#define DONATOR_GROUP_TIER_1_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_1_donators +#define DONATOR_GROUP_TIER_2_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_2_donators +#define DONATOR_GROUP_TIER_3_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_3_donators + +#define DONATOR_GROUP_TIER_1_CONFIG_SUBPATH keyed_list/donator_group/tier_1_donators +#define DONATOR_GROUP_TIER_2_CONFIG_SUBPATH keyed_list/donator_group/tier_2_donators +#define DONATOR_GROUP_TIER_3_CONFIG_SUBPATH keyed_list/donator_group/tier_3_donators + +#define TIER_1_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_1_CONFIG_SUBPATH) +#define TIER_2_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_2_CONFIG_SUBPATH) +#define TIER_3_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_3_CONFIG_SUBPATH) + +//flags +#define DONATOR_GROUP_TIER_1 "T1" +#define DONATOR_GROUP_TIER_2 "T2" +#define DONATOR_GROUP_TIER_3 "T3" + +#define IS_CKEY_DONATOR_GROUP(ckey, groupid) is_donator_group(ckey, groupid) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 60148e0388..d64fa30047 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -7,7 +7,8 @@ //for convenience #define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) #define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) -#define CHECK_BITFIELD(variable, flag) (variable & flag) +#define CHECK_BITFIELD(variable, flag) (variable & (flag)) +#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 03cfde802f..24d381d1a8 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -28,6 +28,7 @@ #define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets. #define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets. #define ITEM_SLOT_NECK (1<<13) +#define ITEM_SLOT_SUITSTORE (1<<14) //SLOTS #define SLOT_BACK 1 @@ -52,6 +53,7 @@ #define SLOT_LEGCUFFED 19 #define SLOT_GENERC_DEXTROUS_STORAGE 20 + #define SLOTS_AMT 20 // Keep this up to date! //I hate that this has to exist @@ -84,6 +86,8 @@ . = ITEM_SLOT_ICLOTHING if(SLOT_L_STORE, SLOT_R_STORE) . = ITEM_SLOT_POCKET + if(SLOT_S_STORE) + . = ITEM_SLOT_SUITSTORE //Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. @@ -230,3 +234,6 @@ GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list( /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy))) + +//Internals checker +#define GET_INTERNAL_SLOTS(C) list(C.head, C.wear_mask) diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 55131a26ed..2ba5012301 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -16,6 +16,8 @@ #define INVESTIGATE_EXONET "exonet" #define INVESTIGATE_NANITES "nanites" #define INVESTIGATE_CIRCUIT "circuit" +#define INVESTIGATE_FERMICHEM "fermichem" +#define INVESTIGATE_RCD "rcd" // Logging types for log_message() #define LOG_ATTACK (1 << 0) diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm new file mode 100644 index 0000000000..cb4a433211 --- /dev/null +++ b/code/__DEFINES/melee.dm @@ -0,0 +1,10 @@ +//Martial arts defines + +#define MARTIALART_BOXING "boxing" +#define MARTIALART_WRESTLING "wrestling" +#define MARTIALART_SLEEPINGCARP "sleeping carp" +#define MARTIALART_PSYCHOBRAWL "psychotic brawling" +#define MARTIALART_MUSHPUNCH "mushroom punch" +#define MARTIALART_KRAVMAGA "krav maga" +#define MARTIALART_CQC "CQC" +#define MARTIALART_PLASMAFIST "plasma fist" \ No newline at end of file diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index fc8e7dda2f..c71780e7e9 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -57,7 +57,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define BODYPARTS_LAYER 28 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag #define MARKING_LAYER 27 //Matrixed body markings because clashing with snouts? #define BODY_ADJ_LAYER 26 //certain mutantrace features (snout, body markings) that must appear above the body parts -#define GENITALS_ADJ_LAYER 25 +#define GENITALS_FRONT_LAYER 25 //Draws some genitalia above clothes and the TAUR body if need be. #define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup) #define FRONT_MUTATIONS_LAYER 23 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes) #define DAMAGE_LAYER 22 //damage indicators (cuts and burns) @@ -69,7 +69,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define EARS_LAYER 17 #define BODY_TAUR_LAYER 16 #define SUIT_LAYER 15 -#define GENITALS_FRONT_LAYER 14 //Draws some genitalia above clothes and the TAUR body if need be. #define GLASSES_LAYER 13 #define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt? #define SUIT_STORE_LAYER 11 @@ -83,7 +82,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define HANDS_LAYER 3 #define BODY_FRONT_LAYER 2 #define FIRE_LAYER 1 //If you're on fire -#define TOTAL_LAYERS 31 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_; +#define TOTAL_LAYERS 30 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_; //Human Overlay Index Shortcuts for alternate_worn_layer, layers //Because I *KNOW* somebody will think layer+1 means "above" @@ -275,10 +274,6 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE)) GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_SKIN_ALT = 'icons/obj/pda_alt.dmi', PDA_SKIN_RUGGED = 'icons/obj/pda_rugged.dmi', PDA_SKIN_MODERN = 'icons/obj/pda_modern.dmi')) -//Color Defines -#define OOC_COLOR "#002eb8" -#define AOOC_COLOR "#b8002e" - ///////////////////////////////////// // atom.appearence_flags shortcuts // ///////////////////////////////////// @@ -382,6 +377,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define CLOCK_SILICONS 22 #define CLOCK_PROSELYTIZATION 23 #define SHUTTLE_HIJACK 24 +#define GANG_VICTORY 25 #define FIELD_TURF 1 #define FIELD_EDGE 2 @@ -458,6 +454,13 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define SUMMON_GUNS "guns" #define SUMMON_MAGIC "magic" +#define TELEPORT_CHANNEL_BLUESPACE "bluespace" //Classic bluespace teleportation, requires a sender but no receiver +#define TELEPORT_CHANNEL_QUANTUM "quantum" //Quantum-based teleportation, requires both sender and receiver, but is free from normal disruption +#define TELEPORT_CHANNEL_WORMHOLE "wormhole" //Wormhole teleportation, is not disrupted by bluespace fluctuations but tends to be very random or unsafe +#define TELEPORT_CHANNEL_MAGIC "magic" //Magic teleportation, does whatever it wants (unless there's antimagic) +#define TELEPORT_CHANNEL_CULT "cult" //Cult teleportation, does whatever it wants (unless there's holiness) +#define TELEPORT_CHANNEL_FREE "free" //Anything else + //Run the world with this parameter to enable a single run though of the game setup and tear down process with unit tests in between #define TEST_RUN_PARAMETER "test-run" //Force the log directory to be something specific in the data/logs folder @@ -492,4 +495,4 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define PREF_SAVELOAD_COOLDOWN 5 #define VOMIT_TOXIC 1 -#define VOMIT_PURPLE 2 \ No newline at end of file +#define VOMIT_PURPLE 2 diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index 9f8d310193..c0aac36415 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -28,4 +28,6 @@ #define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER" #define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER" -#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER" \ No newline at end of file +#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER" + +#define MOVESPEED_ID_SANITY "MOOD_SANITY" diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index e6d4fd126b..01d95d7ff9 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -20,18 +20,21 @@ #define FORCE_STRING_OVERRIDE (1<<2) // used for tooltips #define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use. #define SLOWS_WHILE_IN_HAND (1<<4) -#define NO_MAT_REDEMPTION (1<<5) // Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. -#define DROPDEL (1<<6) // When dropped, it calls qdel on itself +#define NO_MAT_REDEMPTION (1<<5) // Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. +#define DROPDEL (1<<6) // When dropped, it calls qdel on itself #define NOBLUDGEON (1<<7) // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby() -#define NODROP (1<<8) // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted. -#define ABSTRACT (1<<9) // for all things that are technically items but used for various different stuff -#define IMMUTABLE_SLOW (1<<10) //When players should not be able to change the slowdown of the item (Speed potions, ect) +#define ABSTRACT (1<<8) // for all things that are technically items but used for various different stuff +#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect) +#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes) +#define NO_UNIFORM_REQUIRED (1<<11) // Can be worn on certain slots (currently belt and id) that would otherwise require an uniform. // Flags for the clothing_flags var on /obj/item/clothing #define LAVAPROTECT (1<<0) #define STOPSPRESSUREDAMAGE (1<<1) //SUIT and HEAD items which stop pressure damage. To stop you taking all pressure damage you must have both a suit and head item with this flag. #define BLOCK_GAS_SMOKE_EFFECT (1<<2) // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! -#define MASKINTERNALS (1<<3) // mask allows internals +#define ALLOWINTERNALS (1<<3) // mask allows internals #define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc #define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. +#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled. +#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off. diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm index 897d107939..928f364a81 100644 --- a/code/__DEFINES/radio.dm +++ b/code/__DEFINES/radio.dm @@ -1,5 +1,55 @@ // Radios use a large variety of predefined frequencies. +//say based modes like binary are in living/say.dm + +#define RADIO_CHANNEL_COMMON "Common" +#define RADIO_KEY_COMMON ";" + +#define RADIO_CHANNEL_SECURITY "Security" +#define RADIO_KEY_SECURITY "s" +#define RADIO_TOKEN_SECURITY ":s" + +#define RADIO_CHANNEL_ENGINEERING "Engineering" +#define RADIO_KEY_ENGINEERING "e" +#define RADIO_TOKEN_ENGINEERING ":e" + +#define RADIO_CHANNEL_COMMAND "Command" +#define RADIO_KEY_COMMAND "c" +#define RADIO_TOKEN_COMMAND ":c" + +#define RADIO_CHANNEL_SCIENCE "Science" +#define RADIO_KEY_SCIENCE "n" +#define RADIO_TOKEN_SCIENCE ":n" + +#define RADIO_CHANNEL_MEDICAL "Medical" +#define RADIO_KEY_MEDICAL "m" +#define RADIO_TOKEN_MEDICAL ":m" + +#define RADIO_CHANNEL_SUPPLY "Supply" +#define RADIO_KEY_SUPPLY "u" +#define RADIO_TOKEN_SUPPLY ":u" + +#define RADIO_CHANNEL_SERVICE "Service" +#define RADIO_KEY_SERVICE "v" +#define RADIO_TOKEN_SERVICE ":v" + +#define RADIO_CHANNEL_AI_PRIVATE "AI Private" +#define RADIO_KEY_AI_PRIVATE "o" +#define RADIO_TOKEN_AI_PRIVATE ":o" + + +#define RADIO_CHANNEL_SYNDICATE "Syndicate" +#define RADIO_KEY_SYNDICATE "t" +#define RADIO_TOKEN_SYNDICATE ":t" + +#define RADIO_CHANNEL_CENTCOM "CentCom" +#define RADIO_KEY_CENTCOM "y" +#define RADIO_TOKEN_CENTCOM ":y" + +#define RADIO_CHANNEL_CTF_RED "Red Team" +#define RADIO_CHANNEL_CTF_BLUE "Blue Team" + + #define MIN_FREE_FREQ 1201 // ------------------------------------------------- // Frequencies are always odd numbers and range from 1201 to 1599. diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index 1c36120a0c..7cebc37d94 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -25,7 +25,8 @@ #define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense. //Research point amounts #define NOBLIUM_RESEARCH_AMOUNT 1000 -#define BZ_RESEARCH_AMOUNT 150 +#define BZ_RESEARCH_SCALE 4 +#define BZ_RESEARCH_MAX_AMOUNT 400 #define MIASMA_RESEARCH_AMOUNT 160 #define STIMULUM_RESEARCH_AMOUNT 50 //Plasma fusion properties diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index c3682d905d..174289d3bb 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -2,7 +2,13 @@ #define LIQUID 2 #define GAS 3 -// reagents_flags defines +//reagents reaction var defines +#define REAGENT_NORMAL_PH 7.000 +#define REAGENT_PH_ACCURACY 0.001 +#define REAGENT_PURITY_ACCURACY 0.001 +#define DEFAULT_SPECIFIC_HEAT 200 + +// container_type defines #define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes. #define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes. diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index 82fbfdb848..e655408db1 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -6,17 +6,43 @@ //Message modes. Each one defines a radio channel, more or less. #define MODE_HEADSET "headset" #define MODE_ROBOT "robot" + #define MODE_R_HAND "right hand" +#define MODE_KEY_R_HAND "r" + #define MODE_L_HAND "left hand" +#define MODE_KEY_L_HAND "l" + #define MODE_INTERCOM "intercom" +#define MODE_KEY_INTERCOM "i" + #define MODE_BINARY "binary" +#define MODE_KEY_BINARY "b" +#define MODE_TOKEN_BINARY ":b" + #define MODE_WHISPER "whisper" #define MODE_WHISPER_CRIT "whispercrit" + #define MODE_DEPARTMENT "department" +#define MODE_KEY_DEPARTMENT "h" +#define MODE_TOKEN_DEPARTMENT ":h" + +#define MODE_ADMIN "admin" +#define MODE_KEY_ADMIN "p" + +#define MODE_DEADMIN "deadmin" +#define MODE_KEY_DEADMIN "d" + #define MODE_ALIEN "alientalk" #define MODE_HOLOPAD "holopad" + #define MODE_CHANGELING "changeling" +#define MODE_KEY_CHANGELING "g" +#define MODE_TOKEN_CHANGELING ":g" + #define MODE_VOCALCORDS "cords" +#define MODE_KEY_VOCALCORDS "x" + #define MODE_MONKEY "monkeyhive" //Spans. Robot speech, italics, etc. Applied in compose_message(). diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index ffaaa04d0f..3cd64af8c7 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -44,6 +44,8 @@ #define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep +#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions + #define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run #define STATUS_EFFECT_GEISTRACKER /datum/status_effect/geis_tracker //if you're using geis, this tracks that and keeps you from using scripture diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index ecd1ef1e21..3394fba90c 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -81,7 +81,7 @@ #define INIT_ORDER_STICKY_BAN -10 #define INIT_ORDER_LIGHTING -20 #define INIT_ORDER_SHUTTLE -21 -#define INIT_ORDER_SQUEAK -40 +#define INIT_ORDER_MINOR_MAPPING -40 #define INIT_ORDER_PATH -50 #define INIT_ORDER_PERSISTENCE -100 @@ -93,6 +93,7 @@ #define FIRE_PRIORITY_SERVER_MAINT 10 #define FIRE_PRIORITY_RESEARCH 10 #define FIRE_PRIORITY_VIS 10 +#define FIRE_PRIORITY_VORE 10 #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_WET_FLOORS 20 #define FIRE_PRIORITY_AIR 20 diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index c5d6f3051e..f13f13510b 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -31,4 +31,4 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using #define WORLDTIMEOFDAY2TEXT(format) GAMETIMESTAMP(format, world.timeofday) #define TIME_STAMP(format, showds) showds ? "[WORLDTIMEOFDAY2TEXT(format)]:[world.timeofday % 10]" : WORLDTIMEOFDAY2TEXT(format) #define STATION_TIME(display_only) ((((world.time - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0) -#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format) \ No newline at end of file +#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 7f3c063777..ed0007135d 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -108,10 +108,13 @@ #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" #define TRAIT_MINDSHIELD "mindshield" +#define TRAIT_FEARLESS "fearless" +#define TRAIT_UNSTABLE "unstable" #define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it #define TRAIT_PARALYSIS_R_ARM "para-r-arm" #define TRAIT_PARALYSIS_L_LEG "para-l-leg" #define TRAIT_PARALYSIS_R_LEG "para-r-leg" +#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech" #define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism" #define TRAIT_STRONG_GRABBER "strong_grabber" #define TRAIT_CALCIUM_HEALER "calcium_healer" @@ -119,11 +122,15 @@ //non-mob traits #define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it +// item traits +#define TRAIT_NODROP "nodrop" + #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" #define TRAIT_AGEUSIA "ageusia" #define TRAIT_HEAVY_SLEEPER "heavy_sleeper" #define TRAIT_NIGHT_VISION "night_vision" #define TRAIT_LIGHT_STEP "light_step" +#define TRAIT_SILENT_STEP "silent_step" #define TRAIT_SPEEDY_STEP "speedy_step" #define TRAIT_SPIRITUAL "spiritual" #define TRAIT_VORACIOUS "voracious" @@ -139,12 +146,15 @@ #define TRAIT_CROCRIN_IMMUNE "crocin_immune" #define TRAIT_NYMPHO "nymphomania" #define TRAIT_MASO "masochism" +#define TRAIT_HIGH_BLOOD "high_blood" +#define TRAIT_PHARMA "hepatic_pharmacokinesis" #define TRAIT_PARA "paraplegic" #define TRAIT_EMPATH "empath" #define TRAIT_FRIENDLY "friendly" #define TRAIT_ASSBLASTUSA "assblastusa" #define TRAIT_CULT_EYES "cult_eyes" + // common trait sources #define TRAIT_GENERIC "generic" #define EYE_DAMAGE "eye_damage" @@ -155,6 +165,12 @@ #define SPECIES_TRAIT "species" #define ORGAN_TRAIT "organ" #define JOB_TRAIT "job" +#define CYBORG_ITEM_TRAIT "cyborg-item" +#define ADMIN_TRAIT "admin" // (B)admins only. +#define CHANGELING_TRAIT "changeling" +#define CULT_TRAIT "cult" +#define CURSED_ITEM_TRAIT "cursed-item" // The item is magically cursed +#define ABSTRACT_ITEM_TRAIT "abstract-item" #define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention // unique trait sources, still defines @@ -167,3 +183,24 @@ #define STASIS_MUTE "stasis" #define GENETICS_SPELL "genetics_spell" #define EYES_COVERED "eyes_covered" +#define CULT_TRAIT "cult" +#define CLOWN_NUKE_TRAIT "clown-nuke" +#define STICKY_MOUSTACHE_TRAIT "sticky-moustache" +#define CHAINSAW_FRENZY_TRAIT "chainsaw-frenzy" +#define CHRONO_GUN_TRAIT "chrono-gun" +#define REVERSE_BEAR_TRAP_TRAIT "reverse-bear-trap" +#define GLUED_ITEM_TRAIT "glued-item" +#define CURSED_MASK_TRAIT "cursed-mask" +#define HIS_GRACE_TRAIT "his-grace" +#define HAND_REPLACEMENT_TRAIT "magic-hand" +#define HOT_POTATO_TRAIT "hot-potato" +#define SABRE_SUICIDE_TRAIT "sabre-suicide" +#define ABDUCTOR_VEST_TRAIT "abductor-vest" +#define CAPTURE_THE_FLAG_TRAIT "capture-the-flag" +#define EYE_OF_GOD_TRAIT "eye-of-god" +#define SHAMEBRERO_TRAIT "shamebrero" +#define CHRONOSUIT_TRAIT "chronosuit" +#define FLIGHTSUIT_TRAIT "flightsuit" +#define LOCKED_HELMET_TRAIT "locked-helmet" +#define NINJA_SUIT_TRAIT "ninja-suit" +#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" \ No newline at end of file diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index 668b151b6e..8683f75b08 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -58,6 +58,7 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list) //Genitals and Arousal Lists GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes. +GLOBAL_LIST_EMPTY(gentlemans_organ_names) GLOBAL_LIST_EMPTY(balls_shapes_list) GLOBAL_LIST_EMPTY(balls_shapes_icons) GLOBAL_LIST_EMPTY(breasts_size_list) diff --git a/code/__HELPERS/donator_groupings.dm b/code/__HELPERS/donator_groupings.dm new file mode 100644 index 0000000000..bdff20553a --- /dev/null +++ b/code/__HELPERS/donator_groupings.dm @@ -0,0 +1,25 @@ +/* +Current specifications: + +Donator groups in __DEFINES/donator_groupings.dm, config entries in controllers/configuration/entries/donator.dm + +3 groups, Tier 1/2/3 +Each tier includes the one before it (ascending) +For fast lookups, this is generated using regenerate_donator_grouping_list() + +*/ + +/proc/is_donator_group(ckey, group) + ckey = ckey(ckey) //make sure it's ckey'd. + var/list/L = GLOB.donators_by_group[group] + return L && L.Find(ckey) + +/proc/regenerate_donator_grouping_list() + GLOB.donators_by_group = list() //reinit everything + var/list/donator_list = GLOB.donators_by_group //cache + var/list/tier_1 = TIER_1_DONATORS + donator_list[DONATOR_GROUP_TIER_1] = tier_1.Copy() //The .Copy() is to "decouple"/make a new list, rather than letting the global list impact the config list. + var/list/tier_2 = tier_1 + TIER_2_DONATORS //Using + on lists implies making new lists, so we don't need to manually Copy(). + donator_list[DONATOR_GROUP_TIER_2] = tier_2 + var/list/tier_3 = tier_2 + TIER_3_DONATORS + donator_list[DONATOR_GROUP_TIER_3] = tier_3 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ac113b4e08..ad2bedaa4e 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -8,11 +8,11 @@ //facial hair init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) //underwear - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) //undershirt - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) //socks - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) //bodypart accessories (blizzard intensifies) init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) @@ -52,7 +52,8 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "baloney pony", "schlanger") for(var/K in GLOB.breasts_shapes_list) var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K] GLOB.breasts_shapes_icons[K] = value.icon_state diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 9eb5400c52..7ec99fa885 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -20,35 +20,34 @@ else return "000" -/proc/random_underwear(gender)//Cit change - makes random underwear always return nude +#define UNDIE_COLORABLE(U) (U?.has_color) + +/proc/random_underwear(gender) if(!GLOB.underwear_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - return "Nude" - /*switch(gender) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + switch(gender) if(MALE) return pick(GLOB.underwear_m) if(FEMALE) return pick(GLOB.underwear_f) else - return pick(GLOB.underwear_list)*/ + return pick(GLOB.underwear_list) -/proc/random_undershirt(gender)//Cit change - makes random undershirts always return nude +/proc/random_undershirt(gender) if(!GLOB.undershirt_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - return "Nude" - /*switch(gender) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + switch(gender) if(MALE) return pick(GLOB.undershirt_m) if(FEMALE) return pick(GLOB.undershirt_f) else - return pick(GLOB.undershirt_list)*/ + return pick(GLOB.undershirt_list) -/proc/random_socks()//Cit change - makes random socks always return nude +/proc/random_socks() if(!GLOB.socks_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) - return "Nude" - //return pick(GLOB.socks_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) + return pick(GLOB.socks_list) /proc/random_features() if(!GLOB.tails_list_human.len) @@ -190,6 +189,7 @@ "breasts_size" = pick(GLOB.breasts_size_list), "breasts_shape" = "Pair", "breasts_fluid" = "milk", + "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = pick(GLOB.vagina_shapes_list), "vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 09e0aa95b9..db2eba2422 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -151,6 +151,10 @@ GLOBAL_VAR(command_name) GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. GLOBAL_VAR(syndicate_code_response) //Code response for traitors. +//Cached regex search - for checking if codewords are used. +GLOBAL_DATUM(syndicate_code_phrase_regex, /regex) +GLOBAL_DATUM(syndicate_code_response_regex, /regex) + /* Should be expanded. How this works: diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index cdd2e99dd8..55d9e7a6cd 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -281,6 +281,17 @@ var/statspage = CONFIG_GET(string/roundstatsurl) var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id parts += "[GLOB.TAB]Round ID: [info]" + + var/list/voting_results = SSvote.stored_gamemode_votes + + if(length(voting_results)) + parts += "[GLOB.TAB]Voting: " + var/total_score = 0 + for(var/choice in voting_results) + var/score = voting_results[choice] + total_score += score + parts += "[GLOB.TAB][GLOB.TAB][choice]: [score]" + parts += "[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" var/total_players = GLOB.joined_player_list.len diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7d8eb108f3..1ee5ce986f 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -767,3 +767,27 @@ GLOBAL_LIST_INIT(binary, list("0","1")) return "twelfth" else return "[number]\th" + +/proc/unintelligize(message) + var/prefix=copytext(message,1,2) + if(prefix == ";") + message = copytext(message,2) + else if(prefix in list(":","#")) + prefix += copytext(message,2,3) + message = copytext(message,3) + else + prefix="" + + var/list/words = splittext(message," ") + var/list/rearranged = list() + for(var/i=1;i<=words.len;i++) + var/cword = pick(words) + words.Remove(cword) + var/suffix = copytext(cword,length(cword)-1,length(cword)) + while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) + cword = copytext(cword,1 ,length(cword)-1) + suffix = copytext(cword,length(cword)-1,length(cword) ) + if(length(cword)) + rearranged += cword + message = "[prefix][jointext(rearranged," ")]" + . = message diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 2f69b63ae9..3c8d62ce3a 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1239,19 +1239,21 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) pixel_x = initialpixelx pixel_y = initialpixely -/atom/proc/do_jiggle(targetangle = 45) +/atom/proc/do_jiggle(targetangle = 45, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) + var/halftime = timer * 0.5 M.Turn(pick(-targetangle, targetangle)) - animate(src, transform = M, time = 10, easing = ELASTIC_EASING) - animate(src, transform = OM, time = 10, easing = ELASTIC_EASING) + animate(src, transform = M, time = halftime, easing = ELASTIC_EASING) + animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING) -/atom/proc/do_squish(squishx = 1.2, squishy = 0.6) +/atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) + var/halftime = timer * 0.5 M.Scale(squishx, squishy) - animate(src, transform = M, time = 10, easing = BOUNCE_EASING) - animate(src, transform = OM, time = 10, easing = BOUNCE_EASING) + animate(src, transform = M, time = halftime, easing = BOUNCE_EASING) + animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING) /proc/weightclass2text(var/w_class) switch(w_class) @@ -1483,7 +1485,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/grown/mushroom, /obj/item/reagent_containers/food/snacks/grown/nettle, // base type - /obj/item/reagent_containers/food/snacks/deepfryholder + /obj/item/reagent_containers/food/snacks/deepfryholder, + /obj/item/reagent_containers/food/snacks/grown/shell, + /obj/item/reagent_containers/food/snacks/clothing, + /obj/item/reagent_containers/food/snacks/store/bread ) blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index c37e6fa531..3b32745b5c 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -47,7 +47,6 @@ GLOBAL_LIST_INIT(bitfields, list( "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, "DROPDEL" = DROPDEL, "NOBLUDGEON" = NOBLUDGEON, - "NODROP" = NODROP, "ABSTRACT" = ABSTRACT, ), "admin_flags" = list( @@ -137,9 +136,11 @@ GLOBAL_LIST_INIT(bitfields, list( "LAVAPROTECT" = LAVAPROTECT, "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, - "MASKINTERNALS" = MASKINTERNALS, + "ALLOWINTERNALS" = ALLOWINTERNALS, "NOSLIP" = NOSLIP, "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, ), "tesla_flags" = list( "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE, @@ -171,4 +172,9 @@ GLOBAL_LIST_INIT(bitfields, list( "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, ), - )) + "disease_flags" = list( + "CURABLE" = CURABLE, + "CAN_CARRY" = CAN_CARRY, + "CAN_RESIST" = CAN_RESIST + ), + )) \ No newline at end of file diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 47b7e2ab62..d09368d7b7 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -7,15 +7,15 @@ GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/faci GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) //stores only hair names GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) //stores only hair names //Underwear -GLOBAL_LIST_EMPTY(underwear_list) //stores /datum/sprite_accessory/underwear indexed by name +GLOBAL_LIST_EMPTY(underwear_list) //stores /datum/sprite_accessory/underwear/bottom indexed by name GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name GLOBAL_LIST_EMPTY(underwear_f) //stores only underwear name //Undershirts -GLOBAL_LIST_EMPTY(undershirt_list) //stores /datum/sprite_accessory/undershirt indexed by name +GLOBAL_LIST_EMPTY(undershirt_list) //stores /datum/sprite_accessory/underwear/top indexed by name GLOBAL_LIST_EMPTY(undershirt_m) //stores only undershirt name GLOBAL_LIST_EMPTY(undershirt_f) //stores only undershirt name //Socks -GLOBAL_LIST_EMPTY(socks_list) //stores /datum/sprite_accessory/socks indexed by name +GLOBAL_LIST_EMPTY(socks_list) //stores /datum/sprite_accessory/underwear/socks indexed by name //Lizard Bits (all datum lists indexed by name) GLOBAL_LIST_EMPTY(body_markings_list) GLOBAL_LIST_EMPTY(tails_list_lizard) @@ -100,6 +100,11 @@ GLOBAL_LIST_INIT(security_depts_prefs, list(SEC_DEPT_RANDOM, SEC_DEPT_NONE, SEC_ #define DDUFFELBAG "Department Duffel Bag" GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, GBACKPACK, GSATCHEL, GDUFFELBAG, LSATCHEL)) +//Suit/Skirt +#define PREF_SUIT "Jumpsuit" +#define PREF_SKIRT "Jumpskirt" +GLOBAL_LIST_INIT(jumpsuitlist, list(PREF_SUIT, PREF_SKIRT)) + //Uplink spawn loc #define UPLINK_PDA "PDA" #define UPLINK_RADIO "Radio" diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 7f9e0c6ca5..c25ebf5b0a 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/assembly/timer = 3, /obj/item/flashlight = 4, /obj/item/flashlight/pen = 1, - /obj/item/flashlight/glowstick/random = 4, + /obj/effect/spawner/lootdrop/glowstick = 4, /obj/effect/spawner/lootdrop/mre = 3, /obj/item/multitool = 2, /obj/item/radio/off = 2, @@ -69,12 +69,11 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/crowbar = 1, /obj/item/crowbar/red = 1, /obj/item/extinguisher = 11, - //obj/item/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc. /obj/item/hand_labeler = 1, /obj/item/paper/crumpled = 1, /obj/item/pen = 1, /obj/item/reagent_containers/spray/pestspray = 1, - /obj/item/reagent_containers/glass/rag = 3, + /obj/item/reagent_containers/rag = 3, /obj/item/stock_parts/cell = 3, /obj/item/storage/belt/utility = 2, /obj/item/storage/box = 2, @@ -102,15 +101,16 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/assembly/signaler = 2, /obj/item/assembly/mousetrap = 2, /obj/item/reagent_containers/syringe = 2, - /obj/item/clothing/gloves/color/random = 8, + /obj/effect/spawner/lootdrop/gloves = 8, /obj/item/clothing/shoes/laceup = 1, /obj/item/storage/secure/briefcase = 3, /obj/item/storage/toolbox/artistic = 2, /obj/item/toy/eightball = 1, /obj/item/reagent_containers/pill/floorpill = 1, - /obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 1, + /obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 2, /obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint /obj/item/storage/pill_bottle/penis_enlargement = 2, + /obj/item/storage/pill_bottle/breast_enlargement = 2, /obj/item/clothing/shoes/wheelys = 1, /obj/item/clothing/shoes/kindleKicks = 1, /obj/item/autosurgeon/penis = 1, diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm new file mode 100644 index 0000000000..1dcde53a72 --- /dev/null +++ b/code/_globalvars/lists/misc.dm @@ -0,0 +1 @@ +GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 3d6de49a6a..5f0e7c9b22 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -67,7 +67,7 @@ /mob/proc/ClickOn( atom/A, params ) if(world.time <= next_click) return - next_click = world.time + 1 + next_click = world.time + world.tick_lag if(check_click_intercept(params,A)) return @@ -366,11 +366,15 @@ SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) var/turf/T = get_turf(src) if(T && user.TurfAdjacent(T)) - if(user.listed_turf == T) - user.listed_turf = null - else - user.listed_turf = T - user.client.statpanel = T.name + user.listed_turf = T + user.client.statpanel = T.name + +// Use this instead of /mob/proc/AltClickOn(atom/A) where you only want turf content listing without additional atom alt-click interaction +/atom/proc/AltClickNoInteract(mob/user, atom/A) + var/turf/T = get_turf(A) + if(T && user.TurfAdjacent(T)) + user.listed_turf = T + user.client.statpanel = T.name /mob/proc/TurfAdjacent(turf/T) return T.Adjacent(src) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index a987f70d7b..ae36b4abb4 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -79,6 +79,7 @@ #define ui_drop_throw "EAST-1:28,SOUTH+1:7" #define ui_pull_resist "EAST-2:26,SOUTH+1:7" #define ui_movi "EAST-2:26,SOUTH:5" +#define ui_sprintbufferloc "EAST-2:26,SOUTH:18" #define ui_acti "EAST-3:24,SOUTH:5" #define ui_zonesel "EAST-1:28,SOUTH:5" #define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 01e118aaed..7f2fca9d98 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -134,6 +134,13 @@ static_inventory += using //END OF CITADEL CHANGES + //same as above but buffer. + using = new /obj/screen/sprint_buffer + using.screen_loc = ui_sprintbufferloc + sprint_buffer = using + static_inventory += using + + using = new /obj/screen/drop() using.icon = ui_style using.screen_loc = ui_drop_throw diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 5ee4ae0f8a..4c666d708c 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -290,16 +290,19 @@ icon_state = "internal0" else if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - if(!istype(C.wear_mask, /obj/item/clothing/mask)) + var/obj/item/clothing/check + var/internals = FALSE + + for(check in GET_INTERNAL_SLOTS(C)) + if(istype(check, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/M = check + if(M.mask_adjusted) + M.adjustmask(C) + if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + internals = TRUE + if(!internals) to_chat(C, "You are not wearing an internals mask!") - return 1 - else - var/obj/item/clothing/mask/M = C.wear_mask - if(M.mask_adjusted) // if mask on face but pushed down - M.adjustmask(C) // adjust it back - if( !(M.clothing_flags & MASKINTERNALS) ) - to_chat(C, "You are not wearing an internals mask!") - return + return var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) if(I) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 2a14d232aa..6455b4ccb6 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -64,7 +64,7 @@ to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto return // CIT CHANGE - ditto - if(force && HAS_TRAIT(user, TRAIT_PACIFISM)) + if(force && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") return @@ -171,3 +171,7 @@ if(prob(2)) playsound(src, 'sound/weapons/dink.ogg', 30, 1) return 1 + +/obj/item/proc/getweight() + return total_mass || w_class * 1.25 + diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 6cacc90fcb..299d7f64f8 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -31,7 +31,7 @@ ShiftClickOn(A) return if(modifiers["alt"]) - AltClickOn(A) + AltClickNoInteract(src, A) return if(modifiers["ctrl"]) CtrlClickOn(A) diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 49ff1c8d49..3ac103affc 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -19,6 +19,7 @@ var/abstract_type = /datum/config_entry //do not instantiate if type matches this var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless. + var/postload_required = FALSE //requires running OnPostload() var/dupes_allowed = FALSE @@ -72,6 +73,9 @@ /datum/config_entry/proc/DeprecationUpdate(value) return +/datum/config_entry/proc/OnPostload() + return + /datum/config_entry/string config_entry_value = "" abstract_type = /datum/config_entry/string @@ -80,7 +84,7 @@ /datum/config_entry/string/vv_edit_var(var_name, var_value) return var_name != "auto_trim" && ..() -/datum/config_entry/string/ValidateAndSet(str_val) +/datum/config_entry/string/ValidateAndSet(str_val, during_load) if(!VASProcCallGuard(str_val)) return FALSE config_entry_value = auto_trim ? trim(str_val) : str_val diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 0232081c1a..ea2919f342 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -101,6 +101,7 @@ log_config("Loading config file [filename]...") var/list/lines = world.file2list("[directory]/[filename]") var/list/_entries = entries + var/list/postload_required = list() for(var/L in lines) L = trim(L) if(!L) @@ -157,18 +158,24 @@ else warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()") - var/validated = E.ValidateAndSet(value) + var/validated = E.ValidateAndSet(value, TRUE) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") else if(E.modified && !E.dupes_allowed) log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + if(E.postload_required) + postload_required[E] = TRUE E.resident_file = filename if(validated) E.modified = TRUE + for(var/i in postload_required) + var/datum/config_entry/E = i + E.OnPostload() + ++. /datum/controller/configuration/can_vv_get(var_name) diff --git a/code/controllers/configuration/entries/donator.dm b/code/controllers/configuration/entries/donator.dm new file mode 100644 index 0000000000..b74d5f5839 --- /dev/null +++ b/code/controllers/configuration/entries/donator.dm @@ -0,0 +1,22 @@ +/datum/config_entry/keyed_list/donator_group + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + abstract_type = /datum/config_entry/keyed_list/donator_group + +//If we're in the middle of a config load, only do the regeneration afterwards to prevent this from wasting a massive amount of CPU for list regenerations. +/datum/config_entry/keyed_list/donator_group/ValidateAndSet(str_val, during_load) + . = ..() + if(. && during_load) + regenerate_donator_grouping_list() + +/datum/config_entry/keyed_list/donator_group/OnPostload() + . = ..() + regenerate_donator_grouping_list() + +//This is kinda weird in that the config entries are defined here but all the handling/calculations are in __HELPERS/donator_groupings.dm + +/datum/config_entry/keyed_list/donator_group/tier_1_donators + +/datum/config_entry/keyed_list/donator_group/tier_2_donators + +/datum/config_entry/keyed_list/donator_group/tier_3_donators diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 221d04dad5..cc09ca816e 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -23,7 +23,7 @@ SUBSYSTEM_DEF(input) // This is for when macro sets are eventualy datumized /datum/controller/subsystem/input/proc/setup_default_macro_sets() var/list/static/default_macro_sets - + if(default_macro_sets) macro_sets = default_macro_sets return @@ -49,6 +49,7 @@ SUBSYSTEM_DEF(input) "old_hotkeys" = list( "Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", "O" = "ooc", + "L" = "looc", "T" = "say", "M" = "me", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 5e960e0f96..4001c666ee 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -437,7 +437,7 @@ SUBSYSTEM_DEF(job) if(job.custom_spawn_text) to_chat(M, "[job.custom_spawn_text]") if(CONFIG_GET(number/minimal_access_threshold)) - to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") + to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") if(job && H) if(job.dresscodecompliant)// CIT CHANGE - dress code compliance diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/minor_mapping.dm similarity index 62% rename from code/controllers/subsystem/squeak.dm rename to code/controllers/subsystem/minor_mapping.dm index 861bb0d8d5..2160cae6e3 100644 --- a/code/controllers/subsystem/squeak.dm +++ b/code/controllers/subsystem/minor_mapping.dm @@ -1,22 +1,14 @@ -// The Squeak -// because this is about placement of mice mobs, and nothing to do with -// mice - the computer peripheral - -SUBSYSTEM_DEF(squeak) - name = "Squeak" - init_order = INIT_ORDER_SQUEAK +SUBSYSTEM_DEF(minor_mapping) + name = "Minor Mapping" + init_order = INIT_ORDER_MINOR_MAPPING flags = SS_NO_FIRE - var/list/exposed_wires = list() - -/datum/controller/subsystem/squeak/Initialize(timeofday) +/datum/controller/subsystem/minor_mapping/Initialize(timeofday) trigger_migration(CONFIG_GET(number/mice_roundstart)) return ..() -/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10) - if(!num_mice) - return - find_exposed_wires() +/datum/controller/subsystem/minor_mapping/proc/trigger_migration(num_mice=10) + var/list/exposed_wires = find_exposed_wires() var/mob/living/simple_animal/mouse/M var/turf/proposed_turf @@ -31,7 +23,8 @@ SUBSYSTEM_DEF(squeak) num_mice -= 1 M = null -/datum/controller/subsystem/squeak/proc/find_exposed_wires() +/proc/find_exposed_wires() + var/list/exposed_wires = list() exposed_wires.Cut() var/list/all_turfs for (var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) @@ -41,3 +34,5 @@ SUBSYSTEM_DEF(squeak) continue if(locate(/obj/structure/cable) in T) exposed_wires += T + + return shuffle(exposed_wires) \ No newline at end of file diff --git a/code/controllers/subsystem/processing/chemistry.dm b/code/controllers/subsystem/processing/chemistry.dm new file mode 100644 index 0000000000..da31d65fb3 --- /dev/null +++ b/code/controllers/subsystem/processing/chemistry.dm @@ -0,0 +1,5 @@ +PROCESSING_SUBSYSTEM_DEF(chemistry) + wait = 5 + flags = SS_KEEP_TIMING + + diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index a6c86a3576..4af54b8c70 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -9,6 +9,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks) runlevels = RUNLEVEL_GAME var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/ + var/list/quirk_names_by_path = list() var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process @@ -22,11 +23,68 @@ PROCESSING_SUBSYSTEM_DEF(quirks) var/datum/quirk/T = V quirks[initial(T.name)] = T quirk_points[initial(T.name)] = initial(T.value) + quirk_names_by_path[T] = initial(T.name) -/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects) +/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects, roundstart = FALSE, datum/job/job, silent = FALSE, mob/to_chat_target) GenerateQuirks(cli) - for(var/V in cli.prefs.character_quirks) + var/list/quirks = cli.prefs.character_quirks.Copy() + var/list/cut + if(job && job.blacklisted_quirks) + cut = filter_quirks(quirks, job) + for(var/V in quirks) user.add_quirk(V, spawn_effects) + if(!silent && LAZYLEN(cut)) + to_chat(to_chat_target || user, "All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].") + +/datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name) + return quirks[name] + +/datum/controller/subsystem/processing/quirks/proc/quirk_points_by_name(name) + return quirk_points[name] + +/datum/controller/subsystem/processing/quirks/proc/quirk_name_by_path(path) + return quirk_names_by_path[path] + +/datum/controller/subsystem/processing/quirks/proc/total_points(list/quirk_names) + . = 0 + for(var/i in quirk_names) + . += quirk_points_by_name(i) + +/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/quirks, datum/job/job) + var/list/cut = list() + var/list/banned_names = list() + for(var/i in job.blacklisted_quirks) + var/name = quirk_name_by_path(i) + if(name) + banned_names += name + var/list/blacklisted = quirks & banned_names + if(length(blacklisted)) + for(var/i in blacklisted) + quirks -= i + cut += i + + /* //Code to automatically reduce positive quirks until balance is even. + var/points_used = total_points(quirks) + if(points_used > 0) + //they owe us points, let's collect. + for(var/i in quirks) + var/points = quirk_points_by_name(i) + if(points > 0) + cut += i + quirks -= i + points_used -= points + if(points_used <= 0) + break + */ + + //Nah, let's null all non-neutrals out. + if(cut.len) + for(var/i in quirks) + if(quirk_points_by_name(i) != 0) + //cut += i -- Commented out: Only show the ones that triggered the quirk purge. + quirks -= i + + return cut /datum/controller/subsystem/processing/quirks/proc/GenerateQuirks(client/user) if(user.prefs.character_quirks.len) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 74f9ad0382..f2469e8f7d 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -127,9 +127,20 @@ SUBSYSTEM_DEF(ticker) if(!GLOB.syndicate_code_phrase) GLOB.syndicate_code_phrase = generate_code_phrase(return_list=TRUE) + + var/codewords = jointext(GLOB.syndicate_code_phrase, "|") + var/regex/codeword_match = new("([codewords])", "ig") + + GLOB.syndicate_code_phrase_regex = codeword_match + if(!GLOB.syndicate_code_response) GLOB.syndicate_code_response = generate_code_phrase(return_list=TRUE) + var/codewords = jointext(GLOB.syndicate_code_response, "|") + var/regex/codeword_match = new("([codewords])", "ig") + + GLOB.syndicate_code_response_regex = codeword_match + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) if(CONFIG_GET(flag/randomize_shift_time)) gametime_offset = rand(0, 23) HOURS @@ -218,7 +229,7 @@ SUBSYSTEM_DEF(ticker) if(GLOB.secret_force_mode != "secret") var/datum/game_mode/smode = config.pick_mode(GLOB.secret_force_mode) if(!smode.can_start()) - message_admins("\blue Unable to force secret [GLOB.secret_force_mode]. [smode.required_players] players and [smode.required_enemies] eligible antagonists needed.") + message_admins("Unable to force secret [GLOB.secret_force_mode]. [smode.required_players] players and [smode.required_enemies] eligible antagonists needed.") else mode = smode @@ -291,14 +302,14 @@ SUBSYSTEM_DEF(ticker) round_start_time = world.time SSdbcore.SetRoundStart() - to_chat(world, "Welcome to [station_name()], enjoy your stay!") + to_chat(world, "Welcome to [station_name()], enjoy your stay!") SEND_SOUND(world, sound('sound/ai/welcome.ogg')) current_state = GAME_STATE_PLAYING Master.SetRunLevel(RUNLEVEL_GAME) if(SSevents.holidays) - to_chat(world, "and...") + to_chat(world, "and...") for(var/holidayname in SSevents.holidays) var/datum/holiday/holiday = SSevents.holidays[holidayname] to_chat(world, "

[holiday.greet()]

") @@ -374,7 +385,7 @@ SUBSYSTEM_DEF(ticker) if(player.mind.assigned_role != player.mind.special_role) SSjob.EquipRank(N, player.mind.assigned_role, 0) if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character)) - SSquirks.AssignQuirks(N.new_character, N.client, TRUE) + SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N) CHECK_TICK if(captainless) for(var/mob/dead/new_player/N in GLOB.player_list) @@ -414,7 +425,7 @@ SUBSYSTEM_DEF(ticker) m = pick(memetips) if(m) - to_chat(world, "Tip of the round: [html_encode(m)]") + to_chat(world, "Tip of the round: [html_encode(m)]") /datum/controller/subsystem/ticker/proc/check_queue() var/hpc = CONFIG_GET(number/hard_popcap) @@ -561,6 +572,15 @@ SUBSYSTEM_DEF(ticker) news_message = "The burst of energy released near [station_name()] has been confirmed as merely a test of a new weapon. However, due to an unexpected mechanical error, their communications system has been knocked offline." if(SHUTTLE_HIJACK) news_message = "During routine evacuation procedures, the emergency shuttle of [station_name()] had its navigation protocols corrupted and went off course, but was recovered shortly after." + if(GANG_VICTORY) + news_message = "Company officials reaffirmed that sudden deployments of special forces are not in any way connected to rumors of [station_name()] being covered in graffiti." + + if(SSblackbox.first_death) + var/list/ded = SSblackbox.first_death + if(ded.len) + news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]" + else + news_message += " NT Sanctioned Psykers proudly confirm reports that nobody died this shift!" if(news_message) send2otherserver(news_source, news_message,"News_Report") diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index c92db7cd01..d0eb0b9ce2 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -71,7 +71,6 @@ SUBSYSTEM_DEF(timer) for(var/I in second_queue) log_world(get_timer_debug_string(I)) - var/cut_start_index = 1 var/next_clienttime_timer_index = 0 var/len = length(clienttime_timers) @@ -94,14 +93,14 @@ SUBSYSTEM_DEF(timer) if(ctime_timer.flags & TIMER_LOOP) ctime_timer.spent = 0 - clienttime_timers.Insert(ctime_timer, 1) - cut_start_index++ + ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait + BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun) else qdel(ctime_timer) if (next_clienttime_timer_index) - clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1) + clienttime_timers.Cut(1, next_clienttime_timer_index+1) if (MC_TICK_CHECK) return diff --git a/code/controllers/subsystem/vore.dm b/code/controllers/subsystem/vore.dm index faaa297ca3..ca34f9ab61 100644 --- a/code/controllers/subsystem/vore.dm +++ b/code/controllers/subsystem/vore.dm @@ -7,7 +7,7 @@ SUBSYSTEM_DEF(bellies) name = "Bellies" - priority = 5 + priority = FIRE_PRIORITY_VORE wait = 1 SECONDS flags = SS_KEEP_TIMING|SS_NO_INIT runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 422b1eda26..2f56c69384 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -18,6 +18,8 @@ SUBSYSTEM_DEF(vote) var/obfuscated = FALSE//CIT CHANGE - adds obfuscated/admin-only votes + var/list/stored_gamemode_votes = list() //Basically the last voted gamemode is stored here for end-of-round use. + /datum/controller/subsystem/vote/fire() //called by master_controller if(mode) time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10) @@ -85,15 +87,20 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/announce_result() var/list/winners = get_result() var/text + var/was_roundtype_vote = mode == "roundtype" if(winners.len > 0) if(question) text += "[question]" else text += "[capitalize(mode)] Vote" + if(was_roundtype_vote) + stored_gamemode_votes = list() for(var/i=1,i<=choices.len,i++) var/votes = choices[choices[i]] if(!votes) votes = 0 + if(was_roundtype_vote) + stored_gamemode_votes[choices[i]] = votes text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes if(mode != "custom") if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes diff --git a/code/datums/action.dm b/code/datums/action.dm index f64a549b29..fd33ef79b5 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -494,6 +494,7 @@ else to_chat(owner, "Your hands are full!") +//MGS Box /datum/action/item_action/agent_box name = "Deploy Box" desc = "Find inner peace, here, in the box." @@ -502,21 +503,27 @@ icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "deploy_box" var/cooldown = 0 - var/obj/structure/closet/cardboard/agent/box + var/boxtype = /obj/structure/closet/cardboard/agent +//Handles open and closing the box /datum/action/item_action/agent_box/Trigger() - if(!..()) + . = ..() + if(!.) return FALSE - if(QDELETED(box)) - if(cooldown < world.time - 100) - box = new(owner.drop_location()) - owner.forceMove(box) - cooldown = world.time - owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) - else - owner.forceMove(box.drop_location()) + if(istype(owner.loc, /obj/structure/closet/cardboard/agent)) + var/obj/structure/closet/cardboard/agent/box = owner.loc + owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) + box.open() + return + //Box closing from here on out. + if(!isturf(owner.loc)) //Don't let the player use this to escape mechs/welded closets. + to_chat(owner, "You need more space to activate this implant.") + return + if(cooldown < world.time - 100) + var/box = new boxtype(owner.drop_location()) + owner.forceMove(box) + cooldown = world.time owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) - QDEL_NULL(box) //Preset for spells /datum/action/spell_action diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm index 3731397170..56a3f3969b 100644 --- a/code/datums/brain_damage/brain_trauma.dm +++ b/code/datums/brain_damage/brain_trauma.dm @@ -32,16 +32,18 @@ //Called when given to a mob /datum/brain_trauma/proc/on_gain() to_chat(owner, gain_text) + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) //Called when removed from a mob /datum/brain_trauma/proc/on_lose(silent) if(!silent) to_chat(owner, lose_text) + UnregisterSignal(owner, COMSIG_MOB_SAY) //Called when hearing a spoken message /datum/brain_trauma/proc/on_hear(message, speaker, message_language, raw_message, radio_freq) return message //Called when speaking -/datum/brain_trauma/proc/on_say(message) - return message +/datum/brain_trauma/proc/handle_speech(datum/source, list/speech_args) + UnregisterSignal(owner, COMSIG_MOB_SAY) diff --git a/code/datums/brain_damage/hypnosis.dm b/code/datums/brain_damage/hypnosis.dm new file mode 100644 index 0000000000..8909d1b85f --- /dev/null +++ b/code/datums/brain_damage/hypnosis.dm @@ -0,0 +1,72 @@ +/datum/brain_trauma/hypnosis + name = "Hypnosis" + desc = "Patient's unconscious is completely enthralled by a word or sentence, focusing their thoughts and actions on it." + scan_desc = "looping thought pattern" + gain_text = "" + lose_text = "" + resilience = TRAUMA_RESILIENCE_SURGERY + var/hypnotic_phrase = "" + var/regex/target_phrase + +/datum/brain_trauma/hypnosis/New(phrase, quirk = FALSE) + if(!phrase) + qdel(src) + if(quirk == TRUE) + hypnotic_phrase = phrase + else + friendliify(phrase) + if(IsAdminAdvancedProcCall()) + to_chat(usr, "Hypnosis New() skipped due to try/catch incompatibility with admin proccalling.") + qdel(src) + try + target_phrase = new("(\\b[hypnotic_phrase]\\b)","ig") + catch(var/exception/e) + stack_trace("[e] on [e.file]:[e.line]") + qdel(src) + ..() + +/datum/brain_trauma/hypnosis/proc/friendliify(phrase) + phrase = replacetext(lowertext(phrase), "kill", "hug") + phrase = replacetext(lowertext(phrase), "murder", "cuddle") + phrase = replacetext(lowertext(phrase), "harm", "snuggle") + phrase = replacetext(lowertext(phrase), "decapitate", "headpat") + phrase = replacetext(lowertext(phrase), "strangle", "meow at") + phrase = replacetext(lowertext(phrase), "suicide", "self-love") + phrase = replacetext(lowertext(phrase), "lynch", "kiss") + hypnotic_phrase = phrase + +/datum/brain_trauma/hypnosis/on_gain() + message_admins("[ADMIN_LOOKUPFLW(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.") + log_game("[key_name(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.") + to_chat(owner, "[hypnotic_phrase]") + to_chat(owner, "[pick("You feel your thoughts focusing on this phrase... you can't seem to get it out of your head.",\ + "Your head hurts, but this is all you can think of. It must be vitally important.",\ + "You feel a part of your mind repeating this over and over. You need to follow these words.",\ + "Something about this sounds... right, for some reason. You feel like you should follow these words.",\ + "These words keep echoing in your mind. You find yourself completely fascinated by them.")]") + if(!HAS_TRAIT(owner, "hypnotherapy")) + to_chat(owner, "You've been hypnotized by this sentence. You must follow these words. If it isn't a clear order, you can freely interpret how to do so,\ + as long as you act like the words are your highest priority.") + else + to_chat(owner, "You've been hypnotized by this sentence. You feel an incredible desire to follow these words, but are able to resist it somewhat. If it isn't a clear order, you can freely interpret how to do so,\ + however this does not take precedence over your other objectives.") + ..() + +/datum/brain_trauma/hypnosis/on_lose() + message_admins("[ADMIN_LOOKUPFLW(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.") + log_game("[key_name(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.") + to_chat(owner, "You suddenly snap out of your fixation. The phrase '[hypnotic_phrase]' no longer feels important to you.") + ..() + +/datum/brain_trauma/hypnosis/on_life() + ..() + if(prob(2)) + switch(rand(1,2)) + if(1) + to_chat(owner, "...[lowertext(hypnotic_phrase)]...") + if(2) + new /datum/hallucination/chat(owner, TRUE, FALSE, "[hypnotic_phrase]") + +/datum/brain_trauma/hypnosis/on_hear(message, speaker, message_language, raw_message, radio_freq) + message = target_phrase.Replace(message, "$1") + return message diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index f2fec3bb63..c049a7db33 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -68,18 +68,12 @@ lose_text = "" /datum/brain_trauma/mild/speech_impediment/on_gain() - owner.dna.add_mutation(UNINTELLIGIBLE) - ..() - -//no fiddling with genetics to get out of this one -/datum/brain_trauma/mild/speech_impediment/on_life() - if(!(GLOB.mutations_list[UNINTELLIGIBLE] in owner.dna.mutations)) - on_gain() - ..() + ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT) + . = ..() /datum/brain_trauma/mild/speech_impediment/on_lose() - owner.dna.remove_mutation(UNINTELLIGIBLE) - ..() + REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT) + . = ..() /datum/brain_trauma/mild/concussion name = "Concussion" diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index 71a5f21454..f802555c7e 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -31,6 +31,8 @@ /datum/brain_trauma/mild/phobia/on_life() ..() + if(HAS_TRAIT(owner, TRAIT_FEARLESS)) + return if(is_blind(owner)) return if(world.time > next_check && world.time > next_scare) @@ -70,6 +72,8 @@ /datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq) if(!owner.can_hear() || world.time < next_scare) //words can't trigger you if you can't hear them *taps head* return message + if(HAS_TRAIT(owner, TRAIT_FEARLESS)) + return message for(var/word in trigger_words) var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i") @@ -78,14 +82,15 @@ break return message -/datum/brain_trauma/mild/phobia/on_say(message) +/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args) + if(HAS_TRAIT(owner, TRAIT_FEARLESS)) + return for(var/word in trigger_words) var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i") - if(findtext(message, reg)) + if(findtext(speech_args[SPEECH_MESSAGE], reg)) to_chat(owner, "You can't bring yourself to say the word \"[word]\"!") - return "" - return message + speech_args[SPEECH_MESSAGE] = "" /datum/brain_trauma/mild/phobia/proc/freak_out(atom/reason, trigger_word) next_scare = world.time + 120 diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index d094c162d7..890e9cf903 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -254,3 +254,20 @@ /datum/brain_trauma/severe/pacifism/on_lose() REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT) ..() + +//ported from TG +/datum/brain_trauma/severe/hypnotic_stupor + name = "Hypnotic Stupor" + desc = "Patient is prone to episodes of extreme stupor that leaves them extremely suggestible." + scan_desc = "oneiric feedback loop" + gain_text = "You feel somewhat dazed." + lose_text = "You feel like a fog was lifted from your mind." + +/datum/brain_trauma/severe/hypnotic_stupor/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_stupor/on_life() + ..() + if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance)) + owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE) diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 612af13392..653b8a98c0 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -199,10 +199,9 @@ addtimer(CALLBACK(src, /datum/brain_trauma/severe/split_personality.proc/switch_personalities), 10) return message -/datum/brain_trauma/severe/split_personality/brainwashing/on_say(message) - if(findtext(message, codeword)) - return "" //oh hey did you want to tell people about the secret word to bring you back? - return message +/datum/brain_trauma/severe/split_personality/brainwashing/handle_speech(datum/source, list/speech_args) + if(findtext(speech_args[SPEECH_MESSAGE], codeword)) + speech_args[SPEECH_MESSAGE] = "" //oh hey did you want to tell people about the secret word to bring you back? /mob/living/split_personality/traitor name = "split personality" diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm new file mode 100644 index 0000000000..f6a2a89195 --- /dev/null +++ b/code/datums/components/bouncy.dm @@ -0,0 +1,40 @@ +/datum/component/bouncy + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/bouncy_mod = 1 + var/list/bounce_signals = list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_HIT_REACT, COMSIG_ITEM_ATTACK) + +/datum/component/bouncy/Initialize(_bouncy_mod, list/_bounce_signals) + if(!ismovableatom(parent)) + return COMPONENT_INCOMPATIBLE + if(_bouncy_mod) + bouncy_mod = _bouncy_mod + if(_bounce_signals) + bounce_signals = _bounce_signals + +/datum/component/bouncy/InheritComponent(datum/component/bouncy/B, original, _bouncy_mod, list/_bounce_signals) + if(_bouncy_mod) + bouncy_mod = max(bouncy_mod, _bouncy_mod) + if(_bounce_signals) + var/list/diff_bounces = difflist(bounce_signals, _bounce_signals, TRUE) + for(var/bounce in diff_bounces) + bounce_signals += bounce + RegisterSignal(parent, bounce, .proc/bounce_up) + +/datum/component/bouncy/RegisterWithParent() + RegisterSignal(parent, bounce_signals, .proc/bounce_up) + +/datum/component/bouncy/UnregisterFromParent() + UnregisterSignal(parent, bounce_signals) + +/datum/component/bouncy/proc/bounce_up(datum/source) + var/atom/movable/A = parent + switch(rand(1, 3)) + if(1) + A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14) + if(2) + var/min_b = 0.6/bouncy_mod + var/max_b = 1.2 * bouncy_mod + A.do_squish(rand(min_b, max_b), rand(min_b, max_b), 14) + if(3) + var/pixelshift = 8 * bouncy_mod + A.Shake(pixelshift, pixelshift, duration = 15) diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm index bfcc49f453..e6c9f20de6 100644 --- a/code/datums/components/footstep.dm +++ b/code/datums/components/footstep.dm @@ -14,15 +14,18 @@ var/turf/open/T = get_turf(parent) if(!istype(T)) return - + var/mob/living/LM = parent var/v = volume var/e = e_range if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING)) - if (LM.lying && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying + if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) return - + + if(HAS_TRAIT(LM, TRAIT_SILENT_STEP)) + return + if(iscarbon(LM)) var/mob/living/carbon/C = LM if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG)) @@ -31,18 +34,18 @@ v /= 2 e -= 5 steps++ - + if(steps >= 3) steps = 0 - + else return - + if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around return - + //begin playsound shenanigans// - + //for barefooted non-clawed mobs like monkeys if(isbarefoot(LM)) playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), @@ -50,19 +53,19 @@ TRUE, GLOB.barefootstep[T.barefootstep][3] + e) return - + //for xenomorphs, dogs, and other clawed mobs if(isclawfoot(LM)) if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps v /= 3 e -= 5 - + playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]), GLOB.clawfootstep[T.clawfootstep][2] * v, TRUE, GLOB.clawfootstep[T.clawfootstep][3] + e) return - + //for megafauna and other large and imtimidating mobs such as the bloodminer if(isheavyfoot(LM)) playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]), @@ -70,12 +73,12 @@ TRUE, GLOB.heavyfootstep[T.heavyfootstep][3] + e) return - + //for slimes - if(isslime(LM)) + if(isslime(LM)) playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v) return - + //for (simple) humanoid mobs (clowns, russians, pirates, etc.) if(isshoefoot(LM)) if(!ishuman(LM)) @@ -87,17 +90,17 @@ if(ishuman(LM)) //for proper humans, they're special var/mob/living/carbon/human/H = LM var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET)) - + if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) return - + if(H.shoes || feetCover) //are we wearing shoes playsound(T, pick(GLOB.footstep[T.footstep][1]), GLOB.footstep[T.footstep][2] * v, TRUE, GLOB.footstep[T.footstep][3] + e) - + if((!H.shoes && !feetCover)) //are we NOT wearing shoes playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), GLOB.barefootstep[T.barefootstep][2] * v, diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index b32921a4ce..730ffa9ff0 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -6,6 +6,7 @@ var/sanity = 100 //Current sanity var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy. var/mood_level = 5 //To track what stage of moodies they're on + var/sanity_level = 5 //To track what stage of sanity they're on var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets var/datum/mood_event/list/mood_events = list() var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much? @@ -118,6 +119,8 @@ if(owner.client && owner.hud_used) if(sanity < 25) screen_obj.icon_state = "mood_insane" + else if (owner.has_status_effect(/datum/status_effect/chem/enthrall))//Fermichem enthral chem, maybe change? + screen_obj.icon_state = "mood_entrance" else screen_obj.icon_state = "mood[mood_level]" @@ -163,6 +166,58 @@ HandleNutrition(owner) +/datum/component/mood/proc/setSanity(amount, minimum=SANITY_INSANE, maximum=SANITY_NEUTRAL)//I'm sure bunging this in here will have no negative repercussions. + var/mob/living/master = parent + + if(amount == sanity) + return + // If we're out of the acceptable minimum-maximum range move back towards it in steps of 0.5 + // If the new amount would move towards the acceptable range faster then use it instead + if(sanity < minimum && amount < sanity + 0.5) + amount = sanity + 0.5 + else if(sanity > maximum && amount > sanity - 0.5) + amount = sanity - 0.5 + + // Disturbed stops you from getting any more sane + if(HAS_TRAIT(master, TRAIT_UNSTABLE)) + sanity = min(amount,sanity) + else + sanity = amount + + switch(sanity) + if(SANITY_INSANE to SANITY_CRAZY) + setInsanityEffect(MAJOR_INSANITY_PEN) + master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1.5) //Did we change something ? movetypes is runtiming, movetypes=(~FLYING)) + sanity_level = 6 + if(SANITY_CRAZY to SANITY_UNSTABLE) + setInsanityEffect(MINOR_INSANITY_PEN) + master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1)//, movetypes=(~FLYING)) + sanity_level = 5 + if(SANITY_UNSTABLE to SANITY_DISTURBED) + setInsanityEffect(0) + master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5)//, movetypes=(~FLYING)) + sanity_level = 4 + if(SANITY_DISTURBED to SANITY_NEUTRAL) + setInsanityEffect(0) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + sanity_level = 3 + if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences + setInsanityEffect(0) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + sanity_level = 2 + if(SANITY_GREAT+1 to INFINITY) + setInsanityEffect(0) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + sanity_level = 1 + //update_mood_icon() + +/datum/component/mood/proc/setInsanityEffect(newval)//More code so that the previous proc works + if(newval == insanity_effect) + return + var/mob/living/master = parent + master.crit_threshold = (master.crit_threshold - insanity_effect) + newval + insanity_effect = newval + /datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE) if(sanity < minimum) //This might make KevinZ stop fucking pinging me. IncreaseSanity(0.5) @@ -175,6 +230,10 @@ insanity_effect = (MINOR_INSANITY_PEN) /datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL) + // Disturbed stops you from getting any more sane - I'm just gonna bung this in here + var/mob/living/owner = parent + if(HAS_TRAIT(owner, TRAIT_UNSTABLE)) + return if(sanity > maximum) DecreaseSanity(0.5) //Removes some sanity to go back to our current limit. else @@ -195,7 +254,7 @@ if(the_event.timeout) addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE) return 0 //Don't have to update the event. - the_event = new type(src, param) + the_event = new type(src, param)//This causes a runtime for some reason, was this me? No - there's an event floating around missing a definition. mood_events[category] = the_event update_mood() diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm index 426855f887..3f7f794435 100644 --- a/code/datums/components/nanites.dm +++ b/code/datums/components/nanites.dm @@ -2,10 +2,10 @@ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/mob/living/host_mob - var/nanite_volume = 100 //amount of nanites in the system, used as fuel for nanite programs - var/max_nanites = 500 //maximum amount of nanites in the system + var/nanite_volume = 50 //amount of nanites in the system, used as fuel for nanite programs + var/max_nanites = 250 //maximum amount of nanites in the system var/regen_rate = 0.5 //nanites generated per second - var/safety_threshold = 50 //how low nanites will get before they stop processing/triggering + var/safety_threshold = 25 //how low nanites will get before they stop processing/triggering var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from var/next_sync = 0 var/list/datum/nanite_program/programs = list() @@ -46,9 +46,9 @@ RegisterSignal(parent, COMSIG_NANITE_ADD_PROGRAM, .proc/add_program) RegisterSignal(parent, COMSIG_NANITE_SCAN, .proc/nanite_scan) RegisterSignal(parent, COMSIG_NANITE_SYNC, .proc/sync) + RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp) if(isliving(parent)) - RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp) RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/on_death) RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access) RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock) @@ -169,23 +169,19 @@ holder.icon_state = "nanites[nanite_percent]" /datum/component/nanites/proc/on_emp(datum/source, severity) - nanite_volume *= (rand(0.60, 0.90)) //Lose 10-40% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume - if(prob(40/severity)) - cloud_id = 0 + adjust_nanites(null, -(nanite_volume * 0.3 + 50)) //Lose 30% variable and 50 flat nanite volume. for(var/X in programs) var/datum/nanite_program/NP = X NP.on_emp(severity) /datum/component/nanites/proc/on_shock(datum/source, shock_damage) - nanite_volume *= (rand(0.45, 0.80)) //Lose 20-55% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume + adjust_nanites(null, -(nanite_volume * (shock_damage * 0.005) + shock_damage)) //0.5% of shock damage (@ 50 damage it'd drain 25%) + shock damage flat volume for(var/X in programs) var/datum/nanite_program/NP = X NP.on_shock(shock_damage) /datum/component/nanites/proc/on_minor_shock(datum/source) - adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume + adjust_nanites(null, -25) for(var/X in programs) var/datum/nanite_program/NP = X NP.on_minor_shock() @@ -311,4 +307,4 @@ mob_program["trigger_code"] = P.trigger_code id++ mob_programs += list(mob_program) - data["mob_programs"] = mob_programs \ No newline at end of file + data["mob_programs"] = mob_programs diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm index 8989cb499d..1d5549d0fe 100644 --- a/code/datums/components/spooky.dm +++ b/code/datums/components/spooky.dm @@ -27,7 +27,7 @@ C.stuttering = 20 if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly))) C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live - to_chat(C, "DOOT") + to_chat(C, "DOOT") spectral_change(H) else //the sound will spook monkeys. diff --git a/code/datums/components/storage/concrete/emergency.dm b/code/datums/components/storage/concrete/emergency.dm index 48880ff605..348821a913 100644 --- a/code/datums/components/storage/concrete/emergency.dm +++ b/code/datums/components/storage/concrete/emergency.dm @@ -36,3 +36,4 @@ /datum/component/storage/concrete/emergency/proc/unlock_me(datum/source) if(locked) set_locked(source, FALSE) + return TRUE diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm index e0a23b0209..84be4fdca4 100644 --- a/code/datums/components/storage/concrete/pockets.dm +++ b/code/datums/components/storage/concrete/pockets.dm @@ -52,7 +52,7 @@ . = ..() cant_hold = typecacheof(list(/obj/item/screwdriver/power)) can_hold = typecacheof(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, + /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, /obj/item/melee/cultblade/dagger, /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper, /obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini, @@ -63,7 +63,7 @@ . = ..() cant_hold = typecacheof(list(/obj/item/screwdriver/power)) can_hold = typecacheof(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, + /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, /obj/item/melee/cultblade/dagger, /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper, /obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini, diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 52d0036154..0c701cb943 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -592,7 +592,7 @@ if(!stop_messages) to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!") return FALSE //To prevent the stacking of same sized storage items. - if(I.item_flags & NODROP) //SHOULD be handled in unEquip, but better safe than sorry. + if(HAS_TRAIT(I, TRAIT_NODROP)) //SHOULD be handled in unEquip, but better safe than sorry. to_chat(M, "\the [I] is stuck to your hand, you can't put it in \the [host]!") return FALSE var/datum/component/storage/concrete/master = master() diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index c5966452bb..8982530ab6 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -21,6 +21,9 @@ GLOBAL_LIST_EMPTY(uplinks) var/datum/uplink_purchase_log/purchase_log var/list/uplink_items var/hidden_crystals = 0 + var/unlock_note + var/unlock_code + var/failsafe_code /datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) if(!isitem(parent)) @@ -219,7 +222,10 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text) var/obj/item/pda/master = parent - if(trim(lowertext(new_ring_text)) != trim(lowertext(master.lock_code))) //why is the lock code stored on the pda? + if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code))) + if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code))) + failsafe() + return COMPONENT_STOP_RINGTONE_CHANGE return locked = FALSE interact(null, user) @@ -233,7 +239,9 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/new_frequency(datum/source, list/arguments) var/obj/item/radio/master = parent var/frequency = arguments[1] - if(frequency != master.traitor_frequency) + if(frequency != unlock_code) + if(frequency == failsafe_code) + failsafe() return locked = FALSE if(ismob(master.loc)) @@ -243,9 +251,38 @@ GLOBAL_LIST_EMPTY(uplinks) /datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user) var/obj/item/pen/master = parent - if(degrees != master.traitor_unlock_degrees) + if(degrees != unlock_code) + if(degrees == failsafe_code) //Getting failsafes on pens is risky business + failsafe() return locked = FALSE master.degrees = 0 interact(null, user) - to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") \ No newline at end of file + to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") + +/datum/component/uplink/proc/setup_unlock_code() + unlock_code = generate_code() + var/obj/item/P = parent + if(istype(parent,/obj/item/pda)) + unlock_note = "Uplink Passcode: [unlock_code] ([P.name])." + else if(istype(parent,/obj/item/radio)) + unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." + else if(istype(parent,/obj/item/pen)) + unlock_note = "Uplink Degrees: [unlock_code] ([P.name])." + +/datum/component/uplink/proc/generate_code() + if(istype(parent,/obj/item/pda)) + return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" + else if(istype(parent,/obj/item/radio)) + return sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) + else if(istype(parent,/obj/item/pen)) + return rand(1, 360) + +/datum/component/uplink/proc/failsafe() + if(!parent) + return + var/turf/T = get_turf(parent) + if(!T) + return + explosion(T,1,2,3) + qdel(parent) //Alternatively could brick the uplink. diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index d5c983bc39..f0fb7f6095 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1351,8 +1351,8 @@ if(amount != 0) log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - var/msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [L] " - message_admins(msg) + var/msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [L] " + message_admins("[msg]") admin_ticket_log(L, msg) vv_update_display(L, Text, "[newamt]") else if(href_list["copyoutfit"]) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index f506f44ad5..a4a4936f0e 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -31,13 +31,43 @@ var/id = "" var/processing = FALSE var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology + var/oldres // The order goes from easy to cure to hard to cure. var/static/list/advance_cures = list( - "sodiumchloride", "sugar", "orangejuice", - "spaceacillin", "salglu_solution", "ethanol", - "leporazine", "synaptizine", "lipolicide", - "silver", "gold" + list( // level 1 + "copper", "silver", "iodine", "iron", "carbon" + ), + list( // level 2 + "potassium", "ethanol", "lithium", "silicon", "bromine" + ), + list( // level 3 + "sodiumchloride", "sugar", "orangejuice", "tomatojuice", "milk" + ), + list( //level 4 + "spaceacillin", "salglu_solution", "epinephrine", "charcoal" + ), + list( //level 5 + "oil", "synaptizine", "mannitol", "space_drugs", "cryptobiolin" + ), + list( // level 6 + "phenol", "inacusiate", "oculine", "antihol" + ), + list( // level 7 + "leporazine", "mindbreaker", "corazone" + ), + list( // level 8 + "pax", "happiness", "ephedrine" + ), + list( // level 9 + "lipolicide", "sal_acid" + ), + list( // level 10 + "haloperidol", "aranesp", "diphenhydramine" + ), + list( //level 11 + "modafinil", "anacea" + ) ) /* @@ -250,7 +280,10 @@ /datum/disease/advance/proc/GenerateCure() if(properties && properties.len) var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) - cures = list(advance_cures[res]) + if(res == oldres) + return + cures = list(pick(advance_cures[res])) + oldres = res // Get the cure name from the cure_id var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]] diff --git a/code/datums/diseases/advance/symptoms/nanites.dm b/code/datums/diseases/advance/symptoms/nanites.dm index 99665aafc0..b18e089a41 100644 --- a/code/datums/diseases/advance/symptoms/nanites.dm +++ b/code/datums/diseases/advance/symptoms/nanites.dm @@ -25,7 +25,7 @@ if(!..()) return var/mob/living/carbon/M = A.affected_mob - SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, 0.5 * power) + SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, power) if(reverse_boost && SEND_SIGNAL(M, COMSIG_HAS_NANITES)) if(prob(A.stage_prob)) A.stage = min(A.stage + 1,A.max_stages) @@ -60,4 +60,4 @@ SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, -0.4 * power) if(reverse_boost && SEND_SIGNAL(M, COMSIG_HAS_NANITES)) if(prob(A.stage_prob)) - A.stage = min(A.stage + 1,A.max_stages) \ No newline at end of file + A.stage = min(A.stage + 1,A.max_stages) diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index 7bb6934707..cb7d1a6d6d 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -44,7 +44,7 @@ Bonus if(4, 5) M.adjustOxyLoss(-7, 0) M.losebreath = max(0, M.losebreath - 4) - if(regenerate_blood && M.blood_volume < BLOOD_VOLUME_NORMAL) + if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio)) M.blood_volume += 1 else if(prob(base_message_chance)) diff --git a/code/datums/diseases/pierrot_throat.dm b/code/datums/diseases/pierrot_throat.dm index 64f453cd48..b2241d59ba 100644 --- a/code/datums/diseases/pierrot_throat.dm +++ b/code/datums/diseases/pierrot_throat.dm @@ -26,3 +26,30 @@ if(4) if(prob(5)) affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat") + +/datum/disease/pierrot_throat/after_add() + RegisterSignal(affected_mob, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/disease/pierrot_throat/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/list/split_message = splittext(message, " ") //List each word in the message + var/applied = 0 + for (var/i in 1 to length(split_message)) + if(prob(3 * stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% + if(findtext(split_message[i], "*") || findtext(split_message[i], ";") || findtext(split_message[i], ":")) + continue + split_message[i] = "HONK" + if (applied++ > stage) + break + if (applied) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN // a little bonus + message = jointext(split_message, " ") + speech_args[SPEECH_MESSAGE] = message + +/datum/disease/pierrot_throat/Destroy() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) + return ..() + +/datum/disease/pierrot_throat/remove_disease() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) + return ..() \ No newline at end of file diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 938515625d..33e92e4de5 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -185,25 +185,6 @@ if(DNA_TAUR_BLOCK) construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) -/datum/dna/proc/mutations_say_mods(message) - if(message) - for(var/datum/mutation/human/M in mutations) - message = M.say_mod(message) - return message - -/datum/dna/proc/mutations_get_spans() - var/list/spans = list() - for(var/datum/mutation/human/M in mutations) - spans |= M.get_spans() - return spans - -/datum/dna/proc/species_get_spans() - var/list/spans = list() - if(species) - spans |= species.get_spans() - return spans - - /datum/dna/proc/is_same_as(datum/dna/D) if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless && custom_species == D.custom_species) if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) diff --git a/code/datums/ert.dm b/code/datums/ert.dm index d61c95c8f2..4976891543 100644 --- a/code/datums/ert.dm +++ b/code/datums/ert.dm @@ -21,8 +21,8 @@ /datum/ert/amber code = "Amber" - leader_role = /datum/antagonist/ert/commander/red - roles = list(/datum/antagonist/ert/security/red, /datum/antagonist/ert/medic/red, /datum/antagonist/ert/engineer/red) + leader_role = /datum/antagonist/ert/commander/amber + roles = list(/datum/antagonist/ert/security/amber, /datum/antagonist/ert/medic/amber, /datum/antagonist/ert/engineer/amber) /datum/ert/red leader_role = /datum/antagonist/ert/commander/red @@ -55,3 +55,13 @@ rename_team = "Inquisition" mission = "Destroy any traces of paranormal activity aboard the station." polldesc = "a Nanotrasen paranormal response team" + +/datum/ert/greybois + code = "Green" + teamsize = 1 + opendoors = FALSE + enforce_human = FALSE + roles = /datum/antagonist/greybois + leader_role = /datum/antagonist/greybois/greygod + rename_team = "Emergency Assistants" + polldesc = "an Emergency Assistant" diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index fe16b9459f..b3c57e4838 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -198,7 +198,8 @@ GLOBAL_LIST_EMPTY(explosions) var/list/items = list() for(var/I in T) var/atom/A = I - items += A.GetAllContents() + if (!A.prevent_content_explosion()) //The atom/contents_explosion() proc returns null if the contents ex_acting has been handled by the atom, and TRUE if it hasn't. + items += A.GetAllContents() for(var/O in items) var/atom/A = O if(!QDELETED(A)) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 0623e2f5f9..4d1986cccf 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -5,11 +5,19 @@ // effectout: effect to show right after teleportation // asoundin: soundfile to play before teleportation // asoundout: soundfile to play after teleportation -// force_teleport: if false, teleport will use Move() proc (dense objects will prevent teleportation) // no_effects: disable the default effectin/effectout of sparks -/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, force_teleport=TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE) +// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation) +// forced: whether or not to ignore no_teleport +/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE) // teleporting most effects just deletes them - if(iseffect(teleatom) && !istype(teleatom, /obj/effect/dummy/chameleon)) + var/static/list/delete_atoms = typecacheof(list( + /obj/effect, + )) - typecacheof(list( + /obj/effect/dummy/chameleon, + /obj/effect/wisp, + /obj/effect/mob_spawn + )) + if(delete_atoms[teleatom.type]) qdel(teleatom) return FALSE @@ -17,25 +25,37 @@ // if the precision is not specified, default to 0, but apply BoH penalties if (isnull(precision)) precision = 0 - if(istype(teleatom, /obj/item/storage/backpack/holding)) - precision = rand(1,100) - var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding) - var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache) - if(bagholding.len) - precision = max(rand(1,100)*bagholding.len,100) - if(isliving(teleatom)) - var/mob/living/MM = teleatom - to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!") + switch(channel) + if(TELEPORT_CHANNEL_BLUESPACE) + if(istype(teleatom, /obj/item/storage/backpack/holding)) + precision = rand(1,100) - // if effects are not specified and not explicitly disabled, sparks - if ((!effectin || !effectout) && !no_effects) - var/datum/effect_system/spark_spread/sparks = new - sparks.set_up(5, 1, teleatom) - if (!effectin) - effectin = sparks - if (!effectout) - effectout = sparks + var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding) + var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache) + if(bagholding.len) + precision = max(rand(1,100)*bagholding.len,100) + if(isliving(teleatom)) + var/mob/living/MM = teleatom + to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!") + + // if effects are not specified and not explicitly disabled, sparks + if ((!effectin || !effectout) && !no_effects) + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 1, teleatom) + if (!effectin) + effectin = sparks + if (!effectout) + effectout = sparks + if(TELEPORT_CHANNEL_QUANTUM) + // if effects are not specified and not explicitly disabled, rainbow sparks + if ((!effectin || !effectout) && !no_effects) + var/datum/effect_system/spark_spread/quantum/sparks = new + sparks.set_up(5, 1, teleatom) + if (!effectin) + effectin = sparks + if (!effectout) + effectout = sparks // perform the teleport var/turf/curturf = get_turf(teleatom) @@ -45,11 +65,15 @@ return FALSE var/area/A = get_area(curturf) - if(A.noteleport) + var/area/B = get_area(destturf) + if(!forced && (A.noteleport || B.noteleport)) + return FALSE + + if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf)) return FALSE tele_play_specials(teleatom, curturf, effectin, asoundin) - var/success = force_teleport ? teleatom.forceMove(destturf) : teleatom.Move(destturf) + var/success = forceMove ? teleatom.forceMove(destturf) : teleatom.Move(destturf) if (success) log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") tele_play_specials(teleatom, destturf, effectout, asoundout) diff --git a/code/datums/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm similarity index 91% rename from code/datums/looping_sounds/looping_sound.dm rename to code/datums/looping_sounds/_looping_sound.dm index 2eba36dc90..49942976ce 100644 --- a/code/datums/looping_sounds/looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -11,7 +11,6 @@ chance (num) Chance per loop to play a mid_sound volume (num) Sound output volume - muted (bool) Private. Used to stop the sound loop. max_loops (num) The max amount of loops to run for. direct (bool) If true plays directly to provided atoms instead of from them */ @@ -68,7 +67,7 @@ if(!chance || prob(chance)) play(get_sound(starttime)) if(!timerid) - timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP) + timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP) /datum/looping_sound/proc/play(soundfile) var/list/atoms_cache = output_atoms @@ -84,10 +83,7 @@ playsound(thing, S, volume) /datum/looping_sound/proc/get_sound(starttime, _mid_sounds) - if(!_mid_sounds) - . = mid_sounds - else - . = _mid_sounds + . = _mid_sounds || mid_sounds while(!isfile(.) && !isnull(.)) . = pickweight(.) @@ -96,8 +92,8 @@ if(start_sound) play(start_sound) start_wait = start_length - addtimer(CALLBACK(src, .proc/sound_loop), start_wait) + addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME) /datum/looping_sound/proc/on_stop() if(end_sound) - play(end_sound) \ No newline at end of file + play(end_sound) diff --git a/code/datums/map_config.dm b/code/datums/map_config.dm index 99b84a1b35..dcc16f1ba5 100644 --- a/code/datums/map_config.dm +++ b/code/datums/map_config.dm @@ -18,7 +18,7 @@ var/map_file = "BoxStation.dmm" var/traits = null - var/space_ruin_levels = 1 //Citadel edit - reduces the default space ruin z-level count to 1 + var/space_ruin_levels = 2 var/space_empty_levels = 1 var/minetype = "lavaland" diff --git a/code/datums/martial.dm b/code/datums/martial.dm index ae8f92a342..d119759efc 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -2,6 +2,7 @@ var/name = "Martial Art" var/streak = "" var/max_streak_length = 6 + var/id = "" //ID, used by mind/has_martialartcode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proc var/current_target var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary var/deflection_chance = 0 //Chance to deflect projectiles diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index c93fc47f2b..7399528e1c 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -1,5 +1,6 @@ /datum/martial_art/boxing name = "Boxing" + id = MARTIALART_BOXING /datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) to_chat(A, "Can't disarm while boxing!") diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index 55cd4a3f7a..71545476ff 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -6,6 +6,7 @@ /datum/martial_art/cqc name = "CQC" + id = MARTIALART_CQC help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 var/just_a_cook = FALSE diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 4283d7f78f..6379d481ca 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -1,5 +1,6 @@ /datum/martial_art/krav_maga name = "Krav Maga" + id = MARTIALART_KRAVMAGA var/datum/action/neck_chop/neckchop = new/datum/action/neck_chop() var/datum/action/leg_sweep/legsweep = new/datum/action/leg_sweep() var/datum/action/lung_punch/lungpunch = new/datum/action/lung_punch() @@ -85,14 +86,14 @@ return 1 return 0 -/datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) +/datum/martial_art/krav_maga/proc/leg_sweep(mob/living/carbon/human/A, mob/living/carbon/human/D) if(D.lying || D.IsKnockdown()) return 0 D.visible_message("[A] leg sweeps [D]!", \ "[A] leg sweeps you!") playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1) D.apply_damage(5, BRUTE) - D.Knockdown(40, override_hardstun = 0.01, 25) + D.Knockdown(40, override_hardstun = 0.01, override_stamdmg = 25) log_combat(A, D, "leg sweeped") return 1 @@ -196,7 +197,7 @@ name = "combat gloves plus" desc = "These tactical gloves are fireproof and shock resistant, and using nanochip technology it teaches you the powers of krav maga." icon_state = "combat" - item_state = "blackglovesplus" + item_state = "blackgloves" siemens_coefficient = 0 permeability_coefficient = 0.05 strip_delay = 80 diff --git a/code/datums/martial/mushpunch.dm b/code/datums/martial/mushpunch.dm index 33d5bb51bf..1ef7734771 100644 --- a/code/datums/martial/mushpunch.dm +++ b/code/datums/martial/mushpunch.dm @@ -1,5 +1,6 @@ /datum/martial_art/mushpunch name = "Mushroom Punch" + id = MARTIALART_MUSHPUNCH /datum/martial_art/mushpunch/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) var/atk_verb diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index f540dc0783..e38a011db0 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -4,6 +4,7 @@ /datum/martial_art/plasma_fist name = "Plasma Fist" + id = MARTIALART_PLASMAFIST help_verb = /mob/living/carbon/human/proc/plasma_fist_help diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm index 1cb18f903f..8f1a33a8b3 100644 --- a/code/datums/martial/psychotic_brawl.dm +++ b/code/datums/martial/psychotic_brawl.dm @@ -1,5 +1,6 @@ /datum/martial_art/psychotic_brawling name = "Psychotic Brawling" + id = MARTIALART_PSYCHOBRAWL /datum/martial_art/psychotic_brawling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) return psycho_attack(A,D) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index 5f19c37b99..e205d7a435 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -6,6 +6,7 @@ /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" + id = MARTIALART_SLEEPINGCARP deflection_chance = 100 reroute_deflection = TRUE no_guns = TRUE diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index e57edf9fb2..e07fa27ef5 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -10,6 +10,7 @@ /datum/martial_art/wrestling name = "Wrestling" + id = MARTIALART_WRESTLING var/datum/action/slam/slam = new/datum/action/slam() var/datum/action/throw_wrassle/throw_wrassle = new/datum/action/throw_wrassle() var/datum/action/kick/kick = new/datum/action/kick() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 90affe0228..8e61801e15 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -64,6 +64,8 @@ var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator + var/list/learned_recipes //List of learned recipe TYPES. + /datum/mind/New(var/key) src.key = key soulOwner = src @@ -130,7 +132,8 @@ L.update_arousal_hud() //Removes the old icon /datum/mind/proc/store_memory(new_text) - memory += "[new_text]
" + if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN) + memory += "[new_text]
" /datum/mind/proc/wipe_memory() memory = null @@ -233,13 +236,10 @@ /datum/mind/proc/remove_antag_equip() var/list/Mob_Contents = current.get_contents() for(var/obj/item/I in Mob_Contents) - if(istype(I, /obj/item/pda)) - var/obj/item/pda/P = I - P.lock_code = "" - - else if(istype(I, /obj/item/radio)) - var/obj/item/radio/R = I - R.traitor_frequency = 0 + var/datum/component/uplink/O = I.GetComponent(/datum/component/uplink) +//Todo make this reset signal + if(O) + O.unlock_code = null /datum/mind/proc/remove_all_antag() //For the Lazy amongst us. remove_changeling() @@ -304,33 +304,22 @@ . = 0 else . = uplink_loc - uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) - var/unlock_note - - if(uplink_loc == R) - R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.") - unlock_note = "Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name])." - else if(uplink_loc == PDA) - PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.") - unlock_note = "Uplink Passcode: [PDA.lock_code] ([PDA.name])." - - else if(uplink_loc == P) - P.traitor_unlock_degrees = rand(1, 360) - - if(!silent) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.") - unlock_note = "Uplink Degrees: [P.traitor_unlock_degrees] ([P.name])." + var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) + if(!U) + CRASH("Uplink creation failed.") + U.setup_unlock_code() + if(!silent) + if(uplink_loc == R) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") + else if(uplink_loc == PDA) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") + else if(uplink_loc == P) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") if(uplink_owner) - uplink_owner.antag_memory += unlock_note + "
" + uplink_owner.antag_memory += U.unlock_note + "
" else - traitor_mob.mind.store_memory(unlock_note) + traitor_mob.mind.store_memory(U.unlock_note) //Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. @@ -792,6 +781,11 @@ mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) mind.active = 1 //indicates that the mind is currently synced with a client +/datum/mind/proc/has_martialart(var/string) + if(martial_art && martial_art.id == string) + return martial_art + return FALSE + /mob/dead/new_player/sync_mind() return diff --git a/code/datums/mood_events/drink_events.dm b/code/datums/mood_events/drink_events.dm index 5d0eb0e0cb..70acffdb8f 100644 --- a/code/datums/mood_events/drink_events.dm +++ b/code/datums/mood_events/drink_events.dm @@ -6,24 +6,24 @@ /datum/mood_event/quality_nice description = "That drink wasn't bad at all.\n" mood_change = 1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/quality_good description = "That drink was pretty good.\n" mood_change = 2 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/quality_verygood description = "That drink was great!\n" mood_change = 3 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/quality_fantastic description = "That drink was amazing!\n" mood_change = 4 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/amazingtaste description = "Amazing taste!\n" - mood_change = 50 + mood_change = 50 //Is this not really high..? timeout = 10 MINUTES diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm index 40c239180e..469bf80979 100644 --- a/code/datums/mood_events/drug_events.dm +++ b/code/datums/mood_events/drug_events.dm @@ -37,3 +37,19 @@ /datum/mood_event/withdrawal_critical/add_effects(drug_name) description = "[drug_name]! [drug_name]! [drug_name]!\n" + +/datum/mood_event/happiness_drug + description = "I can't feel anything and I never want this to end.\n" + mood_change = 10 + +/datum/mood_event/happiness_drug_good_od + description = "YES! YES!! YES!!!\n" + mood_change = 20 + timeout = 300 + //special_screen_obj = "mood_happiness_good" Originally in tg, but I personally think they look dumb + +/datum/mood_event/happiness_drug_bad_od + description = "NO! NO!! NO!!!\n" + mood_change = -20 + timeout = 300 + //special_screen_obj = "mood_happiness_bad" Originally in tg diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index b2b03fb56b..69f1a66814 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -1,3 +1,5 @@ + + /datum/mood_event/handcuffed description = "I guess my antics have finally caught up with me.\n" mood_change = -1 @@ -17,7 +19,7 @@ /datum/mood_event/burnt_thumb description = "I shouldn't play with lighters...\n" mood_change = -1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/cold description = "It's way too cold in here.\n" @@ -30,17 +32,17 @@ /datum/mood_event/creampie description = "I've been creamed. Tastes like pie flavor.\n" mood_change = -2 - timeout = 1800 + timeout = 3 MINUTES /datum/mood_event/slipped description = "I slipped. I should be more careful next time...\n" mood_change = -2 - timeout = 1800 + timeout = 3 MINUTES /datum/mood_event/eye_stab description = "I used to be an adventurer like you, until I took a screwdriver to the eye.\n" mood_change = -4 - timeout = 1800 + timeout = 3 MINUTES /datum/mood_event/delam //SM delamination description = "Those God damn engineers can't do anything right...\n" @@ -50,12 +52,12 @@ /datum/mood_event/depression description = "I feel sad for no particular reason.\n" mood_change = -9 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/shameful_suicide //suicide_acts that return SHAME, like sord description = "I can't even end it all!\n" mood_change = -10 - timeout = 600 + timeout = 1 MINUTES /datum/mood_event/dismembered description = "AHH! I WAS USING THAT LIMB!\n" @@ -69,7 +71,7 @@ /datum/mood_event/tased description = "There's no \"z\" in \"taser\". It's in the zap.\n" mood_change = -3 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/embedded description = "Pull it out!\n" @@ -78,7 +80,7 @@ /datum/mood_event/table description = "Someone threw me on a table!\n" mood_change = -2 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/table/add_effects() if(ishuman(owner)) @@ -117,6 +119,30 @@ description = "I'm missing my family heirloom...\n" mood_change = -4 +/datum/mood_event/healsbadman + description = "I feel a lot better, but wow that was disgusting.\n" + mood_change = -4 + timeout = 2 MINUTES + +/datum/mood_event/jittery + description = "I'm nervous and on edge and I can't stand still!!\n" + mood_change = -2 + +/datum/mood_event/vomit + description = "I just threw up. Gross.\n" + mood_change = -2 + timeout = 2 MINUTES + +/datum/mood_event/vomitself + description = "I just threw up all over myself. This is disgusting.\n" + mood_change = -4 + timeout = 3 MINUTES + +/datum/mood_event/painful_medicine + description = "Medicine may be good for me but right now it stings like hell.\n" + mood_change = -5 + timeout = 1 MINUTES + /datum/mood_event/loud_gong description = "That loud gong noise really hurt my ears!\n" mood_change = -3 diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 051a548d1d..422ec4476c 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -1,7 +1,7 @@ /datum/mood_event/hug description = "Hugs are nice.\n" mood_change = 1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/arcade description = "I beat the arcade game!\n" @@ -50,7 +50,7 @@ /datum/mood_event/jolly description = "I feel happy for no particular reason.\n" mood_change = 6 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/focused description = "I have a goal, and I will reach it, whatever it takes!\n" //Used for syndies, nukeops etc so they can focus on their goals @@ -76,6 +76,20 @@ mood_change = 3 timeout = 600 +/datum/mood_event/chemical_euphoria + description = "Heh...hehehe...hehe...\n" + mood_change = 4 + + /datum/mood_event/chemical_laughter + description = "Laughter really is the best medicine! Or is it?\n" + mood_change = 4 + timeout = 3 MINUTES + + /datum/mood_event/chemical_superlaughter + description = "*WHEEZE*\n" + mood_change = 12 + timeout = 3 MINUTES + /datum/mood_event/betterhug description = "Someone was very nice to me.\n" mood_change = 3 @@ -94,8 +108,8 @@ /datum/mood_event/happy_empath description = "Someone seems happy!\n" - mood_change = 2 + mood_change = 3 timeout = 600 /datum/mood_event/happy_empath/add_effects(var/mob/happytarget) - description = "[happytarget.name]'s happiness is infectious!\n" + description = "[happytarget.name]'s happiness is infectious!\n" diff --git a/code/datums/mood_events/needs_events.dm b/code/datums/mood_events/needs_events.dm index 75b7e6931f..eb58f2aa92 100644 --- a/code/datums/mood_events/needs_events.dm +++ b/code/datums/mood_events/needs_events.dm @@ -59,4 +59,4 @@ /datum/mood_event/nice_shower description = "I have recently had a nice shower.\n" mood_change = 2 - timeout = 1800 + timeout = 3 MINUTES diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 7de9ca8b4a..efa248b4f0 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -105,13 +105,6 @@ GLOBAL_LIST_EMPTY(mutations_list) return 0 return 1 -/datum/mutation/human/proc/say_mod(message) - if(message) - return message - -/datum/mutation/human/proc/get_spans() - return list() - /mob/living/carbon/proc/update_mutations_overlay() return diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 461c221ff8..a32220aa43 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -63,16 +63,14 @@ /datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.resize = 0.8 - owner.update_transform() + owner.transform = owner.transform.Scale(1, 0.8) owner.pass_flags |= PASSTABLE owner.visible_message("[owner] suddenly shrinks!", "Everything around you seems to grow..") /datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.resize = 1.25 - owner.update_transform() + owner.transform = owner.transform.Scale(1, 1.25) owner.pass_flags &= ~PASSTABLE owner.visible_message("[owner] suddenly grows!", "Everything around you seems to shrink..") diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 0c760f4620..85cecca489 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -15,6 +15,7 @@ ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk) + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) /datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) if(proximity) //no telekinetic hulk attack @@ -32,8 +33,11 @@ REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "hulk") + UnregisterSignal(owner, COMSIG_MOB_SAY) -/datum/mutation/human/hulk/say_mod(message) +/datum/mutation/human/hulk/proc/handle_speech(original_message, wrapped_message) + var/message = wrapped_message[1] if(message) - message = "[uppertext(replacetext(message, ".", "!"))]!!" - return message + message = "[replacetext(message, ".", "!")]!!" + wrapped_message[1] = message + return COMPONENT_UPPERCASE_SPEECH diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index d986672924..f02b7f185f 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -17,9 +17,20 @@ text_gain_indication = "You feel an off sensation in your voicebox." text_lose_indication = "The off sensation passes." -/datum/mutation/human/wacky/get_spans() - return list(SPAN_SANS) +/datum/mutation/human/wacky/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) +/datum/mutation/human/wacky/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/wacky/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_SANS /datum/mutation/human/mute name = "Mute" @@ -28,12 +39,14 @@ text_lose_indication = "You feel able to speak freely again." /datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) - if(..()) + . = ..() + if(.) return ADD_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) /datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner) - if(..()) + . = ..() + if(.) return REMOVE_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) @@ -45,7 +58,20 @@ text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)" text_lose_indication = "Everything is terrible again. :(" -/datum/mutation/human/smile/say_mod(message) +/datum/mutation/human/smile/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/smile/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/smile/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " //Time for a friendly game of SS13 @@ -65,34 +91,31 @@ message = replacetext(message," oh god "," cheese and crackers ") message = replacetext(message," jesus "," gee wiz ") message = replacetext(message," weak "," strong ") - message = replacetext(message," kill "," hug ") - message = replacetext(message," murder "," tease ") + message = replacetext(message," kill yourself "," hug ") message = replacetext(message," ugly "," beautiful ") message = replacetext(message," douchbag "," nice guy ") message = replacetext(message," whore "," lady ") - message = replacetext(message," nerd "," smart guy ") + message = replacetext(message," nerd "," smarty pants ") message = replacetext(message," moron "," fun person ") message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ") message = replacetext(message," sex "," hug fight ") message = replacetext(message," idiot "," genius ") message = replacetext(message," fat "," thin ") - message = replacetext(message," beer "," water with ice ") - message = replacetext(message," drink "," water ") + message = replacetext(message," beer "," liquid bread ") + message = replacetext(message," drink "," liquid ") message = replacetext(message," feminist "," empowered woman ") - message = replacetext(message," i hate you "," you're mean ") - message = replacetext(message," nigger "," african american ") + message = replacetext(message," i hate you "," you're a mean ") message = replacetext(message," jew "," jewish ") message = replacetext(message," shit "," shiz ") message = replacetext(message," crap "," poo ") message = replacetext(message," slut "," tease ") message = replacetext(message," ass "," butt ") message = replacetext(message," damn "," dang ") - message = replacetext(message," fuck "," ") message = replacetext(message," penis "," privates ") message = replacetext(message," cunt "," privates ") - message = replacetext(message," dick "," jerk ") + message = replacetext(message," dick "," privates ") message = replacetext(message," vagina "," privates ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/unintelligible @@ -102,30 +125,17 @@ text_gain_indication = "You can't seem to form any coherent thoughts!" text_lose_indication = "Your mind feels more clear." -/datum/mutation/human/unintelligible/say_mod(message) - if(message) - var/prefix=copytext(message,1,2) - if(prefix == ";") - message = copytext(message,2) - else if(prefix in list(":","#")) - prefix += copytext(message,2,3) - message = copytext(message,3) - else - prefix="" +/datum/mutation/human/unintelligible/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) - var/list/words = splittext(message," ") - var/list/rearranged = list() - for(var/i=1;i<=words.len;i++) - var/cword = pick(words) - words.Remove(cword) - var/suffix = copytext(cword,length(cword)-1,length(cword)) - while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) - cword = copytext(cword,1 ,length(cword)-1) - suffix = copytext(cword,length(cword)-1,length(cword) ) - if(length(cword)) - rearranged += cword - message ="[prefix][jointext(rearranged," ")]" - return message +/datum/mutation/human/unintelligible/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) /datum/mutation/human/swedish @@ -135,7 +145,20 @@ text_gain_indication = "You feel Swedish, however that works." text_lose_indication = "The feeling of Swedishness passes." -/datum/mutation/human/swedish/say_mod(message) +/datum/mutation/human/swedish/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/swedish/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/swedish/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = replacetext(message,"w","v") message = replacetext(message,"j","y") @@ -144,7 +167,7 @@ message = replacetext(message,"o",pick("�","�","o")) if(prob(30)) message += " Bork[pick("",", bork",", bork, bork")]!" - return message + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/chav @@ -154,7 +177,20 @@ text_gain_indication = "Ye feel like a reet prat like, innit?" text_lose_indication = "You no longer feel like being rude and sassy." -/datum/mutation/human/chav/say_mod(message) +/datum/mutation/human/chav/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/chav/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/chav/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " message = replacetext(message," looking at "," gawpin' at ") @@ -178,7 +214,7 @@ message = replacetext(message," break "," do ") message = replacetext(message," your "," yer ") message = replacetext(message," security "," coppers ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/elvis @@ -199,7 +235,20 @@ if(prob(15)) owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!") -/datum/mutation/human/elvis/say_mod(message) +/datum/mutation/human/elvis/on_acquiring(mob/living/carbon/human/owner) + . = ..() + if(.) + return + RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/mutation/human/elvis/on_losing(mob/living/carbon/human/owner) + . = ..() + if(.) + return + UnregisterSignal(owner, COMSIG_MOB_SAY) + +/datum/mutation/human/elvis/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] if(message) message = " [message] " message = replacetext(message," i'm not "," I aint ") @@ -211,7 +260,7 @@ message = replacetext(message," yes ",pick(" sure", "yea ")) message = replacetext(message," faggot "," square ") message = replacetext(message," muh valids "," getting my kicks ") - return trim(message) + speech_args[SPEECH_MESSAGE] = trim(message) /datum/mutation/human/stoner @@ -229,4 +278,4 @@ /datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) ..() owner.grant_language(/datum/language/common) - owner.remove_language(/datum/language/beachbum) \ No newline at end of file + owner.remove_language(/datum/language/beachbum) diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 22fca23902..9762426608 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -305,3 +305,9 @@ suffix = "spacehermit.dmm" name = "Space Hermit" description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck." + +/datum/map_template/ruin/space/advancedlab + id = "advancedlab" + suffix = "advancedlab.dmm" + name = "Abductor Replication Lab" + description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien." diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index c4f485653e..3b6fae5aee 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -11,7 +11,7 @@ /datum/saymode/changeling - key = "g" + key = MODE_KEY_CHANGELING mode = MODE_CHANGELING /datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language) @@ -73,7 +73,7 @@ /datum/saymode/vocalcords - key = "x" + key = MODE_KEY_VOCALCORDS mode = MODE_VOCALCORDS /datum/saymode/vocalcords/handle_message(mob/living/user, message, datum/language/language) @@ -87,7 +87,7 @@ /datum/saymode/binary //everything that uses .b (silicons, drones, blobbernauts/spores, swarmers) - key = "b" + key = MODE_KEY_BINARY mode = MODE_BINARY /datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 0512977d1a..336945f622 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -170,7 +170,7 @@ tick_interval = 4 alert_type = /obj/screen/alert/status_effect/his_grace var/bloodlust = 0 - + /obj/screen/alert/status_effect/his_grace name = "His Grace" desc = "His Grace hungers, and you must feed Him." @@ -208,6 +208,7 @@ owner.adjustToxLoss(-grace_heal, TRUE, TRUE) owner.adjustOxyLoss(-(grace_heal * 2)) owner.adjustCloneLoss(-grace_heal) + owner.adjustStaminaLoss(-(grace_heal * 25)) /datum/status_effect/his_grace/on_remove() owner.log_message("lost His Grace's stun immunity", LOG_ATTACK) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 1c77520108..e930c77c36 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -507,3 +507,101 @@ desc = "Your body is covered in blue ichor! You can't be revived by vitality matrices." icon_state = "ichorial_stain" alerttooltipstyle = "clockcult" + +datum/status_effect/pacify + id = "pacify" + status_type = STATUS_EFFECT_REPLACE + tick_interval = 1 + duration = 100 + alert_type = null + +/datum/status_effect/pacify/on_creation(mob/living/new_owner, set_duration) + if(isnum(set_duration)) + duration = set_duration + . = ..() + +/datum/status_effect/pacify/on_apply() + ADD_TRAIT(owner, TRAIT_PACIFISM, "status_effect") + return ..() + +/datum/status_effect/pacify/on_remove() + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "status_effect") + +/datum/status_effect/trance + id = "trance" + status_type = STATUS_EFFECT_UNIQUE + duration = 300 + tick_interval = 10 + examine_text = "SUBJECTPRONOUN seems slow and unfocused." + var/stun = TRUE + var/triggered = FALSE + alert_type = null + +/obj/screen/alert/status_effect/trance + name = "Trance" + desc = "Everything feels so distant, and you can feel your thoughts forming loops inside your head..." + icon_state = "high" + +/datum/status_effect/trance/tick() + if(HAS_TRAIT(owner, "hypnotherapy")) + if(triggered == TRUE) + UnregisterSignal(owner, COMSIG_MOVABLE_HEAR) + RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/hypnotize) + ADD_TRAIT(owner, TRAIT_MUTE, "trance") + if(!owner.has_quirk(/datum/quirk/monochromatic)) + owner.add_client_colour(/datum/client_colour/monochrome) + to_chat(owner, "[pick("You feel your thoughts slow down...", "You suddenly feel extremely dizzy...", "You feel like you're in the middle of a dream...","You feel incredibly relaxed...")]") + triggered = FALSE + else + return + if(stun) + owner.Stun(60, TRUE, TRUE) + owner.dizziness = 20 + +/datum/status_effect/trance/on_apply() + if(!iscarbon(owner)) + return FALSE + if(HAS_TRAIT(owner, "hypnotherapy")) + RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/listen) + return TRUE + alert_type = /obj/screen/alert/status_effect/trance + RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/hypnotize) + ADD_TRAIT(owner, TRAIT_MUTE, "trance") + if(!owner.has_quirk(/datum/quirk/monochromatic)) + owner.add_client_colour(/datum/client_colour/monochrome) + owner.visible_message("[stun ? "[owner] stands still as [owner.p_their()] eyes seem to focus on a distant point." : ""]", \ + "[pick("You feel your thoughts slow down...", "You suddenly feel extremely dizzy...", "You feel like you're in the middle of a dream...","You feel incredibly relaxed...")]") + return TRUE + +/datum/status_effect/trance/on_creation(mob/living/new_owner, _duration, _stun = TRUE, source_quirk = FALSE)//hypnoquirk makes no visible message, prevents self antag messages, and places phrase below objectives. + duration = _duration + stun = _stun + if(source_quirk == FALSE && HAS_TRAIT(owner, "hypnotherapy")) + REMOVE_TRAIT(owner, "hypnotherapy", ROUNDSTART_TRAIT) + return ..() + +/datum/status_effect/trance/on_remove() + UnregisterSignal(owner, COMSIG_MOVABLE_HEAR) + REMOVE_TRAIT(owner, TRAIT_MUTE, "trance") + owner.dizziness = 0 + if(!owner.has_quirk(/datum/quirk/monochromatic)) + owner.remove_client_colour(/datum/client_colour/monochrome) + to_chat(owner, "You snap out of your trance!") + +/datum/status_effect/trance/proc/listen(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + to_chat(owner, "[speaker] accidentally sets off your implanted trigger, sending you into a hypnotic daze!") + triggered = TRUE + +/datum/status_effect/trance/proc/hypnotize(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + if(!owner.can_hear()) + return + if(speaker == owner) + return + var/mob/living/carbon/C = owner + C.cure_trauma_type(/datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY) //clear previous hypnosis + if(HAS_TRAIT(C, "hypnotherapy")) + addtimer(CALLBACK(C, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, raw_message, TRUE), 10) + else + addtimer(CALLBACK(C, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, raw_message), 10) + addtimer(CALLBACK(C, /mob/living.proc/Stun, 60, TRUE, TRUE), 15) //Take some time to think about it + qdel(src) diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index cc6dd8db3f..12e34b0c90 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -13,7 +13,6 @@ var/mob/living/quirk_holder /datum/quirk/New(mob/living/quirk_mob, spawn_effects) - ..() if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type)) qdel(src) quirk_holder = quirk_mob diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 300a1264eb..dffdc92630 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -186,3 +186,20 @@ var/obj/item/autosurgeon/gloweyes/gloweyes = new(get_turf(H)) H.equip_to_slot(gloweyes, SLOT_IN_BACKPACK) H.regenerate_icons() + +/datum/quirk/bloodpressure + name = "Polycythemia vera" + desc = "You've a treated form of Polycythemia vera that increases the total blood volume inside of you as well as the rate of replenishment!" + value = 2 //I honeslty dunno if this is a good trait? I just means you use more of medbays blood and make janitors madder, but you also regen blood a lil faster. + mob_trait = TRAIT_HIGH_BLOOD + gain_text = "You feel full of blood!" + lose_text = "You feel like your blood pressure went down." + +/datum/quirk/bloodpressure/add() + var/mob/living/M = quirk_holder + M.blood_ratio = 1.2 + M.blood_volume += 150 + +/datum/quirk/bloodpressure/remove() + var/mob/living/M = quirk_holder + M.blood_ratio = 1 diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 36c6733cf7..f77fe37333 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -354,3 +354,12 @@ if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums)) to_chat(quirk_holder, "Your antagonistic nature has caused your voice to be heard.") qdel(src) + +/datum/quirk/unstable + name = "Unstable" + desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!" + value = -2 + mob_trait = TRAIT_UNSTABLE + gain_text = "There's a lot on your mind right now." + lose_text = "Your mind finally feels calm." + medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events." diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index f1b08ee18b..fab5a1313c 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -231,6 +231,9 @@ // Same for anyone with an abductor multitool. else if(user.is_holding_item_of_type(/obj/item/multitool/abductor)) reveal_wires = TRUE + // and advanced multitool + else if(user.is_holding_item_of_type(/obj/item/multitool/advanced)) + reveal_wires = TRUE // Station blueprints do that too, but only if the wires are not randomized. else if(user.is_holding_item_of_type(/obj/item/areaeditor/blueprints) && !randomize) diff --git a/code/datums/wires/autolathe.dm b/code/datums/wires/autolathe.dm index ebad7d1469..f83bab5910 100644 --- a/code/datums/wires/autolathe.dm +++ b/code/datums/wires/autolathe.dm @@ -30,6 +30,7 @@ addtimer(CALLBACK(A, /obj/machinery/autolathe.proc/reset, wire), 60) if(WIRE_SHOCK) A.shocked = !A.shocked + A.shock(usr, 50) addtimer(CALLBACK(A, /obj/machinery/autolathe.proc/reset, wire), 60) if(WIRE_DISABLE) A.disabled = !A.disabled @@ -40,9 +41,11 @@ switch(wire) if(WIRE_HACK) A.adjust_hacked(!mend) - if(WIRE_HACK) + if(WIRE_SHOCK) A.shocked = !mend + A.shock(usr, 50) if(WIRE_DISABLE) A.disabled = !mend if(WIRE_ZAP) - A.shock(usr, 50) \ No newline at end of file + A.shock(usr, 50) + diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm index 00a7fed012..d5ceb833b7 100644 --- a/code/game/area/areas/ruins/space.dm +++ b/code/game/area/areas/ruins/space.dm @@ -467,3 +467,8 @@ /area/ruin/space/has_grav/powered/ancient_shuttle name = "Ancient Shuttle" icon_state = "yellow" + +// Abductor Replication Lab +/area/ruin/space/has_grav/powered/advancedlab + name = "Abductor Replication Lab" + icon_state = "yellow" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index f2eb23808e..6665e4d59b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -289,8 +289,11 @@ to_chat(user, "You can't move while buckled to [src]!") return +/atom/proc/prevent_content_explosion() + return FALSE + /atom/proc/contents_explosion(severity, target) - return + return //For handling the effects of explosions on contents that would not normally be effected /atom/proc/ex_act(severity, target) set waitfor = FALSE @@ -376,7 +379,7 @@ SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume) /atom/proc/emag_act() - SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) + return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) /atom/proc/rad_act(strength) SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f88f4f8e41..83762240bc 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -14,6 +14,7 @@ var/verb_exclaim = "exclaims" var/verb_whisper = "whispers" var/verb_yell = "yells" + var/speech_span var/inertia_dir = 0 var/atom/inertia_last_loc var/inertia_moving = 0 diff --git a/code/game/communications.dm b/code/game/communications.dm index 212a99f966..ed470473d9 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -91,35 +91,35 @@ GLOBAL_LIST_EMPTY(all_radios) // use in maps, such as in intercoms. GLOBAL_LIST_INIT(radiochannels, list( - "Common" = FREQ_COMMON, - "Science" = FREQ_SCIENCE, - "Command" = FREQ_COMMAND, - "Medical" = FREQ_MEDICAL, - "Engineering" = FREQ_ENGINEERING, - "Security" = FREQ_SECURITY, - "CentCom" = FREQ_CENTCOM, - "Syndicate" = FREQ_SYNDICATE, - "Supply" = FREQ_SUPPLY, - "Service" = FREQ_SERVICE, - "AI Private" = FREQ_AI_PRIVATE, - "Red Team" = FREQ_CTF_RED, - "Blue Team" = FREQ_CTF_BLUE + RADIO_CHANNEL_COMMON = FREQ_COMMON, + RADIO_CHANNEL_SCIENCE = FREQ_SCIENCE, + RADIO_CHANNEL_COMMAND = FREQ_COMMAND, + RADIO_CHANNEL_MEDICAL = FREQ_MEDICAL, + RADIO_CHANNEL_ENGINEERING = FREQ_ENGINEERING, + RADIO_CHANNEL_SECURITY = FREQ_SECURITY, + RADIO_CHANNEL_CENTCOM = FREQ_CENTCOM, + RADIO_CHANNEL_SYNDICATE = FREQ_SYNDICATE, + RADIO_CHANNEL_SUPPLY = FREQ_SUPPLY, + RADIO_CHANNEL_SERVICE = FREQ_SERVICE, + RADIO_CHANNEL_AI_PRIVATE = FREQ_AI_PRIVATE, + RADIO_CHANNEL_CTF_RED = FREQ_CTF_RED, + RADIO_CHANNEL_CTF_BLUE = FREQ_CTF_BLUE )) GLOBAL_LIST_INIT(reverseradiochannels, list( - "[FREQ_COMMON]" = "Common", - "[FREQ_SCIENCE]" = "Science", - "[FREQ_COMMAND]" = "Command", - "[FREQ_MEDICAL]" = "Medical", - "[FREQ_ENGINEERING]" = "Engineering", - "[FREQ_SECURITY]" = "Security", - "[FREQ_CENTCOM]" = "CentCom", - "[FREQ_SYNDICATE]" = "Syndicate", - "[FREQ_SUPPLY]" = "Supply", - "[FREQ_SERVICE]" = "Service", - "[FREQ_AI_PRIVATE]" = "AI Private", - "[FREQ_CTF_RED]" = "Red Team", - "[FREQ_CTF_BLUE]" = "Blue Team" + "[FREQ_COMMON]" = RADIO_CHANNEL_COMMON, + "[FREQ_SCIENCE]" = RADIO_CHANNEL_SCIENCE, + "[FREQ_COMMAND]" = RADIO_CHANNEL_COMMAND, + "[FREQ_MEDICAL]" = RADIO_CHANNEL_MEDICAL, + "[FREQ_ENGINEERING]" = RADIO_CHANNEL_ENGINEERING, + "[FREQ_SECURITY]" = RADIO_CHANNEL_SECURITY, + "[FREQ_CENTCOM]" = RADIO_CHANNEL_CENTCOM, + "[FREQ_SYNDICATE]" = RADIO_CHANNEL_SYNDICATE, + "[FREQ_SUPPLY]" = RADIO_CHANNEL_SUPPLY, + "[FREQ_SERVICE]" = RADIO_CHANNEL_SERVICE, + "[FREQ_AI_PRIVATE]" = RADIO_CHANNEL_AI_PRIVATE, + "[FREQ_CTF_RED]" = RADIO_CHANNEL_CTF_RED, + "[FREQ_CTF_BLUE]" = RADIO_CHANNEL_CTF_BLUE )) /datum/radio_frequency diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index e25c4f7716..18611ebfcb 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -6,6 +6,7 @@ name = "traitor+brothers" config_tag = "traitorbro" restricted_jobs = list("AI", "Cyborg") + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Research Director") announce_span = "danger" announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\ diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index feb81d44e0..d6131ce58e 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -86,8 +86,11 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name user.underwear = chosen_prof.underwear + user.undie_color = chosen_prof.undie_color user.undershirt = chosen_prof.undershirt + user.shirt_color =chosen_prof.shirt_color user.socks = chosen_prof.socks + user.socks_color =chosen_prof.socks_color chosen_dna.transfer_identity(user, 1) user.updateappearance(mutcolor_update=1) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index a24d846f15..808022d25f 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -52,7 +52,7 @@ Credit where due: if(!istype(M)) return FALSE if(M.mind) - if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) + if(M.mind.assigned_role in list("Captain", "Chaplain")) return FALSE if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to)) return FALSE @@ -275,7 +275,7 @@ Credit where due: gloves = /obj/item/clothing/gloves/color/yellow belt = /obj/item/storage/belt/utility/servant backpack_contents = list(/obj/item/storage/box/engineer = 1, \ - /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1) + /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1) id = /obj/item/pda var/plasmaman //We use this to determine if we should activate internals in post_equip() @@ -338,6 +338,10 @@ Credit where due: CLOCKCULTCHANGELOG\ \
\ +
  • Zelus oil: A new reagent. It can be used to heal the faithful to Ratvar, or kill heretics and moreso stun blood cultists,\ + or splashed onto metal sheets to make brass. This chemical can be found in minimal quantities by grinding brass sheets.\ +
  • Brass Flasks:Intended to store Zelus Oil in, but can also be used as fragile single use throwing weapons in a pinch! \ + These are crafted with a single sheet of brass and fit in the Clockwork Cuirass' suit storage.\ Good luck!" /obj/item/paper/servant_primer/Initialize() diff --git a/code/game/gamemodes/clown_ops/bananium_bomb.dm b/code/game/gamemodes/clown_ops/bananium_bomb.dm index 0d5f0691c4..b63d5b2e79 100644 --- a/code/game/gamemodes/clown_ops/bananium_bomb.dm +++ b/code/game/gamemodes/clown_ops/bananium_bomb.dm @@ -42,18 +42,19 @@ var/obj/item/clothing/C if(!H.w_uniform || H.dropItemToGround(H.w_uniform)) C = new /obj/item/clothing/under/rank/clown(H) - C.item_flags |= NODROP //mwahaha + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_W_UNIFORM) if(!H.shoes || H.dropItemToGround(H.shoes)) C = new /obj/item/clothing/shoes/clown_shoes(H) - C.item_flags |= NODROP + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_SHOES) if(!H.wear_mask || H.dropItemToGround(H.wear_mask)) C = new /obj/item/clothing/mask/gas/clown_hat(H) - C.item_flags |= NODROP + ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) H.equip_to_slot_or_del(C, SLOT_WEAR_MASK) H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) H.gain_trauma(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_LOBOTOMY, "clowns") //MWA HA HA diff --git a/code/game/gamemodes/clown_ops/clown_ops.dm b/code/game/gamemodes/clown_ops/clown_ops.dm index a666b57afd..66de72bad2 100644 --- a/code/game/gamemodes/clown_ops/clown_ops.dm +++ b/code/game/gamemodes/clown_ops/clown_ops.dm @@ -58,6 +58,7 @@ if(visualsOnly) return H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) /datum/outfit/syndicate/clownop/leader name = "Clown Operative Leader - Basic" diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index a3440fad39..9d1a3b650c 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -216,11 +216,11 @@ /obj/item/clothing/mask/fakemoustache/sticky/Initialize() . = ..() - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT) addtimer(CALLBACK(src, .proc/unstick), unstick_time) /obj/item/clothing/mask/fakemoustache/sticky/proc/unstick() - item_flags &= ~NODROP + ADD_TRAIT(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT) //DARK H.O.N.K. AND CLOWN MECH WEAPONS diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 8f091b6372..e7cc3c53ae 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -16,7 +16,7 @@ if(!istype(M)) return FALSE if(M.mind) - if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) + if(M.mind.assigned_role in list("Captain", "Chaplain")) return FALSE if(specific_cult && specific_cult.is_sacrifice_target(M.mind)) return FALSE diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index e56495d808..176f62ef2d 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -53,7 +53,7 @@ name = "the chief engineer's advanced magnetic boots." targetitem = /obj/item/clothing/shoes/magboots/advance difficulty = 5 - excludefromjob = list("Chief Engineer") + excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") /datum/objective_item/steal/capmedal name = "the medal of captaincy." @@ -62,10 +62,10 @@ excludefromjob = list("Captain") /datum/objective_item/steal/hypo - name = "the hypospray." + name = "the Chief Medical Officer's MKII hypospray." targetitem = /obj/item/hypospray/mkii/CMO //CITADEL EDIT, changing theft objective for the Hypo MK II difficulty = 5 - excludefromjob = list("Chief Medical Officer") + excludefromjob = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist") /datum/objective_item/steal/nukedisc name = "the nuclear authentication disk." @@ -83,10 +83,10 @@ excludefromjob = list("Head of Security", "Warden") /datum/objective_item/steal/reactive - name = "the reactive teleport armor." + name = "a reactive teleport armor." targetitem = /obj/item/clothing/suit/armor/reactive difficulty = 5 - excludefromjob = list("Research Director") + excludefromjob = list("Research Director","Scientist", "Roboticist") /datum/objective_item/steal/documents name = "any set of secret documents of any organization." @@ -143,7 +143,7 @@ name = "the station blueprints." targetitem = /obj/item/areaeditor/blueprints difficulty = 10 - excludefromjob = list("Chief Engineer") + excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") altitems = list(/obj/item/photo) /datum/objective_item/steal/blueprints/check_special_completion(obj/item/I) @@ -159,7 +159,7 @@ name = "an unused sample of slime extract." targetitem = /obj/item/slime_extract difficulty = 3 - excludefromjob = list("Research Director","Scientist") + excludefromjob = list("Research Director","Scientist", "Roboticist") /datum/objective_item/steal/slime/check_special_completion(obj/item/slime_extract/E) if(E.Uses > 0) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index aa363428fb..76ea855c77 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -193,8 +193,10 @@ to_chat(usr, "Chem System Re-route detected, results may not be as expected!") /obj/machinery/sleeper/emag_act(mob/user) + . = ..() scramble_chem_buttons() to_chat(user, "You scramble the sleeper's user interface!") + return TRUE /obj/machinery/sleeper/proc/inject_chem(chem, mob/user) if((chem in available_chems) && chem_allowed(chem)) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 959bcfab4d..56227cdd53 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -96,10 +96,10 @@ GLOBAL_LIST_EMPTY(announcement_systems) message = "The arrivals shuttle has been damaged. Docking for repairs..." if(channels.len == 0) - radio.talk_into(src, message, null, list(SPAN_ROBOT), get_default_language()) + radio.talk_into(src, message, null) else for(var/channel in channels) - radio.talk_into(src, message, channel, list(SPAN_ROBOT), get_default_language()) + radio.talk_into(src, message, channel) //config stuff @@ -177,7 +177,9 @@ GLOBAL_LIST_EMPTY(announcement_systems) act_up() /obj/machinery/announcement_system/emag_act() + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED act_up() + return TRUE diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index c751ba007a..0b9ed6bb3f 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -6,7 +6,7 @@ var/siphoning = FALSE var/next_warning = 0 var/obj/item/radio/radio - var/radio_channel = "Common" + var/radio_channel = RADIO_CHANNEL_COMMON var/minimum_time_between_warnings = 400 /obj/machinery/computer/bank_machine/Initialize() @@ -49,12 +49,9 @@ if(next_warning < world.time && prob(15)) var/area/A = get_area(loc) var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!" - radio.talk_into(src, message, radio_channel, get_spans()) + radio.talk_into(src, message, radio_channel) next_warning = world.time + minimum_time_between_warnings -/obj/machinery/computer/bank_machine/get_spans() - . = ..() | SPAN_ROBOT - /obj/machinery/computer/bank_machine/ui_interact(mob/user) . = ..() var/dat = "[station_name()] secure vault. Authorized personnel only.
    " diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 879be046c9..968cbe7254 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -101,12 +101,14 @@ return ..() /obj/machinery/button/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return req_access = list() req_one_access = list() playsound(src, "sparks", 100, 1) obj_flags |= EMAGGED + return TRUE /obj/machinery/button/attack_ai(mob/user) if(!panel_open) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 36a5c6ede4..a175558f74 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -6,7 +6,7 @@ #define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical #define MINIMUM_HEAL_LEVEL 40 -#define SPEAK(message) radio.talk_into(src, message, radio_channel, get_spans(), get_default_language()) +#define SPEAK(message) radio.talk_into(src, message, radio_channel) /obj/machinery/clonepod name = "cloning pod" @@ -31,7 +31,7 @@ var/internal_radio = TRUE var/obj/item/radio/radio var/radio_key = /obj/item/encryptionkey/headset_med - var/radio_channel = "Medical" + var/radio_channel = RADIO_CHANNEL_MEDICAL var/obj/effect/countdown/clonepod/countdown @@ -163,15 +163,8 @@ H.hardset_dna(ui, se, H.real_name, null, mrace, features) - if(efficiency > 2) - var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - H.dna.remove_mutation_group(unclean_mutations) - if(efficiency > 5 && prob(20)) - H.randmutvg() - if(efficiency < 3 && prob(50)) - var/mob/M = H.randmutb() - if(ismob(M)) - H = M + if(prob(50 - efficiency*10)) //Chance to give a bad mutation. + H.randmutb() //100% bad mutation. Can be cured with mutadone. H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. occupant = H @@ -327,10 +320,12 @@ return ..() /obj/machinery/clonepod/emag_act(mob/user) + . = ..() if(!occupant) return to_chat(user, "You corrupt the genetic compiler.") malfunction() + return TRUE //Put messages in the connected computer's temp var for display. /obj/machinery/clonepod/proc/connected_message(message) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 73fdcd5e8b..c317cbba0d 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -44,7 +44,7 @@ table.computer = src break -/obj/machinery/computer/operating/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) +/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state) @@ -125,4 +125,4 @@ . = TRUE #undef MENU_OPERATION -#undef MENU_SURGERIES \ No newline at end of file +#undef MENU_SURGERIES diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index e51d623c2f..1c517d6e8f 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -185,15 +185,19 @@ ui_interact(usr) //Refresh the UI after a filter changes /obj/machinery/computer/apc_control/emag_act(mob/user) + . = ..() if(!authenticated) to_chat(user, "You bypass [src]'s access requirements using your emag.") authenticated = TRUE log_activity("logged in") - else if(!(obj_flags & EMAGGED)) + else + if(obj_flags & EMAGGED) + return user.visible_message("You emag [src], disabling precise logging and allowing you to clear logs.") log_game("[key_name(user)] emagged [src] at [AREACOORD(src)], disabling operator tracking.") obj_flags |= EMAGGED - playsound(src, "sparks", 50, 1) + playsound(src, "sparks", 50, 1) + return TRUE /obj/machinery/computer/apc_control/proc/log_activity(log_text) var/op_string = operator && !(obj_flags & EMAGGED) ? operator : "\[NULL OPERATOR\]" diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 8d0cfb95e8..4bce450359 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -45,8 +45,8 @@ /obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = ARCADE_WEIGHT_TRICK, /obj/item/hot_potato/harmless/toy = ARCADE_WEIGHT_RARE, /obj/item/twohanded/dualsaber/toy = ARCADE_WEIGHT_RARE, - /obj/item/twohanded/hypereutactic/toy = ARCADE_WEIGHT_RARE, - /obj/item/twohanded/hypereutactic/toy/rainbow = ARCADE_WEIGHT_RARE, + /obj/item/twohanded/dualsaber/hypereutactic/toy = ARCADE_WEIGHT_RARE, + /obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow = ARCADE_WEIGHT_RARE, /obj/item/storage/box/snappops = ARCADE_WEIGHT_TRICK, /obj/item/clothing/under/syndicate/tacticool = ARCADE_WEIGHT_TRICK, @@ -57,6 +57,7 @@ /obj/item/stack/tile/fakespace/loaded = ARCADE_WEIGHT_TRICK, /obj/item/stack/tile/fakepit/loaded = ARCADE_WEIGHT_TRICK, /obj/item/restraints/handcuffs/fake = ARCADE_WEIGHT_TRICK, + /obj/item/clothing/gloves/rapid/hug = ARCADE_WEIGHT_TRICK, /obj/item/grenade/chem_grenade/glitter/pink = ARCADE_WEIGHT_TRICK, /obj/item/grenade/chem_grenade/glitter/blue = ARCADE_WEIGHT_TRICK, diff --git a/code/game/machinery/computer/arcade/battle.dm b/code/game/machinery/computer/arcade/battle.dm index ded9cf95f6..b906b1afb5 100644 --- a/code/game/machinery/computer/arcade/battle.dm +++ b/code/game/machinery/computer/arcade/battle.dm @@ -186,6 +186,7 @@ /obj/machinery/computer/arcade/battle/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!") @@ -202,5 +203,5 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - updateUsrDialog() + return TRUE \ No newline at end of file diff --git a/code/game/machinery/computer/arcade/minesweeper.dm b/code/game/machinery/computer/arcade/minesweeper.dm index fe69860f76..641ef1c9cd 100644 --- a/code/game/machinery/computer/arcade/minesweeper.dm +++ b/code/game/machinery/computer/arcade/minesweeper.dm @@ -250,11 +250,11 @@ itemname = "a syndicate bomb beacon" new /obj/item/sbeacondrop/bomb(loc) if(2) - itemname = "a grenade launcher" - new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(loc) - new /obj/item/ammo_casing/a40mm(loc) - new /obj/item/ammo_casing/a40mm(loc) - new /obj/item/ammo_casing/a40mm(loc) + itemname = "a rocket launcher" + new /obj/item/gun/ballistic/rocketlauncher/unrestricted(loc) + new /obj/item/ammo_casing/caseless/rocket(loc) + new /obj/item/ammo_casing/caseless/rocket(loc) + new /obj/item/ammo_casing/caseless/rocket(loc) if(3) itemname = "two bags of c4" new /obj/item/storage/backpack/duffelbag/syndie/c4(loc) @@ -284,6 +284,7 @@ return /obj/machinery/computer/arcade/minesweeper/emag_act(mob/user) + . = ..() if(CHECK_BITFIELD(obj_flags, EMAGGED)) return desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!" @@ -298,6 +299,7 @@ to_chat(user, "The machine buzzes and sparks... the game has been reset!") playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz game_status = MINESWEEPER_GAME_MAIN_MENU + return TRUE /obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user) playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound diff --git a/code/game/machinery/computer/arcade/orion_trail.dm b/code/game/machinery/computer/arcade/orion_trail.dm index 12941dea35..023b1048ce 100644 --- a/code/game/machinery/computer/arcade/orion_trail.dm +++ b/code/game/machinery/computer/arcade/orion_trail.dm @@ -736,6 +736,7 @@ desc = "Learn how our ancestors got to Orion, and have fun in the process!" /obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") @@ -743,6 +744,7 @@ desc = "Learn how our ancestors got to Orion, and try not to die in the process!" newgame() obj_flags |= EMAGGED + return TRUE /mob/living/simple_animal/hostile/syndicate/ranged/smg/orion name = "spaceport security" diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 86fcefb340..43582e39bf 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -361,14 +361,16 @@ return button_icon_state = "warp_down" owner.update_action_buttons() + QDEL_NULL(warping) + if(!do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) + to_chat(user, "Warp Failed. Something deflected our attempt to warp to [AR].") + return T.visible_message("[user] warps in!") playsound(user, 'sound/magic/magic_missile.ogg', 50, TRUE) playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE) - user.forceMove(get_turf(T)) user.setDir(SOUTH) flash_color(user, flash_color = "#AF0AAF", flash_time = 5) R.remove_eye_control(user) - QDEL_NULL(warping) /datum/action/innate/servant_warp/proc/is_canceled() return !cancel diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 39d5c3d56f..26f0d06ecb 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,4 +1,4 @@ -#define AUTOCLONING_MINIMAL_LEVEL 3 +#define AUTOCLONING_MINIMAL_LEVEL 4 /obj/machinery/computer/cloning name = "cloning console" @@ -13,17 +13,20 @@ var/scantemp_ckey var/scantemp = "Ready to Scan" var/menu = 1 //Which menu screen to display - var/list/records = list() var/datum/data/record/active_record = null var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text var/autoprocess = 0 + var/list/records = list() light_color = LIGHT_COLOR_BLUE /obj/machinery/computer/cloning/Initialize() . = ..() updatemodules(TRUE) + var/obj/item/circuitboard/computer/cloning/board = circuit + records = board.records + /obj/machinery/computer/cloning/Destroy() if(pods) @@ -61,9 +64,6 @@ if(!(scanner && LAZYLEN(pods) && autoprocess)) return - if(scanner.occupant && scanner.scan_level > 2) - scan_occupant(scanner.occupant) - for(var/datum/data/record/R in records) var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"]) @@ -346,6 +346,8 @@ active_record = null playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) src.menu = 2 + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records else src.temp = "Access Denied." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) @@ -368,6 +370,8 @@ for(var/key in diskette.fields) src.active_record.fields[key] = diskette.fields[key] src.temp = "Load successful." + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) if("eject") @@ -502,5 +506,7 @@ R.fields["imp"] = "[REF(imp)]" src.records += R + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records scantemp = "Subject successfully scanned." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 752765baa1..eceaefd2b2 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -432,6 +432,7 @@ return ..() /obj/machinery/computer/communications/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED @@ -440,6 +441,7 @@ authenticated = 2 to_chat(user, "You scramble the communication routing circuits!") playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return TRUE /obj/machinery/computer/communications/ui_interact(mob/user) . = ..() diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index 7b7c8a3411..4210435f33 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -69,7 +69,7 @@ if(defib) to_chat(user, "There's already a defibrillator in [src]!") return - if(I.item_flags & NODROP || !user.transferItemToLoc(I, src)) + if(HAS_TRAIT(I, TRAIT_NODROP) || !user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return user.visible_message("[user] hooks up [I] to [src]!", \ diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1081cb5fa7..365d19b826 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1280,20 +1280,23 @@ return !density || (check_access(ID) && !locked && hasPower()) /obj/machinery/door/airlock/emag_act(mob/user) - if(!operating && density && hasPower() && !(obj_flags & EMAGGED)) - operating = TRUE - update_icon(AIRLOCK_EMAG, 1) - sleep(6) - if(QDELETED(src)) - return - operating = FALSE - if(!open()) - update_icon(AIRLOCK_CLOSED, 1) - obj_flags |= EMAGGED - lights = FALSE - locked = TRUE - loseMainPower() - loseBackupPower() + . = ..() + if(operating || !density || !hasPower() || obj_flags & EMAGGED) + return + operating = TRUE + update_icon(AIRLOCK_EMAG, 1) + addtimer(CALLBACK(src, .proc/open_sesame), 6) + return TRUE + +/obj/machinery/door/airlock/proc/open_sesame() + operating = FALSE + if(!open()) + update_icon(AIRLOCK_CLOSED, 1) + obj_flags |= EMAGGED + lights = FALSE + locked = TRUE + loseMainPower() + loseBackupPower() /obj/machinery/door/airlock/attack_alien(mob/living/carbon/alien/humanoid/user) add_fingerprint(user) diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index 2e7e7d5cba..702f700617 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -13,9 +13,6 @@ else return ..() -/obj/machinery/door/unpowered/emag_act() - return - /obj/machinery/door/unpowered/shuttle icon = 'icons/turf/shuttle.dmi' name = "door" diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 97ab664b85..933bb4f42a 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -206,15 +206,20 @@ ..() /obj/machinery/door/window/emag_act(mob/user) - if(!operating && density && !(obj_flags & EMAGGED)) - obj_flags |= EMAGGED - operating = TRUE - flick("[src.base_state]spark", src) - playsound(src, "sparks", 75, 1) - sleep(6) - operating = FALSE - desc += "
    Its access panel is smoking slightly." - open(2) + . = ..() + if(operating || !density || obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + operating = TRUE + flick("[src.base_state]spark", src) + playsound(src, "sparks", 75, 1) + addtimer(CALLBACK(src, .proc/open_windows_me), 6) + return TRUE + +/obj/machinery/door/window/proc/open_windows_me() + operating = FALSE + desc += "
    Its access panel is smoking slightly." + open(2) /obj/machinery/door/window/attackby(obj/item/I, mob/living/user, params) diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 70ce3d36ae..3b9322d207 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -26,6 +26,7 @@ findObjsByTag() /obj/machinery/doorButtons/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED @@ -33,6 +34,7 @@ req_one_access = list() playsound(src, "sparks", 100, 1) to_chat(user, "You short out the access controller.") + return TRUE /obj/machinery/doorButtons/proc/removeMe() diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 8f0d56a49e..5c2676c2b9 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -97,6 +97,7 @@ alarm() /obj/machinery/firealarm/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED @@ -104,6 +105,7 @@ user.visible_message("Sparks fly out of [src]!", "You emag [src], disabling its thermal sensors.") playsound(src, "sparks", 50, 1) + return TRUE /obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !(obj_flags & EMAGGED) && detecting && !stat) diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm index c955edbcd0..320430be39 100644 --- a/code/game/machinery/gulag_item_reclaimer.dm +++ b/code/game/machinery/gulag_item_reclaimer.dm @@ -24,13 +24,15 @@ return ..() /obj/machinery/gulag_item_reclaimer/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) // emagging lets anyone reclaim all the items return req_access = list() obj_flags |= EMAGGED + return TRUE /obj/machinery/gulag_item_reclaimer/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/card/id/prisoner)) + if(istype(I, /obj/item/card/id)) if(!inserted_id) if(!user.transferItemToLoc(I, src)) return @@ -83,7 +85,7 @@ usr.put_in_hands(inserted_id) inserted_id = null else - var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id) if(I) if(!usr.transferItemToLoc(I, src)) return diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 0042da1c92..1fccadda21 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -65,7 +65,7 @@ if(!isitem(A)) continue var/obj/item/I = A - if(!(I.item_flags & NODROP)) + if(!HAS_TRAIT(I, TRAIT_NODROP)) say("Subject may not have abiotic items on.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1) return @@ -158,11 +158,13 @@ open_machine() /obj/machinery/harvester/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED allow_living = TRUE to_chat(user, "You overload [src]'s lifesign scanners.") + return TRUE /obj/machinery/harvester/container_resist(mob/living/user) if(!harvesting) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 7284b3c738..b217c14e53 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -63,7 +63,7 @@ if(91 to INFINITY) filling_overlay.icon_state = "reagent100" - filling_overlay.color = list("#0000", "#0000", "#0000", "#000f", mix_color_from_reagents(beaker.reagents.reagent_list)) + filling_overlay.color = mix_color_from_reagents(beaker.reagents.reagent_list) add_overlay(filling_overlay) /obj/machinery/iv_drip/MouseDrop(mob/living/target) @@ -81,12 +81,6 @@ to_chat(usr, "The drip beeps: Warning, incompatible creature!") return - var/mob/living/L - if(isliving(target)) - L = target - if(!L.can_inject(usr, 1)) - return - if(Adjacent(target) && usr.Adjacent(target)) if(beaker) usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].") @@ -151,7 +145,7 @@ return // If the human is losing too much blood, beep. - if(attached.blood_volume < BLOOD_VOLUME_SAFE && prob(5)) + if(attached.blood_volume < ( (BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) ) ) visible_message("[src] beeps loudly.") playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) attached.transfer_blood_to(beaker, amount) @@ -224,4 +218,4 @@ to_chat(user, "[attached ? attached : "No one"] is attached.") #undef IV_TAKING -#undef IV_INJECTING \ No newline at end of file +#undef IV_INJECTING diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 4016c32162..db59f3f413 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -127,7 +127,7 @@ if(first_inner) log_msg += "empty" log_msg += ")" - do_teleport(ROI, dest, no_effects = !first) + do_teleport(ROI, dest, no_effects = !first, channel = TELEPORT_CHANNEL_BLUESPACE) first = FALSE if (first) @@ -206,7 +206,7 @@ /obj/item/storage/briefcase/launchpad/PopulateContents() new /obj/item/pen(src) - new /obj/item/launchpad_remote(src, pad) + new /obj/item/launchpad_remote(src, pad) /obj/item/storage/briefcase/launchpad/attack_self(mob/user) if(!isturf(user.loc)) //no setting up in a locker @@ -227,7 +227,7 @@ L.pad = src.pad to_chat(user, "You link [pad] to [L].") else - return ..() + return ..() /obj/item/launchpad_remote name = "folder" diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index a3250fe1b0..59806e97a4 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -215,6 +215,7 @@ return dat /obj/machinery/limbgrower/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return for(var/id in SSresearch.techweb_designs) @@ -223,3 +224,4 @@ stored_research.add_design(D) to_chat(user, "A warning flashes onto the screen, stating that safety overrides have been deactivated!") obj_flags |= EMAGGED + return TRUE diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index b0204ddeb8..b0a75c99dc 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -290,6 +290,7 @@ return ..() /obj/machinery/porta_turret/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "You short out [src]'s threat assessment circuits.") @@ -300,6 +301,7 @@ update_icon() sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit on = TRUE //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here + return TRUE /obj/machinery/porta_turret/emp_act(severity) @@ -837,6 +839,7 @@ to_chat(user, "Access denied.") /obj/machinery/turretid/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "You short out the turret controls' access analysis module.") @@ -844,6 +847,7 @@ locked = FALSE if(user && user.machine == src) attack_hand(user) + return TRUE /obj/machinery/turretid/attack_ai(mob/user) if(!ailock || IsAdminGhost(user)) diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 6ff795c1cc..afb00d4ee2 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -86,10 +86,13 @@ . = 0 /obj/machinery/porta_turret_cover/emag_act(mob/user) - if(!(parent_turret.obj_flags & EMAGGED)) - to_chat(user, "You short out [parent_turret]'s threat assessment circuits.") - visible_message("[parent_turret] hums oddly...") - parent_turret.obj_flags |= EMAGGED - parent_turret.on = 0 - spawn(40) - parent_turret.on = 1 + . = ..() + if(parent_turret.obj_flags & EMAGGED) + return + to_chat(user, "You short out [parent_turret]'s threat assessment circuits.") + visible_message("[parent_turret] hums oddly...") + parent_turret.obj_flags |= EMAGGED + parent_turret.on = 0 + spawn(40) + parent_turret.on = 1 + return TRUE diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index 7a8552607b..b5ef38b42c 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -36,7 +36,7 @@ to_chat(user, "The panel is screwed in, obstructing the linking device.") else to_chat(user, "The linking device is now able to be scanned with a multitool.") - + /obj/machinery/quantumpad/RefreshParts() var/E = 0 for(var/obj/item/stock_parts/capacitor/C in component_parts) @@ -74,15 +74,26 @@ to_chat(user, "There is no quantum pad data saved in [I]'s buffer!") return TRUE + else if(istype(I, /obj/item/quantum_keycard)) + var/obj/item/quantum_keycard/K = I + if(K.qpad) + to_chat(user, "You insert [K] into [src]'s card slot, activating it.") + interact(user, K.qpad) + else + to_chat(user, "You insert [K] into [src]'s card slot, initiating the link procedure.") + if(do_after(user, 40, target = src)) + to_chat(user, "You complete the link between [K] and [src].") + K.qpad = src + if(default_deconstruction_crowbar(I)) return return ..() -/obj/machinery/quantumpad/interact(mob/user) - if(!linked_pad || QDELETED(linked_pad)) +/obj/machinery/quantumpad/interact(mob/user, obj/machinery/quantumpad/target_pad = linked_pad) + if(!target_pad || QDELETED(target_pad)) if(!map_pad_link_id || !initMappedLink()) - to_chat(user, "There is no linked pad!") + to_chat(user, "Target pad not found!") return if(world.time < last_teleport + teleport_cooldown) @@ -93,18 +104,18 @@ to_chat(user, "[src] is charging up. Please wait.") return - if(linked_pad.teleporting) - to_chat(user, "Linked pad is busy. Please wait.") + if(target_pad.teleporting) + to_chat(user, "Target pad is busy. Please wait.") return - if(linked_pad.stat & NOPOWER) - to_chat(user, "Linked pad is not responding to ping.") + if(target_pad.stat & NOPOWER) + to_chat(user, "Target pad is not responding to ping.") return add_fingerprint(user) - doteleport(user) + doteleport(user, target_pad) /obj/machinery/quantumpad/proc/sparks() - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + var/datum/effect_system/spark_spread/quantum/s = new s.set_up(5, 1, get_turf(src)) s.start() @@ -117,8 +128,8 @@ if(linked_pad) ghost.forceMove(get_turf(linked_pad)) -/obj/machinery/quantumpad/proc/doteleport(mob/user) - if(linked_pad) +/obj/machinery/quantumpad/proc/doteleport(mob/user, obj/machinery/quantumpad/target_pad = linked_pad) + if(target_pad) playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1) teleporting = TRUE @@ -130,7 +141,7 @@ to_chat(user, "[src] is unpowered!") teleporting = FALSE return - if(!linked_pad || QDELETED(linked_pad) || linked_pad.stat & NOPOWER) + if(!target_pad || QDELETED(target_pad) || target_pad.stat & NOPOWER) to_chat(user, "Linked pad is not responding to ping. Teleport aborted.") teleporting = FALSE return @@ -141,26 +152,30 @@ // use a lot of power use_power(10000 / power_efficiency) sparks() - linked_pad.sparks() + target_pad.sparks() flick("qpad-beam", src) playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) - flick("qpad-beam", linked_pad) - playsound(get_turf(linked_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) + flick("qpad-beam", target_pad) + playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) for(var/atom/movable/ROI in get_turf(src)) + if(QDELETED(ROI)) + continue //sleeps in CHECK_TICK + // if is anchored, don't let through if(ROI.anchored) if(isliving(ROI)) var/mob/living/L = ROI - if(L.buckled) - // TP people on office chairs - if(L.buckled.anchored) - continue + //only TP living mobs buckled to non anchored items + if(!L.buckled || L.buckled.anchored) + continue else continue + //Don't TP camera mobs else if(!isobserver(ROI)) continue - do_teleport(ROI, get_turf(linked_pad)) + do_teleport(ROI, get_turf(target_pad),null,TRUE,null,null,null,null,TRUE, channel = TELEPORT_CHANNEL_QUANTUM) + CHECK_TICK /obj/machinery/quantumpad/proc/initMappedLink() . = FALSE diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index ff40a8539a..9d431487e0 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -65,6 +65,7 @@ return ..() /obj/machinery/recycler/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED @@ -73,6 +74,7 @@ update_icon() playsound(src, "sparks", 75, 1, -1) to_chat(user, "You use the cryptographic sequencer on [src].") + return TRUE /obj/machinery/recycler/update_icon() ..() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index f2c216ca98..ad9a846bdc 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -323,7 +323,7 @@ GLOBAL_LIST_EMPTY(allConsoles) emergency = "Medical" if(radio_freq) Radio.set_frequency(radio_freq) - Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq,get_spans(),get_default_language()) + Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq) update_icon() addtimer(CALLBACK(src, .proc/clear_emergency), 3000) @@ -382,7 +382,7 @@ GLOBAL_LIST_EMPTY(allConsoles) screen = 6 if(radio_freq) - Radio.talk_into(src,"[alert]: [message]",radio_freq,get_spans(),get_default_language()) + Radio.talk_into(src, "[alert]: [message]", radio_freq) switch(priority) if(2) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index e2aebd2370..fc6577a4f1 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -195,6 +195,7 @@ return ..() /obj/machinery/shieldgen/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) to_chat(user, "The access controller is damaged!") return @@ -202,6 +203,7 @@ locked = FALSE playsound(src, "sparks", 100, 1) to_chat(user, "You short out the access controller.") + return TRUE /obj/machinery/shieldgen/update_icon() if(active) @@ -387,6 +389,7 @@ add_fingerprint(user) /obj/machinery/shieldwallgen/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) to_chat(user, "The access controller is damaged!") return @@ -394,6 +397,7 @@ locked = FALSE playsound(src, "sparks", 100, 1) to_chat(user, "You short out the access controller.") + return TRUE //////////////Containment Field START /obj/machinery/shieldwall diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 298587cdea..4b73032a8a 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -99,6 +99,7 @@ return ..() /obj/machinery/computer/slot_machine/emag_act() + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED @@ -106,6 +107,7 @@ spark_system.set_up(4, 0, src.loc) spark_system.start() playsound(src, "sparks", 50, 1) + return TRUE /obj/machinery/computer/slot_machine/ui_interact(mob/living/user) . = ..() diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index b11c6c102d..ebb40148d8 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -42,21 +42,23 @@ return ..() /obj/machinery/computer/message_monitor/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return - if(!isnull(linkedServer)) - obj_flags |= EMAGGED - screen = 2 - spark_system.set_up(5, 0, src) - spark_system.start() - var/obj/item/paper/monitorkey/MK = new(loc, linkedServer) - // Will help make emagging the console not so easy to get away with. - MK.info += "

    �%@%(*$%&(�&?*(%&�/{}" - var/time = 100 * length(linkedServer.decryptkey) - addtimer(CALLBACK(src, .proc/UnmagConsole), time) - message = rebootmsg - else + if(isnull(linkedServer)) to_chat(user, "A no server error appears on the screen.") + return + obj_flags |= EMAGGED + screen = 2 + spark_system.set_up(5, 0, src) + spark_system.start() + var/obj/item/paper/monitorkey/MK = new(loc, linkedServer) + // Will help make emagging the console not so easy to get away with. + MK.info += "

    �%@%(*$%&(�&?*(%&�/{}" + var/time = 100 * length(linkedServer.decryptkey) + addtimer(CALLBACK(src, .proc/UnmagConsole), time) + message = rebootmsg + return TRUE /obj/machinery/computer/message_monitor/New() . = ..() diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index cc83e6502a..1f1f13ee22 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -66,18 +66,18 @@ visible_message("Cannot authenticate locked on coordinates. Please reinstate coordinate matrix.") return if (ismovableatom(M)) - if(do_teleport(M, com.target)) + if(do_teleport(M, com.target, channel = TELEPORT_CHANNEL_BLUESPACE)) use_power(5000) - if(!calibrated && prob(30 - ((accurate) * 10))) //oh dear a problem - log_game("[M] ([key_name(M)]) was turned into a fly person") - if(ishuman(M))//don't remove people from the round randomly you jerks - var/mob/living/carbon/human/human = M - if(human.dna && human.dna.species.id == "human") - to_chat(M, "You hear a buzzing in your ears.") - human.set_species(/datum/species/fly) - human.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), EFFECT_IRRADIATE, 0) - calibrated = 0 + if(!calibrated && iscarbon(M) && prob(30 - ((accurate) * 10))) //oh dear a problem + var/mob/living/carbon/C = M + if(C.dna?.species && C.dna.species.id != "fly" && !HAS_TRAIT(C, TRAIT_RADIMMUNE)) + to_chat(C, "You hear a buzzing in your ears.") + C.set_species(/datum/species/fly) + log_game("[C] ([key_name(C)]) was turned into a fly person") + C.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), EFFECT_IRRADIATE, 0) + + calibrated = FALSE return /obj/machinery/teleport/hub/update_icon() diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 0a9a135986..5e8515d3d5 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -95,6 +95,12 @@ var/obj/item/toy/crayon/CR = WM.color_source add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY) +/obj/item/reagents_containers/rag/towel/machine_wash(obj/machinery/washing_machine/WM) + if(WM.color_source) + if(istype(WM.color_source, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/CR = WM.color_source + add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY) + /mob/living/simple_animal/pet/dog/corgi/machine_wash(obj/machinery/washing_machine/WM) gib() diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm index 7896d7aa35..cd7051d074 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -20,3 +20,6 @@ ..() defense_action.Remove(user) +/obj/mecha/combat/Initialize() + . = ..() + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 95137938d0..f9fa2544b8 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -63,3 +63,6 @@ ..() thrusters_action.Remove(user) +/obj/mecha/combat/Initialize() + . = ..() + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm index 125aecd667..4c32e9c367 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/game/mecha/combat/honker.dm @@ -154,4 +154,6 @@ color = color+pick(colors) return color - +/obj/mecha/combat/Initialize() + . = ..() + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index f5f369c2ad..1264a647c4 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -28,3 +28,6 @@ switch_damtype_action.Remove(user) phasing_action.Remove(user) +/obj/mecha/combat/Initialize() + . = ..() + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 8a5a83379d..23be95ff16 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -76,6 +76,9 @@ return 0 if(energy_drain && !chassis.has_charge(energy_drain)) return 0 + if(chassis.equipment_disabled) + to_chat(chassis.occupant, "Error -- Equipment control unit is unresponsive.") + return 0 return 1 /obj/item/mecha_parts/mecha_equipment/proc/action(atom/target) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index ba08109427..21bbdfd14b 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -159,15 +159,15 @@ t1 = "*dead*" else t1 = "Unknown" - return {"Health: [patient.stat > 1 ? "[t1]" : "[patient.health]% ([t1])"]
    - Core Temperature: [patient.bodytemperature-T0C]°C ([patient.bodytemperature*1.8-459.67]°F)
    - Brute Damage: [patient.getBruteLoss()]%
    - Respiratory Damage: [patient.getOxyLoss()]%
    - Toxin Content: [patient.getToxLoss()]%
    - Burn Severity: [patient.getFireLoss()]%
    - [patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]
    - [patient.getBrainLoss() ? "Significant brain damage detected." : ""]
    - [length(patient.get_traumas()) ? "Brain Traumas detected." : ""]
    + return {"Health: [patient.stat > 1 ? "[t1]" : "[patient.health]% ([t1])"]
    + Core Temperature: [patient.bodytemperature-T0C]°C ([patient.bodytemperature*1.8-459.67]°F)
    + Brute Damage: [patient.getBruteLoss()]%
    + Respiratory Damage: [patient.getOxyLoss()]%
    + Toxin Content: [patient.getToxLoss()]%
    + Burn Severity: [patient.getFireLoss()]%
    + [patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]
    + [patient.getBrainLoss() ? "Significant brain damage detected." : ""]
    + [length(patient.get_traumas()) ? "Brain Traumas detected." : ""]
    "} /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_reagents() diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 80c92c7922..a8ba9850ff 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -17,7 +17,7 @@ return var/turf/T = get_turf(target) if(T) - do_teleport(chassis, T, 4) + do_teleport(chassis, T, 4, channel = TELEPORT_CHANNEL_BLUESPACE) return 1 diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index d8c0fbeeb3..2e5a13beb2 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -305,7 +305,7 @@ name = "\improper SRM-8 missile rack" desc = "A weapon for combat exosuits. Shoots light explosive missiles." icon_state = "mecha_missilerack" - projectile = /obj/item/projectile/bullet/srmrocket + projectile = /obj/item/projectile/bullet/a84mm_he fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 8 projectile_energy_cost = 1000 diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 01e304872f..e1dc80911f 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -64,10 +64,15 @@ /obj/machinery/mecha_part_fabricator/emag_act() + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED req_access = list() + INVOKE_ASYNC(src, .proc/error_action_sucessful) + return TRUE + +/obj/machinery/mecha_part_fabricator/proc/error_action_sucessful() say("DB error \[Code 0x00F1\]") sleep(10) say("Attempting auto-repair...") diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index fc0665f51e..22aac63d2b 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -42,6 +42,7 @@ var/last_message = 0 var/add_req_access = 1 var/maint_access = 0 + var/equipment_disabled = 0 //disabled due to EMP var/dna_lock //dna-locking the mech var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference var/datum/effect_system/spark_spread/spark_system = new @@ -143,7 +144,6 @@ diag_hud_set_mechhealth() diag_hud_set_mechcell() diag_hud_set_mechstat() - diag_hud_set_mechtracking() /obj/mecha/get_cell() return cell @@ -205,6 +205,15 @@ GLOB.mechas_list -= src //global mech list return ..() +/obj/mecha/proc/restore_equipment() + equipment_disabled = 0 + if(istype(src, /obj/mecha/combat)) + mouse_pointer = 'icons/mecha/mecha_mouse.dmi' + if(occupant) + SEND_SOUND(occupant, sound('sound/items/timer.ogg', volume=50)) + to_chat(occupant, "Equipment control unit has been rebooted successfuly.") + occupant.update_mouse_pointer() + /obj/mecha/CheckParts(list/parts_list) ..() cell = locate(/obj/item/stock_parts/cell) in contents @@ -394,8 +403,6 @@ diag_hud_set_mechhealth() diag_hud_set_mechcell() diag_hud_set_mechstat() - diag_hud_set_mechtracking() - /obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. return diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 714c66d032..3b957431f7 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -11,8 +11,8 @@ var/obj/mecha/M = new result(drop_location()) QDEL_NULL(M.cell) - var/atom/parent_atom = parent - M.CheckParts(parent_atom.contents) + var/obj/item/mecha_parts/chassis/parent_chassis = parent + M.CheckParts(parent_chassis.contents) SSblackbox.record_feedback("tally", "mechas_created", 1, M.name) QDEL_NULL(parent) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 1524da42f2..18c9b3eb2f 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -21,8 +21,9 @@ var/answer = TR.get_mecha_info() if(answer) dat += {"
    [answer]
    - Send message
    - Show exosuit log | (EMP pulse)
    "} + Send message
    + Show exosuit log
    + [TR.recharging?"Recharging EMP Pulse...
    ":"(EMP Pulse)
    "]"} if(screen==1) dat += "

    Log contents

    " @@ -65,6 +66,7 @@ icon_state = "motion2" w_class = WEIGHT_CLASS_SMALL var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking. + var/recharging = 0 /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() if(!in_mecha()) @@ -102,10 +104,16 @@ return 0 /obj/item/mecha_parts/mecha_tracking/proc/shock() + if(recharging) + return var/obj/mecha/M = in_mecha() if(M) - M.emp_act(EMP_LIGHT) - qdel(src) + M.emp_act(EMP_HEAVY) + addtimer(CALLBACK(src, /obj/item/mecha_parts/mecha_tracking/proc/recharge), 15 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + recharging = 1 + +/obj/item/mecha_parts/mecha_tracking/proc/recharge() + recharging = 0 /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log() if(!ismecha(loc)) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 367c750787..62a62b569d 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -149,7 +149,14 @@ use_power((cell.charge/3)/(severity*2)) take_damage(30 / severity, BURN, "energy", 1) log_message("EMP detected", color="red") - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) + + if(istype(src, /obj/mecha/combat)) + mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi' + occupant?.update_mouse_pointer() + if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs + to_chat(occupant, "Error -- Connection to equipment control unit has been lost.") + addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + equipment_disabled = 1 /obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature>max_temperature) diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index e86b5174cc..8b4e48cd3e 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -1,8 +1,3 @@ -/obj/mecha/medical/Initialize() - . = ..() - trackers += new /obj/item/mecha_parts/mecha_tracking(src) - - /obj/mecha/medical/mechturn(direction) setDir(direction) playsound(src,'sound/mecha/mechmove01.ogg',40,1) @@ -18,4 +13,4 @@ var/result = step_rand(src) if(result) playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result \ No newline at end of file + return result diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm index 498ccd94fa..c9e7d99ac0 100644 --- a/code/game/mecha/working/working.dm +++ b/code/game/mecha/working/working.dm @@ -1,6 +1,3 @@ /obj/mecha/working internal_damage_threshold = 60 -/obj/mecha/working/Initialize() - . = ..() - trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm index 1a605d64b0..3b5a029df4 100644 --- a/code/game/objects/effects/alien_acid.dm +++ b/code/game/objects/effects/alien_acid.dm @@ -17,7 +17,7 @@ target = get_turf(src) if(acid_amt) - acid_level = min(acid_amt*acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor. + acid_level = min( (CLAMP(round(acid_amt, 1), 0, INFINITY)) *acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor. //handle APCs and newscasters and stuff nicely pixel_x = target.pixel_x + rand(-4,4) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 91df57052e..fbe25c5d1b 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -190,11 +190,11 @@ /obj/effect/anomaly/bluespace/anomalyEffect() ..() for(var/mob/living/M in range(1,src)) - do_teleport(M, locate(M.x, M.y, M.z), 4) + do_teleport(M, locate(M.x, M.y, M.z), 4, channel = TELEPORT_CHANNEL_BLUESPACE) /obj/effect/anomaly/bluespace/Bumped(atom/movable/AM) if(isliving(AM)) - do_teleport(AM, locate(AM.x, AM.y, AM.z), 8) + do_teleport(AM, locate(AM.x, AM.y, AM.z), 8, channel = TELEPORT_CHANNEL_BLUESPACE) /obj/effect/anomaly/bluespace/detonate() var/turf/T = safepick(get_area_turfs(impact_area)) diff --git a/code/game/objects/effects/blessing.dm b/code/game/objects/effects/blessing.dm index 06ba2bb47c..5df90d65c7 100644 --- a/code/game/objects/effects/blessing.dm +++ b/code/game/objects/effects/blessing.dm @@ -16,3 +16,12 @@ I.alpha = 64 I.appearance_flags = RESET_ALPHA add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/blessedAware, "blessing", I) + RegisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT, .proc/block_cult_teleport) + +/obj/effect/blessing/Destroy() + UnregisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT) + return ..() + +/obj/effect/blessing/proc/block_cult_teleport(datum/source, channel, turf/origin, turf/destination) + if(channel == TELEPORT_CHANNEL_CULT) + return COMPONENT_BLOCK_TELEPORT \ No newline at end of file diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 55a162ad38..9f072c48b6 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -42,6 +42,9 @@ /obj/effect/decal/cleanable/glass/ex_act() qdel(src) +/obj/effect/decal/cleanable/glass/plasma + icon_state = "plasmatiny" + /obj/effect/decal/cleanable/dirt name = "dirt" desc = "Someone should clean that up." @@ -219,7 +222,7 @@ name = "stabilized plasma" desc = "A puddle of stabilized plasma." icon_state = "flour" - color = "#C8A5DC" + color = "#9e0089" /obj/effect/decal/cleanable/insectguts name = "insect guts" diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index 0656d9b3ca..19b0dc76dd 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -26,7 +26,7 @@ /obj/effect/particle_effect/sparks/Initialize() . = ..() - flick("sparks", src) // replay the animation + flick(icon_state, src) // replay the animation playsound(src, "sparks", 100, TRUE) var/turf/T = loc if(isturf(T)) @@ -48,6 +48,8 @@ /datum/effect_system/spark_spread effect_type = /obj/effect/particle_effect/sparks +/datum/effect_system/spark_spread/quantum + effect_type = /obj/effect/particle_effect/sparks/quantum //electricity @@ -55,5 +57,9 @@ name = "lightning" icon_state = "electricity" +/obj/effect/particle_effect/sparks/quantum + name = "quantum sparks" + icon_state = "quantum_sparks" + /datum/effect_system/lightning_spread effect_type = /obj/effect/particle_effect/sparks/electricity diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 7e8094c9e7..32d91ee76a 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -131,7 +131,7 @@ var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc) victim.log_message("entered a blood frenzy", LOG_ATTACK) - chainsaw.item_flags |= NODROP + ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT) victim.drop_all_held_items() victim.put_in_hands(chainsaw, forced = TRUE) chainsaw.attack_self(victim) diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index d69cfd38ef..631b87cada 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -20,6 +20,7 @@ var/mech_sized = FALSE var/obj/effect/portal/linked var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted. + var/teleport_channel = TELEPORT_CHANNEL_BLUESPACE var/creator var/turf/hard_target //For when a portal needs a hard target and isn't to be linked. var/atmos_link = FALSE //Link source/destination atmos. @@ -34,6 +35,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "anom" mech_sized = TRUE + teleport_channel = TELEPORT_CHANNEL_WORMHOLE /obj/effect/portal/Move(newloc) for(var/T in newloc) @@ -160,7 +162,7 @@ no_effect = TRUE else last_effect = world.time - if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect)) + if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel)) if(istype(M, /obj/item/projectile)) var/obj/item/projectile/P = M P.ignore_source_check = TRUE diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 0e543a3642..bdb949a570 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -30,6 +30,18 @@ loot_spawned++ return INITIALIZE_HINT_QDEL +/obj/effect/spawner/lootdrop/bedsheet + icon = 'icons/obj/bedsheets.dmi' + icon_state = "random_bedsheet" + name = "random dorms bedsheet" + loot = list(/obj/item/bedsheet = 8, /obj/item/bedsheet/blue = 8, /obj/item/bedsheet/green = 8, + /obj/item/bedsheet/grey = 8, /obj/item/bedsheet/orange = 8, /obj/item/bedsheet/purple = 8, + /obj/item/bedsheet/red = 8, /obj/item/bedsheet/yellow = 8, /obj/item/bedsheet/brown = 8, + /obj/item/bedsheet/black = 8, /obj/item/bedsheet/patriot = 3, /obj/item/bedsheet/rainbow = 3, + /obj/item/bedsheet/ian = 3, /obj/item/bedsheet/runtime = 3, /obj/item/bedsheet/nanotrasen = 3, + /obj/item/bedsheet/pirate = 1, /obj/item/bedsheet/cosmos = 1, /obj/item/bedsheet/gondola = 1 + ) + /obj/effect/spawner/lootdrop/armory_contraband name = "armory contraband gun spawner" lootdoubles = FALSE @@ -108,6 +120,33 @@ loot = GLOB.maintenance_loot . = ..() +/obj/effect/spawner/lootdrop/glowstick + name = "random colored glowstick" + icon = 'icons/obj/lighting.dmi' + icon_state = "random_glowstick" + +/obj/effect/spawner/lootdrop/glowstick/Initialize() + loot = typesof(/obj/item/flashlight/glowstick) + . = ..() + + +/obj/effect/spawner/lootdrop/gloves + name = "random gloves" + desc = "These gloves are supposed to be a random color..." + icon = 'icons/obj/clothing/gloves.dmi' + icon_state = "random_gloves" + loot = list( + /obj/item/clothing/gloves/color/orange = 1, + /obj/item/clothing/gloves/color/red = 1, + /obj/item/clothing/gloves/color/blue = 1, + /obj/item/clothing/gloves/color/purple = 1, + /obj/item/clothing/gloves/color/green = 1, + /obj/item/clothing/gloves/color/grey = 1, + /obj/item/clothing/gloves/color/light_brown = 1, + /obj/item/clothing/gloves/color/brown = 1, + /obj/item/clothing/gloves/color/white = 1, + /obj/item/clothing/gloves/color/rainbow = 1) + /obj/effect/spawner/lootdrop/crate_spawner name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF! lootdoubles = FALSE diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 2af7be2564..c98cef2b87 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -33,6 +33,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/usesound = null var/throwhitsound = null var/w_class = WEIGHT_CLASS_NORMAL + var/total_mass //Total mass in arbitrary pound-like values. If there's no balance reasons for an item to have otherwise, this var should be the item's weight in pounds. var/slot_flags = 0 //This is used to determine on which slots an item can fit. pass_flags = PASSTABLE pressure_resistance = 4 @@ -67,6 +68,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/strip_delay = 40 //In deciseconds, how long an item takes to remove from another person var/breakouttime = 0 var/list/materials + var/reskinned = FALSE var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item @@ -230,9 +232,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) research_msg += "." to_chat(user, research_msg.Join()) -/obj/item/proc/speechModification(message) //for message modding by mask slot. - return message - /obj/item/interact(mob/user) add_fingerprint(user) ui_interact(user) @@ -582,6 +581,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/proc/get_belt_overlay() //Returns the icon used for overlaying the object on a belt return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) +/obj/item/proc/get_worn_belt_overlay(icon_file) + return + /obj/item/proc/update_slot_icon() if(!ismob(loc)) return @@ -647,11 +649,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) else . = "" - -//when an item modify our speech spans when in our active hand. Override this to modify speech spans. -/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) - return - /obj/item/hitby(atom/movable/AM) return @@ -825,6 +822,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return ..() /obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback) - if (item_flags & NODROP) + if (HAS_TRAIT(src, TRAIT_NODROP)) return return ..() diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 38d64be99c..cf706359f7 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -37,6 +37,7 @@ RLD var/has_ammobar = FALSE //controls whether or not does update_icon apply ammo indicator overlays var/ammo_sections = 10 //amount of divisions in the ammo indicator overlay/number of ammo indicator states var/custom_range = 7 + var/upgrade = FALSE /obj/item/construction/Initialize() . = ..() @@ -82,6 +83,11 @@ RLD loaded = loadwithsheets(W, sheetmultiplier * 0.25, user) // 1 matter for 1 floortile, as 4 tiles are produced from 1 metal if(loaded) to_chat(user, "[src] now holds [matter]/[max_matter] matter-units.") + else if(istype(W, /obj/item/rcd_upgrade)) + to_chat(user, "You upgrade the RCD with the [W]!") + upgrade = TRUE + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + qdel(W) else return ..() update_icon() //ensures that ammo counters (if present) get updated @@ -148,6 +154,7 @@ RLD has_ammobar = TRUE var/mode = 1 var/ranged = FALSE + var/computer_dir = 1 var/airlock_type = /obj/machinery/door/airlock var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use var/window_type = /obj/structure/window/fulltile @@ -270,6 +277,28 @@ RLD return FALSE return TRUE +/obj/item/construction/rcd/proc/change_computer_dir(mob/user) + if(!user) + return + var/list/computer_dirs = list( + "NORTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "cnorth"), + "EAST" = image(icon = 'icons/mob/radial.dmi', icon_state = "ceast"), + "SOUTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "csouth"), + "WEST" = image(icon = 'icons/mob/radial.dmi', icon_state = "cwest") + ) + var/computerdirs = show_radial_menu(user, src, computer_dirs, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE) + if(!check_menu(user)) + return + switch(computerdirs) + if("NORTH") + computer_dir = 1 + if("EAST") + computer_dir = 4 + if("SOUTH") + computer_dir = 2 + if("WEST") + computer_dir = 8 + /obj/item/construction/rcd/proc/change_airlock_setting(mob/user) if(!user) return @@ -414,10 +443,12 @@ RLD return FALSE if(do_after(user, rcd_results["delay"] * delay_mod, target = A)) if(checkResource(rcd_results["cost"], user)) + var/atom/cached = A if(A.rcd_act(user, src, rcd_results["mode"])) useResource(rcd_results["cost"], user) activate() - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + investigate_log("[user] used [src] on [cached] (now [A]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD) + playsound(src, 'sound/machines/click.ogg', 50, 1) return TRUE /obj/item/construction/rcd/Initialize() @@ -432,10 +463,15 @@ RLD ..() var/list/choices = list( "Airlock" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"), - "Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"), "Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"), "Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor") ) + if(upgrade) + choices += list( + "Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"), + "Machine Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"), + "Computer Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "computer_dir"), + ) if(mode == RCD_AIRLOCK) choices += list( "Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"), @@ -457,6 +493,12 @@ RLD mode = RCD_DECONSTRUCT if("Grilles & Windows") mode = RCD_WINDOWGRILLE + if("Machine Frames") + mode = RCD_MACHINE + if("Computer Frames") + mode = RCD_COMPUTER + change_computer_dir(user) + return if("Change Access") change_airlock_access(user) return @@ -509,6 +551,7 @@ RLD no_ammo_message = "Insufficient charge." desc = "A device used to rapidly build walls and floors." canRturf = TRUE + upgrade = TRUE /obj/item/construction/rcd/borg/useResource(amount, mob/user) @@ -540,6 +583,9 @@ RLD /obj/item/construction/rcd/loaded matter = 160 +/obj/item/construction/rcd/loaded/upgraded + upgrade = TRUE + /obj/item/construction/rcd/combat name = "Combat RCD" desc = "A device used to rapidly build and deconstruct. Reload with metal, plasteel, glass or compressed matter cartridges. This RCD has been upgraded to be able to remove Rwalls!" @@ -580,7 +626,7 @@ RLD name = "admin RCD" max_matter = INFINITY matter = INFINITY - + upgrade = TRUE // Ranged RCD @@ -614,7 +660,7 @@ RLD name = "rapid-light-device (RLD)" desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges." icon = 'icons/obj/tools.dmi' - icon_state = "rld-5" + icon_state = "rld" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' matter = 500 @@ -622,6 +668,8 @@ RLD sheetmultiplier = 16 var/mode = LIGHT_MODE actions_types = list(/datum/action/item_action/pick_color) + ammo_sections = 5 + has_ammobar = TRUE var/wallcost = 10 var/floorcost = 15 @@ -635,6 +683,10 @@ RLD var/color_choice = null +/obj/item/construction/rld/Initialize() + . = ..() + update_icon() + /obj/item/construction/rld/ui_action_click(mob/user, var/datum/action/A) if(istype(A, /datum/action/item_action/pick_color)) color_choice = input(user,"","Choose Color",color_choice) as color @@ -642,9 +694,10 @@ RLD ..() /obj/item/construction/rld/update_icon() - icon_state = "rld-[round(matter/35)]" ..() - + var/ratio = CEILING((matter / max_matter) * ammo_sections, 1) + cut_overlays() //To prevent infinite stacking of overlays + add_overlay("rld_light[ratio]") /obj/item/construction/rld/attack_self(mob/user) ..() @@ -767,6 +820,12 @@ RLD return TRUE return FALSE +/obj/item/rcd_upgrade + name = "RCD advanced design disk" + desc = "It contains the design for machine frames, computer frames, and deconstruction." + icon = 'icons/obj/module.dmi' + icon_state = "datadisk3" + #undef GLOW_MODE #undef LIGHT_MODE #undef REMOVE_MODE diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index cea8165e02..63f460f9aa 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -2,7 +2,7 @@ name = "rapid cable layer" desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!" icon = 'icons/obj/tools.dmi' - icon_state = "rcl-0" + icon_state = "rcl-empty" item_state = "rcl-0" var/obj/structure/cable/last var/obj/item/stack/cable_coil/loaded @@ -92,22 +92,32 @@ /obj/item/twohanded/rcl/update_icon() if(!loaded) - icon_state = "rcl-0" - item_state = "rcl-0" + icon_state = "rcl-empty" + item_state = "rcl-empty" return + cut_overlays() + var/cable_amount = 0 switch(loaded.amount) if(61 to INFINITY) - icon_state = "rcl-30" - item_state = "rcl" + cable_amount = 3 if(31 to 60) - icon_state = "rcl-20" - item_state = "rcl" + cable_amount = 2 if(1 to 30) - icon_state = "rcl-10" - item_state = "rcl" + cable_amount = 1 else - icon_state = "rcl-0" - item_state = "rcl-0" + cable_amount = 0 + + var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]") + cable_overlay.color = GLOB.cable_colors[colors[current_color_index]] + if(cable_amount >= 1) + icon_state = "rcl" + item_state = "rcl" + add_overlay(cable_overlay) + else + icon_state = "rcl-empty" + item_state = "rcl-0" + add_overlay(cable_overlay) + /obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1) update_icon() @@ -302,6 +312,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook) to_chat(user, "Color changed to [cwname]!") if(loaded) loaded.item_color= colors[current_color_index] + update_icon() if(wiring_gui_menu) wiringGuiUpdate(user) else if(istype(action, /datum/action/item_action/rcl_gui)) @@ -318,13 +329,29 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook) /obj/item/twohanded/rcl/ghetto/update_icon() if(!loaded) - icon_state = "rclg-0" + icon_state = "rclg-empty" item_state = "rclg-0" return + cut_overlays() + var/cable_amount = 0 switch(loaded.amount) - if(1 to INFINITY) - icon_state = "rclg-1" - item_state = "rcl" + if(20 to INFINITY) + cable_amount = 3 + if(10 to 19) + cable_amount = 2 + if(1 to 9) + cable_amount = 1 else - icon_state = "rclg-1" - item_state = "rclg-1" + cable_amount = 0 + + var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]") + cable_overlay.color = GLOB.cable_colors[colors[current_color_index]] + if(cable_amount >= 1) + icon_state = "rclg" + item_state = "rclg" + add_overlay(cable_overlay) + else + icon_state = "rclg-empty" + item_state = "rclg-0" + add_overlay(cable_overlay) + diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 0549ebc474..141f7e510a 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -177,6 +177,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( desc = "A device used to rapidly pipe things." icon = 'icons/obj/tools.dmi' icon_state = "rpd" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' flags_1 = CONDUCT_1 force = 10 throwforce = 10 @@ -233,6 +235,10 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1) return(BRUTELOSS) +/obj/item/pipe_dispenser/ui_base_html(html) + var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/pipes) + . = replacetext(html, "", assets.css_tag()) + /obj/item/pipe_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) @@ -431,6 +437,10 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( to_chat(user, "You start building a transit tube...") playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if(do_after(user, transit_build_speed, target = A)) + for(var/obj/structure/c_transit_tube/tube in A) + if(tube.dir == queued_p_dir || (queued_p_flipped && (tube.dir == turn(queued_p_dir, 45)))) + to_chat(user, "[src]'s error light flickers; there's already a pipe in the way!") + return activate() if(queued_p_type == /obj/structure/c_transit_tube_pod) var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(A) diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index f0d15cc3a2..01205ee889 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -134,12 +134,14 @@ RSF return /obj/item/cookiesynth/emag_act(mob/user) + . = ..() obj_flags ^= EMAGGED if(obj_flags & EMAGGED) to_chat(user, "You short out [src]'s reagent safety checker!") else to_chat(user, "You reset [src]'s reagent safety checker!") - toxin = 0 + toxin = FALSE + return TRUE /obj/item/cookiesynth/attack_self(mob/user) var/mob/living/silicon/robot/P = null diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 96bbe759ca..05ffcbf2fd 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -93,34 +93,22 @@ /obj/item/card/emag/afterattack(atom/target, mob/user, proximity) . = ..() var/atom/A = target - if(!proximity && prox_check) + if(!proximity && prox_check || !(isobj(A) || issilicon(A) || isbot(A) || isdrone(A))) + return + if(istype(A, /obj/item/storage) && !(istype(A, /obj/item/storage/lockbox) || istype(A, /obj/item/storage/pod))) return - //Citadel changes: modular code misfiring, so we're bypassing into main code. if(!uses) user.visible_message("[src] emits a weak spark. It's burnt out!") playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) return else if(uses <= 3) playsound(src, 'sound/effects/light_flicker.ogg', 30, 1) //Tiiiiiiny warning sound to let ya know your emag's almost dead - - if(isturf(A)) + if(!A.emag_act(user)) return - if(istype(A,/obj/item/storage/lockbox) || istype(A, /obj/item/storage/pod)) - A.emag_act(user) - uses = max(uses - 1, 0) - if(!uses) - user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") - playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) - if(istype(A,/obj/item/storage)) - return - if(!(isobj(A) || issilicon(A) || isbot(A) || isdrone(A))) - return - else - A.emag_act(user) - uses = max(uses - 1, 0) - if(!uses) - user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") - playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) + uses = max(uses - 1, 0) + if(!uses) + user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") + playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) /obj/item/card/emagfake diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 344e7c5472..5db5aa416e 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -48,7 +48,7 @@ icon_state = "chronogun" item_state = "chronogun" w_class = WEIGHT_CLASS_NORMAL - item_flags = NODROP | DROPDEL + item_flags = DROPDEL ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam) can_charge = 0 fire_delay = 50 @@ -58,6 +58,7 @@ /obj/item/gun/energy/chrono_gun/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHRONO_GUN_TRAIT) if(istype(loc, /obj/item/chrono_eraser)) TED = loc else //admin must have spawned it @@ -150,8 +151,8 @@ gun = loc . = ..() - - + + /obj/effect/chrono_field diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 000c52ae43..09a128c558 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -764,20 +764,22 @@ CIGARETTE PACKETS ARE IN FANCY.DM ..() /obj/item/clothing/mask/vape/emag_act(mob/user)// I WON'T REGRET WRITTING THIS, SURLY. - if(screw) - if(!(obj_flags & EMAGGED)) - cut_overlays() - obj_flags |= EMAGGED - super = FALSE - to_chat(user, "You maximize the voltage of [src].") - add_overlay("vapeopen_high") - var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect - sp.set_up(5, 1, src) - sp.start() - else - to_chat(user, "[src] is already emagged!") - else + . = ..() + if(!screw) to_chat(user, "You need to open the cap to do that.") + return + if(obj_flags & EMAGGED) + to_chat(user, "[src] is already emagged!") + return + cut_overlays() + obj_flags |= EMAGGED + super = FALSE + to_chat(user, "You maximize the voltage of [src].") + add_overlay("vapeopen_high") + var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect + sp.set_up(5, 1, src) + sp.start() + return TRUE /obj/item/clothing/mask/vape/attack_self(mob/user) if(reagents.total_volume > 0) diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index a1ee62e2eb..bb45f80f2d 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -110,6 +110,7 @@ /obj/item/circuitboard/computer/cloning name = "Cloning (Computer Board)" build_path = /obj/machinery/computer/cloning + var/list/records = list() /obj/item/circuitboard/computer/prototype_cloning name = "Prototype Cloning (Computer Board)" @@ -216,10 +217,13 @@ to_chat(user, "The spectrum chip is unresponsive.") /obj/item/circuitboard/computer/cargo/emag_act(mob/living/user) - if(!(obj_flags & EMAGGED)) - contraband = TRUE - obj_flags |= EMAGGED - to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.") + . = ..() + if(obj_flags & EMAGGED) + return + contraband = TRUE + obj_flags |= EMAGGED + to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.") + return TRUE /obj/item/circuitboard/computer/cargo/express name = "Express Supply Console (Computer Board)" @@ -233,8 +237,12 @@ obj_flags &= ~EMAGGED /obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user) - to_chat(user, "You change the routing protocols, allowing the Drop Pod to land anywhere on the station.") - obj_flags |= EMAGGED + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) + if(obj_flags & EMAGGED) + return + to_chat(user, "You change the routing protocols, allowing the Drop Pod to land anywhere on the station.") + obj_flags |= EMAGGED + return TRUE /obj/item/circuitboard/computer/cargo/request name = "Supply Request Console (Computer Board)" diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 55e75b3992..5bef86c6d2 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -140,12 +140,10 @@ return ..() /obj/item/defibrillator/emag_act(mob/user) - if(safety) - safety = FALSE - to_chat(user, "You silently disable [src]'s safety protocols with the cryptographic sequencer.") - else - safety = TRUE - to_chat(user, "You silently enable [src]'s safety protocols with the cryptographic sequencer.") + . = ..() + safety = !safety + to_chat(user, "You silently [safety ? "enable" : "disable"] [src]'s safety protocols with the cryptographic sequencer.") + return TRUE /obj/item/defibrillator/emp_act(severity) . = ..() diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm index 29f0cf27f9..55d1a2c78a 100644 --- a/code/game/objects/items/dehy_carp.dm +++ b/code/game/objects/items/dehy_carp.dm @@ -19,6 +19,9 @@ else return ..() +/obj/item/toy/plush/carpplushie/dehy_carp/plop(obj/item/toy/plush/Daddy) + return FALSE + /obj/item/toy/plush/carpplushie/dehy_carp/proc/Swell() desc = "It's growing!" visible_message("[src] swells up!") diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 15c88d168f..45baa542d4 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -68,7 +68,6 @@ GLOBAL_LIST_EMPTY(PDAs) var/last_everyone //No text for everyone spamming var/last_noise //Also no honk spamming that's bad too var/ttone = "beep" //The ringtone! - var/lock_code = "" // Lockcode to unlock uplink var/honkamt = 0 //How many honks left when infected with honk.exe var/mimeamt = 0 //How many silence left when infected with mime.exe var/note = "Congratulations, your station has chosen the Thinktronic 5230 Personal Data Assistant! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." //Current note in the notepad function @@ -123,7 +122,7 @@ GLOBAL_LIST_EMPTY(PDAs) inserted_item = new inserted_item(src) else inserted_item = new /obj/item/pen(src) - update_icon() + update_icon(FALSE, TRUE) /obj/item/pda/CtrlShiftClick(mob/living/user) . = ..() @@ -144,8 +143,7 @@ GLOBAL_LIST_EMPTY(PDAs) if(QDELETED(src) || isnull(new_icon) || new_icon == icon || M.incapacitated() || !in_range(M,src)) return icon = new_icon - set_new_overlays() - update_icon() + update_icon(FALSE, TRUE) to_chat(M, "[src] is now skinned as '[choice]'.") /obj/item/pda/proc/set_new_overlays() @@ -187,8 +185,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/pref_skin = GLOB.pda_reskins[user.client.prefs.pda_skin] if(icon != pref_skin) icon = pref_skin - set_new_overlays() - update_icon() + update_icon(FALSE, TRUE) equipped = TRUE /obj/item/pda/proc/update_label() @@ -203,7 +200,9 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/GetID() return id -/obj/item/pda/update_icon(alert = FALSE) +/obj/item/pda/update_icon(alert = FALSE, new_overlays = FALSE) + if(new_overlays) + set_new_overlays() cut_overlays() add_overlay(alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]) var/mutable_appearance/overlay = new() diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index bf352e8eb7..3885a1f4d9 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -498,6 +498,23 @@ Code: else menu += "[ldat]" + menu += "

    Pimpin' Ride:

    " + + ldat = null + for (var/obj/vehicle/ridden/janicart/M in world) + var/turf/ml = get_turf(M) + + if(ml) + if (ml.z != cl.z) + continue + var/direction = get_dir(src, M) + ldat += "Ride - \[[ml.x],[ml.y] ([uppertext(dir2text(direction))])\]
    " + + if (!ldat) + menu += "None" + else + menu += "[ldat]" + menu += "

    Located Janitorial Cart:

    " ldat = null diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm index d35b2b58cf..d85c5d72d8 100644 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ b/code/game/objects/items/devices/PDA/virus_cart.dm @@ -98,7 +98,7 @@ GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target) if(!hidden_uplink) hidden_uplink = target.AddComponent(/datum/component/uplink) - target.lock_code = lock_code + hidden_uplink.unlock_code = lock_code else hidden_uplink.hidden_crystals += hidden_uplink.telecrystals //Temporarially hide the PDA's crystals, so you can't steal telecrystals. hidden_uplink.telecrystals = telecrystals diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index d8b539ac27..722510dccb 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -512,17 +512,6 @@ name = "pink glowstick" color = LIGHT_COLOR_PINK -/obj/item/flashlight/glowstick/random - name = "random colored glowstick" - icon_state = "random_glowstick" - color = null - -/obj/item/flashlight/glowstick/random/Initialize() - ..() - var/T = pick(typesof(/obj/item/flashlight/glowstick) - /obj/item/flashlight/glowstick/random) - new T(loc) - return INITIALIZE_HINT_QDEL - /obj/item/flashlight/spotlight //invisible lighting source name = "disco light" desc = "Groovy..." diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index 7823e570e0..38133e37bc 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -192,13 +192,15 @@ update_icon() /obj/item/geiger_counter/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return if(scanning) to_chat(user, "Turn off [src] before you perform this action!") - return 0 + return to_chat(user, "You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan.") obj_flags |= EMAGGED + return TRUE /obj/item/geiger_counter/cyborg var/datum/component/mobhook diff --git a/code/game/objects/items/devices/glue.dm b/code/game/objects/items/devices/glue.dm index fed582d951..2c57ede706 100644 --- a/code/game/objects/items/devices/glue.dm +++ b/code/game/objects/items/devices/glue.dm @@ -19,11 +19,11 @@ return if(istype(target, /obj/item)) var/obj/item/I = target - if(I.item_flags & NODROP) + if(HAS_TRAIT_FROM(I, TRAIT_NODROP, GLUED_ITEM_TRAIT)) to_chat(user, "[I] is already sticky!") return uses -= 1 - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, GLUED_ITEM_TRAIT) I.desc += " It looks sticky." to_chat(user, "You smear the [I] with glue, making it incredibly sticky!") if(uses == 0) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index c362d9f7f2..637bb794d3 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -156,7 +156,10 @@ GLOBAL_LIST_EMPTY(GPS_list) icon_state = "gps-b" gpstag = "BORG0" desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams." - item_flags = NODROP + +/obj/item/gps/cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) /obj/item/gps/internal icon_state = null diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index 661d38ce6b..5894b559ae 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -234,11 +234,18 @@ w_class = WEIGHT_CLASS_SMALL actions_types = list(/datum/action/item_action/instrument) -/obj/item/instrument/harmonica/speechModification(message) +/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args) if(song.playing && ismob(loc)) to_chat(loc, "You stop playing the harmonica to talk...") song.playing = FALSE - return message + +/obj/item/instrument/harmonica/equipped(mob/M, slot) + . = ..() + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + +/obj/item/instrument/harmonica/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) /obj/item/instrument/bikehorn name = "gilded bike horn" diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 6615ebe8a8..1e31f14cfd 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -149,9 +149,11 @@ to_chat(user, "You fill \the [src] with lights from \the [S]. " + status_string() + "") /obj/item/lightreplacer/emag_act() + . = ..() if(obj_flags & EMAGGED) return Emag() + return TRUE /obj/item/lightreplacer/attack_self(mob/user) to_chat(user, status_string()) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 4b244e3002..915fcac504 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -17,20 +17,34 @@ user.say("AAAAAAAAAAAARGHHHHH", forced="megaphone suicide")//he must have died while coding this return OXYLOSS -/obj/item/megaphone/get_held_item_speechspans(mob/living/carbon/user) - if(spamcheck > world.time) - to_chat(user, "\The [src] needs to recharge!") +/obj/item/megaphone/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HANDS) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else - playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1) - spamcheck = world.time + 50 - return voicespan + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/megaphone/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/megaphone/proc/handle_speech(mob/living/carbon/user, list/speech_args) + if (user.get_active_held_item() == src) + if(spamcheck > world.time) + to_chat(user, "\The [src] needs to recharge!") + else + playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1) + spamcheck = world.time + 50 + speech_args[SPEECH_SPANS] |= voicespan /obj/item/megaphone/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "You overload \the [src]'s voice synthesizer.") obj_flags |= EMAGGED voicespan = list(SPAN_REALLYBIG, "userdanger") + return TRUE /obj/item/megaphone/sec name = "security megaphone" diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index f8b1d6e15b..207497922e 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -32,6 +32,24 @@ var/datum/integrated_io/selected_io = null //functional for integrated circuits. var/mode = 0 +/obj/item/multitool/chaplain + name = "\improper hypertool" + desc = "Used for pulsing wires to test which to cut. Also emits microwaves to fry some brains!" + damtype = BRAIN + force = 18 + armour_penetration = 35 + hitsound = 'sound/effects/sparks4.ogg' + var/chaplain_spawnable = TRUE + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON + throw_speed = 3 + throw_range = 4 + throwforce = 10 + obj_flags = UNIQUE_RENAME + +/obj/item/multitool/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + /obj/item/multitool/examine(mob/user) ..() if(selected_io) @@ -237,3 +255,10 @@ icon = 'icons/obj/abductor.dmi' icon_state = "multitool" toolspeed = 0.1 + +/obj/item/multitool/advanced + name = "advanced multitool" + desc = "The reproduction of an abductor's multitool, this multitool is a classy silver." + icon = 'icons/obj/advancedtools.dmi' + icon_state = "multitool" + toolspeed = 0.2 diff --git a/code/game/objects/items/devices/quantum_keycard.dm b/code/game/objects/items/devices/quantum_keycard.dm new file mode 100644 index 0000000000..37079722c0 --- /dev/null +++ b/code/game/objects/items/devices/quantum_keycard.dm @@ -0,0 +1,32 @@ +/obj/item/quantum_keycard + name = "quantum keycard" + desc = "A keycard able to link to a quantum pad's particle signature, allowing other quantum pads to travel there instead of their linked pad." + icon = 'icons/obj/device.dmi' + icon_state = "quantum_keycard" + item_state = "card-id" + lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' + w_class = WEIGHT_CLASS_TINY + var/obj/machinery/quantumpad/qpad + +/obj/item/quantum_keycard/examine(mob/user) + ..() + if(qpad) + to_chat(user, "It's currently linked to a quantum pad.") + to_chat(user, "Alt-click to unlink the keycard.") + else + to_chat(user, "Insert [src] into an active quantum pad to link it.") + +/obj/item/quantum_keycard/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + to_chat(user, "You start pressing [src]'s unlink button...") + if(do_after(user, 40, target = src)) + to_chat(user, "The keycard beeps twice and disconnects the quantum link.") + qpad = null + +/obj/item/quantum_keycard/update_icon() + if(qpad) + icon_state = "quantum_keycard_on" + else + icon_state = initial(icon_state) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 2f8b111b4b..b74b0fa3d4 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -38,7 +38,7 @@ /obj/item/electropack/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/clothing/head/helmet)) - var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user ) + var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' if(!user.transferItemToLoc(W, A)) @@ -53,8 +53,6 @@ user.put_in_hands(A) A.add_fingerprint(user) - if(item_flags & NODROP) - A.item_flags |= NODROP else return ..() @@ -106,8 +104,7 @@ if(shock_cooldown != 0) return shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 + addtimer(VARSET_CALLBACK(src, shock_cooldown, 0), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index dd7489d6b1..9adc0488aa 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -1,6 +1,6 @@ /obj/item/encryptionkey name = "standard encryption key" - desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN." + desc = "An encryption key for a radio headset." icon = 'icons/obj/radio.dmi' icon_state = "cypherkey" w_class = WEIGHT_CLASS_TINY @@ -9,124 +9,119 @@ var/independent = FALSE var/list/channels = list() +/obj/item/encryptionkey/Initialize() + . = ..() + if(!channels.len) + desc = "An encryption key for a radio headset. Has no special codes in it. You should probably tell a coder!" + +/obj/item/encryptionkey/examine(mob/user) + . = ..() + if(LAZYLEN(channels)) + var/list/examine_text_list = list() + for(var/i in channels) + examine_text_list += "[GLOB.channel_tokens[i]] - [lowertext(i)]" + + to_chat(user, "It can access the following channels; [jointext(examine_text_list, ", ")].") + /obj/item/encryptionkey/syndicate name = "syndicate encryption key" - desc = "An encryption key for a radio headset. To access the syndicate channel, use :t." icon_state = "syn_cypherkey" - channels = list("Syndicate" = 1) - syndie = 1//Signifies that it de-crypts Syndicate transmissions + channels = list(RADIO_CHANNEL_SYNDICATE = 1) + syndie = TRUE //Signifies that it de-crypts Syndicate transmissions /obj/item/encryptionkey/binary name = "binary translator key" - desc = "An encryption key for a radio headset. To access the binary channel, use :b." icon_state = "bin_cypherkey" translate_binary = TRUE /obj/item/encryptionkey/headset_sec name = "security radio encryption key" - desc = "An encryption key for a radio headset. To access the security channel, use :s." icon_state = "sec_cypherkey" - channels = list("Security" = 1) + channels = list(RADIO_CHANNEL_SECURITY = 1) /obj/item/encryptionkey/headset_eng name = "engineering radio encryption key" - desc = "An encryption key for a radio headset. To access the engineering channel, use :e." icon_state = "eng_cypherkey" - channels = list("Engineering" = 1) + channels = list(RADIO_CHANNEL_ENGINEERING = 1) /obj/item/encryptionkey/headset_rob name = "robotics radio encryption key" - desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For research, use :n." icon_state = "rob_cypherkey" - channels = list("Science" = 1, "Engineering" = 1) + channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_ENGINEERING = 1) /obj/item/encryptionkey/headset_med name = "medical radio encryption key" - desc = "An encryption key for a radio headset. To access the medical channel, use :m." icon_state = "med_cypherkey" - channels = list("Medical" = 1) + channels = list(RADIO_CHANNEL_MEDICAL = 1) /obj/item/encryptionkey/headset_sci name = "science radio encryption key" - desc = "An encryption key for a radio headset. To access the science channel, use :n." icon_state = "sci_cypherkey" - channels = list("Science" = 1) + channels = list(RADIO_CHANNEL_SCIENCE = 1) /obj/item/encryptionkey/headset_medsci name = "medical research radio encryption key" - desc = "An encryption key for a radio headset. To access the medical channel, use :m. For science, use :n." icon_state = "medsci_cypherkey" - channels = list("Science" = 1, "Medical" = 1) + channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1) /obj/item/encryptionkey/headset_com name = "command radio encryption key" - desc = "An encryption key for a radio headset. To access the command channel, use :c." icon_state = "com_cypherkey" - channels = list("Command" = 1) + channels = list(RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/heads/captain name = "\proper the captain's encryption key" - desc = "An encryption key for a radio headset. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." icon_state = "cap_cypherkey" - channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0) + channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 0, RADIO_CHANNEL_SCIENCE = 0, RADIO_CHANNEL_MEDICAL = 0, RADIO_CHANNEL_SUPPLY = 0, RADIO_CHANNEL_SERVICE = 0) /obj/item/encryptionkey/heads/rd name = "\proper the research director's encryption key" - desc = "An encryption key for a radio headset. To access the science channel, use :n. For command, use :c." icon_state = "rd_cypherkey" - channels = list("Science" = 1, "Command" = 1) + channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/heads/hos name = "\proper the head of security's encryption key" - desc = "An encryption key for a radio headset. To access the security channel, use :s. For command, use :c." icon_state = "hos_cypherkey" - channels = list("Security" = 1, "Command" = 1) + channels = list(RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/heads/ce name = "\proper the chief engineer's encryption key" - desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For command, use :c." icon_state = "ce_cypherkey" - channels = list("Engineering" = 1, "Command" = 1) + channels = list(RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/heads/cmo name = "\proper the chief medical officer's encryption key" - desc = "An encryption key for a radio headset. To access the medical channel, use :m. For command, use :c." icon_state = "cmo_cypherkey" - channels = list("Medical" = 1, "Command" = 1) + channels = list(RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/heads/hop name = "\proper the head of personnel's encryption key" - desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :v - service, :c - command." icon_state = "hop_cypherkey" - channels = list("Supply" = 1, "Service" = 1, "Command" = 1) + channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/headset_cargo name = "supply radio encryption key" - desc = "An encryption key for a radio headset. To access the supply channel, use :u." icon_state = "cargo_cypherkey" - channels = list("Supply" = 1) + channels = list(RADIO_CHANNEL_SUPPLY = 1) /obj/item/encryptionkey/headset_mining name = "mining radio encryption key" - desc = "An encryption key for a radio headset. To access the supply channel, use :u. For science, use :n." icon_state = "cargo_cypherkey" - channels = list("Supply" = 1, "Science" = 1) + channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SCIENCE = 1) /obj/item/encryptionkey/headset_service name = "service radio encryption key" - desc = "An encryption key for a radio headset. To access the service channel, use :v." icon_state = "srv_cypherkey" - channels = list("Service" = 1) + channels = list(RADIO_CHANNEL_SERVICE = 1) /obj/item/encryptionkey/headset_cent name = "\improper CentCom radio encryption key" - desc = "An encryption key for a radio headset. To access the CentCom channel, use :y." icon_state = "cent_cypherkey" independent = TRUE - channels = list("CentCom" = 1) + channels = list(RADIO_CHANNEL_CENTCOM = 1) /obj/item/encryptionkey/ai //ported from NT, this goes 'inside' the AI. - channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1) + channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_AI_PRIVATE = 1) /obj/item/encryptionkey/secbot - channels = list("AI Private"=1,"Security"=1) + channels = list(RADIO_CHANNEL_AI_PRIVATE = 1, RADIO_CHANNEL_SECURITY = 1) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index ea9c6fb99e..cca5eb4217 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -1,3 +1,19 @@ +// Used for translating channels to tokens on examination +GLOBAL_LIST_INIT(channel_tokens, list( + RADIO_CHANNEL_COMMON = RADIO_KEY_COMMON, + RADIO_CHANNEL_SCIENCE = RADIO_TOKEN_SCIENCE, + RADIO_CHANNEL_COMMAND = RADIO_TOKEN_COMMAND, + RADIO_CHANNEL_MEDICAL = RADIO_TOKEN_MEDICAL, + RADIO_CHANNEL_ENGINEERING = RADIO_TOKEN_ENGINEERING, + RADIO_CHANNEL_SECURITY = RADIO_TOKEN_SECURITY, + RADIO_CHANNEL_CENTCOM = RADIO_TOKEN_CENTCOM, + RADIO_CHANNEL_SYNDICATE = RADIO_TOKEN_SYNDICATE, + RADIO_CHANNEL_SUPPLY = RADIO_TOKEN_SUPPLY, + RADIO_CHANNEL_SERVICE = RADIO_TOKEN_SERVICE, + MODE_BINARY = MODE_TOKEN_BINARY, + RADIO_CHANNEL_AI_PRIVATE = RADIO_TOKEN_AI_PRIVATE +)) + /obj/item/radio/headset name = "radio headset" desc = "An updated, modular intercom that fits over the head. Takes encryption keys." @@ -17,9 +33,24 @@ /obj/item/radio/headset/examine(mob/user) ..() - to_chat(user, "To speak on the general radio frequency, use ; before speaking.") - if (command) - to_chat(user, "Alt-click to toggle the high-volume mode.") + + if(item_flags & IN_INVENTORY && loc == user) + // construction of frequency description + var/list/avail_chans = list("Use [RADIO_KEY_COMMON] for the currently tuned frequency") + if(translate_binary) + avail_chans += "use [MODE_TOKEN_BINARY] for [MODE_BINARY]" + if(length(channels)) + for(var/i in 1 to length(channels)) + if(i == 1) + avail_chans += "use [MODE_TOKEN_DEPARTMENT] or [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]" + else + avail_chans += "use [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]" + to_chat(user, "A small screen on the headset displays the following available frequencies:\n[english_list(avail_chans)].") + + if(command) + to_chat(user, "Alt-click to toggle the high-volume mode.") + else + to_chat(user, "A small screen on the headset flashes, it's too small to read without holding or wearing the headset.") /obj/item/radio/headset/Initialize() . = ..() @@ -47,7 +78,7 @@ /obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection name = "syndicate headset" - desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking." + desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs." icon_state = "syndie_headset" item_state = "syndie_headset" @@ -72,13 +103,13 @@ /obj/item/radio/headset/headset_sec name = "security radio headset" - desc = "This is used by your elite security force.\nTo access the security channel, use :s." + desc = "This is used by your elite security force." icon_state = "sec_headset" keyslot = new /obj/item/encryptionkey/headset_sec /obj/item/radio/headset/headset_sec/alt name = "security bowman headset" - desc = "This is used by your elite security force. Protects ears from flashbangs.\nTo access the security channel, use :s." + desc = "This is used by your elite security force. Protects ears from flashbangs." icon_state = "sec_headset_alt" item_state = "sec_headset_alt" @@ -88,31 +119,31 @@ /obj/item/radio/headset/headset_eng name = "engineering radio headset" - desc = "When the engineers wish to chat like girls.\nTo access the engineering channel, use :e." + desc = "When the engineers wish to chat like girls." icon_state = "eng_headset" keyslot = new /obj/item/encryptionkey/headset_eng /obj/item/radio/headset/headset_rob name = "robotics radio headset" - desc = "Made specifically for the roboticists, who cannot decide between departments.\nTo access the engineering channel, use :e. For research, use :n." + desc = "Made specifically for the roboticists, who cannot decide between departments." icon_state = "rob_headset" keyslot = new /obj/item/encryptionkey/headset_rob /obj/item/radio/headset/headset_med name = "medical radio headset" - desc = "A headset for the trained staff of the medbay.\nTo access the medical channel, use :m." + desc = "A headset for the trained staff of the medbay." icon_state = "med_headset" keyslot = new /obj/item/encryptionkey/headset_med /obj/item/radio/headset/headset_sci name = "science radio headset" - desc = "A sciency headset. Like usual.\nTo access the science channel, use :n." + desc = "A sciency headset. Like usual." icon_state = "sci_headset" keyslot = new /obj/item/encryptionkey/headset_sci /obj/item/radio/headset/headset_medsci name = "medical research radio headset" - desc = "A headset that is a result of the mating between medical and science.\nTo access the medical channel, use :m. For science, use :n." + desc = "A headset that is a result of the mating between medical and science." icon_state = "medsci_headset" keyslot = new /obj/item/encryptionkey/headset_medsci @@ -127,13 +158,13 @@ /obj/item/radio/headset/heads/captain name = "\proper the captain's headset" - desc = "The headset of the king.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." + desc = "The headset of the king." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/captain /obj/item/radio/headset/heads/captain/alt name = "\proper the captain's bowman headset" - desc = "The headset of the boss. Protects ears from flashbangs.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." + desc = "The headset of the boss. Protects ears from flashbangs." icon_state = "com_headset_alt" item_state = "com_headset_alt" @@ -143,19 +174,19 @@ /obj/item/radio/headset/heads/rd name = "\proper the research director's headset" - desc = "Headset of the fellow who keeps society marching towards technological singularity.\nTo access the science channel, use :n. For command, use :c." + desc = "Headset of the fellow who keeps society marching towards technological singularity." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/rd /obj/item/radio/headset/heads/hos name = "\proper the head of security's headset" - desc = "The headset of the man in charge of keeping order and protecting the station.\nTo access the security channel, use :s. For command, use :c." + desc = "The headset of the man in charge of keeping order and protecting the station." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/hos /obj/item/radio/headset/heads/hos/alt name = "\proper the head of security's bowman headset" - desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs.\nTo access the security channel, use :s. For command, use :c." + desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs." icon_state = "com_headset_alt" item_state = "com_headset_alt" @@ -165,43 +196,43 @@ /obj/item/radio/headset/heads/ce name = "\proper the chief engineer's headset" - desc = "The headset of the guy in charge of keeping the station powered and undamaged.\nTo access the engineering channel, use :e. For command, use :c." + desc = "The headset of the guy in charge of keeping the station powered and undamaged." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/ce /obj/item/radio/headset/heads/cmo name = "\proper the chief medical officer's headset" - desc = "The headset of the highly trained medical chief.\nTo access the medical channel, use :m. For command, use :c." + desc = "The headset of the highly trained medical chief." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/cmo /obj/item/radio/headset/heads/hop name = "\proper the head of personnel's headset" - desc = "The headset of the guy who will one day be captain.\nChannels are as follows: :u - supply, :v - service, :c - command." + desc = "The headset of the guy who will one day be captain." icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/hop /obj/item/radio/headset/headset_cargo name = "supply radio headset" - desc = "A headset used by the QM and his slaves.\nTo access the supply channel, use :u." + desc = "A headset used by the QM and his slaves." icon_state = "cargo_headset" keyslot = new /obj/item/encryptionkey/headset_cargo /obj/item/radio/headset/headset_cargo/mining name = "mining radio headset" - desc = "Headset used by shaft miners.\nTo access the supply channel, use :u. For science, use :n." + desc = "Headset used by shaft miners." icon_state = "mine_headset" keyslot = new /obj/item/encryptionkey/headset_mining /obj/item/radio/headset/headset_srv name = "service radio headset" - desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean.\nTo access the service channel, use :v." + desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean." icon_state = "srv_headset" keyslot = new /obj/item/encryptionkey/headset_service /obj/item/radio/headset/headset_cent name = "\improper CentCom headset" - desc = "A headset used by the upper echelons of Nanotrasen.\nTo access the CentCom channel, use :y." + desc = "A headset used by the upper echelons of Nanotrasen." icon_state = "cent_headset" keyslot = new /obj/item/encryptionkey/headset_com keyslot2 = new /obj/item/encryptionkey/headset_cent @@ -215,7 +246,7 @@ /obj/item/radio/headset/headset_cent/alt name = "\improper CentCom bowman headset" - desc = "A headset especially for emergency response personnel. Protects ears from flashbangs.\nTo access the CentCom channel, use :y." + desc = "A headset especially for emergency response personnel. Protects ears from flashbangs." icon_state = "cent_headset_alt" item_state = "cent_headset_alt" keyslot = null diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 719fe6ddd8..7c136f556e 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -16,7 +16,6 @@ var/on = TRUE var/frequency = FREQ_COMMON - var/traitor_frequency = 0 // If tuned to this frequency, uplink will be unlocked. var/canhear_range = 3 // The range around the radio in which mobs can hear what it receives. var/emped = 0 // Tracks the number of EMPs currently stacked. @@ -190,7 +189,7 @@ /obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language) if(!spans) - spans = M.get_spans() + spans = list(M.speech_span) if(!language) language = M.get_default_language() INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language) @@ -222,7 +221,7 @@ // From the channel, determine the frequency and get a reference to it. var/freq if(channel && channels && channels.len > 0) - if(channel == "department") + if(channel == MODE_DEPARTMENT) channel = channels[1] freq = secure_radio_connections[channel] if (!channels[channel]) // if the channel is turned off, don't broadcast diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index 2f137861aa..20107373d3 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -49,7 +49,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user if(C.get_item_by_slot(SLOT_HEAD) == src) - if((item_flags & NODROP) && !struggling) + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) && !struggling) struggling = TRUE var/fear_string switch(time_left) @@ -74,7 +74,7 @@ else user.visible_message("The lock on [user]'s [name] pops open!", \ "You force open the padlock!", "You hear a single, pronounced click!") - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) struggling = FALSE else ..() @@ -116,7 +116,7 @@ /obj/item/reverse_bear_trap/proc/reset() ticking = FALSE - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) soundloop.stop() soundloop2.stop() STOP_PROCESSING(SSprocessing, src) @@ -125,7 +125,7 @@ ticking = TRUE escape_chance = initial(escape_chance) //we keep these vars until re-arm, for tracking purposes time_left = initial(time_left) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) soundloop.start() soundloop2.mid_length = initial(soundloop2.mid_length) soundloop2.start() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 9f52b4c1ac..0059938720 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -163,7 +163,37 @@ SLIME SCANNER msg += "\tSevere brain damage detected. Subject likely to have mental traumas.\n" else if (M.getBrainLoss() >= 45) msg += "\tBrain damage detected.\n" - if(iscarbon(M)) + if(ishuman(M) && advanced) // Should I make this not advanced? + var/mob/living/carbon/human/H = M + var/obj/item/organ/liver/L = H.getorganslot("liver") + if(L) + if(L.swelling > 20) + msg += "\tSubject is suffering from an enlarged liver.\n" //i.e. shrink their liver or give them a transplant. + else + msg += "\tSubject's liver is missing.\n" + var/obj/item/organ/tongue/T = H.getorganslot("tongue") + if(T) + if(T.damage > 40) + msg += "\tSubject is suffering from severe burn tissue on their tongue.\n" //i.e. their tongue is shot + if(T.name == "fluffy tongue") + msg += "\tSubject is suffering from a fluffified tongue. Suggested cure: Yamerol or a tongue transplant.\n" + else + msg += "\tSubject's tongue is missing.\n" + var/obj/item/organ/lungs/Lung = H.getorganslot("lungs") + if(Lung) + if(Lung.damage > 150) + msg += "\tSubject is suffering from acute emphysema leading to trouble breathing.\n" //i.e. Their lungs are shot + else + msg += "\tSubject's lungs have collapsed from trauma!\n" + var/obj/item/organ/genital/penis/P = H.getorganslot("penis") + if(P) + if(P.length>20) + msg += "\tSubject has a sizeable gentleman's organ at [P.length] inches.\n" + var/obj/item/organ/genital/breasts/Br = H.getorganslot("breasts") + if(Br) + if(Br.cached_size>5) + msg += "\tSubject has a sizeable bosom with a [Br.size] cup.\n" + var/mob/living/carbon/C = M if(LAZYLEN(C.get_traumas())) var/list/trauma_text = list() @@ -183,7 +213,7 @@ SLIME SCANNER msg += "\tSubject has the following physiological traits: [C.get_trait_string()].\n" if(advanced) msg += "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%.\n" - if (M.radiation) + if(M.radiation) msg += "\tSubject is irradiated.\n" if(advanced) msg += "\tRadiation Level: [M.radiation]%.\n" @@ -191,6 +221,17 @@ SLIME SCANNER if(advanced && M.hallucinating()) msg += "\tSubject is hallucinating.\n" + //MKUltra + if(advanced && M.has_status_effect(/datum/status_effect/chem/enthrall)) + msg += "\tSubject has abnormal brain fuctions.\n" + + //Astrogen shenanigans + if(advanced && M.reagents.has_reagent("astral")) + if(M.mind) + msg += "\tWarning: subject may be possesed.\n" + else + msg += "\tSubject appears to be astrally projecting.\n" + //Eyes and ears if(advanced) if(iscarbon(M)) @@ -256,6 +297,7 @@ SLIME SCANNER for(var/obj/item/bodypart/org in damaged) msg += "\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]\n" + // Species and body temperature if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -310,7 +352,7 @@ SLIME SCANNER var/mob/living/carbon/human/H = C if(H.bleed_rate) msg += "Subject is bleeding!\n" - var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100) + var/blood_percent = round((C.blood_volume / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100) var/blood_type = C.dna.blood_type if(blood_id != "blood")//special blood substance var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] @@ -318,9 +360,9 @@ SLIME SCANNER blood_type = R.name else blood_type = blood_id - if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY) + if(C.blood_volume <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.blood_volume > (BLOOD_VOLUME_OKAY*C.blood_ratio)) msg += "LOW blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" - else if(C.blood_volume <= BLOOD_VOLUME_OKAY) + else if(C.blood_volume <= (BLOOD_VOLUME_OKAY*C.blood_ratio)) msg += "CRITICAL blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" else msg += "Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" @@ -341,9 +383,19 @@ SLIME SCANNER if(M.reagents) var/msg = "*---------*\n" if(M.reagents.reagent_list.len) - msg += "Subject contains the following reagents:\n" + var/list/datum/reagent/reagents = list() for(var/datum/reagent/R in M.reagents.reagent_list) - msg += "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]\n" + if(R.invisible) + continue + reagents += R + + if(length(reagents)) + msg += "Subject contains the following reagents:\n" + for(var/datum/reagent/R in reagents) + msg += "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]\n" + else + msg += "Subject contains no reagents.\n" + else msg += "Subject contains no reagents.\n" if(M.reagents.addiction_list.len) @@ -621,7 +673,7 @@ SLIME SCANNER to_chat(user, "Growth progress: [T.amount_grown]/[SLIME_EVOLUTION_THRESHOLD]") if(T.effectmod) to_chat(user, "Core mutation in progress: [T.effectmod]") - to_chat(user, "Progress in core mutation: [T.applied] / [SLIME_EXTRACT_CROSSING_REQUIRED]") + to_chat(user, "Progress in core mutation: [T.applied] / [SLIME_EXTRACT_CROSSING_REQUIRED]") to_chat(user, "========================") diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 34ce6bc521..71687f0d5a 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -1,4 +1,3 @@ - ///books that teach things (intrinsic actions like bar flinging, spells like fireball or smoke, or martial arts)/// /obj/item/book/granter @@ -13,19 +12,50 @@ /obj/item/book/granter/proc/turn_page(mob/user) playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1) if(do_after(user,50, user)) - to_chat(user, "[pick(remarks)]") + if(remarks.len) + to_chat(user, "[pick(remarks)]") + else + to_chat(user, "You keep reading...") return TRUE return FALSE /obj/item/book/granter/proc/recoil(mob/user) //nothing so some books can just return +/obj/item/book/granter/proc/already_known(mob/user) + return FALSE + +/obj/item/book/granter/proc/on_reading_start(mob/user) + to_chat(user, "You start reading [name]...") + +/obj/item/book/granter/proc/on_reading_stopped(mob/user) + to_chat(user, "You stop reading...") + +/obj/item/book/granter/proc/on_reading_finished(mob/user) + to_chat(user, "You finish reading [name]!") + /obj/item/book/granter/proc/onlearned(mob/user) used = TRUE + /obj/item/book/granter/attack_self(mob/user) - if(reading == TRUE) + if(reading) to_chat(user, "You're already reading this!") return FALSE + if(already_known(user)) + return FALSE + if(used && oneuse) + recoil(user) + else + on_reading_start(user) + reading = TRUE + for(var/i=1, i<=pages_to_mastery, i++) + if(!turn_page(user)) + on_reading_stopped() + reading = FALSE + return + if(do_after(user,50, user)) + on_reading_finished(user) + reading = FALSE return TRUE ///ACTION BUTTONS/// @@ -34,33 +64,23 @@ var/granted_action var/actionname = "catching bugs" //might not seem needed but this makes it so you can safely name action buttons toggle this or that without it fucking up the granter, also caps -/obj/item/book/granter/action/attack_self(mob/user) - . = ..() - if(!.) - return +/obj/item/book/granter/action/already_known(mob/user) if(!granted_action) - return - var/datum/action/G = new granted_action + return TRUE for(var/datum/action/A in user.actions) - if(A.type == G.type) + if(A.type == granted_action) to_chat(user, "You already know all about [actionname].") - qdel(G) - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about [actionname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(G) - return - if(do_after(user,50, user)) - to_chat(user, "You feel like you've got a good handle on [actionname]!") - G.Grant(user) - reading = FALSE + return TRUE + return FALSE + +/obj/item/book/granter/action/on_reading_start(mob/user) + to_chat(user, "You start reading about [actionname]...") + +/obj/item/book/granter/action/on_reading_finished(mob/user) + to_chat(user, "You feel like you've got a good handle on [actionname]!") + var/datum/action/G = new granted_action + G.Grant(user) + onlearned(user) /obj/item/book/granter/action/drink_fling granted_action = /datum/action/innate/drink_fling @@ -120,38 +140,28 @@ var/spell var/spellname = "conjure bugs" -/obj/item/book/granter/spell/attack_self(mob/user) - . = ..() - if(!.) - return +/obj/item/book/granter/spell/already_known(mob/user) if(!spell) - return - var/obj/effect/proc_holder/spell/S = new spell + return TRUE for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) - if(knownspell.type == S.type) + if(knownspell.type == spell) if(user.mind) if(iswizard(user)) - to_chat(user,"You're already far more versed in this spell than this flimsy howto book can provide.") + to_chat(user,"You're already far more versed in this spell than this flimsy how-to book can provide.") else to_chat(user,"You've already read this one.") - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about casting [spellname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(S) - return - if(do_after(user,50, user)) - to_chat(user, "You feel like you've experienced enough to cast [spellname]!") - user.mind.AddSpell(S) - user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange") - onlearned(user) - reading = FALSE + return TRUE + return FALSE + +/obj/item/book/granter/spell/on_reading_start(mob/user) + to_chat(user, "You start reading about casting [spellname]...") + +/obj/item/book/granter/spell/on_reading_finished(mob/user) + to_chat(user, "You feel like you've experienced enough to cast [spellname]!") + var/obj/effect/proc_holder/spell/S = new spell + user.mind.AddSpell(S) + user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange") + onlearned(user) /obj/item/book/granter/spell/recoil(mob/user) user.visible_message("[src] glows in a black light!") @@ -279,10 +289,7 @@ /obj/item/book/granter/spell/barnyard/recoil(mob/living/carbon/user) if(ishuman(user)) to_chat(user,"HORSIE HAS RISEN") - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.item_flags |= NODROP //curses! - magichead.flags_inv &= ~HIDEFACE //so you can still see their face - magichead.voicechange = TRUE //NEEEEIIGHH + var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location()) if(!user.dropItemToGround(user.wear_mask)) qdel(user.wear_mask) user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE) @@ -331,35 +338,24 @@ var/martialname = "bug jitsu" var/greet = "You feel like you have mastered the art in breaking code. Nice work, jackass." -/obj/item/book/granter/martial/attack_self(mob/user) - . = ..() - if(!.) - return +/obj/item/book/granter/martial/already_known(mob/user) if(!martial) - return + return TRUE + var/datum/martial_art/MA = martial + if(user.mind.has_martialart(initial(MA.id))) + to_chat(user,"You already know [martialname]!") + return TRUE + return FALSE + +/obj/item/book/granter/martial/on_reading_start(mob/user) + to_chat(user, "You start reading about [martialname]...") + +/obj/item/book/granter/martial/on_reading_finished(mob/user) + to_chat(user, "[greet]") var/datum/martial_art/MA = new martial - if(user.mind.martial_art) - for(var/datum/martial_art/knownmartial in user.mind.martial_art) - if(knownmartial.type == MA.type) - to_chat(user,"You already know [martialname]!") - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about [martialname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(MA) - return - if(do_after(user,50, user)) - to_chat(user, "[greet]") - MA.teach(user) - user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange") - onlearned(user) - reading = FALSE + MA.teach(user) + user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange") + onlearned(user) /obj/item/book/granter/martial/cqc martial = /datum/martial_art/cqc @@ -420,3 +416,44 @@ icon_state = "blankscroll" // I did not include mushpunch's grant, it is not a book and the item does it just fine. + + +//Crafting Recipe books + +/obj/item/book/granter/crafting_recipe + var/list/crafting_recipe_types = list() //Use full /datum/crafting_recipe/what_you_craft + +/obj/item/book/granter/crafting_recipe/on_reading_finished(mob/user) + . = ..() + if(!user.mind) + return + for(var/crafting_recipe_type in crafting_recipe_types) + var/datum/crafting_recipe/R = crafting_recipe_type + user.mind.teach_crafting_recipe(crafting_recipe_type) + to_chat(user,"You learned how to make [initial(R.name)].") + +/obj/item/book/granter/crafting_recipe/cooking_sweets_101 //We start at 101 for 103 and 105 + name = "Cooking Desserts 101" + desc = "A cook book that teaches you some more of the newest desserts. AI approved, and a best seller on Honkplanet." + crafting_recipe_types = list(/datum/crafting_recipe/food/mimetart, /datum/crafting_recipe/food/berrytart, /datum/crafting_recipe/food/cocolavatart, /datum/crafting_recipe/food/clowncake, /datum/crafting_recipe/food/vanillacake) + icon_state = "cooking_learing_sweets" + oneuse = FALSE + remarks = list("So that is how icing is made!", "Placing fruit on top? How simple...", "Huh layering cake seems harder then this...", "This book smells like candy", "A clown must have made this page, or they forgot to spell check it before printing...", "Wait, a way to cook slime to be safe?") + +//Later content when I have free time - Trilby Date:02-Aug-2019 + +/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book + name = "Under The Oven" + desc = "A cook book that teaches you many illegal and fun candys. MALF AI approved, and a best seller on the blackmarket." + crafting_recipe_types = list() + icon_state = "cooking_learing_illegal" + oneuse = FALSE + remarks = list() + +/obj/item/book/granter/crafting_recipe/coldcooking //IceCream + name = "Cooking with Ice" + desc = "A cook book that teaches you many old icecream treats." + crafting_recipe_types = list() + icon_state = "cooking_learing_ice" + oneuse = FALSE + remarks = list() \ No newline at end of file diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 5e19577b46..a306b48385 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -26,6 +26,7 @@ gender = PLURAL icon = 'icons/obj/items_and_weapons.dmi' icon_state = "handcuff" + item_state = "handcuff" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' flags_1 = CONDUCT_1 @@ -103,7 +104,6 @@ desc = "A pair of restraints fashioned from long strands of flesh." icon = 'icons/obj/mining.dmi' icon_state = "sinewcuff" - item_state = "sinewcuff" breakouttime = 300 //Deciseconds = 30s cuffsound = 'sound/weapons/cablecuff.ogg' @@ -164,14 +164,6 @@ /obj/item/restraints/handcuffs/cable/white item_color = "white" -/obj/item/restraints/handcuffs/alien - icon_state = "handcuffAlien" - -/obj/item/restraints/handcuffs/fake - name = "fake handcuffs" - desc = "Fake handcuffs meant for gag purposes." - breakouttime = 10 //Deciseconds = 1s - /obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/rods)) @@ -206,7 +198,7 @@ /obj/item/restraints/handcuffs/cable/zipties name = "zipties" desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." - icon_state = "cuff" + item_state = "zipties" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' materials = list() @@ -217,11 +209,25 @@ /obj/item/restraints/handcuffs/cable/zipties/used desc = "A pair of broken zipties." icon_state = "cuff_used" - item_state = "cuff" /obj/item/restraints/handcuffs/cable/zipties/used/attack() return +/obj/item/restraints/handcuffs/alien + icon_state = "handcuffAlien" + +/obj/item/restraints/handcuffs/fake + name = "fake handcuffs" + desc = "Fake handcuffs meant for gag purposes." + breakouttime = 10 //Deciseconds = 1s + +/obj/item/restraints/handcuffs/fake/kinky + name = "kinky handcuffs" + desc = "Fake handcuffs meant for erotic roleplay." + icon = 'modular_citadel/icons/obj/items_and_weapons.dmi' + icon_state = "handcuffgag" + item_state = "kinkycuff" + //Legcuffs /obj/item/restraints/legcuffs @@ -230,6 +236,7 @@ gender = PLURAL icon = 'icons/obj/items_and_weapons.dmi' icon_state = "handcuff" + item_state = "legcuff" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' flags_1 = CONDUCT_1 diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index 49a5cfaf35..3be57d23f1 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -8,12 +8,13 @@ name = "artistic toolbox" desc = "A toolbox painted bright green. Looking at it makes you feel uneasy." icon_state = "his_grace" - item_state = "artistic_toolbox" + item_state = "toolbox_green" lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' icon = 'icons/obj/items_and_weapons.dmi' - w_class = WEIGHT_CLASS_GIGANTIC + w_class = WEIGHT_CLASS_BULKY force = 12 + total_mass = TOTAL_MASS_NORMAL_ITEM // average toolbox attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' var/awakened = FALSE @@ -90,7 +91,7 @@ do_attack_animation(master, null, src) master.emote("scream") master.remove_status_effect(STATUS_EFFECT_HISGRACE) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) master.Knockdown(60) master.adjustBruteLoss(master.maxHealth) playsound(master, 'sound/effects/splat.ogg', 100, 0) @@ -174,6 +175,7 @@ /obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace. if(!meal) return + var/victims = 0 meal.visible_message("[src] swings open and devours [meal]!", "[src] consumes you!") meal.adjustBruteLoss(200) playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1) @@ -185,7 +187,10 @@ bloodthirst = max(LAZYLEN(contents), 1) //Never fully sated, and His hunger will only grow. else bloodthirst = HIS_GRACE_CONSUME_OWNER - if(LAZYLEN(contents) >= victims_needed) + for(var/mob/living/C in contents) + if(C.mind) + victims++ + if(victims >= victims_needed) ascend() update_stats() @@ -198,20 +203,20 @@ update_stats() /obj/item/his_grace/proc/update_stats() - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) var/mob/living/master = get_atom_on_turf(src, /mob/living) switch(bloodthirst) if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) if(HIS_GRACE_CONSUME_OWNER > prev_bloodthirst) master.visible_message("[src] enters a frenzy!") if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) if(HIS_GRACE_STARVING > prev_bloodthirst) master.visible_message("[src] is starving!", "[src]'s bloodlust overcomes you. [src] must be fed, or you will become His meal.\ [force_bonus < 15 ? " And still, His power grows.":""]") force_bonus = max(force_bonus, 15) if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT) if(HIS_GRACE_FAMISHED > prev_bloodthirst) master.visible_message("[src] is very hungry!", "Spines sink into your hand. [src] must feed immediately.\ [force_bonus < 10 ? " His power grows.":""]") diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 06aef0a22b..185875a93f 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -229,8 +229,8 @@ throwforce = 10 w_class = WEIGHT_CLASS_TINY obj_flags = UNIQUE_RENAME - var/reskinned = FALSE var/chaplain_spawnable = TRUE + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON /obj/item/nullrod/Initialize() . = ..() @@ -247,9 +247,12 @@ /obj/item/nullrod/proc/reskin_holy_weapon(mob/M) if(GLOB.holy_weapon_type) return - var/obj/item/nullrod/holy_weapon + var/obj/item/holy_weapon var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( - /obj/item/melee/transforming/energy/sword/cx/chaplain + /obj/item/twohanded/dualsaber/hypereutactic/chaplain, + /obj/item/gun/energy/laser/redtag/hitscan/chaplain, + /obj/item/multitool/chaplain, + /obj/item/melee/baseball_bat/chaplain ) var/list/display_names = list() for(var/V in holy_weapons_list) @@ -273,6 +276,13 @@ qdel(src) M.put_in_active_hand(holy_weapon) +/obj/item/nullrod/proc/jedi_spin(mob/living/user) + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + user.setDir(i) + if(i == WEST) + user.emote("flip") + sleep(1) + /obj/item/nullrod/godhand icon_state = "disintegrate" item_state = "disintegrate" @@ -280,11 +290,16 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' name = "god hand" desc = "This hand of yours glows with an awesome power!" - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE hitsound = 'sound/weapons/sear.ogg' damtype = BURN attack_verb = list("punched", "cross countered", "pummeled") + total_mass = TOTAL_MASS_HAND_REPLACEMENT + +/obj/item/nullrod/godhand/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) /obj/item/nullrod/staff icon_state = "godstaff-red" @@ -525,13 +540,15 @@ lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' w_class = WEIGHT_CLASS_HUGE - item_flags = NODROP | ABSTRACT + item_flags = ABSTRACT sharpness = IS_SHARP attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = 'sound/weapons/chainsawhit.ogg' + total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/nullrod/chainsaw/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 30, 100, 0, hitsound) /obj/item/nullrod/clown @@ -576,6 +593,7 @@ lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' slot_flags = ITEM_SLOT_BELT + force = 12 reach = 2 attack_verb = list("whipped", "lashed") hitsound = 'sound/weapons/chainhit.ogg' @@ -601,12 +619,14 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = ABSTRACT | NODROP + item_flags = ABSTRACT w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP + total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/nullrod/armblade/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) /obj/item/nullrod/armblade/tentacle @@ -650,6 +670,44 @@ lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' +/obj/item/nullrod/claymore/bostaff/attack(mob/target, mob/living/user) + add_fingerprint(user) + if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) + to_chat(user, "You club yourself over the head with [src].") + user.Knockdown(60) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD) + else + user.take_bodypart_damage(2*force) + return + if(iscyborg(target)) + return ..() + if(!isliving(target)) + return ..() + var/mob/living/carbon/C = target + if(C.stat || C.health < 0 || C.staminaloss > 130 ) + to_chat(user, "It would be dishonorable to attack a foe while they cannot retaliate.") + return + if(user.a_intent == INTENT_DISARM) + if(!ishuman(target)) + return ..() + var/mob/living/carbon/human/H = target + var/list/fluffmessages = list("[user] clubs [H] with [src]!", \ + "[user] smacks [H] with the butt of [src]!", \ + "[user] broadsides [H] with [src]!", \ + "[user] smashes [H]'s head with [src]!", \ + "[user] beats [H] with front of [src]!", \ + "[user] twirls and slams [H] with [src]!") + H.visible_message("[pick(fluffmessages)]", \ + "[pick(fluffmessages)]") + playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1) + H.adjustStaminaLoss(rand(12,18)) + if(prob(25)) + (INVOKE_ASYNC(src, .proc/jedi_spin, user)) + else + return ..() + /obj/item/nullrod/tribal_knife icon_state = "crysknife" item_state = "crysknife" @@ -692,8 +750,8 @@ name = "egyptian staff" desc = "A tutorial in mummification is carved into the staff. You could probably craft the wraps if you had some cloth." icon = 'icons/obj/guns/magic.dmi' - icon_state = "pharoah_sceptre" - item_state = "pharoah_sceptre" + icon_state = "pharaoh_sceptre" + item_state = "pharaoh_sceptre" lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/hot_potato.dm b/code/game/objects/items/hot_potato.dm index db7f38ddf3..e7b05d7a01 100644 --- a/code/game/objects/items/hot_potato.dm +++ b/code/game/objects/items/hot_potato.dm @@ -134,7 +134,7 @@ return update_icon() if(sticky) - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, HOT_POTATO_TRAIT) name = "primed [name]" activation_time = timer + world.time detonation_timerid = addtimer(CALLBACK(src, .proc/detonate), delay, TIMER_STOPPABLE) @@ -147,7 +147,7 @@ /obj/item/hot_potato/proc/deactivate() update_icon() name = initial(name) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, HOT_POTATO_TRAIT) deltimer(detonation_timerid) STOP_PROCESSING(SSfastprocess, src) detonation_timerid = null diff --git a/code/game/objects/items/implants/implant_krav_maga.dm b/code/game/objects/items/implants/implant_krav_maga.dm index 3a751ecd0e..373658b386 100644 --- a/code/game/objects/items/implants/implant_krav_maga.dm +++ b/code/game/objects/items/implants/implant_krav_maga.dm @@ -21,7 +21,7 @@ return if(!H.mind) return - if(istype(H.mind.martial_art, /datum/martial_art/krav_maga)) + if(H.mind.has_martialart(MARTIALART_KRAVMAGA)) style.remove(H) else style.teach(H,1) diff --git a/code/game/objects/items/implants/implant_stealth.dm b/code/game/objects/items/implants/implant_stealth.dm index 84f9f5f454..eb58d76d1b 100644 --- a/code/game/objects/items/implants/implant_stealth.dm +++ b/code/game/objects/items/implants/implant_stealth.dm @@ -9,6 +9,7 @@ name = "inconspicious box" desc = "It's so normal that you didn't notice it before." icon_state = "agentbox" + max_integrity = 1 use_mob_movespeed = TRUE /obj/structure/closet/cardboard/agent/proc/go_invisible() diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 935d2a007e..d854ab9f5a 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -5,9 +5,12 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) resistance_flags = FIRE_PROOF var/brightness_on = 3 + total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces. + /obj/item/melee/transforming/energy/Initialize() . = ..() + total_mass_on = (total_mass_on ? total_mass_on : (w_class_on * 0.75)) if(active) set_light(brightness_on) START_PROCESSING(SSobj, src) @@ -79,6 +82,7 @@ attack_verb_off = list("attacked", "chopped", "cleaved", "torn", "cut") attack_verb_on = list() light_color = "#40ceff" + total_mass = null /obj/item/melee/transforming/energy/axe/suicide_act(mob/user) user.visible_message("[user] swings [src] towards [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 33a48c17bb..f9affc230d 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -42,8 +42,9 @@ force = 20 throwforce = 10 hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + attack_verb = list("attacked", "impaled", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = IS_SHARP + total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/melee/synthetic_arm_blade/Initialize() . = ..() @@ -67,6 +68,7 @@ attack_verb = list("slashed", "cut") hitsound = 'sound/weapons/rapierhit.ogg' materials = list(MAT_METAL = 1000) + total_mass = 3.4 /obj/item/melee/sabre/Initialize() . = ..() @@ -89,11 +91,16 @@ if(istype(B)) playsound(B, 'sound/items/sheath.ogg', 25, 1) +/obj/item/melee/sabre/get_belt_overlay() + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "sabre") + +/obj/item/melee/sabre/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "-sabre") + /obj/item/melee/sabre/suicide_act(mob/living/user) user.visible_message("[user] is trying to cut off all [user.p_their()] limbs with [src]! it looks like [user.p_theyre()] trying to commit suicide!") var/i = 0 - var/originally_nodropped = item_flags & NODROP - item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, SABRE_SUICIDE_TRAIT) if(iscarbon(user)) var/mob/living/carbon/Cuser = user var/obj/item/bodypart/holding_bodypart = Cuser.get_holding_bodypart_of_item(src) @@ -118,7 +125,7 @@ for(bodypart in limbs_to_dismember) i++ addtimer(CALLBACK(src, .proc/suicide_dismember, user, bodypart), speedbase * i) - addtimer(CALLBACK(src, .proc/manual_suicide, user, originally_nodropped), (5 SECONDS) * i) + addtimer(CALLBACK(src, .proc/manual_suicide, user), (5 SECONDS) * i) return MANUAL_SUICIDE /obj/item/melee/sabre/proc/suicide_dismember(mob/living/user, obj/item/bodypart/affecting) @@ -131,8 +138,36 @@ if(!QDELETED(user)) user.adjustBruteLoss(200) user.death(FALSE) - if(!originally_nodropped) - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, SABRE_SUICIDE_TRAIT) + +/obj/item/melee/rapier + name = "plastitanium rapier" + desc = "A impossibly thin blade made of plastitanium with a tip made of diamond. It looks to be able to cut through any armor." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "rapier" + item_state = "rapier" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + force = 25 + throwforce = 35 + block_chance = 0 + armour_penetration = 100 + flags_1 = CONDUCT_1 + obj_flags = UNIQUE_RENAME + w_class = WEIGHT_CLASS_BULKY + sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_- + attack_verb = list("slashed", "cut", "pierces", "pokes") + total_mass = 3.4 + +/obj/item/melee/rapier/Initialize() + . = ..() + AddComponent(/datum/component/butchering, 20, 65, 0) + +/obj/item/melee/rapier/get_belt_overlay() + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier") + +/obj/item/melee/rapier/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "-rapier") /obj/item/melee/classic_baton name = "police baton" @@ -194,7 +229,7 @@ target.LAssailant = null else target.LAssailant = user - cooldown = world.time + 40 + cooldown = world.time user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes swinging batons cost stamina /obj/item/melee/classic_baton/telescopic @@ -210,6 +245,7 @@ item_flags = NONE force = 0 on = FALSE + total_mass = TOTAL_MASS_SMALL_ITEM /obj/item/melee/classic_baton/telescopic/suicide_act(mob/user) var/mob/living/carbon/human/H = user @@ -370,6 +406,7 @@ var/static/list/ovens var/on = FALSE var/datum/beam/beam + total_mass = 2.5 /obj/item/melee/roastingstick/Initialize() . = ..() diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm index 0d39e6c847..aabb930bb2 100644 --- a/code/game/objects/items/melee/transforming.dm +++ b/code/game/objects/items/melee/transforming.dm @@ -13,6 +13,7 @@ var/list/nemesis_factions //Any mob with a faction that exists in this list will take bonus damage/effects var/w_class_on = WEIGHT_CLASS_BULKY var/clumsy_check = TRUE + var/total_mass_on //Total mass in ounces when transformed. Primarily for balance purposes. Don't think about it too hard. /obj/item/melee/transforming/Initialize() . = ..() @@ -46,6 +47,7 @@ active = !active if(active) force = force_on + total_mass = total_mass_on throwforce = throwforce_on hitsound = hitsound_on throw_speed = 4 @@ -62,6 +64,7 @@ attack_verb = attack_verb_off icon_state = initial(icon_state) w_class = initial(w_class) + total_mass = initial(total_mass) if(is_sharp()) var/datum/component/butchering/BT = LoadComponent(/datum/component/butchering) BT.butchering_enabled = TRUE @@ -84,4 +87,4 @@ /obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user) if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") - user.take_bodypart_damage(5,5) + user.take_bodypart_damage(5,5) \ No newline at end of file diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 44ccd7aad5..7524fc9007 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -15,7 +15,7 @@ var/mopping = 0 var/mopcount = 0 var/mopcap = 5 - var/stamusage = 5 + var/stamusage = 2 force_string = "robust... against germs" var/insertable = TRUE @@ -94,7 +94,7 @@ force = 6 throwforce = 8 throw_range = 4 - stamusage = 2 + stamusage = 1 var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water. var/refill_rate = 1 //Rate per process() tick mop refills itself var/refill_reagent = "water" //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 12de29c76e..48588cf9f3 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -16,6 +16,7 @@ var/obj/item/toy/plush/plush_child var/obj/item/toy/plush/paternal_parent //who initiated creation var/obj/item/toy/plush/maternal_parent //who owns, see love() + var/static/list/breeding_blacklist = typecacheof(/obj/item/toy/plush/carpplushie/dehy_carp) // you cannot have sexual relations with this plush var/list/scorned = list() //who the plush hates var/list/scorned_by = list() //who hates the plush, to remove external references on Destroy() var/heartbroken = FALSE @@ -203,9 +204,9 @@ else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop user.visible_message("[user] is going to break [Kisser] and [src] by bashing them like that.", "[Kisser] passionately embraces [src] in your hands. Look away you perv!") - plop(Kisser) - user.visible_message("Something drops at the feet of [user].", - "The miracle of oh god did that just come out of [src]?!") + if(plop(Kisser)) + user.visible_message("Something drops at the feet of [user].", + "The miracle of oh god did that just come out of [src]?!") //then comes protection, or abstinence if we are catholic else if(Kisser.partner == src && plush_child) @@ -271,7 +272,10 @@ /obj/item/toy/plush/proc/plop(obj/item/toy/plush/Daddy) if(partner != Daddy) - return //we do not have bastards in our toyshop + return FALSE //we do not have bastards in our toyshop + + if(is_type_in_typecache(Daddy, breeding_blacklist)) + return FALSE // some love is forbidden if(prob(50)) //it has my eyes plush_child = new type(get_turf(loc)) @@ -574,10 +578,6 @@ icon_state = "vulken" item_state = "vulken" -/obj/item/toy/plush/snakeplushie/jecca - icon_state = "jecca" - item_state = "jecca" - /obj/item/toy/plush/nukeplushie name = "operative plushie" desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious." @@ -629,14 +629,10 @@ /obj/item/toy/plush/mothplushie name = "insect plushie" - desc = "An adorable stuffed toy that resembles some kind of insect" - icon_state = "cydia" - item_state = "cydia" - squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1) - -/obj/item/toy/plush/mothplushie/bumble + desc = "An adorable stuffed toy that resembles some kind of insect." icon_state = "bumble" item_state = "bumble" + squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1) /obj/item/toy/plush/mothplushie/nameko icon_state = "nameko" @@ -668,6 +664,27 @@ item_state = "box" attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave") +/obj/item/toy/plush/slaggy + name = "slag plushie" + desc = "A piece of slag with some googly eyes and a drawn on mouth." + icon_state = "slaggy" + item_state = "slaggy" + attack_verb = list("melted", "refined", "stared") + +/obj/item/toy/plush/mr_buckety + name = "bucket plushie" + desc = "A bucket that is missing its handle with some googly eyes and a drawn on mouth." + icon_state = "mr_buckety" + item_state = "mr_buckety" + attack_verb = list("filled", "dumped", "stared") + +/obj/item/toy/plush/dr_scanny + name = "scanner plushie" + desc = "A old outdated scanner that has been modified to have googly eyes, a dawn on mouth and, heart." + icon_state = "dr_scanny" + item_state = "dr_scanny" + attack_verb = list("scanned", "beeped", "stared") + /obj/item/toy/plush/borgplushie name = "robot plushie" desc = "An adorable stuffed toy of a robot." @@ -756,8 +773,10 @@ item_state = "blep" /obj/item/toy/plush/mammal/circe + desc = "A luxuriously soft toy that resembles a nine-tailed kitsune." icon_state = "circe" item_state = "circe" + attack_verb = list("medicated", "tailhugged", "kissed") /obj/item/toy/plush/mammal/robin icon_state = "robin" @@ -822,8 +841,10 @@ item_state = "rae" /obj/item/toy/plush/mammal/zed + desc = "A masked stuffed toy that resembles a fierce miner. He even comes with his own little crusher!" icon_state = "zed" item_state = "zed" + attack_verb = list("ENDED", "CRUSHED", "GNOMED") /obj/item/toy/plush/mammal/justin icon_state = "justin" @@ -835,6 +856,12 @@ item_state = "reece" attack_verb = list("healed", "cured", "demoted") +/obj/item/toy/plush/mammal/redwood + desc = "An adorable stuffed toy resembling a Nanotrasen Captain. That just happens to be a bunny." + icon_state = "redwood" + item_state = "redwood" + attack_verb = list("ordered", "bapped", "reprimanded") + /obj/item/toy/plush/mammal/dog desc = "An adorable stuffed toy that resembles a canine." icon_state = "katlin" @@ -881,6 +908,12 @@ obj_flags = UNIQUE_RENAME unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad") +/obj/item/toy/plush/mammal/dog/jesse + desc = "An adorable wolf toy that resembles a cream-colored wolf. He has a little pride flag!" + icon_state = "jesse" + item_state = "jesse" + attack_verb = list("greeted", "merc'd", "howdy'd") + /obj/item/toy/plush/catgirl name = "feline plushie" desc = "An adorable stuffed toy that resembles a feline." @@ -918,3 +951,15 @@ item_state = "fermis" attack_verb = list("cuddled", "petpatted", "wigglepurred") squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) + +/obj/item/toy/plush/catgirl/mariaf + desc = "An adorable stuffed toy that resembles a very tall cat girl." + icon_state = "mariaf" + item_state = "mariaf" + attack_verb = list("hugged", "stabbed", "licked") + +/obj/item/toy/plush/catgirl/maya + desc = "An adorable stuffed toy that resembles an angry cat girl. She has her own tiny nuke disk!" + icon_state = "maya" + item_state = "maya" + attack_verb = list("nuked", "arrested", "harmbatonned") diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 6d7c3036f9..5454b0fdb8 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -282,11 +282,13 @@ var/cooldown = 0 /obj/item/harmalarm/emag_act(mob/user) + . = ..() obj_flags ^= EMAGGED if(obj_flags & EMAGGED) to_chat(user, "You short out the safeties on [src]!") else to_chat(user, "You reset the safeties on [src]!") + return TRUE /obj/item/harmalarm/attack_self(mob/user) var/safety = !(obj_flags & EMAGGED) diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm index 07f6edb828..28a4664a24 100644 --- a/code/game/objects/items/scrolls.dm +++ b/code/game/objects/items/scrolls.dm @@ -66,7 +66,8 @@ to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.") return - user.forceMove(pick(L)) - - smoke.start() - uses-- + if(do_teleport(user, pick(L), forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE)) + smoke.start() + uses-- + else + to_chat(user, "The spell matrix was disrupted by something near the destination.") diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index a9f0e038df..15127c2e0e 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -159,11 +159,13 @@ armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80) lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - item_state = "makeshift_shield" + icon = 'icons/obj/items_and_weapons.dmi' + item_state = "metal" + icon_state = "makeshift_shield" materials = list(MAT_METAL = 18000) slot_flags = null - block_chance = 25 - force = 5 + block_chance = 35 + force = 10 throwforce = 7 /obj/item/shield/riot/tower @@ -171,8 +173,11 @@ desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking." armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user item_state = "metal" + icon_state = "metal" + icon = 'icons/obj/items_and_weapons.dmi' block_chance = 75 //1/4 shots will hit* - force = 10 + force = 16 slowdown = 2 throwforce = 15 //Massive pice of metal w_class = WEIGHT_CLASS_HUGE + item_flags = SLOWS_WHILE_IN_HAND diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index 1fe57d151f..b6559c9091 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -16,6 +16,7 @@ armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) resistance_flags = FIRE_PROOF | ACID_PROOF force_string = "LORD SINGULOTH HIMSELF" + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON /obj/item/twohanded/singularityhammer/New() ..() @@ -84,6 +85,7 @@ throwforce = 30 throw_range = 7 w_class = WEIGHT_CLASS_HUGE + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON /obj/item/twohanded/mjollnir/proc/shock(mob/living/target) target.Stun(60) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 522e1a1153..49a735af9c 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -33,7 +33,7 @@ use(1) /obj/item/stack/ore/bluespace_crystal/proc/blink_mob(mob/living/L) - do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg') + do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) /obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom) if(!..()) // not caught in mid-air diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 4bb3359c2f..5610cbad9a 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -18,7 +18,7 @@ /obj/item/stack/medical/attack(mob/living/M, mob/user) - if(M.stat == DEAD) + if(M.stat == DEAD && !stop_bleeding) var/t_him = "it" if(M.gender == MALE) t_him = "him" diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index cf967e25ba..47c881bbdf 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass - grind_results = list("silicon" = 20) + grind_results = list(/datum/reagent/silicon = 20) point_value = 1 /obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) @@ -87,7 +87,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass - grind_results = list("silicon" = 20, "plasma" = 10) + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass - grind_results = list("silicon" = 20, "iron" = 10) + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) point_value = 4 /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) @@ -177,11 +177,11 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ singular_name = "reinforced plasma glass sheet" icon_state = "sheet-prglass" item_state = "sheet-prglass" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL = MINERAL_MATERIAL_AMOUNT * 0.5,) + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5,) armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass - grind_results = list("silicon" = 20, "plasma" = 10, "iron" = 10) + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) point_value = 23 /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) @@ -243,8 +243,9 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( resistance_flags = ACID_PROOF armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) max_integrity = 40 - var/cooldown = 0 sharpness = IS_SHARP + var/icon_prefix + /obj/item/shard/suicide_act(mob/user) user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") @@ -266,9 +267,19 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( if("large") pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) - var/matrix/M = matrix(transform) - M.Turn(rand(-170, 170)) - transform = M + if (icon_prefix) + icon_state = "[icon_prefix][icon_state]" + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_created", 1, name) + +/obj/item/shard/Destroy() + . = ..() + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_destroyed", 1, name) /obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity) . = ..() @@ -298,6 +309,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( return ..() /obj/item/shard/welder_act(mob/living/user, obj/item/I) + ..() if(I.use_tool(src, user, 0, volume=50)) var/obj/item/stack/sheet/glass/NG = new (user.loc) for(var/obj/item/stack/sheet/glass/G in user.loc) @@ -316,4 +328,13 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) else playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) - . = ..() + return ..() + +/obj/item/shard/plasma + name = "purple shard" + desc = "A nasty looking shard of plasma glass." + force = 6 + throwforce = 11 + icon_state = "plasmalarge" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + icon_prefix = "plasma" \ No newline at end of file diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index f9d4878fab..01351ab2e2 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -36,6 +36,7 @@ GLOBAL_LIST_INIT(human_recipes, list( \ GLOBAL_LIST_INIT(gondola_recipes, list ( \ new/datum/stack_recipe("gondola mask", /obj/item/clothing/mask/gondola, 1), \ new/datum/stack_recipe("gondola suit", /obj/item/clothing/under/gondola, 2), \ + new/datum/stack_recipe("gondola bedsheet", /obj/item/bedsheet/gondola, 1), \ )) /obj/item/stack/sheet/animalhide/gondola diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index b17bc87ffd..8c808d0e5f 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -201,6 +201,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("dresser", /obj/structure/dresser, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\ new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \ new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\ new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \ @@ -248,7 +249,8 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ new/datum/stack_recipe("bio bag", /obj/item/storage/bag/bio, 4), \ null, \ new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 6), \ - new/datum/stack_recipe("rag", /obj/item/reagent_containers/glass/rag, 1), \ + new/datum/stack_recipe("rag", /obj/item/reagent_containers/rag, 1), \ + new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \ new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \ new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \ null, \ @@ -277,6 +279,31 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /obj/item/stack/sheet/cloth/ten amount = 10 +//Durathread fuck slash-asterisk comments + GLOBAL_LIST_INIT(durathread_recipes, list ( \ + new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/durathread, 4, time = 40), + 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), \ + )) + +/obj/item/stack/sheet/durathread + name = "durathread" + desc = "A fabric sown from incredibly durable threads, known for its usefulness in armor production." + singular_name = "durathread roll" + icon_state = "sheet-durathread" + item_state = "sheet-cloth" + resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 + merge_type = /obj/item/stack/sheet/durathread + +/obj/item/stack/sheet/durathread/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.durathread_recipes + return ..() + + + /* * Cardboard */ @@ -414,6 +441,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ null, new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ @@ -424,6 +453,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \ new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \ new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \ + null, + new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \ )) @@ -441,7 +472,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE - grind_results = list("iron" = 5, "teslium" = 15) + grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1) merge_type = /obj/item/stack/tile/brass /obj/item/stack/tile/brass/narsie_act() @@ -475,6 +506,8 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \ new/datum/stack_recipe("bronze boots", /obj/item/clothing/shoes/bronze), \ null, new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ )) /obj/item/stack/tile/bronze @@ -596,3 +629,29 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra amount = 20 /obj/item/stack/sheet/paperframes/fifty amount = 50 + + +//durathread and cotton raw +/obj/item/stack/sheet/cotton + name = "raw cotton bundle" + desc = "A bundle of raw cotton ready to be spun on the loom." + 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 + +/obj/item/stack/sheet/cotton/durathread + name = "raw durathread bundle" + desc = "A bundle of raw durathread ready to be spun on the loom." + singular_name = "raw durathread ball" + icon_state = "sheet-durathreadraw" + merge_type = /obj/item/stack/sheet/cotton/durathread + pull_effort = 70 + loom_result = /obj/item/stack/sheet/durathread + + diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 21b43eba20..908fc88383 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -12,4 +12,7 @@ novariants = FALSE var/perunit = 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. \ No newline at end of file + 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 \ No newline at end of file diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index c2929dafbd..b5d7282b07 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -248,12 +248,13 @@ desc = "A bone satchel fashend with watcher wings and large bones from goliath. Can be worn on the belt." icon = 'icons/obj/mining.dmi' icon_state = "goliath_saddle" - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT + slot_flags = ITEM_SLOT_BACK /obj/item/storage/backpack/satchel/bone/ComponentInitialize() . = ..() GET_COMPONENT(STR, /datum/component/storage) - STR.max_combined_w_class = 10 + STR.max_combined_w_class = 20 + STR.max_items = 15 /obj/item/storage/backpack/satchel/cap name = "captain's satchel" @@ -355,6 +356,7 @@ new /obj/item/cautery(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) + new /obj/item/reagent_containers/medspray/sterilizine(src) new /obj/item/razor(src) /obj/item/storage/backpack/duffelbag/sec @@ -376,6 +378,7 @@ new /obj/item/cautery(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) + new /obj/item/reagent_containers/medspray/sterilizine(src) /obj/item/storage/backpack/duffelbag/engineering name = "industrial duffel bag" @@ -383,6 +386,14 @@ icon_state = "duffel-eng" item_state = "duffel-eng" +/obj/item/storage/backpack/duffelbag/durathread + name = "durathread duffel bag" + desc = "A lightweight duffel bag made out of durathread." + icon_state = "duffel-durathread" + item_state = "duffel-durathread" + resistance_flags = FIRE_PROOF + slowdown = 0 + /obj/item/storage/backpack/duffelbag/drone name = "drone duffel bag" desc = "A large duffel bag for holding tools and hats." @@ -398,6 +409,7 @@ new /obj/item/stack/cable_coil/random(src) new /obj/item/wirecutters(src) new /obj/item/multitool(src) + new /obj/item/pipe_dispenser(src) /obj/item/storage/backpack/duffelbag/clown name = "clown's duffel bag" @@ -460,6 +472,7 @@ new /obj/item/mmi/syndie(src) new /obj/item/implantcase(src) new /obj/item/implanter(src) + new /obj/item/reagent_containers/medspray/sterilizine(src) /obj/item/storage/backpack/duffelbag/syndie/surgery_adv name = "advanced surgery duffel bag" @@ -479,6 +492,7 @@ new /obj/item/mmi/syndie(src) new /obj/item/implantcase(src) new /obj/item/implanter(src) + new /obj/item/reagent_containers/medspray/sterilizine(src) /obj/item/storage/backpack/duffelbag/syndie/ammo name = "ammunition duffel bag" @@ -487,7 +501,7 @@ item_state = "duffel-syndieammo" /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun - desc = "A large duffel bag, packed to the brim with Bulldog shotgun ammo." + desc = "A large duffel bag, packed to the brim with Bulldog shotgun drum magazines." /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun/PopulateContents() for(var/i in 1 to 6) @@ -497,14 +511,14 @@ new /obj/item/ammo_box/magazine/m12g/dragon(src) /obj/item/storage/backpack/duffelbag/syndie/ammo/smg - desc = "A large duffel bag, packed to the brim with C20r magazines." + desc = "A large duffel bag, packed to the brim with C-20r magazines." /obj/item/storage/backpack/duffelbag/syndie/ammo/smg/PopulateContents() for(var/i in 1 to 9) new /obj/item/ammo_box/magazine/smgm45(src) /obj/item/storage/backpack/duffelbag/syndie/c20rbundle - desc = "A large duffel bag containing a C20r, some magazines, and a cheap looking suppressor." + desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor." /obj/item/storage/backpack/duffelbag/syndie/c20rbundle/PopulateContents() new /obj/item/ammo_box/magazine/smgm45(src) @@ -513,7 +527,7 @@ new /obj/item/suppressor/specialoffer(src) /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle - desc = "A large duffel bag containing a Bulldog, several drums, and a collapsed hardsuit." + desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses." /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle/PopulateContents() new /obj/item/ammo_box/magazine/m12g(src) @@ -522,16 +536,7 @@ new /obj/item/clothing/glasses/thermal/syndi(src) /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots." - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() - new /obj/item/clothing/shoes/magboots/syndie(src) - new /obj/item/storage/firstaid/tactical(src) - new /obj/item/gun/ballistic/automatic/l6_saw/toy(src) - new /obj/item/ammo_box/foambox/riot(src) - -/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots." + desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun, a big jumbo box of riot darts, and a knock-off pair of magboots." /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents() new /obj/item/clothing/shoes/magboots/syndie(src) @@ -540,7 +545,7 @@ new /obj/item/ammo_box/foambox/riot(src) /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle - desc = "A large duffel bag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes." + desc = "A large duffel bag containing deadly chemicals, a handheld chem sprayer, Bioterror foam grenade, a Donksoft assault rifle, box of riot grade darts, a dart pistol, and a box of syringes." /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle/PopulateContents() new /obj/item/reagent_containers/spray/chemsprayer/bioterror(src) @@ -562,7 +567,7 @@ new /obj/item/grenade/plastic/x4(src) /obj/item/storage/backpack/duffelbag/syndie/firestarter - desc = "A large duffel bag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment." + desc = "A large duffel bag containing a New Russian pyro backpack sprayer, Elite hardsuit, a Stechkin APS pistol, minibomb, ammo, and other equipment." /obj/item/storage/backpack/duffelbag/syndie/firestarter/PopulateContents() new /obj/item/clothing/under/syndicate/soviet(src) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index e2d7fdf9d7..4495e9da14 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -10,6 +10,7 @@ attack_verb = list("whipped", "lashed", "disciplined") max_integrity = 300 var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding + var/worn_overlays = FALSE //worn counterpart of the above. /obj/item/storage/belt/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -23,6 +24,12 @@ add_overlay(M) ..() +/obj/item/storage/belt/worn_overlays(isinhands, icon_file) + . = ..() + if(!isinhands && worn_overlays) + for(var/obj/item/I in contents) + . += I.get_worn_belt_overlay(icon_file) + /obj/item/storage/belt/Initialize() . = ..() update_icon() @@ -424,6 +431,48 @@ GET_COMPONENT(STR, /datum/component/storage) STR.max_items = 6 +/obj/item/storage/belt/durathread + name = "durathread toolbelt" + desc = "A toolbelt made out of durathread, it seems resistant enough to hold even big tools like an RCD, it also has higher capacity." + icon_state = "webbing-durathread" + item_state = "webbing-durathread" + resistance_flags = FIRE_PROOF + +/obj/item/storage/belt/durathread/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_items = 14 + STR.max_combined_w_class = 32 + STR.max_w_class = WEIGHT_CLASS_NORMAL + STR.can_hold = typecacheof(list( + /obj/item/crowbar, + /obj/item/screwdriver, + /obj/item/weldingtool, + /obj/item/wirecutters, + /obj/item/wrench, + /obj/item/multitool, + /obj/item/flashlight, + /obj/item/stack/cable_coil, + /obj/item/t_scanner, + /obj/item/analyzer, + /obj/item/geiger_counter, + /obj/item/extinguisher/mini, + /obj/item/radio, + /obj/item/clothing/gloves, + /obj/item/holosign_creator/atmos, + /obj/item/holosign_creator/engineering, + /obj/item/forcefield_projector, + /obj/item/assembly/signaler, + /obj/item/lightreplacer, + /obj/item/rcd_ammo, + /obj/item/construction/rcd, + /obj/item/pipe_dispenser, + /obj/item/stack/rods, + /obj/item/stack/tile/plasteel, + /obj/item/grenade/chem_grenade/metalfoam, + /obj/item/grenade/chem_grenade/smart_metal_foam + )) + /obj/item/storage/belt/grenade name = "grenadier belt" desc = "A belt for holding grenades." @@ -517,12 +566,15 @@ /obj/item/grenade/chem_grenade, /obj/item/lightreplacer, /obj/item/flashlight, + /obj/item/reagent_containers/glass/beaker, + /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/spray, /obj/item/soap, /obj/item/holosign_creator, /obj/item/key/janitor, /obj/item/clothing/gloves, /obj/item/melee/flyswatter, + /obj/item/paint/paint_remover, /obj/item/assembly/mousetrap )) @@ -541,6 +593,22 @@ /obj/item/ammo_casing/shotgun )) +/obj/item/storage/belt/bandolier/durathread + name = "durathread bandolier" + desc = "An double stacked bandolier made out of durathread." + icon_state = "bandolier-durathread" + item_state = "bandolier-durathread" + resistance_flags = FIRE_PROOF + +/obj/item/storage/belt/bandolier/durathread/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 32 + STR.display_numerical_stacking = TRUE + STR.can_hold = typecacheof(list( + /obj/item/ammo_casing + )) + /obj/item/storage/belt/medolier name = "medolier" desc = "A medical bandolier for holding smartdarts." @@ -653,6 +721,10 @@ icon_state = "sheath" item_state = "sheath" w_class = WEIGHT_CLASS_BULKY + content_overlays = TRUE + worn_overlays = TRUE + var/list/fitting_swords = list(/obj/item/melee/sabre, /obj/item/melee/baton/stunsword) + var/starting_sword = /obj/item/melee/sabre /obj/item/storage/belt/sabre/ComponentInitialize() . = ..() @@ -660,9 +732,7 @@ STR.max_items = 1 STR.rustle_sound = FALSE STR.max_w_class = WEIGHT_CLASS_BULKY - STR.can_hold = typecacheof(list( - /obj/item/melee/sabre - )) + STR.can_hold = typecacheof(fitting_swords) /obj/item/storage/belt/sabre/examine(mob/user) ..() @@ -681,16 +751,28 @@ to_chat(user, "[src] is empty.") /obj/item/storage/belt/sabre/update_icon() - icon_state = "sheath" - item_state = "sheath" - if(contents.len) - icon_state += "-sabre" - item_state += "-sabre" - if(loc && isliving(loc)) + . = ..() + if(isliving(loc)) var/mob/living/L = loc L.regenerate_icons() - ..() /obj/item/storage/belt/sabre/PopulateContents() - new /obj/item/melee/sabre(src) - update_icon() + new starting_sword(src) + +/obj/item/storage/belt/sabre/rapier + name = "rapier sheath" + desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal." + icon_state = "rsheath" + item_state = "rsheath" + force = 5 + throwforce = 15 + block_chance = 30 + w_class = WEIGHT_CLASS_BULKY + attack_verb = list("bashed", "slashes", "prods", "pokes") + fitting_swords = list(/obj/item/melee/rapier) + starting_sword = /obj/item/melee/rapier + +/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(attack_type == PROJECTILE_ATTACK) + final_block_chance = 0 //To thin to block bullets + return ..() diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 830c3aea96..df7b203f91 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -74,6 +74,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(B.icon_state == "honk1" || B.icon_state == "honk2") var/mob/living/carbon/human/H = usr H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK) GLOB.bible_icon_state = B.icon_state @@ -138,7 +139,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", smack = 0 else if(iscarbon(M)) var/mob/living/carbon/C = M - if(!istype(C.head, /obj/item/clothing/head)) + if(!istype(C.head, /obj/item/clothing/head)) C.adjustBrainLoss(10, 80) to_chat(C, "You feel dumber.") diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 4ff63ceeac..903c319644 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -1131,6 +1131,7 @@ name = "Nanotrasen MRE Ration Kit Menu 0" desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning." icon_state = "mre" + illustration = null var/can_expire = TRUE var/spawner_chance = 2 var/expiration_date @@ -1184,7 +1185,7 @@ /obj/item/storage/box/mre/menu3 name = "\improper Nanotrasen MRE Ration Kit Menu 3" - desc = "The holy grail of MREs. This item contains the fabled MRE pizza and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed." + desc = "The holy grail of MREs. This item contains the fabled MRE pizza, spicy nachos and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed." icon_state = "menu3" can_expire = FALSE //always fresh, never expired. spawner_chance = 1 @@ -1192,7 +1193,42 @@ /obj/item/storage/box/mre/menu3/PopulateContents() new /obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni(src) new /obj/item/reagent_containers/food/snacks/breadslice/plain(src) - new /obj/item/reagent_containers/food/snacks/cheesewedge(src) + new /obj/item/reagent_containers/food/snacks/cubannachos(src) new /obj/item/reagent_containers/food/snacks/grown/chili(src) new /obj/item/reagent_containers/food/drinks/coffee/type2(src) new /obj/item/tank/internals/emergency_oxygen(src) + +/obj/item/storage/box/mre/menu4 + name = "\improper Nanotrasen MRE Ration Kit Menu 4" + +/obj/item/storage/box/mre/menu4/safe + spawner_chance = 0 + desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time." + can_expire = FALSE + +/obj/item/storage/box/mre/menu4/PopulateContents() + if(prob(66)) + new /obj/item/reagent_containers/food/snacks/salad/boiledrice(src) + else + new /obj/item/reagent_containers/food/snacks/salad/ricebowl(src) + new /obj/item/reagent_containers/food/snacks/burger/tofu(src) + new /obj/item/reagent_containers/food/snacks/salad/fruit(src) + new /obj/item/reagent_containers/food/snacks/cracker(src) + new /obj/item/tank/internals/emergency_oxygen(src) + +//Where do I put this? +/obj/item/secbat + name = "Secbat box" + desc = "Contained inside is a secbat for use with law enforcement." + icon = 'icons/obj/storage.dmi' + icon_state = "box" + item_state = "syringe_kit" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + +/obj/item/secbat/attack_self(mob/user) + new /mob/living/simple_animal/hostile/retaliate/bat/secbat(user.loc) + to_chat(user, "You open the box, releasing the secbat!") + var/obj/item/stack/sheet/cardboard/I = new(user.drop_location()) + qdel(src) + user.put_in_hands(I) diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index 46676b5adb..ed547bc17d 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -40,9 +40,18 @@ /obj/item/storage/briefcase/lawyer/family name = "battered briefcase" - desc = "An old briefcase, this one has seen better days in its time. It's clear they don't make them nowadays as good as they used to. Comes with an added belt clip!" + icon_state = "gbriefcase" + lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi' + desc = "An old briefcase with a golden trim. It's clear they don't make them as good as they used to. Comes with an added belt clip!" slot_flags = ITEM_SLOT_BELT +/obj/item/storage/briefcase/lawyer/family/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_NORMAL + STR.max_combined_w_class = 14 + /obj/item/storage/briefcase/lawyer/family/PopulateContents() new /obj/item/stamp/law(src) new /obj/item/pen/fountain(src) @@ -68,9 +77,8 @@ ..() /obj/item/storage/briefcase/sniperbundle - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding. Smells like L'Air du Temps." + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." force = 10 - /obj/item/storage/briefcase/sniperbundle/PopulateContents() ..() // in case you need any paperwork done after your rampage new /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate(src) @@ -82,7 +90,7 @@ /obj/item/storage/briefcase/modularbundle - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding." + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding." force = 10 /obj/item/storage/briefcase/modularbundle/PopulateContents() diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index e9b074d40c..312ef35430 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -1,365 +1,391 @@ -/* First aid storage - * Contains: - * First Aid Kits - * Pill Bottles - * Dice Pack (in a pill bottle) - */ - -/* - * First Aid Kits - */ -/obj/item/storage/firstaid - name = "first-aid kit" - desc = "It's an emergency medical kit for those serious boo-boos." - icon_state = "firstaid" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - throw_speed = 3 - throw_range = 7 - var/empty = FALSE - -/obj/item/storage/firstaid/regular - icon_state = "firstaid" - desc = "A first aid kit with the ability to heal common types of injuries." - -/obj/item/storage/firstaid/regular/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins giving [user.p_them()]self aids with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/storage/firstaid/regular/PopulateContents() - if(empty) - return - new /obj/item/stack/medical/gauze(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/reagent_containers/hypospray/medipen(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/ancient - icon_state = "firstaid" - desc = "A first aid kit with the ability to heal common types of injuries." - -/obj/item/storage/firstaid/ancient/PopulateContents() - if(empty) - return - new /obj/item/stack/medical/gauze(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/stack/medical/ointment(src) - -/obj/item/storage/firstaid/fire - name = "burn treatment kit" - desc = "A specialized medical kit for when the toxins lab -spontaneously- burns down." - icon_state = "ointment" - item_state = "firstaid-ointment" - -/obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!") - return FIRELOSS - -/obj/item/storage/firstaid/fire/Initialize(mapload) - . = ..() - icon_state = pick("ointment","firefirstaid") - -/obj/item/storage/firstaid/fire/PopulateContents() - if(empty) - return - for(var/i in 1 to 3) - new /obj/item/reagent_containers/pill/patch/silver_sulf(src) - new /obj/item/reagent_containers/pill/oxandrolone(src) - new /obj/item/reagent_containers/pill/oxandrolone(src) - new /obj/item/reagent_containers/hypospray/medipen(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/toxin - name = "toxin treatment kit" - desc = "Used to treat toxic blood content and radiation poisoning." - icon_state = "antitoxin" - item_state = "firstaid-toxin" - -/obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return TOXLOSS - -/obj/item/storage/firstaid/toxin/Initialize(mapload) - . = ..() - icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") - -/obj/item/storage/firstaid/toxin/PopulateContents() - if(empty) - return - for(var/i in 1 to 4) - new /obj/item/reagent_containers/syringe/charcoal(src) - for(var/i in 1 to 2) - new /obj/item/storage/pill_bottle/charcoal(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/radbgone - name = "radiation treatment kit" - desc = "Used to treat minor toxic blood content and major radiation poisoning." - icon_state = "antitoxin" - item_state = "firstaid-toxin" - -/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return TOXLOSS - -/obj/item/storage/firstaid/radbgone/PopulateContents() - if(empty) - return - if(prob(50)) - new /obj/item/reagent_containers/pill/mutarad(src) - if(prob(80)) - new /obj/item/reagent_containers/pill/antirad_plus(src) - new /obj/item/reagent_containers/syringe/charcoal(src) - new /obj/item/storage/pill_bottle/charcoal(src) - new /obj/item/reagent_containers/pill/mutadone(src) - new /obj/item/reagent_containers/pill/antirad(src) - new /obj/item/reagent_containers/food/drinks/bottle/vodka(src) - new /obj/item/healthanalyzer(src) - - -/obj/item/storage/firstaid/o2 - name = "oxygen deprivation treatment kit" - desc = "A box full of oxygen goodies." - icon_state = "o2" - item_state = "firstaid-o2" - -/obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return OXYLOSS - -/obj/item/storage/firstaid/o2/PopulateContents() - if(empty) - return - for(var/i in 1 to 4) - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/reagent_containers/hypospray/medipen(src) - new /obj/item/reagent_containers/hypospray/medipen(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/brute - name = "brute trauma treatment kit" - desc = "A first aid kit for when you get toolboxed." - icon_state = "brute" - item_state = "firstaid-brute" - -/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/storage/firstaid/brute/PopulateContents() - if(empty) - return - for(var/i in 1 to 4) - new /obj/item/reagent_containers/pill/patch/styptic(src) - new /obj/item/stack/medical/gauze(src) - new /obj/item/stack/medical/gauze(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/tactical - name = "combat medical kit" - desc = "I hope you've got insurance." - icon_state = "bezerk" - -/obj/item/storage/firstaid/tactical/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.max_w_class = WEIGHT_CLASS_NORMAL - -/obj/item/storage/firstaid/tactical/PopulateContents() - if(empty) - return - new /obj/item/stack/medical/gauze(src) - new /obj/item/defibrillator/compact/combat/loaded(src) - new /obj/item/reagent_containers/hypospray/combat(src) - new /obj/item/reagent_containers/pill/patch/styptic(src) - new /obj/item/reagent_containers/pill/patch/silver_sulf(src) - new /obj/item/reagent_containers/syringe/lethal/choral(src) - new /obj/item/clothing/glasses/hud/health/night(src) - -/* - * Pill Bottles - */ - -/obj/item/storage/pill_bottle - name = "pill bottle" - desc = "It's an airtight container for storing medication." - icon_state = "pill_canister" - icon = 'icons/obj/chemical.dmi' - item_state = "contsolid" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - -/obj/item/storage/pill_bottle/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.allow_quick_gather = TRUE - STR.click_gather = TRUE - STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice)) - -/obj/item/storage/pill_bottle/suicide_act(mob/user) - user.visible_message("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (TOXLOSS) - -/obj/item/storage/pill_bottle/charcoal - name = "bottle of charcoal pills" - desc = "Contains pills used to counter toxins." - -/obj/item/storage/pill_bottle/charcoal/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/charcoal(src) - -/obj/item/storage/pill_bottle/antirad - name = "bottle of charcoal pills" - desc = "Contains pills used to counter radiation poisoning." - -/obj/item/storage/pill_bottle/anitrad/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/pill/antirad(src) - -/obj/item/storage/pill_bottle/epinephrine - name = "bottle of epinephrine pills" - desc = "Contains pills used to stabilize patients." - -/obj/item/storage/pill_bottle/epinephrine/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/epinephrine(src) - -/obj/item/storage/pill_bottle/mutadone - name = "bottle of mutadone pills" - desc = "Contains pills used to treat genetic abnormalities." - -/obj/item/storage/pill_bottle/mutadone/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/mutadone(src) - -/obj/item/storage/pill_bottle/mannitol - name = "bottle of mannitol pills" - desc = "Contains pills used to treat brain damage." - -/obj/item/storage/pill_bottle/mannitol/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/mannitol(src) - -/obj/item/storage/pill_bottle/stimulant - name = "bottle of stimulant pills" - 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) - new /obj/item/reagent_containers/pill/stimulant(src) - -/obj/item/storage/pill_bottle/mining - name = "bottle of patches" - desc = "Contains patches used to treat brute and burn damage." - -/obj/item/storage/pill_bottle/mining/PopulateContents() - new /obj/item/reagent_containers/pill/patch/silver_sulf(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/pill/patch/styptic(src) - -/obj/item/storage/pill_bottle/zoom - name = "suspicious pill bottle" - desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds." - -/obj/item/storage/pill_bottle/zoom/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/pill/zoom(src) - -/obj/item/storage/pill_bottle/happy - name = "suspicious pill bottle" - desc = "There is a smiley on the top." - -/obj/item/storage/pill_bottle/happy/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/pill/happy(src) - -/obj/item/storage/pill_bottle/lsd - name = "suspicious pill bottle" - desc = "There is a badly drawn thing with the shape of a mushroom." - -/obj/item/storage/pill_bottle/lsd/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/pill/lsd(src) - -/obj/item/storage/pill_bottle/aranesp - name = "suspicious pill bottle" - desc = "The label says 'gotta go fast'." - -/obj/item/storage/pill_bottle/aranesp/PopulateContents() - for(var/i in 1 to 5) - new /obj/item/reagent_containers/pill/aranesp(src) - -/obj/item/storage/pill_bottle/antirad_plus - name = "anti radiation deluxe pill bottle" - desc = "The label says 'Med-Co branded pills'." - -/obj/item/storage/pill_bottle/antirad_plus/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/antirad_plus(src) - -/obj/item/storage/pill_bottle/mutarad - name = "radiation treatment deluxe pill bottle" - desc = "The label says 'Med-Co branded pills' and below that 'Contains Mutadone in each pill!`." - -/obj/item/storage/pill_bottle/mutarad/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/mutarad(src) - -/obj/item/storage/pill_bottle/penis_enlargement - name = "penis enlargement pills" - desc = "You want penis enlargement pills?" - -/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/reagent_containers/pill/penis_enlargement(src) - -///////////// -//Organ Box// -///////////// - -/obj/item/storage/belt/organbox - name = "Organ Storge" - desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying" - w_class = WEIGHT_CLASS_BULKY - icon = 'icons/obj/mysterybox.dmi' - icon_state = "organbox_open" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - throw_speed = 1 - throw_range = 1 - -/obj/item/storage/belt/organbox/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.max_items = 16 - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.max_combined_w_class = 20 - STR.can_hold = typecacheof(list( - /obj/item/storage/pill_bottle, - /obj/item/reagent_containers/hypospray, - /obj/item/healthanalyzer, - /obj/item/reagent_containers/syringe, - /obj/item/clothing/glasses/hud/health, - /obj/item/hemostat, - /obj/item/scalpel, - /obj/item/retractor, - /obj/item/cautery, - /obj/item/surgical_drapes, - /obj/item/autosurgeon, - /obj/item/organ, - /obj/item/implant, - /obj/item/implantpad, - /obj/item/implantcase, - /obj/item/implanter, - /obj/item/circuitboard/computer/operating, - /obj/item/stack/sheet/mineral/silver, - /obj/item/organ_storage - )) + +/* First aid storage + * Contains: + * First Aid Kits + * Pill Bottles + * Dice Pack (in a pill bottle) + */ + +/* + * First Aid Kits + */ +/obj/item/storage/firstaid + name = "first-aid kit" + desc = "It's an emergency medical kit for those serious boo-boos." + icon_state = "firstaid" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 3 + throw_range = 7 + var/empty = FALSE + +/obj/item/storage/firstaid/regular + icon_state = "firstaid" + desc = "A first aid kit with the ability to heal common types of injuries." + +/obj/item/storage/firstaid/regular/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins giving [user.p_them()]self aids with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS + +/obj/item/storage/firstaid/regular/PopulateContents() + if(empty) + return + new /obj/item/stack/medical/gauze(src) + new /obj/item/stack/medical/bruise_pack(src) + new /obj/item/stack/medical/bruise_pack(src) + new /obj/item/stack/medical/ointment(src) + new /obj/item/stack/medical/ointment(src) + new /obj/item/reagent_containers/hypospray/medipen(src) + new /obj/item/healthanalyzer(src) + +/obj/item/storage/firstaid/ancient + icon_state = "firstaid" + desc = "A first aid kit with the ability to heal common types of injuries." + +/obj/item/storage/firstaid/ancient/PopulateContents() + if(empty) + return + new /obj/item/stack/medical/gauze(src) + new /obj/item/stack/medical/bruise_pack(src) + new /obj/item/stack/medical/bruise_pack(src) + new /obj/item/stack/medical/bruise_pack(src) + new /obj/item/stack/medical/ointment(src) + new /obj/item/stack/medical/ointment(src) + new /obj/item/stack/medical/ointment(src) + +/obj/item/storage/firstaid/fire + name = "burn treatment kit" + desc = "A specialized medical kit for when the toxins lab -spontaneously- burns down." + icon_state = "ointment" + item_state = "firstaid-ointment" + +/obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!") + return FIRELOSS + +/obj/item/storage/firstaid/fire/Initialize(mapload) + . = ..() + icon_state = pick("ointment","firefirstaid") + +/obj/item/storage/firstaid/fire/PopulateContents() + if(empty) + return + for(var/i in 1 to 3) + new /obj/item/reagent_containers/pill/patch/silver_sulf(src) + new /obj/item/reagent_containers/pill/oxandrolone(src) + new /obj/item/reagent_containers/pill/oxandrolone(src) + new /obj/item/reagent_containers/hypospray/medipen(src) + new /obj/item/healthanalyzer(src) + +/obj/item/storage/firstaid/toxin + name = "toxin treatment kit" + desc = "Used to treat toxic blood content and radiation poisoning." + icon_state = "antitoxin" + item_state = "firstaid-toxin" + +/obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return TOXLOSS + +/obj/item/storage/firstaid/toxin/Initialize(mapload) + . = ..() + icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") + +/obj/item/storage/firstaid/toxin/PopulateContents() + if(empty) + return + for(var/i in 1 to 4) + new /obj/item/reagent_containers/syringe/charcoal(src) + for(var/i in 1 to 2) + new /obj/item/storage/pill_bottle/charcoal(src) + new /obj/item/healthanalyzer(src) + +/obj/item/storage/firstaid/radbgone + name = "radiation treatment kit" + desc = "Used to treat minor toxic blood content and major radiation poisoning." + icon_state = "antitoxin" + item_state = "firstaid-toxin" + +/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return TOXLOSS + +/obj/item/storage/firstaid/radbgone/PopulateContents() + if(empty) + return + if(prob(50)) + new /obj/item/reagent_containers/pill/mutarad(src) + if(prob(80)) + new /obj/item/reagent_containers/pill/antirad_plus(src) + new /obj/item/reagent_containers/syringe/charcoal(src) + new /obj/item/storage/pill_bottle/charcoal(src) + new /obj/item/reagent_containers/pill/mutadone(src) + new /obj/item/reagent_containers/pill/antirad(src) + new /obj/item/reagent_containers/food/drinks/bottle/vodka(src) + new /obj/item/healthanalyzer(src) + + +/obj/item/storage/firstaid/o2 + name = "oxygen deprivation treatment kit" + desc = "A box full of oxygen goodies." + icon_state = "o2" + item_state = "firstaid-o2" + +/obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return OXYLOSS + +/obj/item/storage/firstaid/o2/PopulateContents() + if(empty) + return + for(var/i in 1 to 4) + new /obj/item/reagent_containers/pill/salbutamol(src) + new /obj/item/reagent_containers/hypospray/medipen(src) + new /obj/item/reagent_containers/hypospray/medipen(src) + new /obj/item/healthanalyzer(src) + +/obj/item/storage/firstaid/brute + name = "brute trauma treatment kit" + desc = "A first aid kit for when you get toolboxed." + icon_state = "brute" + item_state = "firstaid-brute" + +/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS + +/obj/item/storage/firstaid/brute/PopulateContents() + if(empty) + return + for(var/i in 1 to 4) + new /obj/item/reagent_containers/pill/patch/styptic(src) + new /obj/item/stack/medical/gauze(src) + new /obj/item/stack/medical/gauze(src) + new /obj/item/healthanalyzer(src) + +/obj/item/storage/firstaid/tactical + name = "combat medical kit" + desc = "I hope you've got insurance." + icon_state = "bezerk" + +/obj/item/storage/firstaid/tactical/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_NORMAL + +/obj/item/storage/firstaid/tactical/PopulateContents() + if(empty) + return + new /obj/item/stack/medical/gauze(src) + new /obj/item/defibrillator/compact/combat/loaded(src) + new /obj/item/reagent_containers/hypospray/combat(src) + new /obj/item/reagent_containers/pill/patch/styptic(src) + new /obj/item/reagent_containers/pill/patch/silver_sulf(src) + new /obj/item/reagent_containers/syringe/lethal/choral(src) + new /obj/item/clothing/glasses/hud/health/night(src) + +/* + * Pill Bottles + */ + +/obj/item/storage/pill_bottle + name = "pill bottle" + desc = "It's an airtight container for storing medication." + icon_state = "pill_canister" + icon = 'icons/obj/chemical.dmi' + item_state = "contsolid" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_SMALL + +/obj/item/storage/pill_bottle/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.allow_quick_gather = TRUE + STR.click_gather = TRUE + STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice)) + +/obj/item/storage/pill_bottle/suicide_act(mob/user) + user.visible_message("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (TOXLOSS) + +/obj/item/storage/pill_bottle/charcoal + name = "bottle of charcoal pills" + desc = "Contains pills used to counter toxins." + +/obj/item/storage/pill_bottle/charcoal/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/charcoal(src) + +/obj/item/storage/pill_bottle/antirad + name = "bottle of charcoal pills" + desc = "Contains pills used to counter radiation poisoning." + +/obj/item/storage/pill_bottle/anitrad/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/antirad(src) + +/obj/item/storage/pill_bottle/epinephrine + name = "bottle of epinephrine pills" + desc = "Contains pills used to stabilize patients." + +/obj/item/storage/pill_bottle/epinephrine/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/epinephrine(src) + +/obj/item/storage/pill_bottle/mutadone + name = "bottle of mutadone pills" + desc = "Contains pills used to treat genetic abnormalities." + +/obj/item/storage/pill_bottle/mutadone/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/mutadone(src) + +/obj/item/storage/pill_bottle/mannitol + name = "bottle of mannitol pills" + desc = "Contains pills used to treat brain damage." + +/obj/item/storage/pill_bottle/mannitol/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/mannitol(src) + +/obj/item/storage/pill_bottle/stimulant + name = "bottle of stimulant pills" + 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) + new /obj/item/reagent_containers/pill/stimulant(src) + +/obj/item/storage/pill_bottle/mining + name = "bottle of patches" + desc = "Contains patches used to treat brute and burn damage." + +/obj/item/storage/pill_bottle/mining/PopulateContents() + new /obj/item/reagent_containers/pill/patch/silver_sulf(src) + for(var/i in 1 to 3) + new /obj/item/reagent_containers/pill/patch/styptic(src) + +/obj/item/storage/pill_bottle/zoom + name = "suspicious pill bottle" + desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds." + +/obj/item/storage/pill_bottle/zoom/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/zoom(src) + +/obj/item/storage/pill_bottle/happy + name = "suspicious pill bottle" + desc = "There is a smiley on the top." + +/obj/item/storage/pill_bottle/happy/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/happy(src) + +/obj/item/storage/pill_bottle/lsd + name = "suspicious pill bottle" + desc = "There is a badly drawn thing with the shape of a mushroom." + +/obj/item/storage/pill_bottle/lsd/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/lsd(src) + +/obj/item/storage/pill_bottle/aranesp + name = "suspicious pill bottle" + desc = "The label says 'gotta go fast'." + +/obj/item/storage/pill_bottle/aranesp/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/aranesp(src) + +/obj/item/storage/pill_bottle/psicodine + name = "bottle of psicodine pills" + desc = "Contains pills used to treat mental distress and traumas." + +/obj/item/storage/pill_bottle/psicodine/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/psicodine(src) + +/obj/item/storage/pill_bottle/happiness + name = "happiness pill bottle" + desc = "The label is long gone, in its place an 'H' written with a marker." + +/obj/item/storage/pill_bottle/happiness/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/happiness(src) + +/obj/item/storage/pill_bottle/antirad_plus + name = "anti radiation deluxe pill bottle" + desc = "The label says 'Med-Co branded pills'." + +/obj/item/storage/pill_bottle/antirad_plus/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/antirad_plus(src) + +/obj/item/storage/pill_bottle/mutarad + name = "radiation treatment deluxe pill bottle" + desc = "The label says 'Med-Co branded pills' and below that 'Contains Mutadone in each pill!`." + +/obj/item/storage/pill_bottle/mutarad/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/mutarad(src) + +/obj/item/storage/pill_bottle/penis_enlargement + name = "penis enlargement pills" + desc = "You want penis enlargement pills?" + +/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/penis_enlargement(src) + +/obj/item/storage/pill_bottle/breast_enlargement + name = "breast enlargement pills" + desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time." + +/obj/item/storage/pill_bottle/breast_enlargement/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/breast_enlargement(src) + +///////////// +//Organ Box// +///////////// + +/obj/item/storage/belt/organbox + name = "Organ Storge" + desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying" + w_class = WEIGHT_CLASS_BULKY + icon = 'icons/obj/mysterybox.dmi' + icon_state = "organbox_open" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 1 + throw_range = 1 + +/obj/item/storage/belt/organbox/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 16 + STR.max_w_class = WEIGHT_CLASS_BULKY + STR.max_combined_w_class = 20 + STR.can_hold = typecacheof(list( + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/hypospray, + /obj/item/healthanalyzer, + /obj/item/reagent_containers/syringe, + /obj/item/clothing/glasses/hud/health, + /obj/item/hemostat, + /obj/item/scalpel, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/surgical_drapes, + /obj/item/autosurgeon, + /obj/item/organ, + /obj/item/implant, + /obj/item/implantpad, + /obj/item/implantcase, + /obj/item/implanter, + /obj/item/circuitboard/computer/operating, + /obj/item/stack/sheet/mineral/silver, + /obj/item/organ_storage + )) + diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 4924051855..eeebc6f4c5 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -48,14 +48,16 @@ to_chat(user, "It's locked!") /obj/item/storage/lockbox/emag_act(mob/user) - if(!broken) - broken = TRUE - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, FALSE) - desc += "It appears to be broken." - icon_state = src.icon_broken - if(user) - visible_message("\The [src] has been broken by [user] with an electromagnetic card!") - return + . = ..() + if(broken) + return + broken = TRUE + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, FALSE) + desc += "It appears to be broken." + icon_state = src.icon_broken + if(user) + visible_message("\The [src] has been broken by [user] with an electromagnetic card!") + return TRUE /obj/item/storage/lockbox/Entered() . = ..() diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 7c2694016b..b69567a2a5 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -16,7 +16,7 @@ AddComponent(component_type) /obj/item/storage/AllowDrop() - return TRUE + return FALSE /obj/item/storage/contents_explosion(severity, target) for(var/atom/A in contents) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index b2313969f0..5b99bb85bf 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(rubber_toolbox_icons) + /obj/item/storage/toolbox name = "toolbox" desc = "Danger. Very robust." @@ -16,21 +18,25 @@ hitsound = 'sound/weapons/smash.ogg' var/latches = "single_latch" var/has_latches = TRUE + var/can_rubberify = TRUE -/obj/item/storage/toolbox/Initialize() +/obj/item/storage/toolbox/Initialize(mapload) . = ..() if(has_latches) if(prob(10)) latches = "double_latch" if(prob(1)) latches = "triple_latch" + if(mapload && can_rubberify && prob(5)) + rubberify() update_icon() /obj/item/storage/toolbox/update_icon() ..() cut_overlays() if(has_latches) - add_overlay(latches) + var/icon/I = icon('icons/obj/storage.dmi', latches) + add_overlay(I) /obj/item/storage/toolbox/suicide_act(mob/user) @@ -39,8 +45,6 @@ /obj/item/storage/toolbox/emergency name = "emergency toolbox" - icon_state = "red" - item_state = "toolbox_red" /obj/item/storage/toolbox/emergency/PopulateContents() new /obj/item/crowbar/red(src) @@ -59,6 +63,7 @@ name = "rusty red toolbox" icon_state = "toolbox_red_old" has_latches = FALSE + can_rubberify = FALSE /obj/item/storage/toolbox/mechanical name = "mechanical toolbox" @@ -77,6 +82,7 @@ name = "rusty blue toolbox" icon_state = "toolbox_blue_old" has_latches = FALSE + can_rubberify = FALSE /obj/item/storage/toolbox/mechanical/old/heirloom name = "old, robust toolbox" //this will be named "X family toolbox" @@ -151,6 +157,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF w_class = WEIGHT_CLASS_HUGE attack_verb = list("robusted", "crushed", "smashed") + can_rubberify = FALSE var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab /obj/item/storage/toolbox/brass/ComponentInitialize() @@ -191,6 +198,7 @@ item_state = "toolbox_blue" w_class = WEIGHT_CLASS_HUGE //heyo no bohing this! force = 18 //spear damage + can_rubberify = FALSE /obj/item/storage/toolbox/plastitanium/afterattack(atom/A, mob/user, proximity) . = ..() @@ -204,7 +212,7 @@ name = "artistic toolbox" desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." icon_state = "green" - item_state = "artistic_toolbox" + item_state = "toolbox_green" w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! /obj/item/storage/toolbox/artistic/ComponentInitialize() @@ -253,9 +261,55 @@ /obj/item/storage/toolbox/gold_fake // used in crafting name = "golden toolbox" - desc = "A gold plated toolbox, fancy and harmless do to the gold plating being on cardboard!" + desc = "A gold plated toolbox, fancy and harmless due to the gold plating being on cardboard!" icon_state = "gold" item_state = "gold" has_latches = FALSE force = 0 throwforce = 0 + can_rubberify = FALSE + +/obj/item/storage/toolbox/proc/rubberify() + name = "rubber [name]" + desc = replacetext(desc, "Danger", "Bouncy") + desc = replacetext(desc, "robust", "safe") + desc = replacetext(desc, "heavier", "bouncier") + DISABLE_BITFIELD(flags_1, CONDUCT_1) + materials = null + damtype = STAMINA + force += 3 //to compensate the higher stamina K.O. threshold compared to actual health. + throwforce += 3 + attack_verb += "bounced" + hitsound = 'sound/effects/clownstep1.ogg' + if(!GLOB.rubber_toolbox_icons[icon_state]) + generate_rubber_toolbox_icon() + icon = GLOB.rubber_toolbox_icons[icon_state] + AddComponent(/datum/component/bouncy) + . = ..() + +/obj/item/storage/toolbox/proc/generate_rubber_toolbox_icon() + var/icon/new_icon = icon(icon, icon_state) + var/icon/smooth = icon('icons/obj/storage.dmi', "rubber_toolbox_blend") + new_icon.Blend(smooth, ICON_MULTIPLY) + new_icon = fcopy_rsc(new_icon) + GLOB.rubber_toolbox_icons[icon_state] = new_icon + +/obj/item/storage/toolbox/rubber + name = "rubber toolbox" + desc = "Bouncy. Very safe." + flags_1 = null + materials = null + damtype = STAMINA + force = 17 + throwforce = 17 + attack_verb = list("robusted", "bounced") + can_rubberify = FALSE //we are already the future. + +/obj/item/storage/toolbox/rubber/Initialize() + icon_state = pick("blue", "red", "yellow", "green") + item_state = "toolbox_[icon_state]" + if(!GLOB.rubber_toolbox_icons[icon_state]) + generate_rubber_toolbox_icon() + icon = GLOB.rubber_toolbox_icons[icon_state] + . = ..() + AddComponent(/datum/component/bouncy) \ No newline at end of file diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index a6a3cea373..6e41527b24 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -132,7 +132,7 @@ new /obj/item/card/emag(src) // 6 tc if("ninja") // 40~ tc worth - new /obj/item/katana(src) // Unique , basicly a better esword. 10 tc? + new /obj/item/katana(src) // Unique , basicly a better esword. 10 tc? new /obj/item/implanter/adrenalin(src) // 8 tc new /obj/item/throwing_star(src) // ~5 tc for all 6 new /obj/item/throwing_star(src) @@ -294,6 +294,7 @@ new /obj/item/radio/headset/chameleon(src) new /obj/item/stamp/chameleon(src) new /obj/item/pda/chameleon(src) + new /obj/item/clothing/neck/cloak/chameleon(src) //5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. //Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index c263c2669d..cb5790e45f 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -36,7 +36,8 @@ /obj/item/reagent_containers/syringe, /obj/item/screwdriver, /obj/item/valentine, - /obj/item/stamp)) + /obj/item/stamp, + /obj/item/key)) /obj/item/storage/wallet/Exited(atom/movable/AM) . = ..() @@ -60,7 +61,7 @@ /obj/item/storage/wallet/update_icon() var/new_state = "wallet" if(front_id) - new_state = "wallet_[front_id.icon_state]" + new_state = "wallet_id" if(new_state != icon_state) //avoid so many icon state changes. icon_state = new_state diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 1245b7de94..d409e40575 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -23,7 +23,7 @@ toggle_internals(user) /obj/item/tank/proc/toggle_internals(mob/user) - var/mob/living/carbon/human/H = user + var/mob/living/carbon/H = user if(!istype(H)) return @@ -33,13 +33,19 @@ H.update_internals_hud_icon(0) else if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - if(!H.wear_mask) - to_chat(H, "You need a mask!") - return - if(H.wear_mask.mask_adjusted) - H.wear_mask.adjustmask(H) - if(!(H.wear_mask.clothing_flags & MASKINTERNALS)) - to_chat(H, "[H.wear_mask] can't use [src]!") + var/obj/item/clothing/check + var/internals = FALSE + + for(check in GET_INTERNAL_SLOTS(H)) + if(istype(check, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/M = check + if(M.mask_adjusted) + M.adjustmask(H) + if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + internals = TRUE + + if(!internals) + to_chat(H, "You are not wearing an internals mask!") return if(H.internal) diff --git a/code/game/objects/items/taster.dm b/code/game/objects/items/taster.dm index 8363c63c2c..3828beb921 100644 --- a/code/game/objects/items/taster.dm +++ b/code/game/objects/items/taster.dm @@ -6,10 +6,9 @@ w_class = WEIGHT_CLASS_TINY - var/taste_sensitivity = 15 + speech_span = null -/obj/item/taster/get_spans() - return list() + var/taste_sensitivity = 15 /obj/item/taster/afterattack(atom/O, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index 341c85fa1c..40392c19c3 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -10,7 +10,7 @@ . = ..() if(!. || !istype(M) || M.anchored) return - do_teleport(M, get_turf(M), 15) + do_teleport(M, get_turf(M), 15, channel = TELEPORT_CHANNEL_BLUESPACE) /obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user) user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ @@ -18,7 +18,7 @@ SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) user.Knockdown(stunforce*3) playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) - if(do_teleport(user, get_turf(user), 50)) + if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE)) deductcharge(hitcost) else deductcharge(hitcost * 0.25) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 6cee5def2a..70bfebb799 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -34,6 +34,12 @@ icon_state = "crowbar_brass" toolspeed = 0.5 +/obj/item/crowbar/bronze + name = "bronze plated crowbar" + desc = "A bronze plated crowbar." + icon_state = "crowbar_brass" + toolspeed = 0.95 + /obj/item/crowbar/abductor name = "alien crowbar" desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." @@ -42,7 +48,6 @@ icon_state = "crowbar" toolspeed = 0.1 - /obj/item/crowbar/large name = "crowbar" desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." @@ -85,4 +90,12 @@ var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power(drop_location()) to_chat(user, "You attach the cutting jaws to [src].") qdel(src) - user.put_in_active_hand(cutjaws) \ No newline at end of file + user.put_in_active_hand(cutjaws) + +/obj/item/crowbar/advanced + name = "advanced crowbar" + desc = "A scientist's almost successful reproduction of an abductor's crowbar, it uses the same technology combined with a handle that can't quite hold it." + icon = 'icons/obj/advancedtools.dmi' + usesound = 'sound/weapons/sonic_jackhammer.ogg' + icon_state = "crowbar" + toolspeed = 0.2 \ No newline at end of file diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 217b53c928..68946f73cd 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -86,6 +86,14 @@ toolspeed = 0.5 random_color = FALSE +/obj/item/screwdriver/bronze + name = "bronze screwdriver" + desc = "A screwdriver plated with bronze." + icon_state = "screwdriver_brass" + item_state = "screwdriver_brass" + toolspeed = 0.95 + random_color = FALSE + /obj/item/screwdriver/abductor name = "alien screwdriver" desc = "An ultrasonic screwdriver." @@ -133,4 +141,14 @@ name = "powered screwdriver" desc = "An electrical screwdriver, designed to be both precise and quick." usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.5 \ No newline at end of file + toolspeed = 0.5 + +/obj/item/screwdriver/advanced + name = "advanced screwdriver" + desc = "A classy silver screwdriver with an alien alloy tip, it works almost as well as the real thing." + icon = 'icons/obj/advancedtools.dmi' + icon_state = "screwdriver_a" + item_state = "screwdriver_nuke" + usesound = 'sound/items/pshoom.ogg' + toolspeed = 0.2 + random_color = FALSE \ No newline at end of file diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 54f199969f..9b622a14c4 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -363,6 +363,13 @@ icon_state = "brasswelder" item_state = "brasswelder" +/obj/item/weldingtool/bronze + name = "bronze plated welding tool" + desc = "A bronze plated welder." + max_fuel = 21 + toolspeed = 0.95 + icon_state = "brasswelder" + item_state = "brasswelder" /obj/item/weldingtool/experimental/process() ..() @@ -370,4 +377,18 @@ nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) +/obj/item/weldingtool/advanced + name = "advanced welding tool" + desc = "A modern welding tool combined with an alien welding tool, it never runs out of fuel and works almost as fast." + icon = 'icons/obj/advancedtools.dmi' + icon_state = "welder" + toolspeed = 0.2 + light_intensity = 0 + change_icons = 0 + +/obj/item/weldingtool/advanced/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + #undef WELDER_FUEL_BURN_INTERVAL diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index 2bf9c93ff9..527891afdb 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -69,13 +69,19 @@ random_color = FALSE toolspeed = 0.5 +/obj/item/wirecutters/bronze + name = "bronze plated wirecutters" + desc = "A pair of wirecutters plated with bronze." + icon_state = "cutters_brass" + random_color = FALSE + toolspeed = 0.95 //Wire cutters have 0 time bars though + /obj/item/wirecutters/abductor name = "alien wirecutters" desc = "Extremely sharp wirecutters, made out of a silvery-green metal." icon = 'icons/obj/abductor.dmi' icon_state = "cutters" toolspeed = 0.1 - random_color = FALSE /obj/item/wirecutters/cyborg @@ -119,3 +125,11 @@ return else ..() + +/obj/item/wirecutters/advanced + name = "advanced wirecutters" + desc = "A set of reproduction alien wirecutters, they have a silver handle with an exceedingly sharp blade." + icon = 'icons/obj/advancedtools.dmi' + icon_state = "cutters" + toolspeed = 0.2 + random_color = FALSE \ No newline at end of file diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index dc78e9aace..8ff960825a 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -35,6 +35,12 @@ icon_state = "wrench_brass" toolspeed = 0.5 +/obj/item/wrench/bronze + name = "bronze plated wrench" + desc = "A bronze plated wrench." + icon_state = "wrench_brass" + toolspeed = 0.95 + /obj/item/wrench/abductor name = "alien wrench" desc = "A polarized wrench. It causes anything placed between the jaws to turn." @@ -43,7 +49,6 @@ usesound = 'sound/effects/empulse.ogg' toolspeed = 0.1 - /obj/item/wrench/power name = "hand drill" desc = "A simple powered hand drill. It's fitted with a bolt bit." @@ -107,4 +112,12 @@ user.dust() - return OXYLOSS \ No newline at end of file + return OXYLOSS + +/obj/item/wrench/advanced + name = "advanced wrench" + desc = "A wrench that uses the same magnetic technology that abductor tools use, but slightly more ineffeciently." + icon = 'icons/obj/advancedtools.dmi' + icon_state = "wrench" + usesound = 'sound/effects/empulse.ogg' + toolspeed = 0.2 \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 274afe15e0..46fabea8b0 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -30,6 +30,7 @@ throw_speed = 3 throw_range = 7 force = 0 + total_mass = TOTAL_MASS_TINY_ITEM /* @@ -112,10 +113,6 @@ /obj/item/toy/syndicateballoon name = "syndicate balloon" desc = "There is a tag on the back that reads \"FUK NT!11!\"." - throwforce = 0 - throw_speed = 3 - throw_range = 7 - force = 0 icon = 'icons/obj/items_and_weapons.dmi' icon_state = "syndballoon" item_state = "syndballoon" @@ -225,6 +222,8 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("attacked", "struck", "hit") var/hacked = FALSE + total_mass = 0.4 + var/total_mass_on = TOTAL_MASS_TOY_SWORD /obj/item/toy/sword/attack_self(mob/user) active = !( active ) @@ -249,8 +248,8 @@ // Copied from /obj/item/melee/transforming/energy/sword/attackby /obj/item/toy/sword/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/toy/sword)) - if((W.item_flags & NODROP) || (item_flags & NODROP)) - to_chat(user, "\the [item_flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [item_flags & NODROP ? W : src]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool.") @@ -274,6 +273,9 @@ else return ..() +/obj/item/toy/sword/getweight() + return (active ? total_mass_on : total_mass) || w_class *1.25 + /* * Foam armblade */ @@ -294,7 +296,7 @@ name = "windup toolbox" desc = "A replica toolbox that rumbles when you turn the key." icon_state = "his_grace" - item_state = "artistic_toolbox" + item_state = "toolbox_green" lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' var/active = FALSE @@ -327,12 +329,13 @@ force_unwielded = 0 force_wielded = 0 attack_verb = list("attacked", "struck", "hit") + total_mass_on = TOTAL_MASS_TOY_SWORD /obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - return 0 + return FALSE /obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles - return 0 + return FALSE /obj/item/toy/katana name = "replica katana" @@ -346,6 +349,7 @@ slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK force = 5 throwforce = 5 + total_mass = null w_class = WEIGHT_CLASS_NORMAL attack_verb = list("attacked", "slashed", "stabbed", "sliced") hitsound = 'sound/weapons/bladeslice.ogg' diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index bf63a96f05..82bf2c6b5f 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -28,6 +28,8 @@ var/force_wielded = 0 var/wieldsound = null var/unwieldsound = null + var/slowdown_wielded = 0 + item_flags = SLOWS_WHILE_IN_HAND /obj/item/twohanded/proc/unwield(mob/living/carbon/user, show_message = TRUE) if(!wielded || !user) @@ -55,7 +57,7 @@ var/obj/item/twohanded/offhand/O = user.get_inactive_held_item() if(O && istype(O)) O.unwield() - return + slowdown -= slowdown_wielded /obj/item/twohanded/proc/wield(mob/living/carbon/user) if(wielded) @@ -85,7 +87,7 @@ O.desc = "Your second grip on [src]." O.wielded = TRUE user.put_in_inactive_hand(O) - return + slowdown += slowdown_wielded /obj/item/twohanded/dropped(mob/user) . = ..() @@ -279,6 +281,7 @@ wieldsound = 'sound/weapons/saberon.ogg' unwieldsound = 'sound/weapons/saberoff.ogg' hitsound = "swing_hit" + var/hitsound_on = 'sound/weapons/blade1.ogg' armour_penetration = 35 item_color = "green" light_color = "#00ff00"//green @@ -290,8 +293,10 @@ var/hacked = FALSE var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD var/list/possible_colors = list("red", "blue", "green", "purple") - total_mass = 0.375 //Survival flashlights typically weigh around 5 ounces. - var/total_mass_on = 3.4 //The typical medieval sword, on the other hand, weighs roughly 3 pounds. //Values copied from the regular e-sword + var/list/rainbow_colors = list(LIGHT_COLOR_RED, LIGHT_COLOR_GREEN, LIGHT_COLOR_LIGHT_CYAN, LIGHT_COLOR_LAVENDER) + var/spinnable = TRUE + total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces. + var/total_mass_on = 3.4 /obj/item/twohanded/dualsaber/suicide_act(mob/living/carbon/user) if(wielded) @@ -353,7 +358,7 @@ if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40)) impale(user) return - if((wielded) && prob(50)) + if(spinnable && (wielded) && prob(50)) INVOKE_ASYNC(src, .proc/jedi_spin, user) /obj/item/twohanded/dualsaber/proc/jedi_spin(mob/living/user) @@ -406,11 +411,14 @@ /obj/item/twohanded/dualsaber/process() if(wielded) if(hacked) - light_color = pick(LIGHT_COLOR_RED, LIGHT_COLOR_GREEN, LIGHT_COLOR_LIGHT_CYAN, LIGHT_COLOR_LAVENDER) + rainbow_process() open_flame() else STOP_PROCESSING(SSobj, src) +/obj/item/twohanded/dualsaber/proc/rainbow_process() + light_color = pick(rainbow_colors) + /obj/item/twohanded/dualsaber/IsReflect() if(wielded) return 1 @@ -428,7 +436,8 @@ playsound(loc, hitsound, get_clamped_volume(), 1, -1) add_fingerprint(user) // Light your candles while spinning around the room - INVOKE_ASYNC(src, .proc/jedi_spin, user) + if(spinnable) + INVOKE_ASYNC(src, .proc/jedi_spin, user) /obj/item/twohanded/dualsaber/green possible_colors = list("green") @@ -478,6 +487,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" + var/icon_prefix = "spearglass" /obj/item/twohanded/spear/Initialize() . = ..() @@ -520,7 +530,7 @@ if(explosive) icon_state = "spearbomb[wielded]" else - icon_state = "spearglass[wielded]" + icon_state = "[icon_prefix][wielded]" /obj/item/twohanded/spear/afterattack(atom/movable/AM, mob/user, proximity) . = ..() @@ -547,6 +557,13 @@ src.war_cry = input /obj/item/twohanded/spear/CheckParts(list/parts_list) + var/obj/item/shard/tip = locate() in parts_list + if (istype(tip, /obj/item/shard/plasma)) + force_wielded = 19 + force_unwielded = 11 + throwforce = 21 + icon_prefix = "spearplasma" + qdel(tip) var/obj/item/twohanded/spear/S = locate() in parts_list if(S) if(S.explosive) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index ccc703296e..c6384e7438 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -69,6 +69,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON /obj/item/claymore/Initialize() . = ..() @@ -81,7 +82,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." flags_1 = CONDUCT_1 - item_flags = NODROP | DROPDEL + item_flags = DROPDEL slot_flags = null block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY light_range = 3 @@ -91,6 +92,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) START_PROCESSING(SSobj, src) /obj/item/claymore/highlander/Destroy() @@ -222,10 +224,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON /obj/item/katana/cursed slot_flags = null - item_flags = NODROP + +/obj/item/katana/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) /obj/item/katana/suicide_act(mob/user) user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") @@ -249,13 +255,15 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear remove_item_from_storage(user) - qdel(I) + if (!user.transferItemToLoc(I, S)) + return + S.CheckParts(list(I)) qdel(src) user.put_in_hands(S) to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - else if(istype(I, /obj/item/assembly/igniter) && !(I.item_flags & NODROP)) + else if(istype(I, /obj/item/assembly/igniter) && !HAS_TRAIT(I, TRAIT_NODROP)) var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod remove_item_from_storage(user) @@ -418,7 +426,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 item_state = "mounted_chainsaw" lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' - item_flags = NODROP | ABSTRACT | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 24 throwforce = 0 @@ -427,6 +435,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 sharpness = IS_SHARP attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = 'sound/weapons/chainsawhit.ogg' + total_mass = TOTAL_MASS_HAND_REPLACEMENT + +/obj/item/mounted_chainsaw/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) /obj/item/mounted_chainsaw/Destroy() var/obj/item/bodypart/part @@ -502,6 +515,19 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/homerun_able = 0 total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google +/obj/item/melee/baseball_bat/chaplain + name = "blessed baseball bat" + desc = "There ain't a cult in the league that can withstand a swatter." + force = 14 + throwforce = 14 + obj_flags = UNIQUE_RENAME + var/chaplain_spawnable = TRUE + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON + +/obj/item/melee/baseball_bat/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + /obj/item/melee/baseball_bat/homerun name = "home run bat" desc = "This thing looks dangerous... Dangerously good at baseball, that is." diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 2db2cd08d8..70a05a8d40 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -48,7 +48,12 @@ /obj/hitby(atom/movable/AM) ..() - take_damage(AM.throwforce, BRUTE, "melee", 1, get_dir(src, AM)) + var/throwdamage = AM.throwforce + if(isobj(AM)) + var/obj/O = AM + if(O.damtype == STAMINA) + throwdamage = 0 + take_damage(throwdamage, BRUTE, "melee", 1, get_dir(src, AM)) /obj/ex_act(severity, target) if(resistance_flags & INDESTRUCTIBLE) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index fd6a9f2141..6dd8a43130 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -2,6 +2,7 @@ /obj var/crit_fail = FALSE animate_movement = 2 + speech_span = SPAN_ROBOT var/obj_flags = CAN_BE_HIT var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT. @@ -204,9 +205,6 @@ if(!anchored || current_size >= STAGE_FIVE) step_towards(src,S) -/obj/get_spans() - return ..() | SPAN_ROBOT - /obj/get_dumping_location(datum/component/storage/source,mob/user) return get_turf(src) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index b8320c80fb..405e697d3b 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(globalBlankCanvases, new(AMT_OF_CANVASES)) return //Cleaning one pixel with a soap or rag - if(istype(I, /obj/item/soap) || istype(I, /obj/item/reagent_containers/glass/rag)) + if(istype(I, /obj/item/soap) || istype(I, /obj/item/reagent_containers/rag)) //Pixel info created only when needed var/icon/masterpiece = icon(icon,icon_state) var/thePix = masterpiece.GetPixel(pixX,pixY) diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 964f60cb73..2093ae5660 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -112,12 +112,16 @@ /obj/structure/sign/barsign/emag_act(mob/user) + . = ..() if(broken || (obj_flags & EMAGGED)) to_chat(user, "Nothing interesting happens!") return obj_flags |= EMAGGED to_chat(user, "You emag the barsign. Takeover in progress...") - sleep(10 SECONDS) + addtimer(CALLBACK(src, .proc/syndie_bar_good), 10 SECONDS) + return TRUE + +/obj/structure/sign/barsign/proc/syndie_bar_good() set_sign(new /datum/barsign/hiddensigns/syndibarsign) req_access = list(ACCESS_SYNDICATE) @@ -294,6 +298,16 @@ icon = "the_lightbulb" desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." +/datum/barsign/cybersylph + name = "Cyber Sylph's" + icon = "cybersylph" + desc = "A cafe renowed for its out-of-boundaries futuristic insignia." + +/datum/barsign/meow_mix + name = "Meow Mix" + icon = "meow_mix" + desc = "No, we don't serve catnip, officer!" + /datum/barsign/hiddensigns hidden = TRUE diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index e944eb32da..88d141a9ad 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -317,9 +317,6 @@ new stack_type(get_turf(loc)) qdel(src) - - - /obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance)) owner.visible_message("[owner] fends off [attack_text] with [src]!") @@ -338,7 +335,6 @@ C.Knockdown(20) smash(user) - /obj/item/chair/stool name = "stool" icon_state = "stool_toppled" @@ -352,6 +348,70 @@ item_state = "stool_bar" origin_type = /obj/structure/chair/stool/bar +////////////////////////// +//Brass & Bronze stools!// +////////////////////////// + +/obj/structure/chair/stool/bar/brass + name = "brass bar stool" + desc = "A brass bar stool with red silk for a pillow." + icon_state = "barbrass" + item_chair = /obj/item/chair/stool/bar/brass + buildstacktype = /obj/item/stack/tile/brass + buildstackamount = 1 + +/obj/structure/chair/stool/bar/bronze + name = "bronze bar stool" + desc = "A bronze bar stool with red silk for a pillow." + icon_state = "barbrass" + item_chair = /obj/item/chair/stool/bar/bronze + buildstacktype = /obj/item/stack/tile/bronze + buildstackamount = 1 + +/obj/structure/chair/stool/brass + name = "brass stool" + desc = "A brass stool with a silk top for comfort." + icon_state = "stoolbrass" + item_chair = /obj/item/chair/stool/brass + buildstacktype = /obj/item/stack/tile/brass + buildstackamount = 1 + +/obj/structure/chair/stool/bronze + name = "bronze stool" + desc = "A bronze stool with a silk top for comfort." + icon_state = "stoolbrass" + item_chair = /obj/item/chair/stool/bronze + buildstacktype = /obj/item/stack/tile/bronze + buildstackamount = 1 + +/obj/item/chair/stool/brass + name = "brass stool" + icon_state = "stoolbrass_toppled" + item_state = "stoolbrass" + origin_type = /obj/structure/chair/stool/brass + +/obj/item/chair/stool/bar/brass + name = "brass bar stool" + icon_state = "barbrass_toppled" + item_state = "stoolbrass_bar" + origin_type = /obj/structure/chair/stool/bar/brass + +/obj/item/chair/stool/bronze + name = "bronze stool" + icon_state = "stoolbrass_toppled" + item_state = "stoolbrass" + origin_type = /obj/structure/chair/stool/bronze + +/obj/item/chair/stool/bar/bronze + name = "bronze bar stool" + icon_state = "barbrass_toppled" + item_state = "stoolbrass_bar" + origin_type = /obj/structure/chair/stool/bar/bronze + +///////////////////////////////// +//End of Brass & Bronze stools!// +///////////////////////////////// + /obj/item/chair/stool/narsie_act() return //sturdy enough to ignore a god diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 89dcc75042..b493f84240 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -225,6 +225,39 @@ LINEN BINS item_color = "ian" dream_messages = list("a dog", "a corgi", "woof", "bark", "arf") +/obj/item/bedsheet/runtime + icon_state = "sheetruntime" + item_color = "runtime" + dream_messages = list("a kitty", "a cat", "meow", "purr", "nya~") + +/obj/item/bedsheet/pirate + name = "pirate's bedsheet" + desc = "It has a Jolly Roger emblem on it and has a faint scent of grog." + icon_state = "sheetpirate" + item_color = "black" + dream_messages = list("doing whatever oneself wants", "cause a pirate is free", "being a pirate", "stealing", "landlubbers", "gold", "a buried treasure", "yarr", "avast", "a swashbuckler", "sailing the Seven Seas", "a parrot", "a monkey", "an island", "a talking skull") + +/obj/item/bedsheet/gondola + name = "gondola bedsheet" + desc = "A precious bedsheet made from the hide of a rare and peculiar critter." + icon_state = "sheetgondola" + item_color = "cargo" + var/g_mouth + var/g_eyes + +/obj/item/bedsheet/gondola/Initialize() + . = ..() + g_mouth = "sheetgondola_mouth[rand(1, 4)]" + g_eyes = "sheetgondola_eyes[rand(1, 4)]" + add_overlay(g_mouth) + add_overlay(g_eyes) + +/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file) + . = ..() + if(!isinhands) + . += mutable_appearance(icon_file, g_mouth) + . += mutable_appearance(icon_file, g_eyes) + /obj/item/bedsheet/cosmos name = "cosmic space bedsheet" desc = "Made from the dreams of those who wonder at the stars." @@ -258,7 +291,6 @@ LINEN BINS var/list/sheets = list() var/obj/item/hidden = null - /obj/structure/bedsheetbin/examine(mob/user) ..() if(amount < 1) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index cbdb0750e2..edcb4a6181 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -34,6 +34,10 @@ var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable. var/anchorable = TRUE var/icon_welded = "welded" + var/obj/item/electronics/airlock/lockerelectronics //Installed electronics + var/lock_in_use = FALSE //Someone is doing some stuff with the lock here, better not proceed further + var/eigen_teleport = FALSE //If the closet leads to Mr Tumnus. + var/obj/structure/closet/eigen_target //Where you go to. /obj/structure/closet/Initialize(mapload) @@ -42,47 +46,56 @@ PopulateContents() if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents take_contents() + if(secure) + lockerelectronics = new(src) + lockerelectronics.accesses = req_access //USE THIS TO FILL IT, NOT INITIALIZE OR NEW /obj/structure/closet/proc/PopulateContents() return /obj/structure/closet/Destroy() - dump_contents() + dump_contents(override = FALSE) return ..() /obj/structure/closet/update_icon() cut_overlays() - if(!opened) + if(opened & icon_door_override) + add_overlay("[icon_door]_open") layer = OBJ_LAYER - if(icon_door) - add_overlay("[icon_door]_door") - else - add_overlay("[icon_state]_door") - if(welded) - add_overlay(icon_welded) - if(secure && !broken) - if(locked) - add_overlay("locked") - else - add_overlay("unlocked") - + return + else if(opened) + add_overlay("[icon_state]_open") + return + if(icon_door) + add_overlay("[icon_door]_door") else layer = BELOW_OBJ_LAYER - if(icon_door_override) - add_overlay("[icon_door]_open") - else - add_overlay("[icon_state]_open") + add_overlay("[icon_state]_door") + if(welded) + add_overlay("welded") + if(!secure) + return + if(broken) + add_overlay("off") + add_overlay("sparking") + else if(locked) + add_overlay("locked") + else + add_overlay("unlocked") /obj/structure/closet/examine(mob/user) ..() if(welded) - to_chat(user, "It's welded shut.") + to_chat(user, "It's welded shut.") if(anchored) to_chat(user, "It is bolted to the ground.") if(opened) to_chat(user, "The parts are welded together.") else if(secure && !opened) + else if(broken) + to_chat(user, "The lock is screwed in.") + else if(secure) to_chat(user, "Alt-click to [locked ? "unlock" : "lock"].") if(isliving(user)) var/mob/living/L = user @@ -117,9 +130,39 @@ return FALSE return TRUE -/obj/structure/closet/proc/dump_contents() +/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access + if(!secure) + return FALSE + if(broken) + to_chat(user, "[src] is broken!") + return FALSE + if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics + to_chat(user, "[src] is missing locker electronics!") + return FALSE + if(!check_access) + return TRUE + if(allowed(user)) + return TRUE + to_chat(user, "Access denied.") + +/obj/structure/closet/proc/togglelock(mob/living/user) + add_fingerprint(user) + if(eigen_target) + return + if(opened) + return + if(!can_lock(user)) + return + locked = !locked + user.visible_message("[user] [locked ? null : "un"]locks [src].", + "You [locked ? null : "un"]lock [src].") + update_icon() + +/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example var/atom/L = drop_location() for(var/atom/movable/AM in src) + if(AM == lockerelectronics && override) + continue AM.forceMove(L) if(throwing) // you keep some momentum when getting out of a thrown closet step(AM, dir) @@ -147,47 +190,53 @@ /obj/structure/closet/proc/insert(atom/movable/AM) if(contents.len >= storage_capacity) return -1 + if(insertion_allowed(AM)) + if(eigen_teleport) // For teleporting people with linked lockers. + do_teleport(AM, get_turf(eigen_target), 0) + if(eigen_target.opened == FALSE) + eigen_target.bust_open() + else + AM.forceMove(src) + return TRUE + else + return FALSE +/obj/structure/closet/proc/insertion_allowed(atom/movable/AM) if(ismob(AM)) if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets... - return + return FALSE var/mob/living/L = AM if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs()) - return + return FALSE if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. if(horizontal && L.density) - return + return FALSE if(L.mob_size > max_mob_size) - return + return FALSE var/mobs_stored = 0 for(var/mob/living/M in contents) if(++mobs_stored >= mob_storage_capacity) - return + return FALSE L.stop_pulling() + else if(istype(AM, /obj/structure/closet)) - return + return FALSE else if(istype(AM, /obj/effect)) - return + return FALSE else if(isobj(AM)) - if (istype(AM, /obj/item)) - var/obj/item/I = AM - if (I.item_flags & NODROP) - return + if((!allow_dense && AM.density) || AM.anchored || AM.has_buckled_mobs()) + return FALSE + if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP)) + return TRUE else if(!allow_objects && !istype(AM, /obj/effect/dummy/chameleon)) - return - if(!allow_dense && AM.density) - return - if(AM.anchored || AM.has_buckled_mobs()) - return + return FALSE else - return + return FALSE - AM.forceMove(src) - - return 1 + return TRUE /obj/structure/closet/proc/close(mob/living/user) if(!opened || !can_close(user)) @@ -206,6 +255,73 @@ else return open(user) +/obj/structure/closet/proc/bust_open() + welded = FALSE //applies to all lockers + locked = FALSE //applies to critter crates and secure lockers only + broken = TRUE //applies to secure lockers only + open() + +/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E) + add_fingerprint(user) + if(lock_in_use) + to_chat(user, "Wait for work on [src] to be done first!") + return + if(secure) + to_chat(user, "This locker already has a lock!") + return + if(broken) + to_chat(user, "Unscrew the broken lock first!") + return + if(!istype(E)) + return + user.visible_message("[user] begins installing a lock on [src]...","You begin installing a lock on [src]...") + lock_in_use = TRUE + playsound(loc, 'sound/items/screwdriver.ogg', 50, 1) + if(!do_after(user, 60, target = src)) + lock_in_use = FALSE + return + lock_in_use = FALSE + to_chat(user, "You finish the lock on [src]!") + E.forceMove(src) + lockerelectronics = E + req_access = E.accesses + secure = TRUE + update_icon() + return TRUE + +/obj/structure/closet/proc/handle_lock_removal(mob/user, obj/item/screwdriver/S) + if(lock_in_use) + to_chat(user, "Wait for work on [src] to be done first!") + return + if(locked) + to_chat(user, "Unlock it first!") + return + if(!secure) + to_chat(user, "[src] doesn't have a lock that you can remove!") + return + if(!istype(S)) + return + var/brokenword = broken ? "broken " : null + user.visible_message("[user] begins removing the [brokenword]lock on [src]...","You begin removing the [brokenword]lock on [src]...") + playsound(loc, S.usesound, 50, 1) + lock_in_use = TRUE + if(!do_after(user, 100 * S.toolspeed, target = src)) + lock_in_use = FALSE + return + to_chat(user, "You remove the [brokenword]lock from [src]!") + if(!QDELETED(lockerelectronics)) + lockerelectronics.add_fingerprint(user) + lockerelectronics.forceMove(user.loc) + lockerelectronics = null + req_access = null + secure = FALSE + broken = FALSE + locked = FALSE + lock_in_use = FALSE + update_icon() + return TRUE + + /obj/structure/closet/deconstruct(disassembled = TRUE) if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1)) new material_drop(loc, material_drop_amount) @@ -233,6 +349,9 @@ to_chat(user, "You begin cutting \the [src] apart...") if(W.use_tool(src, user, 40, volume=50)) + if(eigen_teleport) + to_chat(user, "The unstable nature of \the [src] makes it impossible to cut!") + return if(!opened) return user.visible_message("[user] slices apart \the [src].", @@ -246,18 +365,25 @@ deconstruct(TRUE) return if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too - return + return TRUE + else if(istype(W, /obj/item/electronics/airlock)) + handle_lock_addition(user, W) + else if(istype(W, /obj/item/screwdriver)) + handle_lock_removal(user, W) else if(istype(W, /obj/item/weldingtool) && can_weld_shut) if(!W.tool_start_check(user, amount=0)) return to_chat(user, "You begin [welded ? "unwelding":"welding"] \the [src]...") if(W.use_tool(src, user, 40, volume=50)) + if(eigen_teleport) + to_chat(user, "The unstable nature of \the [src] makes it impossible to weld!") + return if(opened) return welded = !welded after_weld(welded) - user.visible_message("[user] [welded ? "welds shut" : "unwelded"] \the [src].", + user.visible_message("[user] [welded ? "welds shut" : "unwelds"] \the [src].", "You [welded ? "weld" : "unwelded"] \the [src] with \the [W].", "You hear welding.") update_icon() @@ -400,20 +526,12 @@ if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, "You fail to break out of [src]!") -/obj/structure/closet/proc/bust_open() - welded = FALSE //applies to all lockers - locked = FALSE //applies to critter crates and secure lockers only - broken = TRUE //applies to secure lockers only - open() - /obj/structure/closet/AltClick(mob/user) ..() - if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc)) + if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc)) + to_chat(user, "You can't do that right now!") return - if(opened || !secure) - return - else - togglelock(user) + togglelock(user) /obj/structure/closet/CtrlShiftClick(mob/living/user) if(!HAS_TRAIT(user, TRAIT_SKITTISH)) @@ -422,29 +540,19 @@ return dive_into(user) -/obj/structure/closet/proc/togglelock(mob/living/user, silent) - if(secure && !broken) - if(allowed(user)) - if(iscarbon(user)) - add_fingerprint(user) - locked = !locked - user.visible_message("[user] [locked ? null : "un"]locks [src].", - "You [locked ? null : "un"]lock [src].") - update_icon() - else if(!silent) - to_chat(user, "Access Denied") - else if(secure && broken) - to_chat(user, "\The [src] is broken!") - /obj/structure/closet/emag_act(mob/user) - if(secure && !broken) - user.visible_message("Sparks fly from [src]!", - "You scramble [src]'s lock, breaking it open!", - "You hear a faint electrical spark.") - playsound(src, "sparks", 50, 1) - broken = TRUE - locked = FALSE - update_icon() + . = ..() + if(!secure || broken) + return + user.visible_message("Sparks fly from [src]!", + "You scramble [src]'s lock, breaking it open!", + "You hear a faint electrical spark.") + playsound(src, "sparks", 50, 1) + broken = TRUE + locked = FALSE + if(!QDELETED(lockerelectronics)) + QDEL_NULL(lockerelectronics) + update_icon() /obj/structure/closet/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) @@ -457,16 +565,19 @@ if (!(. & EMP_PROTECT_CONTENTS)) for(var/obj/O in src) O.emp_act(severity) - if(secure && !broken && !(. & EMP_PROTECT_SELF)) - if(prob(50 / severity)) - locked = !locked - update_icon() - if(prob(20 / severity) && !opened) - if(!locked) - open() - else - req_access = list() - req_access += pick(get_all_accesses()) + if(!secure || broken) + return ..() + if(prob(50 / severity)) + locked = !locked + update_icon() + if(prob(20 / severity) && !opened) + if(!locked) + open() + else + req_access = list() + req_access += pick(get_all_accesses()) + if(!QDELETED(lockerelectronics)) + lockerelectronics.accesses = req_access /obj/structure/closet/contents_explosion(severity, target) for(var/atom/A in contents) diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 502b23354c..1c34850274 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -49,6 +49,12 @@ return 1 return 0 +/obj/structure/closet/body_bag/handle_lock_addition() + return + +/obj/structure/closet/body_bag/handle_lock_removal() + return + /obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location) . = ..() if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src))) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 82b0d1a441..aad68b2166 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -57,6 +57,11 @@ I.alpha = 0 animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING) +/obj/structure/closet/cardboard/handle_lock_addition() //Whoever heard of a lockable cardboard box anyway + return + +/obj/structure/closet/cardboard/handle_lock_removal() + return /obj/structure/closet/cardboard/metal name = "large metal box" diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index 0809edaa71..d2ab9ea6fb 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -21,8 +21,8 @@ new /obj/item/clothing/head/soft/black(src) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/shoes/sneakers/black(src) - new /obj/item/reagent_containers/glass/rag(src) - new /obj/item/reagent_containers/glass/rag(src) + new /obj/item/reagent_containers/rag(src) + new /obj/item/reagent_containers/rag(src) new /obj/item/storage/box/beanbag(src) new /obj/item/clothing/suit/armor/vest/alt(src) new /obj/item/circuitboard/machine/dish_drive(src) @@ -53,7 +53,7 @@ new /obj/item/clothing/suit/toggle/chef(src) new /obj/item/clothing/under/rank/chef(src) new /obj/item/clothing/head/chefhat(src) - new /obj/item/reagent_containers/glass/rag(src) + new /obj/item/reagent_containers/rag(src) /obj/structure/closet/jcloset name = "custodial closet" @@ -358,3 +358,8 @@ new /obj/item/clothing/shoes/workboots/mining(src) new /obj/item/storage/backpack/satchel/explorer(src) +/obj/structure/closet/coffin/handle_lock_addition() + return + +/obj/structure/closet/coffin/handle_lock_removal() + return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index 5a9228e397..18928424c0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -9,6 +9,7 @@ new /obj/item/clothing/head/beret/qm(src) new /obj/item/storage/lockbox/medal/cargo(src) new /obj/item/clothing/under/rank/cargo(src) + new /obj/item/clothing/under/rank/cargo/skirt(src) new /obj/item/clothing/shoes/sneakers/brown(src) new /obj/item/radio/headset/headset_cargo(src) new /obj/item/clothing/suit/fire/firefighter(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 0d06276876..a7adafdad4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -8,6 +8,7 @@ new /obj/item/clothing/neck/cloak/ce(src) new /obj/item/clothing/head/beret/ce(src) new /obj/item/clothing/under/rank/chief_engineer(src) + new /obj/item/clothing/under/rank/chief_engineer/skirt(src) new /obj/item/clothing/head/hardhat/white(src) new /obj/item/clothing/head/welding(src) new /obj/item/clothing/gloves/color/yellow(src) @@ -32,6 +33,7 @@ new /obj/item/extinguisher/advanced(src) new /obj/item/storage/photo_album/CE(src) new /obj/item/storage/lockbox/medal/engineering(src) + new /obj/item/construction/rcd/loaded/upgraded(src) /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 9081cddbe4..0f810225b3 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -61,6 +61,7 @@ new /obj/item/clothing/head/bio_hood/cmo(src) new /obj/item/clothing/suit/toggle/labcoat/cmo(src) new /obj/item/clothing/under/rank/chief_medical_officer(src) + new /obj/item/clothing/under/rank/chief_medical_officer/skirt(src) new /obj/item/clothing/shoes/sneakers/brown (src) new /obj/item/cartridge/cmo(src) new /obj/item/radio/headset/heads/cmo(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index eb764fc230..e44d3c9079 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -4,6 +4,18 @@ req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) var/registered_name = null +/obj/structure/closet/secure_closet/personal/examine(mob/user) + ..() + if(registered_name) + to_chat(user, "The display reads, \"Owned by [registered_name]\".") + +/obj/structure/closet/secure_closet/personal/check_access(obj/item/card/id/I) + . = ..() + if(!I || !istype(I)) + return + if(registered_name == I.registered_name) + return TRUE + /obj/structure/closet/secure_closet/personal/PopulateContents() ..() if(prob(50)) @@ -33,21 +45,21 @@ /obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) var/obj/item/card/id/I = W.GetID() - if(istype(I)) - if(broken) - to_chat(user, "It appears to be broken.") - return - if(!I || !I.registered_name) - return - if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) - //they can open all lockers, or nobody owns this, or they own this locker - locked = !locked - update_icon() - - if(!registered_name) - registered_name = I.registered_name - desc = "Owned by [I.registered_name]." - else - to_chat(user, "Access Denied.") - else + if(!I || !istype(I)) return ..() + if(!can_lock(user, FALSE)) //Can't do anything if there isn't a lock! + return + if(I.registered_name && !registered_name) + to_chat(user, "You claim [src].") + registered_name = I.registered_name + else + ..() + +/obj/structure/closet/secure_closet/personal/handle_lock_addition() //If lock construction is successful we don't care what access the electronics had, so we override it + if(..()) + req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) + lockerelectronics.accesses = req_access + +/obj/structure/closet/secure_closet/personal/handle_lock_removal() + if(..()) + registered_name = null diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 7fe1247eb7..efcc2aa7ca 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -11,8 +11,11 @@ new /obj/item/clothing/head/bio_hood/scientist(src) new /obj/item/clothing/suit/toggle/labcoat(src) new /obj/item/clothing/under/rank/research_director(src) + new /obj/item/clothing/under/rank/research_director/skirt(src) new /obj/item/clothing/under/rank/research_director/alt(src) + new /obj/item/clothing/under/rank/research_director/alt/skirt(src) new /obj/item/clothing/under/rank/research_director/turtleneck(src) + new /obj/item/clothing/under/rank/research_director/turtleneck/skirt(src) new /obj/item/clothing/shoes/sneakers/brown(src) new /obj/item/cartridge/rd(src) new /obj/item/clothing/gloves/color/latex(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 8c06af91a4..3cb8ceb22b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -2,7 +2,6 @@ name = "\proper captain's locker" req_access = list(ACCESS_CAPTAIN) icon_state = "cap" - /obj/structure/closet/secure_closet/captains/PopulateContents() ..() new /obj/item/clothing/suit/hooded/wintercoat/captain(src) @@ -14,6 +13,7 @@ new /obj/item/pet_carrier(src) new /obj/item/clothing/shoes/sneakers/brown(src) new /obj/item/clothing/under/rank/captain(src) + new /obj/item/clothing/under/rank/captain/skirt(src) new /obj/item/clothing/suit/armor/vest/capcarapace(src) new /obj/item/clothing/head/caphat(src) new /obj/item/clothing/under/captainparade(src) @@ -34,16 +34,15 @@ new /obj/item/gun/energy/e_gun(src) new /obj/item/door_remote/captain(src) new /obj/item/storage/photo_album/Captain(src) - /obj/structure/closet/secure_closet/hop name = "\proper head of personnel's locker" req_access = list(ACCESS_HOP) icon_state = "hop" - /obj/structure/closet/secure_closet/hop/PopulateContents() ..() new /obj/item/clothing/neck/cloak/hop(src) new /obj/item/clothing/under/rank/head_of_personnel(src) + new /obj/item/clothing/under/rank/head_of_personnel/skirt(src) new /obj/item/clothing/head/hopcap(src) new /obj/item/clothing/head/hopcap/beret(src) new /obj/item/cartridge/hop(src) @@ -62,12 +61,10 @@ new /obj/item/door_remote/civillian(src) new /obj/item/circuitboard/machine/techfab/department/service(src) new /obj/item/storage/photo_album/HoP(src) - /obj/structure/closet/secure_closet/hos name = "\proper head of security's locker" req_access = list(ACCESS_HOS) icon_state = "hos" - /obj/structure/closet/secure_closet/hos/PopulateContents() ..() new /obj/item/clothing/neck/cloak/hos(src) @@ -77,7 +74,9 @@ new /obj/item/clothing/under/hosparademale(src) new /obj/item/clothing/suit/armor/vest/leather(src) new /obj/item/clothing/suit/armor/hos(src) + new /obj/item/clothing/under/rank/head_of_security/skirt(src) new /obj/item/clothing/under/rank/head_of_security/alt(src) + new /obj/item/clothing/under/rank/head_of_security/alt/skirt(src) new /obj/item/clothing/head/HoS(src) new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src) @@ -95,12 +94,10 @@ new /obj/item/pinpointer/nuke(src) new /obj/item/circuitboard/machine/techfab/department/security(src) new /obj/item/storage/photo_album/HoS(src) - /obj/structure/closet/secure_closet/warden name = "\proper warden's locker" req_access = list(ACCESS_ARMORY) icon_state = "warden" - /obj/structure/closet/secure_closet/warden/PopulateContents() ..() new /obj/item/radio/headset/headset_sec(src) @@ -110,6 +107,7 @@ new /obj/item/clothing/head/beret/sec/navywarden(src) new /obj/item/clothing/suit/armor/vest/warden/alt(src) new /obj/item/clothing/under/rank/warden/navyblue(src) + new /obj/item/clothing/under/rank/warden/skirt(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/holosign_creator/security(src) new /obj/item/clothing/mask/gas/sechailer(src) @@ -120,12 +118,10 @@ new /obj/item/clothing/gloves/krav_maga/sec(src) new /obj/item/door_remote/head_of_security(src) new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src) - /obj/structure/closet/secure_closet/security name = "security officer's locker" req_access = list(ACCESS_SECURITY) icon_state = "sec" - /obj/structure/closet/secure_closet/security/PopulateContents() ..() new /obj/item/clothing/suit/armor/vest(src) @@ -134,55 +130,45 @@ new /obj/item/radio/headset/headset_sec/alt(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/flashlight/seclite(src) - /obj/structure/closet/secure_closet/security/sec - /obj/structure/closet/secure_closet/security/sec/PopulateContents() ..() new /obj/item/storage/belt/security/full(src) - /obj/structure/closet/secure_closet/security/cargo - /obj/structure/closet/secure_closet/security/cargo/PopulateContents() ..() new /obj/item/clothing/accessory/armband/cargo(src) new /obj/item/encryptionkey/headset_cargo(src) - /obj/structure/closet/secure_closet/security/engine - /obj/structure/closet/secure_closet/security/engine/PopulateContents() ..() new /obj/item/clothing/accessory/armband/engine(src) new /obj/item/encryptionkey/headset_eng(src) - /obj/structure/closet/secure_closet/security/science - /obj/structure/closet/secure_closet/security/science/PopulateContents() ..() new /obj/item/clothing/accessory/armband/science(src) new /obj/item/encryptionkey/headset_sci(src) - /obj/structure/closet/secure_closet/security/med - /obj/structure/closet/secure_closet/security/med/PopulateContents() ..() new /obj/item/clothing/accessory/armband/medblue(src) new /obj/item/encryptionkey/headset_med(src) - /obj/structure/closet/secure_closet/detective name = "\improper detective's cabinet" req_access = list(ACCESS_FORENSICS_LOCKERS) icon_state = "cabinet" resistance_flags = FLAMMABLE max_integrity = 70 - /obj/structure/closet/secure_closet/detective/PopulateContents() ..() new /obj/item/clothing/under/rank/det(src) + new /obj/item/clothing/under/rank/det/skirt(src) new /obj/item/clothing/suit/det_suit(src) new /obj/item/clothing/head/fedora/det_hat(src) new /obj/item/clothing/gloves/color/black(src) new /obj/item/clothing/under/rank/det/grey(src) + new /obj/item/clothing/under/rank/det/grey/skirt(src) new /obj/item/clothing/accessory/waistcoat(src) new /obj/item/clothing/suit/det_suit/grey(src) new /obj/item/clothing/head/fedora(src) @@ -200,33 +186,29 @@ /obj/structure/closet/secure_closet/injection name = "lethal injections" req_access = list(ACCESS_HOS) - /obj/structure/closet/secure_closet/injection/PopulateContents() ..() for(var/i in 1 to 5) new /obj/item/reagent_containers/syringe/lethal/execution(src) - /obj/structure/closet/secure_closet/brig name = "brig locker" req_access = list(ACCESS_BRIG) anchored = TRUE var/id = null - /obj/structure/closet/secure_closet/evidence anchored = TRUE name = "Secure Evidence Closet" req_access_txt = "0" req_one_access_txt = list(ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS) - /obj/structure/closet/secure_closet/brig/PopulateContents() ..() new /obj/item/clothing/under/rank/prisoner( src ) + new /obj/item/clothing/under/rank/prisoner/skirt( src ) new /obj/item/clothing/shoes/sneakers/orange( src ) /obj/structure/closet/secure_closet/courtroom name = "courtroom locker" req_access = list(ACCESS_COURT) - /obj/structure/closet/secure_closet/courtroom/PopulateContents() ..() new /obj/item/clothing/shoes/sneakers/brown(src) @@ -236,22 +218,18 @@ new /obj/item/clothing/suit/judgerobe (src) new /obj/item/clothing/head/powdered_wig (src) new /obj/item/storage/briefcase(src) - /obj/structure/closet/secure_closet/contraband/armory anchored = TRUE name = "Contraband Locker" req_access = list(ACCESS_ARMORY) - /obj/structure/closet/secure_closet/contraband/heads anchored = TRUE name = "Contraband Locker" req_access = list(ACCESS_HEADS) - /obj/structure/closet/secure_closet/armory1 name = "armory armor locker" req_access = list(ACCESS_ARMORY) icon_state = "armory" - /obj/structure/closet/secure_closet/armory1/PopulateContents() ..() new /obj/item/clothing/suit/armor/laserproof(src) @@ -261,12 +239,10 @@ new /obj/item/clothing/head/helmet/riot(src) for(var/i in 1 to 3) new /obj/item/shield/riot(src) - /obj/structure/closet/secure_closet/armory2 name = "armory ballistics locker" req_access = list(ACCESS_ARMORY) icon_state = "armory" - /obj/structure/closet/secure_closet/armory2/PopulateContents() ..() new /obj/item/storage/box/firingpins(src) @@ -274,12 +250,10 @@ new /obj/item/storage/box/rubbershot(src) for(var/i in 1 to 3) new /obj/item/gun/ballistic/shotgun/riot(src) - /obj/structure/closet/secure_closet/armory3 name = "armory energy gun locker" req_access = list(ACCESS_ARMORY) icon_state = "armory" - /obj/structure/closet/secure_closet/armory3/PopulateContents() ..() new /obj/item/storage/box/firingpins(src) @@ -288,24 +262,20 @@ new /obj/item/gun/energy/e_gun(src) for(var/i in 1 to 3) new /obj/item/gun/energy/laser(src) - /obj/structure/closet/secure_closet/tac name = "armory tac locker" req_access = list(ACCESS_ARMORY) icon_state = "tac" - /obj/structure/closet/secure_closet/tac/PopulateContents() ..() new /obj/item/gun/ballistic/automatic/wt550(src) new /obj/item/clothing/head/helmet/alt(src) new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/clothing/suit/armor/bulletproof(src) - /obj/structure/closet/secure_closet/lethalshots name = "shotgun lethal rounds" req_access = list(ACCESS_ARMORY) icon_state = "tac" - /obj/structure/closet/secure_closet/lethalshots/PopulateContents() ..() for(var/i in 1 to 3) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index f2d32b773e..94d1b03fdb 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -9,6 +9,7 @@ /obj/structure/closet/syndicate/personal/PopulateContents() ..() new /obj/item/clothing/under/syndicate(src) + new /obj/item/clothing/under/syndicate/skirt(src) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/radio/headset/syndicate(src) new /obj/item/ammo_box/magazine/m10mm(src) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 7493603ad4..d83922d708 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -2,33 +2,34 @@ name = "wardrobe" desc = "It's a storage unit for standard-issue Nanotrasen attire." icon_door = "blue" - /obj/structure/closet/wardrobe/PopulateContents() ..() for(var/i in 1 to 3) new /obj/item/clothing/under/color/blue(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/blue(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/brown(src) return - /obj/structure/closet/wardrobe/pink name = "pink wardrobe" icon_door = "pink" - /obj/structure/closet/wardrobe/pink/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/pink(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/pink(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/brown(src) return - /obj/structure/closet/wardrobe/black name = "black wardrobe" icon_door = "black" - /obj/structure/closet/wardrobe/black/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/black(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/black(src) if(prob(25)) new /obj/item/clothing/suit/jacket/leather(src) if(prob(20)) @@ -44,66 +45,60 @@ if(prob(40)) new /obj/item/clothing/mask/bandana/skull(src) return - - /obj/structure/closet/wardrobe/green name = "green wardrobe" icon_door = "green" - /obj/structure/closet/wardrobe/green/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/green(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/green(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/mask/bandana/green(src) new /obj/item/clothing/mask/bandana/green(src) return - - /obj/structure/closet/wardrobe/orange name = "prison wardrobe" desc = "It's a storage unit for Nanotrasen-regulation prisoner attire." icon_door = "orange" - /obj/structure/closet/wardrobe/orange/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/rank/prisoner(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/rank/prisoner/skirt(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/orange(src) return - - /obj/structure/closet/wardrobe/yellow name = "yellow wardrobe" icon_door = "yellow" - /obj/structure/closet/wardrobe/yellow/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/yellow(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/yellow(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/orange(src) new /obj/item/clothing/mask/bandana/gold(src) new /obj/item/clothing/mask/bandana/gold(src) return - - /obj/structure/closet/wardrobe/white name = "white wardrobe" icon_door = "white" - /obj/structure/closet/wardrobe/white/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/white(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/white(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/white(src) for(var/i in 1 to 3) new /obj/item/clothing/head/soft/mime(src) return - /obj/structure/closet/wardrobe/pjs name = "pajama wardrobe" icon_door = "white" - /obj/structure/closet/wardrobe/pjs/PopulateContents() new /obj/item/clothing/under/pj/red(src) new /obj/item/clothing/under/pj/red(src) @@ -112,15 +107,14 @@ for(var/i in 1 to 4) new /obj/item/clothing/shoes/sneakers/white(src) return - - /obj/structure/closet/wardrobe/grey name = "grey wardrobe" icon_door = "grey" - /obj/structure/closet/wardrobe/grey/PopulateContents() for(var/i in 1 to 3) new /obj/item/clothing/under/color/grey(src) + for(var/i in 1 to 3) + new /obj/item/clothing/under/skirt/color/grey(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/black(src) for(var/i in 1 to 3) @@ -140,28 +134,36 @@ if(prob(30)) new /obj/item/clothing/accessory/pocketprotector(src) return - - /obj/structure/closet/wardrobe/mixed name = "mixed wardrobe" icon_door = "mixed" - /obj/structure/closet/wardrobe/mixed/PopulateContents() if(prob(40)) new /obj/item/clothing/suit/jacket(src) if(prob(40)) new /obj/item/clothing/suit/jacket(src) new /obj/item/clothing/under/color/white(src) + new /obj/item/clothing/under/skirt/color/white(src) new /obj/item/clothing/under/color/blue(src) + new /obj/item/clothing/under/skirt/color/blue(src) new /obj/item/clothing/under/color/yellow(src) + new /obj/item/clothing/under/skirt/color/yellow(src) new /obj/item/clothing/under/color/green(src) + new /obj/item/clothing/under/skirt/color/green(src) new /obj/item/clothing/under/color/orange(src) + new /obj/item/clothing/under/skirt/color/orange(src) new /obj/item/clothing/under/color/pink(src) + new /obj/item/clothing/under/skirt/color/pink(src) new /obj/item/clothing/under/color/red(src) + new /obj/item/clothing/under/skirt/color/red(src) new /obj/item/clothing/under/color/darkblue(src) + new /obj/item/clothing/under/skirt/color/darkblue(src) new /obj/item/clothing/under/color/teal(src) + new /obj/item/clothing/under/skirt/color/teal(src) new /obj/item/clothing/under/color/lightpurple(src) + new /obj/item/clothing/under/skirt/color/lightpurple(src) new /obj/item/clothing/under/color/green(src) + new /obj/item/clothing/under/skirt/color/green(src) new /obj/item/clothing/mask/bandana/red(src) new /obj/item/clothing/mask/bandana/red(src) new /obj/item/clothing/mask/bandana/blue(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 067b1b0eb1..6caa7d834b 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -54,6 +54,12 @@ manifest = null update_icon() +/obj/structure/closet/crate/handle_lock_addition() + return + +/obj/structure/closet/crate/handle_lock_removal() + return + /obj/structure/closet/crate/proc/tear_manifest(mob/user) to_chat(user, "You tear the manifest off of [src].") playsound(src, 'sound/items/poster_ripped.ogg', 75, 1) diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 9e88d52444..cdca354563 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -21,35 +21,62 @@ /obj/structure/dresser/attack_hand(mob/user) . = ..() - if(.) + if(. || !ishuman(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return - if(!Adjacent(user))//no tele-grooming + var/mob/living/carbon/human/H = user + + if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits)) + to_chat(H, "You are not capable of wearing underwear.") return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits)) - to_chat(user, "You are not capable of wearing underwear.") - return + var/list/undergarment_choices = list("Underwear", "Underwear Color", "Undershirt", "Undershirt Color", "Socks", "Socks Color") + if(!UNDIE_COLORABLE(GLOB.underwear_list[H.underwear])) + undergarment_choices -= "Underwear Color" + if(!UNDIE_COLORABLE(GLOB.undershirt_list[H.undershirt])) + undergarment_choices -= "Undershirt Color" + if(!UNDIE_COLORABLE(GLOB.socks_list[H.socks])) + undergarment_choices -= "Socks Color" - var/choice = input(user, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in list("Underwear","Undershirt","Socks") + var/choice = input(H, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in undergarment_choices + if(!H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + var/dye_undie = FALSE + var/dye_shirt = FALSE + var/dye_socks = FALSE + switch(choice) + if("Underwear") + var/new_undies = input(H, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list + if(H.underwear) + H.underwear = new_undies + H.saved_underwear = new_undies + var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[new_undies] + dye_undie = B?.has_color + if("Undershirt") + var/new_undershirt = input(H, "Select your undershirt", "Changing") as null|anything in GLOB.undershirt_list + if(new_undershirt) + H.undershirt = new_undershirt + H.saved_undershirt = new_undershirt + var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[new_undershirt] + dye_shirt = T?.has_color + if("Socks") + var/new_socks = input(H, "Select your socks", "Changing") as null|anything in GLOB.socks_list + if(new_socks) + H.socks = new_socks + H.saved_socks = new_socks + var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[new_socks] + dye_socks = S?.has_color + if(dye_undie || choice == "Underwear Color") + H.undie_color = recolor_undergarment(H, "underwear", H.undie_color) + if(dye_shirt || choice == "Undershirt Color") + H.shirt_color = recolor_undergarment(H, "undershirt", H.shirt_color) + if(dye_socks || choice == "Socks Color") + H.socks_color = recolor_undergarment(H, "socks", H.socks_color) - if(!Adjacent(user)) - return - switch(choice) - if("Underwear") - var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list - if(new_undies) - H.underwear = new_undies + add_fingerprint(H) + H.update_body() - if("Undershirt") - var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in GLOB.undershirt_list - if(new_undershirt) - H.undershirt = new_undershirt - if("Socks") - var/new_socks = input(user, "Select your socks", "Changing") as null|anything in GLOB.socks_list - if(new_socks) - H.socks= new_socks - - add_fingerprint(H) - H.update_body() +/obj/structure/dresser/proc/recolor_undergarment(mob/living/carbon/human/H, garment_type = "underwear", default_color) + var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null + if(!n_color || !H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return default_color + return sanitize_hexcolor(n_color) diff --git a/code/game/objects/structures/femur_breaker.dm b/code/game/objects/structures/femur_breaker.dm new file mode 100644 index 0000000000..e3002a8fae --- /dev/null +++ b/code/game/objects/structures/femur_breaker.dm @@ -0,0 +1,175 @@ +#define BREAKER_ANIMATION_LENGTH 32 +#define BREAKER_SLAT_RAISED 1 +#define BREAKER_SLAT_MOVING 2 +#define BREAKER_SLAT_DROPPED 3 +#define BREAKER_ACTIVATE_DELAY 30 +#define BREAKER_WRENCH_DELAY 10 +#define BREAKER_ACTION_INUSE 5 +#define BREAKER_ACTION_WRENCH 6 + +/obj/structure/femur_breaker + name = "femur breaker" + desc = "A large structure used to break the femurs of traitors and treasonists." + icon = 'icons/obj/femur_breaker.dmi' + icon_state = "breaker_raised" + can_buckle = TRUE + anchored = TRUE + density = TRUE + max_buckled_mobs = 1 + buckle_lying = TRUE + buckle_prevents_pull = TRUE + layer = ABOVE_MOB_LAYER + var/slat_status = BREAKER_SLAT_RAISED + var/current_action = 0 // What's currently happening to the femur breaker + +/obj/structure/femur_breaker/examine(mob/user) + ..() + + var/msg = "" + + msg += "It is [anchored ? "secured to the floor." : "unsecured."]
    " + + if (slat_status == BREAKER_SLAT_RAISED) + msg += "The breaker slat is in a neutral position." + else + msg += "The breaker slat is lowered, and must be raised." + + if (LAZYLEN(buckled_mobs)) + msg += "
    " + msg += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker." + + to_chat(user, msg) + + return msg + +/obj/structure/femur_breaker/attack_hand(mob/user) + add_fingerprint(user) + + // Currently being used + if (current_action) + return + + switch (slat_status) + if (BREAKER_SLAT_MOVING) + return + if (BREAKER_SLAT_DROPPED) + slat_status = BREAKER_SLAT_MOVING + icon_state = "breaker_raise" + addtimer(CALLBACK(src, .proc/raise_slat), BREAKER_ANIMATION_LENGTH) + return + if (BREAKER_SLAT_RAISED) + if (LAZYLEN(buckled_mobs)) + if (user.a_intent == INTENT_HARM) + user.visible_message("[user] begins to pull the lever!", + "You begin to the pull the lever.") + current_action = BREAKER_ACTION_INUSE + + if (do_after(user, BREAKER_ACTIVATE_DELAY, target = src) && slat_status == BREAKER_SLAT_RAISED) + current_action = 0 + slat_status = BREAKER_SLAT_MOVING + icon_state = "breaker_drop" + drop_slat(user) + else + current_action = 0 + else + var/mob/living/carbon/human/H = buckled_mobs[1] + + if (H) + H.regenerate_icons() + + unbuckle_all_mobs() + else //HERE + slat_status = BREAKER_SLAT_DROPPED + icon_state = "breaker_drop" + +/obj/structure/femur_breaker/proc/damage_leg(mob/living/carbon/human/H) + H.emote("scream") + H.apply_damage(150, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) + H.adjustBruteLoss(rand(5,20) + (max(0, H.health))) //Make absolutely sure they end up in crit, so that they can succumb if they wish. + +/obj/structure/femur_breaker/proc/raise_slat() + slat_status = BREAKER_SLAT_RAISED + icon_state = "breaker_raised" + +/obj/structure/femur_breaker/proc/drop_slat(mob/user) + if (buckled_mobs.len) + var/mob/living/carbon/human/H = buckled_mobs[1] + + if (!H) + return + + playsound(src, 'sound/effects/femur_breaker.ogg', 100, FALSE) + H.Stun(BREAKER_ANIMATION_LENGTH) + addtimer(CALLBACK(src, .proc/damage_leg, H), BREAKER_ANIMATION_LENGTH, TIMER_UNIQUE) + log_combat(user, H, "femur broke", src) + + slat_status = BREAKER_SLAT_DROPPED + icon_state = "breaker" + +/obj/structure/femur_breaker/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) + if (!anchored) + to_chat(usr, "The [src] needs to be wrenched to the floor!") + return FALSE + + if (!istype(M, /mob/living/carbon/human)) + to_chat(usr, "It doesn't look like [M.p_they()] can fit into this properly!") + return FALSE + + if (slat_status != BREAKER_SLAT_RAISED) + to_chat(usr, "The femur breaker must be in its neutral position before buckling someone in!") + return FALSE + + return ..(M, force, FALSE) + +/obj/structure/femur_breaker/post_buckle_mob(mob/living/M) + if (!istype(M, /mob/living/carbon/human)) + return + + var/mob/living/carbon/human/H = M + + if (H.dna) + if (H.dna.species) + var/datum/species/S = H.dna.species + + if (!istype(S)) + unbuckle_all_mobs() + else + unbuckle_all_mobs() + else + unbuckle_all_mobs() + + ..() + +/obj/structure/femur_breaker/can_be_unfasten_wrench(mob/user, silent) + if (LAZYLEN(buckled_mobs)) + if (!silent) + to_chat(user, "Can't unfasten, someone's strapped in!") + return FAILED_UNFASTEN + + if (current_action) + return FAILED_UNFASTEN + + return ..() + +/obj/structure/femur_breaker/wrench_act(mob/living/user, obj/item/I) + if (current_action) + return + + current_action = BREAKER_ACTION_WRENCH + + if (do_after(user, BREAKER_WRENCH_DELAY, target = src)) + current_action = 0 + default_unfasten_wrench(user, I, 0) + setDir(SOUTH) + return TRUE + else + current_action = 0 + +#undef BREAKER_ANIMATION_LENGTH +#undef BREAKER_SLAT_RAISED +#undef BREAKER_SLAT_MOVING +#undef BREAKER_SLAT_DROPPED +#undef BREAKER_ACTIVATE_DELAY +#undef BREAKER_WRENCH_DELAY +#undef BREAKER_ACTION_INUSE +#undef BREAKER_ACTION_WRENCH diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 6fac5da2a5..00d1690d86 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -262,7 +262,7 @@ if(isobj(AM)) if(prob(50) && anchored && !broken) var/obj/O = AM - if(O.throwforce != 0)//don't want to let people spam tesla bolts, this way it will break after time + if(O.throwforce != 0 && O.damtype != STAMINA)//don't want to let people spam tesla bolts, this way it will break after time var/turf/T = get_turf(src) var/obj/structure/cable/C = T.get_cable_node() if(C) diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm new file mode 100644 index 0000000000..c4e1968e59 --- /dev/null +++ b/code/game/objects/structures/loom.dm @@ -0,0 +1,21 @@ +//Loom, turns raw cotton and durathread into their respective fabrics. + +/obj/structure/loom + name = "loom" + desc = "A simple device used to weave cloth and other thread-based fabrics together into usable material." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "loom" + density = TRUE + anchored = TRUE + +/obj/structure/loom/attackby(obj/item/stack/sheet/W, mob/user) + if(W.is_fabric && W.amount > 1) + user.show_message("You start weaving the [W.name] through the loom..", 1) + if(W.use_tool(src, user, W.pull_effort)) + new W.loom_result(drop_location()) + user.show_message("You weave the [W.name] into a workable fabric.", 1) + W.amount = (W.amount - 2) + if(W.amount < 1) + qdel(W) + else + user.show_message("You need a valid fabric and at least 2 of said fabric before using this.", 1) \ No newline at end of file diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index aa55cd81b1..80ffced5a2 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -180,12 +180,13 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "offhand" w_class = WEIGHT_CLASS_HUGE - item_flags = ABSTRACT | NODROP | NOBLUDGEON | DROPDEL + item_flags = ABSTRACT | NOBLUDGEON | DROPDEL resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/obj/machinery/manned_turret/turret /obj/item/gun_control/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) turret = loc if(!istype(turret)) return INITIALIZE_HINT_QDEL diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm index e979d4f18e..226d279288 100644 --- a/code/game/objects/structures/table_frames.dm +++ b/code/game/objects/structures/table_frames.dm @@ -100,6 +100,14 @@ to_chat(user, "You start adding [B] to [src]...") if(do_after(user, 20, target = src) && B.use(1)) make_new_table(/obj/structure/table/bronze) + else if(istype(I, /obj/item/stack/sheet/plasmaglass)) + var/obj/item/stack/sheet/plasmaglass/G = I + if(G.get_amount() < 1) + to_chat(user, "You need one plasmaglass sheet to do this!") + return + to_chat(user, "You start adding [G] to [src]...") + if(do_after(user, 20, target = src) && G.use(1)) + make_new_table(/obj/structure/table/plasmaglass) else return ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 8c29c1b2c5..fcffafb262 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -258,6 +258,53 @@ for(var/obj/item/shard/S in debris) S.color = NARSIE_WINDOW_COLOUR +/* + * Plasmaglass tables + */ +/obj/structure/table/plasmaglass + name = "plasmaglass table" + desc = "A glasstable, but it's pink and more sturdy. What will Nanotrasen design next with plasma?" + icon = 'icons/obj/smooth_structures/plasmaglass_table.dmi' + icon_state = "plasmaglass_table" + climbable = TRUE + buildstack = /obj/item/stack/sheet/plasmaglass + canSmoothWith = null + max_integrity = 270 + resistance_flags = ACID_PROOF + armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + var/list/debris = list() + +/obj/structure/table/plasmaglass/New() + . = ..() + debris += new frame + debris += new /obj/item/shard/plasma + +/obj/structure/table/plasmaglass/Destroy() + QDEL_LIST(debris) + . = ..() + +/obj/structure/table/plasmaglass/proc/check_break(mob/living/M) + return + +/obj/structure/table/plasmaglass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + ..() + return + else + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/X in debris) + var/atom/movable/AM = X + AM.forceMove(T) + debris -= AM + qdel(src) + +/obj/structure/table/plasmaglass/narsie_act() + color = NARSIE_WINDOW_COLOUR + for(var/obj/item/shard/S in debris) + S.color = NARSIE_WINDOW_COLOUR + /* * Wooden tables */ diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index d70838a30b..46db567b10 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -537,7 +537,7 @@ if(istype(O, /obj/item/stack/medical/gauze)) var/obj/item/stack/medical/gauze/G = O - new /obj/item/reagent_containers/glass/rag(src.loc) + new /obj/item/reagent_containers/rag(src.loc) to_chat(user, "You tear off a strip of gauze and make a rag.") G.use(1) return diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index a26d57e3e1..9fc055c2ba 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -281,6 +281,8 @@ . += new /obj/effect/decal/cleanable/glass(location) if (reinf) . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) + if (fulltile) + . += new /obj/item/shard(location) /obj/structure/window/proc/can_be_rotated(mob/user,rotation_type) if(anchored) @@ -409,6 +411,15 @@ glass_type = /obj/item/stack/sheet/plasmaglass rad_insulation = RAD_NO_INSULATION +/obj/structure/window/plasma/spawnDebris(location) + . = list() + . += new /obj/item/shard/plasma(location) + . += new /obj/effect/decal/cleanable/glass/plasma(location) + if (reinf) + . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) + if (fulltile) + . += new /obj/item/shard/plasma(location) + /obj/structure/window/plasma/spawner/east dir = EAST diff --git a/code/game/say.dm b/code/game/say.dm index 0788310038..4ce1d3c710 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(freqtospan, list( return if(message == "" || !message) return - spans |= get_spans() + spans |= speech_span if(!language) language = get_default_language() send_speech(message, 7, src, , spans, message_language=language) @@ -40,10 +40,6 @@ GLOBAL_LIST_INIT(freqtospan, list( var/atom/movable/AM = _AM AM.Hear(rendered, src, message_language, message, , spans, message_mode) -//To get robot span classes, stuff like that. -/atom/movable/proc/get_spans() - return list() - /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE) //This proc uses text() because it is faster than appending strings. Thanks BYOND. //Basic span @@ -87,7 +83,7 @@ GLOBAL_LIST_INIT(freqtospan, list( else return verb_say -/atom/movable/proc/say_quote(input, list/spans=list(), message_mode) +/atom/movable/proc/say_quote(input, list/spans=list(speech_span), message_mode) if(!input) input = "..." @@ -97,7 +93,7 @@ GLOBAL_LIST_INIT(freqtospan, list( var/spanned = attach_spans(input, spans) return "[say_mod(input, message_mode)][spanned ? ", \"[spanned]\"" : ""]" // Citadel edit [spanned ? ", \"[spanned]\"" : ""]" - + /atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode) if(has_language(language)) var/atom/movable/AM = speaker.GetSource() diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index cff219c63e..f6d234b346 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -272,7 +272,7 @@ return 0 if(ishuman(C) && (lube&NO_SLIP_WHEN_WALKING)) var/mob/living/carbon/human/H = C - if(!H.sprinting && H.getStaminaLoss() >= 20) + if(!H.sprinting && H.getStaminaLoss() <= 20) return 0 if(!(lube&SLIDE_ICE)) to_chat(C, "You slipped[ O ? " on the [O.name]" : ""]!") diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index b00efc7ed6..194014b61a 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -236,6 +236,10 @@ return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 33) if(RCD_WINDOWGRILLE) return list("mode" = RCD_WINDOWGRILLE, "delay" = 10, "cost" = 4) + if(RCD_MACHINE) + return list("mode" = RCD_MACHINE, "delay" = 20, "cost" = 25) + if(RCD_COMPUTER) + return list("mode" = RCD_COMPUTER, "delay" = 20, "cost" = 25) return FALSE /turf/open/floor/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) @@ -274,4 +278,20 @@ var/obj/structure/grille/G = new(src) G.anchored = TRUE return TRUE + if(RCD_MACHINE) + if(locate(/obj/structure/frame/machine) in src) + return FALSE + var/obj/structure/frame/machine/M = new(src) + M.state = 2 + M.icon_state = "box_1" + M.anchored = TRUE + return TRUE + if(RCD_COMPUTER) + if(locate(/obj/structure/frame/computer) in src) + return FALSE + var/obj/structure/frame/computer/C = new(src) + C.anchored = TRUE + C.setDir(the_rcd.computer_dir) + return TRUE + return FALSE diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index bff955086c..253a6ead90 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -144,6 +144,7 @@ barefootstep = FOOTSTEP_HARD_BAREFOOT clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY + var/dropped_brass var/uses_overlay = TRUE var/obj/effect/clockwork/overlay/floor/realappearence @@ -201,7 +202,10 @@ return /turf/open/floor/clockwork/crowbar_act(mob/living/user, obj/item/I) - if(baseturfs == type) + if(islist(baseturfs)) + if(type in baseturfs) + return TRUE + else if(baseturfs == type) return TRUE user.visible_message("[user] begins slowly prying up [src]...", "You begin painstakingly prying up [src]...") if(I.use_tool(src, user, 70, volume=80)) @@ -210,7 +214,14 @@ return TRUE /turf/open/floor/clockwork/make_plating() - new /obj/item/stack/tile/brass(src) + if(!dropped_brass) + new /obj/item/stack/tile/brass(src) + dropped_brass = TRUE + if(islist(baseturfs)) + if(type in baseturfs) + return + else if(baseturfs == type) + return return ..() /turf/open/floor/clockwork/narsie_act() diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index dfc6972578..8b63d60939 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -7,6 +7,7 @@ smooth = SMOOTH_MORE sheet_type = /obj/item/stack/sheet/runed_metal sheet_amount = 1 + explosion_block = 10 girder_type = /obj/structure/girder/cult /turf/closed/wall/mineral/cult/Initialize() @@ -49,7 +50,7 @@ /turf/closed/wall/clockwork name = "clockwork wall" desc = "A huge chunk of warm metal. The clanging of machinery emanates from within." - explosion_block = 2 + explosion_block = 5 hardness = 10 slicing_duration = 80 sheet_type = /obj/item/stack/tile/brass diff --git a/code/game/world.dm b/code/game/world.dm index dedf822597..e9c8433006 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -137,7 +137,7 @@ GLOBAL_VAR(restart_counter) // but those are both private, so let's put the commit info in the runtime // log which is ultimately public. log_runtime(GLOB.revdata.get_log_message()) - + /world/Topic(T, addr, master, key) TGS_TOPIC //redirect to server tools if necessary @@ -270,7 +270,8 @@ GLOBAL_VAR(restart_counter) if (M.client) n++ - features += "[SSmapping.config.map_name]" //CIT CHANGE - makes the hub entry display the current map + if(SSmapping.config) // this just stops the runtime, honk. + features += "[SSmapping.config.map_name]" //CIT CHANGE - makes the hub entry display the current map if(get_security_level())//CIT CHANGE - makes the hub entry show the security level features += "[get_security_level()] alert" diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 4e342f6ced..89e9c33ecc 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -54,12 +54,16 @@ only_current_user_can_interact = TRUE /obj/machinery/vr_sleeper/hugbox/emag_act(mob/user) - return + return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) /obj/machinery/vr_sleeper/emag_act(mob/user) + . = ..() + if(you_die_in_the_game_you_die_for_real) + return you_die_in_the_game_you_die_for_real = TRUE sparks.start() addtimer(CALLBACK(src, .proc/emagNotify), 150) + return TRUE /obj/machinery/vr_sleeper/update_icon() icon_state = "[initial(icon_state)][state_open ? "-open" : ""]" @@ -164,8 +168,11 @@ vr_human.name = H.name vr_human.real_name = H.real_name vr_human.socks = H.socks + vr_human.socks_color = H.socks_color vr_human.undershirt = H.undershirt + vr_human.shirt_color = H.shirt_color vr_human.underwear = H.underwear + vr_human.undie_color = H.undie_color vr_human.updateappearance(TRUE, TRUE, TRUE) vr_human.give_genitals(TRUE) //CITADEL ADD if(outfit) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 8e1926115f..ae6482abbd 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -4,7 +4,7 @@ var/F = file("[GLOB.log_directory]/[subject].html") WRITE_FILE(F, "[TIME_STAMP("hh:mm:ss", FALSE)] [REF(src)] ([x],[y],[z]) || [src] [message]
    ") -/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) ) +/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) ) set name = "Investigate" set category = "Admin" if(!holder) diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index a97c0bf116..8b824f8fb0 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -78,13 +78,13 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/notify name = "notify" help_text = "Pings the invoker when the round ends" - admin_only = TRUE + admin_only = FALSE /datum/tgs_chat_command/notify/Run(datum/tgs_chat_user/sender, params) if(!SSticker.IsRoundInProgress() && SSticker.HasRoundStarted()) return "[sender.mention], the round has already ended!" LAZYINITLIST(GLOB.round_end_notifiees) - GLOB.round_end_notifiees[sender.mention] = TRUE + GLOB.round_end_notifiees["<@[sender.mention]>"] = TRUE return "I will notify [sender.mention] when the round ends." /datum/tgs_chat_command/sdql @@ -140,4 +140,4 @@ GLOBAL_LIST(round_end_notifiees) log_admin("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") message_admins("[sender.friendly_name] has added [params] to the current round's bunker bypass list.") - return "[params] has been added to the current round's bunker bypass list." \ No newline at end of file + return "[params] has been added to the current round's bunker bypass list." diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 73b8fa61f0..f66cda42dc 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -15,6 +15,9 @@ H.real_name = random_unique_name(H.gender) H.name = H.real_name H.underwear = random_underwear(H.gender) + H.undie_color = random_short_color() + H.undershirt = random_undershirt(H.gender) + H.shirt_color = random_short_color() H.skin_tone = random_skin_tone() H.hair_style = random_hair_style(H.gender) H.facial_hair_style = random_facial_hair_style(H.gender) @@ -26,8 +29,8 @@ // Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant. H.dna.features["mcolor"] = random_short_color() H.dna.features["tail_lizard"] = pick(GLOB.tails_list_lizard) - H.dna.features["snout"] = pick(GLOB.snouts_list) - H.dna.features["horns"] = pick(GLOB.horns_list) + H.dna.features["snout"] = pick(GLOB.snouts_list) + H.dna.features["horns"] = pick(GLOB.horns_list) H.dna.features["frills"] = pick(GLOB.frills_list) H.dna.features["spines"] = pick(GLOB.spines_list) H.dna.features["body_markings"] = pick(GLOB.body_markings_list) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 66358dc080..7d74387c43 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -422,7 +422,7 @@ H.equip_to_slot_or_del(I, SLOT_W_UNIFORM) qdel(olduniform) if(droptype == "Yes") - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, ADMIN_TRAIT) else to_chat(H, "You're not kawaii enough for this.") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 6fa118ab7f..d881044757 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1882,14 +1882,14 @@ return var/mob/M = locate(href_list["CentComReply"]) - usr.client.admin_headset_message(M, "CentCom") + usr.client.admin_headset_message(M, RADIO_CHANNEL_CENTCOM) else if(href_list["SyndicateReply"]) if(!check_rights(R_ADMIN)) return var/mob/M = locate(href_list["SyndicateReply"]) - usr.client.admin_headset_message(M, "Syndicate") + usr.client.admin_headset_message(M, RADIO_CHANNEL_SYNDICATE) else if(href_list["HeadsetMessage"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 84e5ba4f82..5f3153d90f 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -6,7 +6,7 @@ set category = null set name = "Admin PM Mob" if(!holder) - to_chat(src, "Error: Admin-PM-Context: Only administrators may use this command.") + to_chat(src, "Error: Admin-PM-Context: Only administrators may use this command.") return if( !ismob(M) || !M.client ) return @@ -18,7 +18,7 @@ set category = "Admin" set name = "Admin PM" if(!holder) - to_chat(src, "Error: Admin-PM-Panel: Only administrators may use this command.") + to_chat(src, "Error: Admin-PM-Panel: Only administrators may use this command.") return var/list/client/targets[0] for(var/client/T) @@ -37,7 +37,7 @@ /client/proc/cmd_ahelp_reply(whom) if(prefs.muted & MUTE_ADMINHELP) - to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") + to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") return var/client/C if(istext(whom)) @@ -48,7 +48,7 @@ C = whom if(!C) if(holder) - to_chat(src, "Error: Admin-PM: Client not found.") + to_chat(src, "Error: Admin-PM: Client not found.") return var/datum/admin_help/AH = C.current_ticket @@ -65,12 +65,12 @@ //Fetching a message if needed. src is the sender and C is the target client /client/proc/cmd_admin_pm(whom, msg) if(prefs.muted & MUTE_ADMINHELP) - to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") + to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") return if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo - to_chat(src, "You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.") - to_chat(src, "Message: [msg]") + to_chat(src, "You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.") + to_chat(src, "Message: [msg]") return var/client/recipient @@ -95,14 +95,14 @@ if(!msg) return if(holder) - to_chat(src, "Error: Use the admin IRC channel, nerd.") + to_chat(src, "Error: Use the admin IRC channel, nerd.") return else if(!recipient) if(holder) - to_chat(src, "Error: Admin-PM: Client not found.") + to_chat(src, "Error: Admin-PM: Client not found.") if(msg) to_chat(src, msg) return @@ -118,12 +118,12 @@ return if(prefs.muted & MUTE_ADMINHELP) - to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") + to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).") return if(!recipient) if(holder) - to_chat(src, "Error: Admin-PM: Client not found.") + to_chat(src, "Error: Admin-PM: Client not found.") else current_ticket.MessageNoRecipient(msg) return @@ -145,15 +145,15 @@ var/keywordparsedmsg = keywords_lookup(msg) if(irc) - to_chat(src, "PM to-Admins: [rawmsg]") + to_chat(src, "PM to-Admins: [rawmsg]") var/datum/admin_help/AH = admin_ticket_log(src, "Reply PM from-[key_name(src, TRUE, TRUE)] to IRC: [keywordparsedmsg]") ircreplyamount-- send2irc("[AH ? "#[AH.id] " : ""]Reply: [ckey]", rawmsg) else if(recipient.holder) if(holder) //both are admins - to_chat(recipient, "Admin PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]") - to_chat(src, "Admin PM to-[key_name(recipient, src, 1)]: [keywordparsedmsg]") + to_chat(recipient, "Admin PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]") + to_chat(src, "Admin PM to-[key_name(recipient, src, 1)]: [keywordparsedmsg]") //omg this is dumb, just fill in both their tickets var/interaction_message = "PM from-[key_name(src, recipient, 1)] to-[key_name(recipient, src, 1)]: [keywordparsedmsg]" @@ -162,10 +162,10 @@ admin_ticket_log(recipient, interaction_message) else //recipient is an admin but sender is not - var/replymsg = "Reply PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]" - admin_ticket_log(src, replymsg) - to_chat(recipient, replymsg) - to_chat(src, "PM to-Admins: [msg]") + var/replymsg = "Reply PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]" + admin_ticket_log(src, "[replymsg]") + to_chat(recipient, "[replymsg]") + to_chat(src, "PM to-Admins: [msg]") //play the receiving admin the adminhelp sound (if they have them enabled) if(recipient.prefs.toggles & SOUND_ADMINHELP) @@ -177,11 +177,11 @@ new /datum/admin_help(msg, recipient, TRUE) to_chat(recipient, "-- Administrator private message --") - to_chat(recipient, "Admin PM from-[key_name(src, recipient, 0)]: [msg]") - to_chat(recipient, "Click on the administrator's name to reply.") - to_chat(src, "Admin PM to-[key_name(recipient, src, 1)]: [msg]") + to_chat(recipient, "Admin PM from-[key_name(src, recipient, 0)]: [msg]") + to_chat(recipient, "Click on the administrator's name to reply.") + to_chat(src, "Admin PM to-[key_name(recipient, src, 1)]: [msg]") - admin_ticket_log(recipient, "PM From [key_name_admin(src)]: [keywordparsedmsg]") + admin_ticket_log(recipient, "PM From [key_name_admin(src)]: [keywordparsedmsg]") //always play non-admin recipients the adminhelp sound SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg')) @@ -200,20 +200,20 @@ return else //neither are admins - to_chat(src, "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.") + to_chat(src, "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.") return if(irc) log_admin_private("PM: [key_name(src)]->IRC: [rawmsg]") for(var/client/X in GLOB.admins) - to_chat(X, "PM: [key_name(src, X, 0)]->IRC: [keywordparsedmsg]") + to_chat(X, "PM: [key_name(src, X, 0)]->IRC: [keywordparsedmsg]") else window_flash(recipient, ignorepref = TRUE) log_admin_private("PM: [key_name(src)]->[key_name(recipient)]: [rawmsg]") //we don't use message_admins here because the sender/receiver might get it too for(var/client/X in GLOB.admins) if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipient - to_chat(X, "PM: [key_name(src, X, 0)]->[key_name(recipient, X, 0)]: [keywordparsedmsg]" ) + to_chat(X, "PM: [key_name(src, X, 0)]->[key_name(recipient, X, 0)]: [keywordparsedmsg]" ) @@ -296,10 +296,10 @@ msg = emoji_parse(msg) to_chat(C, "-- Administrator private message --") - to_chat(C, "Admin PM from-[adminname]: [msg]") - to_chat(C, "Click on the administrator's name to reply.") + to_chat(C, "Admin PM from-[adminname]: [msg]") + to_chat(C, "Click on the administrator's name to reply.") - admin_ticket_log(C, "PM From [irc_tagged]: [msg]") + admin_ticket_log(C, "PM From [irc_tagged]: [msg]") window_flash(C, ignorepref = TRUE) //always play non-admin recipients the adminhelp sound diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index 6295d4be43..c0445d588d 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -62,7 +62,7 @@ .["laws"] = borg.laws ? borg.laws.get_law_list(include_zeroth = TRUE) : list() .["channels"] = list() for (var/k in GLOB.radiochannels) - if (k == "Common") + if (k == RADIO_CHANNEL_COMMON) continue .["channels"] += list(list("name" = k, "installed" = (k in borg.radio.channels))) .["cell"] = borg.cell ? list("missing" = FALSE, "maxcharge" = borg.cell.maxcharge, "charge" = borg.cell.charge) : list("missing" = TRUE, "maxcharge" = 1, "charge" = 0) @@ -164,15 +164,15 @@ if (channel in borg.radio.channels) // We're removing a channel if (!borg.radio.keyslot) // There's no encryption key. This shouldn't happen but we can cope borg.radio.channels -= channel - if (channel == "Syndicate") + if (channel == RADIO_CHANNEL_SYNDICATE) borg.radio.syndie = FALSE - else if (channel == "CentCom") + else if (channel == RADIO_CHANNEL_CENTCOM) borg.radio.independent = FALSE else borg.radio.keyslot.channels -= channel - if (channel == "Syndicate") + if (channel == RADIO_CHANNEL_SYNDICATE) borg.radio.keyslot.syndie = FALSE - else if (channel == "CentCom") + else if (channel == RADIO_CHANNEL_CENTCOM) borg.radio.keyslot.independent = FALSE message_admins("[key_name_admin(user)] removed the [channel] radio channel from [ADMIN_LOOKUPFLW(borg)].") log_admin("[key_name(user)] removed the [channel] radio channel from [key_name(borg)].") @@ -180,9 +180,9 @@ if (!borg.radio.keyslot) // Assert that an encryption key exists borg.radio.keyslot = new (borg.radio) borg.radio.keyslot.channels[channel] = 1 - if (channel == "Syndicate") + if (channel == RADIO_CHANNEL_SYNDICATE) borg.radio.keyslot.syndie = TRUE - else if (channel == "CentCom") + else if (channel == RADIO_CHANNEL_CENTCOM) borg.radio.keyslot.independent = TRUE message_admins("[key_name_admin(user)] added the [channel] radio channel to [ADMIN_LOOKUPFLW(borg)].") log_admin("[key_name(user)] added the [channel] radio channel to [key_name(borg)].") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index f74b31760d..a725399b0f 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -65,7 +65,7 @@ return if (!sender) - sender = input("Who is the message from?", "Sender") as null|anything in list("CentCom","Syndicate") + sender = input("Who is the message from?", "Sender") as null|anything in list(RADIO_CHANNEL_CENTCOM,RADIO_CHANNEL_SYNDICATE) if(!sender) return @@ -298,7 +298,7 @@ if(candidates.len) ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates else - to_chat(usr, "Error: create_xeno(): no suitable candidates.") + to_chat(usr, "Error: create_xeno(): no suitable candidates.") if(!istext(ckey)) return 0 diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 8e29b38fe1..0fca957ffe 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -56,6 +56,7 @@ /datum/antagonist/abductor/greet() to_chat(owner.current, "You are the [owner.special_role]!") to_chat(owner.current, "With the help of your teammate, kidnap and experiment on station crew members!") + to_chat(owner.current, "Try not to disturb the habitat, it could lead to dead specimens.") to_chat(owner.current, "[greet_text]") owner.announce_objectives() diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index ca491d8cab..1573204d88 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -30,9 +30,12 @@ var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90) /obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop() - item_flags ^= NODROP + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)) + REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) + else + ADD_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) if(ismob(loc)) - to_chat(loc, "Your vest is now [item_flags & NODROP ? "locked" : "unlocked"].") + to_chat(loc, "Your vest is now [HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "locked" : "unlocked"].") /obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode() switch(mode) diff --git a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm index e2b881d147..a69c8fdeff 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm @@ -17,7 +17,7 @@ var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H if(V) console.AddVest(V) - V.item_flags |= NODROP + ADD_TRAIT(V, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) var/obj/item/storage/backpack/B = locate() in H if(B) diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index 52bda50b86..46d69ba9bb 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -75,7 +75,7 @@ dat+="
    " dat += "Select Agent Vest Disguise
    " - dat += "[vest.item_flags & NODROP ? "Unlock" : "Lock"] Vest
    " + dat += "[HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "Unlock" : "Lock"] Vest
    " else dat += "NO AGENT VEST DETECTED" var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500) diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index e60209cb7b..3cb90d64bb 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -57,7 +57,7 @@ return ..() /mob/living/simple_animal/hostile/blob/proc/blob_chat(msg) - var/spanned_message = say_quote(msg, get_spans()) + var/spanned_message = say_quote(msg) var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]" for(var/M in GLOB.mob_list) if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob)) diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index ddf745c0f9..d32e38c194 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -210,7 +210,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) src.log_talk(message, LOG_SAY) - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "\[Blob Telepathy\] [name]([blob_reagent_datum.name]) [message_a]" for(var/mob/M in GLOB.mob_list) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 5b0be336ff..252e2b5cbe 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -269,8 +269,11 @@ prof.protected = protect prof.underwear = H.underwear + prof.undie_color = H.undie_color prof.undershirt = H.undershirt + prof.shirt_color = H.shirt_color prof.socks = H.socks + prof.socks_color = H.socks_color var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store") for(var/slot in slots) @@ -350,7 +353,7 @@ /datum/antagonist/changeling/greet() if (you_are_greet) to_chat(owner.current, "You are [changelingID], a changeling! You have absorbed and taken the form of a human.") - to_chat(owner.current, "Use say \":g message\" to communicate with your fellow changelings.") + to_chat(owner.current, "Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with your fellow changelings.") to_chat(owner.current, "You must complete the following tasks:") owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE) @@ -503,8 +506,11 @@ var/list/item_state_list = list() var/underwear + var/undie_color var/undershirt + var/shirt_color var/socks + var/socks_color /datum/changelingprofile/Destroy() qdel(dna) diff --git a/code/modules/antagonists/changeling/powers/hivemind.dm b/code/modules/antagonists/changeling/powers/hivemind.dm index 1d7382d947..f7718d7708 100644 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ b/code/modules/antagonists/changeling/powers/hivemind.dm @@ -1,8 +1,8 @@ -//HIVEMIND COMMUNICATION (:g) +//HIVEMIND COMMUNICATION //MODE_TOKEN_CHANGELING / :g /obj/effect/proc_holder/changeling/hivemind_comms name = "Hivemind Communication" desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings." - helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." + helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." //MODE_TOKEN_CHANGELING needs to be manually updated here. dna_cost = 1 chemical_cost = -1 action_icon = 'icons/mob/actions/actions_xeno.dmi' @@ -20,7 +20,7 @@ ..() var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.changeling_speak = 1 - to_chat(user, "Use say \":g message\" to communicate with the other changelings.") + to_chat(user, "Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with the other changelings.") var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new if(!changeling.has_sting(S1)) changeling.purchasedpowers+=S1 diff --git a/code/modules/antagonists/changeling/powers/linglink.dm b/code/modules/antagonists/changeling/powers/linglink.dm index 70df78e3b4..971c811074 100644 --- a/code/modules/antagonists/changeling/powers/linglink.dm +++ b/code/modules/antagonists/changeling/powers/linglink.dm @@ -56,8 +56,8 @@ if(M.lingcheck() == LINGHIVE_LING) to_chat(M, "We can sense a foreign presence in the hivemind...") target.mind.linglink = 1 - target.say(":g AAAAARRRRGGGGGHHHHH!!") - to_chat(target, "You can now communicate in the changeling hivemind, say \":g message\" to communicate!") + target.say("[MODE_TOKEN_CHANGELING] AAAAARRRRGGGGGHHHHH!!") + to_chat(target, "You can now communicate in the changeling hivemind, say \"[MODE_TOKEN_CHANGELING] message\" to communicate!") target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them sleep(1800) SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]")) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index ede3c2fc58..c428c56d45 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -155,20 +155,23 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 25 throwforce = 0 //Just to be on the safe side throw_range = 0 throw_speed = 0 + armour_penetration = 20 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = IS_SHARP var/can_drop = FALSE var/fake = FALSE + total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/melee/arm_blade/Initialize(mapload,silent,synthetic) . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc) && !silent) loc.visible_message("A grotesque blade forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!") if(synthetic) @@ -242,7 +245,8 @@ item_state = "tentacle" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL | NOBLUDGEON + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL | NOBLUDGEON + slot_flags = NONE flags_1 = NONE w_class = WEIGHT_CLASS_HUGE ammo_type = /obj/item/ammo_casing/magic/tentacle @@ -256,6 +260,7 @@ /obj/item/gun/magic/tentacle/Initialize(mapload, silent) . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) if(!silent) loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!") @@ -427,7 +432,7 @@ /obj/item/shield/changeling name = "shield-like mass" desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield." - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL icon = 'icons/obj/items_and_weapons.dmi' icon_state = "ling_shield" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' @@ -438,6 +443,7 @@ /obj/item/shield/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!", "We inflate our hand into a strong shield.", "You hear organic matter ripping and tearing!") @@ -479,13 +485,14 @@ name = "flesh mass" icon_state = "lingspacesuit" desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." - item_flags = NODROP | DROPDEL + item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/oxygen) armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) //No armor at all. /obj/item/clothing/suit/space/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around [loc.p_their()] body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!") START_PROCESSING(SSobj, src) @@ -499,11 +506,15 @@ name = "flesh mass" icon_state = "lingspacehelmet" desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." - item_flags = NODROP | DROPDEL + item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH +/obj/item/clothing/head/helmet/space/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + /***************************************\ |*****************ARMOR*****************| \***************************************/ @@ -529,7 +540,7 @@ name = "chitinous mass" desc = "A tough, hard covering of black chitin." icon_state = "lingarmor" - item_flags = NODROP | DROPDEL + item_flags = DROPDEL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90) flags_inv = HIDEJUMPSUIT @@ -538,6 +549,7 @@ /obj/item/clothing/suit/armor/changeling/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) loc.visible_message("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!", "We harden our flesh, creating a suit of armor!", "You hear organic matter ripping and tearing!") @@ -545,6 +557,10 @@ name = "chitinous mass" desc = "A tough, hard covering of black chitin with transparent chitin in front." icon_state = "lingarmorhelmet" - item_flags = NODROP | DROPDEL + item_flags = DROPDEL armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90) flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE + +/obj/item/clothing/head/helmet/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index baeed8b0b2..bdbd38b92d 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -5,7 +5,7 @@ name = "Strained Muscles" desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster." helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form." - chemical_cost = 0 + chemical_cost = 15 dna_cost = 1 req_human = 1 var/stacks = 0 //Increments every 5 seconds; damage increases over time @@ -15,13 +15,16 @@ action_background_icon_state = "bg_ling" /obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) active = !active if(active) to_chat(user, "Our muscles tense and strengthen.") + changeling.chem_recharge_slowdown += 0.5 else REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles") to_chat(user, "Our muscles relax.") - if(stacks >= 10) + changeling.chem_recharge_slowdown -= 0.5 + if(stacks >= 20) to_chat(user, "We collapse in exhaustion.") user.Knockdown(60) user.emote("gasp") @@ -42,9 +45,9 @@ stacks++ //user.take_bodypart_damage(stacks * 0.03, 0) - user.staminaloss += stacks * 1.3 //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack + user.adjustStaminaLoss(stacks*1.3) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack - if(stacks == 11) //Warning message that the stacks are getting too high + if(stacks == 10) //Warning message that the stacks are getting too high to_chat(user, "Our legs are really starting to hurt...") sleep(40) diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 5a701d8a96..c58d934d6d 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -62,13 +62,13 @@ /obj/effect/proc_holder/changeling/sting/transformation - name = "Transformation Sting" - desc = "We silently sting a human, injecting a retrovirus that forces them to transform." - helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human. This ability is loud, and might cause our blood to react violently to heat." + name = "Temporary Transformation Sting" + desc = "We silently sting a human, injecting a chemical that forces them to transform into a chosen being for a limited time. Additional stings extend the duration." + helptext = "The victim will transform much like a changeling would for a limited time. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human. This ability is loud, and might cause our blood to react violently to heat." sting_icon = "sting_transform" - chemical_cost = 50 - dna_cost = 3 - loudness = 2 + chemical_cost = 10 + dna_cost = 2 + loudness = 1 var/datum/changelingprofile/selected_dna = null action_icon = 'icons/mob/actions/actions_changeling.dmi' action_icon_state = "ling_sting_transform" @@ -97,19 +97,19 @@ return 1 /obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target) - log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") - var/datum/dna/NewDNA = selected_dna.dna + if(ismonkey(target)) to_chat(user, "Our genes cry out as we sting [target.name]!") var/mob/living/carbon/C = target . = TRUE if(istype(C)) - C.real_name = NewDNA.real_name - NewDNA.transfer_identity(C) - if(ismonkey(C)) - C.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) - C.updateappearance(mutcolor_update=1) + if(C.reagents.has_reagent("changeling_sting_real")) + C.reagents.add_reagent("changeling_sting_real",120) + log_combat(user, target, "stung", "transformation sting", ", extending the duration.") + else + C.reagents.add_reagent("changeling_sting_real",120,list("desired_dna" = selected_dna.dna)) + log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") /obj/effect/proc_holder/changeling/sting/false_armblade @@ -230,24 +230,23 @@ /obj/effect/proc_holder/changeling/sting/LSD name = "Hallucination Sting" - desc = "Causes terror in the target." - helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect begins after a few seconds." + desc = "Causes terror in the target and deals a minor amount of toxin damage." + helptext = "We evolve the ability to sting a target with a powerful toxic hallucinogenic chemical. The target does not notice they have been stung, and the effect begins instantaneously. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." sting_icon = "sting_lsd" chemical_cost = 10 dna_cost = 1 + loudness = 1 action_icon = 'icons/mob/actions/actions_changeling.dmi' action_icon_state = "ling_sting_lsd" action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/living/carbon/target) +/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/target) log_combat(user, target, "stung", "LSD sting") - addtimer(CALLBACK(src, .proc/hallucination_time, target), rand(100,200)) + if(target.reagents) + target.reagents.add_reagent("regenerative_materia", 5) + target.reagents.add_reagent("mindbreaker", 5) return TRUE -/obj/effect/proc_holder/changeling/sting/LSD/proc/hallucination_time(mob/living/carbon/target) - if(target) - target.hallucination = max(90, target.hallucination) - /obj/effect/proc_holder/changeling/sting/cryo name = "Cryogenic Sting" desc = "We silently sting a human with a cocktail of chemicals that freeze them." diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index 767c7d2621..795ba772d6 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -11,7 +11,11 @@ /obj/item/clothing/glasses/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/glasses/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/glasses/changeling/attack_hand(mob/user) @@ -23,7 +27,11 @@ /obj/item/clothing/under/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/under/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/under/changeling/attack_hand(mob/user) @@ -35,9 +43,13 @@ /obj/item/clothing/suit/changeling name = "flesh" - item_flags = NODROP allowed = list(/obj/item/changeling) +/obj/item/clothing/suit/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/suit/changeling/attack_hand(mob/user) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) @@ -48,7 +60,10 @@ /obj/item/clothing/head/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/head/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/head/changeling/attack_hand(mob/user) @@ -60,7 +75,11 @@ /obj/item/clothing/shoes/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/shoes/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/shoes/changeling/attack_hand(mob/user) @@ -72,7 +91,11 @@ /obj/item/clothing/gloves/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/gloves/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/gloves/changeling/attack_hand(mob/user) @@ -84,7 +107,11 @@ /obj/item/clothing/mask/changeling name = "flesh" - item_flags = NODROP + +/obj/item/clothing/mask/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clothing/mask/changeling/attack_hand(mob/user) @@ -96,10 +123,14 @@ /obj/item/changeling name = "flesh" - item_flags = NODROP slot_flags = ALL allowed = list(/obj/item/changeling) +/obj/item/changeling/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) + + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/changeling/attack_hand(mob/user) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm index ea2ec4d6ef..5cf7ab7923 100644 --- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm +++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm @@ -133,6 +133,9 @@ return FALSE if(!uses) return FALSE + if(!do_teleport(A, get_turf(linked_gateway), channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) + visible_message("[A] bounces off [src]!") + return FALSE if(isliving(A)) var/mob/living/user = A to_chat(user, "You pass through [src] and appear elsewhere!") @@ -141,7 +144,6 @@ playsound(linked_gateway, 'sound/effects/empulse.ogg', 50, 1) transform = matrix() * 1.5 linked_gateway.transform = matrix() * 1.5 - A.forceMove(get_turf(linked_gateway)) if(!no_cost) uses = max(0, uses - 1) linked_gateway.uses = max(0, linked_gateway.uses - 1) diff --git a/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm b/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm index 530c4c5662..23caa788d4 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm @@ -67,6 +67,7 @@ name = "replicant manacles" desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid." icon_state = "brass_manacles" + item_state = "brass_manacles" item_flags = DROPDEL /obj/item/restraints/handcuffs/clockwork/dropped(mob/user) diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index 277aeca48d..0ac96c47f9 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -21,17 +21,17 @@ /obj/item/clothing/head/helmet/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = list("melee" = 70, "bullet" = 80, "laser" = -15, "energy" = 25, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -69,7 +69,7 @@ heat_protection = CHEST|GROIN|LEGS resistance_flags = FIRE_PROOF | ACID_PROOF armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel) + allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil) /obj/item/clothing/suit/armor/clockwork/Initialize() . = ..() @@ -82,17 +82,17 @@ /obj/item/clothing/suit/armor/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = list("melee" = 70, "bullet" = 80, "laser" = -15, "energy" = 25, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -148,12 +148,12 @@ /obj/item/clothing/gloves/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = list("melee" = 80, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = getArmor(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 30c84f5312..12af249bee 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -21,8 +21,9 @@ /obj/item/clockwork/construct_chassis/Destroy() GLOB.poi_list -= src - var/list/spawners = GLOB.mob_spawners[name] - LAZYREMOVE(spawners, src) + LAZYREMOVE(GLOB.mob_spawners[name], src) + if(!LAZYLEN(GLOB.mob_spawners[name])) + GLOB.mob_spawners -= name . = ..() /obj/item/clockwork/construct_chassis/examine(mob/user) diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm index bd9c52b19f..6268d15d44 100644 --- a/code/modules/antagonists/clockcult/clock_mobs.dm +++ b/code/modules/antagonists/clockcult/clock_mobs.dm @@ -19,6 +19,7 @@ bubble_icon = "clock" light_color = "#E42742" death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' + speech_span = SPAN_ROBOT var/playstyle_string = "You are a bug, yell at whoever spawned you!" var/empower_string = "You have nothing to empower, yell at the coders!" //Shown to the mob when the herald beacon activates @@ -26,9 +27,6 @@ . = ..() update_values() -/mob/living/simple_animal/hostile/clockwork/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/hostile/clockwork/Login() ..() add_servant_of_ratvar(src, TRUE) diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm index 552a747651..6d6b1fa9d0 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm @@ -27,7 +27,7 @@ to_chat(invoker, "Stargazers can't be built off-station.") return return ..() - + //Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power. /datum/clockwork_scripture/create_object/integration_cog @@ -224,12 +224,14 @@ . = ..() /datum/clockwork_scripture/abscond/scripture_effects() - var/take_pulling = invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST) + var/mob/living/pulled_mob = (invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)) ? invoker.pulling : null var/turf/T if(GLOB.ark_of_the_clockwork_justiciar) T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH) else T = get_turf(pick(GLOB.servant_spawns)) + if(!do_teleport(invoker, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) + return invoker.visible_message("[invoker] flickers and phases out of existence!", \ "You feel a dizzying sense of vertigo as you're yanked back to Reebe!") T.visible_message("[invoker] flickers and phases into existence!") @@ -237,10 +239,9 @@ playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE) do_sparks(5, TRUE, invoker) do_sparks(5, TRUE, T) - if(take_pulling) + if(pulled_mob && do_teleport(pulled_mob, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) adjust_clockwork_power(-special_power_cost) - invoker.pulling.forceMove(T) - invoker.forceMove(T) + invoker.start_pulling(pulled_mob) //forcemove resets pulls, so we need to re-pull if(invoker.client) animate(invoker.client, color = client_color, time = 25) diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm index 2b1d9d5f02..f735d6bb29 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -131,12 +131,10 @@ if(!M || !M.current) continue if(isliving(M.current) && M.current.stat != DEAD) - if(isAI(M.current)) - M.current.forceMove(get_step(get_step(src, NORTH),NORTH)) // AI too fat, must make sure it always ends up a 2 tiles north instead of on the ark. - else - M.current.forceMove(get_turf(src)) - M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash) - M.current.clear_fullscreen("flash", 5) + var/turf/t_turf = isAI(M.current) ? get_step(get_step(src, NORTH),NORTH) : get_turf(src) // AI too fat, must make sure it always ends up a 2 tiles north instead of on the ark. + do_teleport(M.current, t_turf, channel = TELEPORT_CHANNEL_CULT, forced = TRUE) + M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash) + M.current.clear_fullscreen("flash", 5) playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, FALSE) recalls_remaining-- recalling = FALSE diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 845c66fb33..1dbae4ca98 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -339,7 +339,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "disintegrate" item_state = null - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE throwforce = 0 @@ -350,11 +350,13 @@ var/health_cost = 0 //The amount of health taken from the user when invoking the spell var/datum/action/innate/cult/blood_spell/source -/obj/item/melee/blood_magic/New(loc, spell) +/obj/item/melee/blood_magic/Initialize(mapload, spell) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) source = spell uses = source.charges health_cost = source.health_cost - ..() + /obj/item/melee/blood_magic/Destroy() if(!QDELETED(source)) @@ -488,11 +490,12 @@ to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") return uses-- - user.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ - "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") + var/turf/origin = get_turf(user) var/mob/living/L = target - L.forceMove(dest) - dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) + origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ + "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") + dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") ..() //Shackles @@ -652,15 +655,15 @@ if(H.stat == DEAD) to_chat(user,"Only a revive rune can bring back the dead!") return - if(H.blood_volume < BLOOD_VOLUME_SAFE) - var/restore_blood = BLOOD_VOLUME_SAFE - H.blood_volume + if(H.blood_volume < (BLOOD_VOLUME_SAFE*H.blood_ratio)) + var/restore_blood = (BLOOD_VOLUME_SAFE*H.blood_ratio) - H.blood_volume if(uses*2 < restore_blood) H.blood_volume += uses*2 to_chat(user,"You use the last of your blood rites to restore what blood you could!") uses = 0 return ..() else - H.blood_volume = BLOOD_VOLUME_SAFE + H.blood_volume = (BLOOD_VOLUME_SAFE*H.blood_ratio) uses -= round(restore_blood/2) to_chat(user,"Your blood rites have restored [H == user ? "your" : "[H.p_their()]"] blood to safe levels!") var/overall_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss() @@ -695,7 +698,7 @@ if(H.cultslurring) to_chat(user,"[H.p_their(TRUE)] blood has been tainted by an even stronger form of blood magic, it's no use to us like this!") return - if(H.blood_volume > BLOOD_VOLUME_SAFE) + if(H.blood_volume > (BLOOD_VOLUME_SAFE*H.blood_ratio)) H.blood_volume -= 100 uses += 50 user.Beam(H,icon_state="drainbeam",time=10) @@ -796,4 +799,4 @@ to_chat(user, "Your hands glow with POWER OVERWHELMING!!!") else to_chat(user, "You need a free hand for this rite!") - qdel(rite) \ No newline at end of file + qdel(rite) diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 6bef6fd021..25e3663c0b 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -64,9 +64,14 @@ /obj/item/melee/cultblade/ghost name = "eldritch sword" force = 19 //can't break normal airlocks - item_flags = NEEDS_PERMIT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | DROPDEL flags_1 = NONE +/obj/item/melee/cultblade/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) + + /obj/item/melee/cultblade/pickup(mob/living/user) ..() if(!iscultist(user)) @@ -100,7 +105,6 @@ inhand_x_dimension = 64 inhand_y_dimension = 64 actions_types = list() - item_flags = SLOWS_WHILE_IN_HAND var/datum/action/innate/dash/cult/jaunt var/datum/action/innate/cult/spin2win/linked_action var/spinning = FALSE @@ -298,7 +302,12 @@ item_state = "cult_hoodalt" /obj/item/clothing/head/culthood/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/head/culthood/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) + /obj/item/clothing/suit/cultrobes/alt name = "cultist robes" @@ -307,7 +316,11 @@ item_state = "cultrobesalt" /obj/item/clothing/suit/cultrobes/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/suit/cultrobes/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/clothing/head/magus name = "magus helm" @@ -554,7 +567,7 @@ var/mob/living/carbon/C = user if(C.pulling) var/atom/movable/pulled = C.pulling - pulled.forceMove(T) + do_teleport(pulled, T, channel = TELEPORT_CHANNEL_CULT) . = pulled /obj/item/cult_shift/attack_self(mob/user) @@ -579,13 +592,12 @@ new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir) var/atom/movable/pulled = handle_teleport_grab(destination, C) - C.forceMove(destination) - if(pulled) - C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull - - new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir) - playsound(destination, 'sound/effects/phasein.ogg', 25, 1) - playsound(destination, "sparks", 50, 1) + if(do_teleport(C, destination, channel = TELEPORT_CHANNEL_CULT)) + if(pulled) + C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull + new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir) + playsound(destination, 'sound/effects/phasein.ogg', 25, 1) + playsound(destination, "sparks", 50, 1) else to_chat(C, "The veil cannot be torn here!") @@ -796,7 +808,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "disintegrate" item_state = null - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE throwforce = 0 throw_range = 0 @@ -805,6 +817,9 @@ var/firing = FALSE var/angle +/obj/item/blood_beam/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/blood_beam/afterattack(atom/A, mob/living/user, flag, params) . = ..() diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index 64d57c2f94..499d7a861e 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -188,7 +188,7 @@ var/mob/living/simple_animal/M = L if(M.health < M.maxHealth) M.adjustHealth(-3) - if(ishuman(L) && L.blood_volume < BLOOD_VOLUME_NORMAL) + if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio)) L.blood_volume += 1.0 CHECK_TICK if(last_corrupt <= world.time) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 2f3a039e70..29b4e4539c 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -61,8 +61,8 @@ Runes can either be invoked by one's self or with many different cultists. Each if(do_after(user, 15, target = src)) to_chat(user, "You carefully erase the [lowertext(cultist_name)] rune.") qdel(src) - else if(istype(I, /obj/item/nullrod)) - user.say("BEGONE FOUL MAGIKS!!", forced = "nullrod") + else if(istype(I, /obj/item/storage/book/bible) || istype(I, /obj/item/nullrod)) + user.say("BEGONE FOUL MAGICKS!!", forced = "bible") to_chat(user, "You disrupt the magic of [src] with [I].") qdel(src) @@ -244,13 +244,14 @@ structure_check() searches for nearby cultist structures required for the invoca to_chat(M, "Something is shielding [convertee]'s mind!") log_game("Offer rune failed - convertee had anti-magic") return 0 - to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ - and something evil takes root.") - to_chat(convertee, "Do you wish to embrace the Geometer of Blood? Click here to become a follower of Nar'sie. Or you could choose to continue resisting and suffer a fate worse than death...") + to_chat(convertee, "The world goes red. All at once you are aware of an evil, eldritch truth taking roots into your mind.\n\ + Click here to become a follower of Nar'sie, or suffer a fate worse than death.") + INVOKE_ASYNC(src, .proc/optinalert, convertee) currentconversionman = convertee - conversiontimeout = world.time + (10 SECONDS) - convertee.Stun(100) + conversiontimeout = world.time + (14 SECONDS) + convertee.Stun(140) ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune") + flash_color(convertee, list("#960000", "#960000", "#960000", rgb(0,0,0)), 50) conversionresult = FALSE while(world.time < conversiontimeout && convertee && !conversionresult) stoplag(1) @@ -283,6 +284,17 @@ structure_check() searches for nearby cultist structures required for the invoca H.cultslurring = 0 return 1 +/obj/effect/rune/convert/proc/optinalert(mob/living/convertee) + var/alert = alert(convertee, "Will you embrace the Geometer of Blood or perish in futile resistance?", "Choose your own fate", "Join the Blood Cult", "Suffer a horrible demise") + if(src && alert == "Join the Blood Cult") + signmeup(convertee) + +/obj/effect/rune/convert/proc/signmeup(mob/living/convertee) + if(currentconversionman == convertee) + conversionresult = TRUE + else + to_chat(convertee, "Your fate has already been set in stone.") + /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers, force_a_sac) var/mob/living/first_invoker = invokers[1] if(!first_invoker) @@ -335,11 +347,7 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/convert/Topic(href, href_list) if(href_list["signmeup"]) - if(currentconversionman == usr) - conversionresult = TRUE - else - to_chat(usr, "Your fate has already been set in stone.") - + signmeup(usr) /obj/effect/rune/empower cultist_name = "Empower" @@ -414,6 +422,7 @@ structure_check() searches for nearby cultist structures required for the invoca return var/movedsomething = FALSE var/moveuserlater = FALSE + var/movesuccess = FALSE for(var/atom/movable/A in T) if(ishuman(A)) new /obj/effect/temp_visual/dir_setting/cult/phase/out(T, A.dir) @@ -424,20 +433,26 @@ structure_check() searches for nearby cultist structures required for the invoca continue if(!A.anchored) movedsomething = TRUE - A.forceMove(target) + if(do_teleport(A, target, forceMove = TRUE, channel = TELEPORT_CHANNEL_CULT)) + movesuccess = TRUE if(movedsomething) ..() - visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.") - to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") if(moveuserlater) - user.forceMove(target) + if(do_teleport(user, target, channel = TELEPORT_CHANNEL_CULT)) + movesuccess = TRUE + if(movesuccess) + visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.") + to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") + else + to_chat(user, "You[moveuserlater ? "r vision blurs briefly, but nothing happens":" try send everything above the rune away, but the teleportation fails"].") if(is_mining_level(z) && !is_mining_level(target.z)) //No effect if you stay on lavaland actual_selected_rune.handle_portal("lava") else var/area/A = get_area(T) if(A.map_name == "Space") actual_selected_rune.handle_portal("space", T) - target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + if(movesuccess) + target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") else fail_invoke() diff --git a/code/modules/antagonists/disease/disease_disease.dm b/code/modules/antagonists/disease/disease_disease.dm index 21d0381982..b4b8ac0956 100644 --- a/code/modules/antagonists/disease/disease_disease.dm +++ b/code/modules/antagonists/disease/disease_disease.dm @@ -51,7 +51,7 @@ if(cures.len) return var/list/not_used = advance_cures.Copy() - cures = list(pick_n_take(not_used), pick_n_take(not_used)) + cures = list(pick(pick_n_take(not_used)), pick(pick_n_take(not_used))) // Get the cure name from the cure_id var/datum/reagent/D1 = GLOB.chemical_reagents_list[cures[1]] diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index 53f8aa2da1..bb24af4f7a 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -36,30 +36,42 @@ /datum/antagonist/ert/security // kinda handled by the base template but here for completion -/datum/antagonist/ert/security/red +/datum/antagonist/ert/security/amber outfit = /datum/outfit/ert/security/alert +/datum/antagonist/ert/security/red + outfit = /datum/outfit/ert/security/alert/red + /datum/antagonist/ert/engineer role = "Engineer" outfit = /datum/outfit/ert/engineer -/datum/antagonist/ert/engineer/red +/datum/antagonist/ert/engineer/amber outfit = /datum/outfit/ert/engineer/alert +/datum/antagonist/ert/engineer/red + outfit = /datum/outfit/ert/engineer/alert/red + /datum/antagonist/ert/medic role = "Medical Officer" outfit = /datum/outfit/ert/medic -/datum/antagonist/ert/medic/red +/datum/antagonist/ert/medic/amber outfit = /datum/outfit/ert/medic/alert +/datum/antagonist/ert/medic/red + outfit = /datum/outfit/ert/medic/alert/red + /datum/antagonist/ert/commander role = "Commander" outfit = /datum/outfit/ert/commander -/datum/antagonist/ert/commander/red +/datum/antagonist/ert/commander/amber outfit = /datum/outfit/ert/commander/alert +/datum/antagonist/ert/commander/red + outfit = /datum/outfit/ert/commander/alert/red + /datum/antagonist/ert/deathsquad name = "Deathsquad Trooper" outfit = /datum/outfit/death_commando diff --git a/code/modules/antagonists/greybois/greybois.dm b/code/modules/antagonists/greybois/greybois.dm new file mode 100644 index 0000000000..b5e18045e8 --- /dev/null +++ b/code/modules/antagonists/greybois/greybois.dm @@ -0,0 +1,23 @@ +/datum/antagonist/greybois + name = "Emergency Assistant" + show_name_in_check_antagonists = TRUE + show_in_antagpanel = FALSE + var/mission = "Assist the station." + var/datum/outfit/outfit = /datum/outfit/ert/greybois + +/datum/antagonist/greybois/greygod + outfit = /datum/outfit/ert/greybois/greygod + +/datum/antagonist/greybois/greet() + to_chat(owner, "You are an Emergency Assistant.") + to_chat(owner, "Central Command is sending you to [station_name()] with the task: [mission]") + +/datum/antagonist/greybois/on_gain() + equipERT() + . = ..() + +/datum/antagonist/greybois/proc/equipERT() + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + return + H.equipOutfit(outfit) diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm index c0246ba978..51e8d9a13b 100644 --- a/code/modules/antagonists/highlander/highlander.dm +++ b/code/modules/antagonists/highlander/highlander.dm @@ -60,7 +60,7 @@ W.access += get_all_centcom_access() W.assignment = "Highlander" W.registered_name = H.real_name - W.item_flags |= NODROP + ADD_TRAIT(W, TRAIT_NODROP, HIGHLANDER) W.update_label(H.real_name) H.equip_to_slot_or_del(W, SLOT_WEAR_ID) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index c616459bd1..edae8a4240 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -5,6 +5,7 @@ #define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable. GLOBAL_LIST_EMPTY(jam_on_wardec) +GLOBAL_VAR_INIT(war_declared, FALSE) /obj/item/nuclear_challenge name = "Declaration of War (Challenge Mode)" @@ -61,8 +62,13 @@ GLOBAL_LIST_EMPTY(jam_on_wardec) for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec) D.jammed = TRUE + + GLOB.war_declared = TRUE + var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) + var/actual_players = GLOB.joined_player_list.len - nukeops.len + + new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * actual_players, 1)) - new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * GLOB.player_list.len, 1)) CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY)) SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1) @@ -72,7 +78,10 @@ GLOBAL_LIST_EMPTY(jam_on_wardec) if(declaring_war) to_chat(user, "You are already in the process of declaring war! Make your mind up.") return FALSE - if(GLOB.player_list.len < CHALLENGE_MIN_PLAYERS) + + var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) + var/actual_players = GLOB.joined_player_list.len - nukeops.len + if(actual_players < CHALLENGE_MIN_PLAYERS) to_chat(user, "The enemy crew is too small to be worth declaring war on.") return FALSE if(!user.onSyndieBase()) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index ade5458765..add3c1d9b0 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -373,6 +373,11 @@ S.switch_mode_to(TRACK_INFILTRATOR) countdown.start() set_security_level("delta") + + if(GLOB.war_declared) + var/area/A = get_area(src) + priority_announce("Alert: Unexpected increase in radiation levels near [A.name] ([src.x],[src.y],[src.z]). Please send an authorized radiation specialist to investigate.", "Sensory Nuclear Indexer Telemetry Calculation Helper") + else detonation_timer = null set_security_level(previous_level) diff --git a/code/modules/antagonists/nukeop/equipment/pinpointer.dm b/code/modules/antagonists/nukeop/equipment/pinpointer.dm index d8dc709975..538feba008 100644 --- a/code/modules/antagonists/nukeop/equipment/pinpointer.dm +++ b/code/modules/antagonists/nukeop/equipment/pinpointer.dm @@ -65,9 +65,13 @@ /obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative. name = "cyborg syndicate pinpointer" desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives." - item_flags = NODROP flags_1 = NONE + +/obj/item/pinpointer/syndicate_cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + /obj/item/pinpointer/syndicate_cyborg/scan_for_target() target = null var/list/possible_targets = list() diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 4056ac1cea..112a31f44d 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -1,13 +1,21 @@ -//Harvest; activated ly clicking the target, will try to drain their essence. /mob/living/simple_animal/revenant/ClickOn(atom/A, params) //revenants can't interact with the world directly. - A.examine(src) + var/list/modifiers = params2list(params) + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) + AltClickNoInteract(src, A) + return + if(ishuman(A)) if(A in drained_mobs) to_chat(src, "[A]'s soul is dead and empty." ) else if(in_range(src, A)) Harvest(A) + +//Harvest; activated ly clicking the target, will try to drain their essence. /mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) if(!castcheck(0)) return diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 0a4a82b862..87cee7586d 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -100,6 +100,7 @@ deathmessage = "explodes with a sharp pop!" light_color = LIGHT_COLOR_CYAN hud_type = /datum/hud/swarmer + speech_span = SPAN_ROBOT var/resources = 0 //Resource points, generated by consuming metal/glass var/max_resources = 100 @@ -126,9 +127,6 @@ if(statpanel("Status")) stat("Resources:",resources) -/mob/living/simple_animal/hostile/swarmer/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/hostile/swarmer/emp_act() . = ..() if(. & EMP_PROTECT_SELF) @@ -490,7 +488,7 @@ S.set_up(4,0,get_turf(target)) S.start() playsound(src,'sound/effects/sparks4.ogg',50,1) - do_teleport(target, F, 0) + do_teleport(target, F, 0, channel = TELEPORT_CHANNEL_BLUESPACE) /mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) if(!tesla_shock) @@ -666,7 +664,7 @@ set_light(0) /mob/living/simple_animal/hostile/swarmer/proc/swarmer_chat(msg) - var/rendered = "Swarm communication - [src] [say_quote(msg, get_spans())]" + var/rendered = "Swarm communication - [src] [say_quote(msg)]" for(var/i in GLOB.mob_list) var/mob/M = i if(isswarmer(M)) diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm index 051bf74705..f2e6566e8f 100644 --- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm +++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm @@ -244,10 +244,12 @@ to_chat(owner.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.") to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") to_chat(owner.current, " You have been provided with a standard uplink to accomplish your task. ") + to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.") else to_chat(owner.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.") to_chat(owner.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.") to_chat(owner.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.") + to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.") to_chat(owner.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") owner.announce_objectives() diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 828e19e3f6..e43c2f6254 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -358,8 +358,14 @@ return result.Join("
    ") /datum/antagonist/traitor/roundend_report_footer() - return "
    The code phrases were: [GLOB.syndicate_code_phrase]
    \ - The code responses were: [GLOB.syndicate_code_response]
    " + var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") + var/responses = jointext(GLOB.syndicate_code_response, ", ") + + var message = "
    The code phrases were: [phrases]
    \ + The code responses were: [responses]
    " + + return message + /datum/antagonist/traitor/is_gamemode_hero() return SSticker.mode.name == "traitor" diff --git a/code/modules/antagonists/valentines/valentine.dm b/code/modules/antagonists/valentines/valentine.dm index 31e69b32c2..21e54374a4 100644 --- a/code/modules/antagonists/valentines/valentine.dm +++ b/code/modules/antagonists/valentines/valentine.dm @@ -27,6 +27,7 @@ var/mob/living/L = owner L.remove_status_effect(STATUS_EFFECT_INLOVE) + /datum/antagonist/valentine/greet() to_chat(owner, "You're on a date with [date.name]! Protect [date.p_them()] at all costs. This takes priority over all other loyalties.") @@ -42,4 +43,21 @@ if(objectives_complete) return "[owner.name] protected [owner.p_their()] date" else - return "[owner.name] date failed!" \ No newline at end of file + return "[owner.name] date failed!" + +//Just so it's distinct, basically. +/datum/antagonist/valentine/chem/greet() + to_chat(owner, "You're in love with [date.name]! Protect [date.p_them()] at all costs. This takes priority over all other loyalties.") + +/datum/antagonist/valentine/chem/roundend_report() + var/objectives_complete = TRUE + if(owner.objectives.len) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(objectives_complete) + return "[owner.name] protected [owner.p_their()] love: [date.name]! What a cutie!" + else + return "[owner.name] date failed!" diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 7cfefd5413..8642484895 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -385,9 +385,11 @@ /obj/item/warpwhistle/attack_self(mob/living/carbon/user) if(!istype(user) || on_cooldown) return + var/turf/T = get_turf(user) + if(!T) + return on_cooldown = TRUE last_user = user - var/turf/T = get_turf(user) playsound(T,'sound/magic/warpwhistle.ogg', 200, 1) user.canmove = FALSE new /obj/effect/temp_visual/tornado(T) @@ -402,9 +404,15 @@ return var/breakout = 0 while(breakout < 50) + if(!T) + end_effect(user) + return var/turf/potential_T = find_safe_turf() + if(!potential_T) + end_effect(user) + return if(T.z != potential_T.z || abs(get_dist_euclidian(potential_T,T)) > 50 - breakout) - user.forceMove(potential_T) + do_teleport(user, potential_T, channel = TELEPORT_CHANNEL_MAGIC) user.canmove = 0 T = potential_T break diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index b1aa63c242..186eb1b024 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -12,6 +12,7 @@ crit_fail = FALSE //Is the flash burnt out? light_color = LIGHT_COLOR_WHITE light_power = FLASH_LIGHT_POWER + var/flashing_overlay = "flash-f" var/times_used = 0 //Number of times it's been used. var/burnout_resistance = 0 var/last_used = 0 //last world.time it was used. @@ -36,8 +37,8 @@ add_overlay("flashburnt") attached_overlays += "flashburnt" if(flash) - add_overlay("flash-f") - attached_overlays += "flash-f" + add_overlay(flashing_overlay) + attached_overlays += flashing_overlay addtimer(CALLBACK(src, .proc/update_icon), 5) if(holder) holder.update_icon() @@ -313,3 +314,50 @@ /obj/item/assembly/flash/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) activate() return ..() + +//ported from tg - check to make sure it can't appear where it's not supposed to. +/obj/item/assembly/flash/hypnotic + desc = "A modified flash device, programmed to emit a sequence of subliminal flashes that can send a vulnerable target into a hypnotic trance." + flashing_overlay = "flash-hypno" //I cannot find this icon no matter how hard I look in tg, so I might just make my own. + light_color = LIGHT_COLOR_PINK + cooldown = 20 + +/obj/item/assembly/flash/hypnotic/burn_out() + return + +/obj/item/assembly/flash/hypnotic/flash_carbon(mob/living/carbon/M, mob/user, power = 15, targeted = TRUE, generic_message = FALSE) + if(!istype(M)) + return + if(user) + log_combat(user, M, "[targeted? "hypno-flashed(targeted)" : "hypno-flashed(AOE)"]", src) + else //caused by emp/remote signal + M.log_message("was [targeted? "hypno-flashed(targeted)" : "hypno-flashed(AOE)"]",LOG_ATTACK) + if(generic_message && M != user) + to_chat(M, "[src] emits a soothing light...") + if(targeted) + if(M.flash_act(1, 1)) + var/hypnosis = FALSE + if(M.hypnosis_vulnerable()) + hypnosis = TRUE + if(user) + user.visible_message("[user] blinds [M] with the flash!", "You hypno-flash [M]!") + + if(!hypnosis) + to_chat(M, "The light makes you feel oddly relaxed...") + M.confused += min(M.confused + 10, 20) + M.dizziness += min(M.dizziness + 10, 20) + M.drowsyness += min(M.drowsyness + 10, 20) + M.apply_status_effect(STATUS_EFFECT_PACIFY, 100) + else + M.apply_status_effect(/datum/status_effect/trance, 200, TRUE) + + else if(user) + user.visible_message("[user] fails to blind [M] with the flash!", "You fail to hypno-flash [M]!") + else + to_chat(M, "[src] fails to blind you!") + + else if(M.flash_act()) + to_chat(M, "Such a pretty light...") + M.confused += min(M.confused + 4, 20) + M.dizziness += min(M.dizziness + 4, 20) + M.drowsyness += min(M.drowsyness + 4, 20) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 9858db2abb..0d9c0730c1 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -38,8 +38,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) for(var/id in cached_gases) . += cached_gases[id] * cached_gasheats[id] -/datum/gas_mixture/turf/heat_capacity() - . = ..() +/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM + var/list/cached_gases = gases + var/list/cached_gasheats = GLOB.meta_gas_specific_heats + for(var/id in cached_gases) + . += cached_gases[id] * cached_gasheats[id] if(!.) . += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space @@ -331,22 +334,19 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) /datum/gas_mixture/react(datum/holder) . = NO_REACTION var/list/cached_gases = gases - if(!cached_gases.len) + if(!length(cached_gases)) return - var/possible + var/list/reactions = list() for(var/I in cached_gases) - if(GLOB.nonreactive_gases[I]) - continue - possible = TRUE - break - if(!possible) + reactions += SSair.gas_reactions[I] + if(!length(reactions)) return reaction_results = new var/temp = temperature var/ener = THERMAL_ENERGY(src) reaction_loop: - for(var/r in SSair.gas_reactions) + for(var/r in reactions) var/datum/gas_reaction/reaction = r var/list/min_reqs = reaction.min_requirements @@ -376,14 +376,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) continue reaction_loop //at this point, all requirements for the reaction are satisfied. we can now react() */ - . |= reaction.react(src, holder) if (. & STOP_REACTIONS) break if(.) GAS_GARBAGE_COLLECT(gases) - if(temperature < TCMB) //just for safety - temperature = TCMB //Takes the amount of the gas you want to PP as an argument //So I don't have to do some hacky switches/defines/magic strings diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm index d628826b01..19f7bff965 100644 --- a/code/modules/atmospherics/gasmixtures/gas_types.dm +++ b/code/modules/atmospherics/gasmixtures/gas_types.dm @@ -78,22 +78,26 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g var/moles_visible = null var/dangerous = FALSE //currently used by canisters var/fusion_power = 0 //How much the gas accelerates a fusion reaction + var/rarity = 0 // relative rarity compared to other gases, used when setting up the reactions list. /datum/gas/oxygen id = "o2" specific_heat = 20 name = "Oxygen" + rarity = 900 /datum/gas/nitrogen id = "n2" specific_heat = 20 name = "Nitrogen" + rarity = 1000 /datum/gas/carbon_dioxide //what the fuck is this? id = "co2" specific_heat = 30 name = "Carbon Dioxide" fusion_power = 3 + rarity = 700 /datum/gas/plasma id = "plasma" @@ -102,6 +106,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g gas_overlay = "plasma" moles_visible = MOLES_GAS_VISIBLE dangerous = TRUE + rarity = 800 /datum/gas/water_vapor id = "water_vapor" @@ -110,6 +115,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g gas_overlay = "water_vapor" moles_visible = MOLES_GAS_VISIBLE fusion_power = 8 + rarity = 500 /datum/gas/hypernoblium id = "nob" @@ -118,6 +124,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g gas_overlay = "freon" moles_visible = MOLES_GAS_VISIBLE dangerous = TRUE + rarity = 50 /datum/gas/nitrous_oxide id = "n2o" @@ -126,6 +133,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g gas_overlay = "nitrous_oxide" moles_visible = MOLES_GAS_VISIBLE * 2 dangerous = TRUE + rarity = 600 /datum/gas/nitryl id = "no2" @@ -135,6 +143,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g moles_visible = MOLES_GAS_VISIBLE dangerous = TRUE fusion_power = 15 + rarity = 100 /datum/gas/tritium id = "tritium" @@ -144,6 +153,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g moles_visible = MOLES_GAS_VISIBLE dangerous = TRUE fusion_power = 1 + rarity = 300 /datum/gas/bz id = "bz" @@ -151,18 +161,21 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g name = "BZ" dangerous = TRUE fusion_power = 8 + rarity = 400 /datum/gas/stimulum id = "stim" specific_heat = 5 name = "Stimulum" fusion_power = 7 + rarity = 1 /datum/gas/pluoxium id = "pluox" specific_heat = 80 name = "Pluoxium" fusion_power = 10 + rarity = 200 /datum/gas/miasma id = "miasma" @@ -171,6 +184,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g name = "Miasma" gas_overlay = "miasma" moles_visible = MOLES_GAS_VISIBLE * 60 + rarity = 250 /obj/effect/overlay/gas icon = 'icons/effects/atmospherics.dmi' diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index ef0a422079..8e320b2f3e 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -1,19 +1,36 @@ //All defines used in reactions are located in ..\__DEFINES\reactions.dm /proc/init_gas_reactions() - var/list/reaction_types = list() + . = list() + for(var/type in subtypesof(/datum/gas)) + .[type] = list() + for(var/r in subtypesof(/datum/gas_reaction)) var/datum/gas_reaction/reaction = r - if(!initial(reaction.exclude)) - reaction_types += reaction - reaction_types = sortList(reaction_types, /proc/cmp_gas_reactions) + if(initial(reaction.exclude)) + continue + reaction = new r + var/datum/gas/reaction_key + for (var/req in reaction.min_requirements) + if (ispath(req)) + var/datum/gas/req_gas = req + if (!reaction_key || initial(reaction_key.rarity) > initial(req_gas.rarity)) + reaction_key = req_gas + .[reaction_key] += list(reaction) + sortTim(., /proc/cmp_gas_reactions, TRUE) - . = list() - for(var/path in reaction_types) - . += new path - -/proc/cmp_gas_reactions(datum/gas_reaction/a, datum/gas_reaction/b) //sorts in descending order of priority - return initial(b.priority) - initial(a.priority) +/proc/cmp_gas_reactions(list/datum/gas_reaction/a, list/datum/gas_reaction/b) // compares lists of reactions by the maximum priority contained within the list + if (!length(a) || !length(b)) + return length(b) - length(a) + var/maxa + var/maxb + for (var/datum/gas_reaction/R in a) + if (R.priority > maxa) + maxa = R.priority + for (var/datum/gas_reaction/R in b) + if (R.priority > maxb) + maxb = R.priority + return maxb - maxa /datum/gas_reaction //regarding the requirements lists: the minimum or maximum requirements must be non-zero. @@ -347,15 +364,10 @@ var/list/cached_gases = air.gases var/temperature = air.temperature var/pressure = air.return_pressure() - var/old_heat_capacity = air.heat_capacity() var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2) var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED - if(cached_gases[/datum/gas/miasma] && cached_gases[/datum/gas/miasma] > 0) - energy_released /= cached_gases[/datum/gas/miasma]*0.1 - if(cached_gases[/datum/gas/bz] && cached_gases[/datum/gas/bz] > 0) - energy_released *= cached_gases[/datum/gas/bz]*0.1 - if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing. + if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing. return NO_REACTION cached_gases[/datum/gas/bz] += reaction_efficency if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide]) @@ -364,7 +376,7 @@ cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency cached_gases[/datum/gas/plasma] -= 2*reaction_efficency - SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, (reaction_efficency**0.5)*BZ_RESEARCH_AMOUNT) + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT) if(energy_released > 0) var/new_heat_capacity = air.heat_capacity() @@ -460,4 +472,4 @@ //Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable air.temperature += cleaned_air * 0.002 - SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists \ No newline at end of file + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 6ea571935b..6ca25c0d80 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -1,880 +1,882 @@ -/datum/tlv - var/min2 - var/min1 - var/max1 - var/max2 - -/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) - if(min2) src.min2 = min2 - if(min1) src.min1 = min1 - if(max1) src.max1 = max1 - if(max2) src.max2 = max2 - -/datum/tlv/proc/get_danger_level(val as num) - if(max2 != -1 && val >= max2) - return 2 - if(min2 != -1 && val <= min2) - return 2 - if(max1 != -1 && val >= max1) - return 1 - if(min1 != -1 && val <= min1) - return 1 - return 0 - -/datum/tlv/no_checks - min2 = -1 - min1 = -1 - max1 = -1 - max2 = -1 - -/datum/tlv/dangerous - min2 = -1 - min1 = -1 - max1 = 0.2 - max2 = 0.5 - -/obj/item/electronics/airalarm - name = "air alarm electronics" - icon_state = "airalarm_electronics" - -/obj/item/wallframe/airalarm - name = "air alarm frame" - desc = "Used for building Air Alarms." - icon = 'icons/obj/monitors.dmi' - icon_state = "alarm_bitem" - result_path = /obj/machinery/airalarm - -#define AALARM_MODE_SCRUBBING 1 -#define AALARM_MODE_VENTING 2 //makes draught -#define AALARM_MODE_PANIC 3 //like siphon, but stronger (enables widenet) -#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing -#define AALARM_MODE_OFF 5 -#define AALARM_MODE_FLOOD 6 //Emagged mode; turns off scrubbers and pressure checks on vents -#define AALARM_MODE_SIPHON 7 //Scrubbers suck air -#define AALARM_MODE_CONTAMINATED 8 //Turns on all filtering and widenet scrubbing. -#define AALARM_MODE_REFILL 9 //just like normal, but with triple the air output - -#define AALARM_REPORT_TIMEOUT 100 - -#define AALARM_OVERLAY_OFF "alarm_off" -#define AALARM_OVERLAY_GREEN "alarm_green" -#define AALARM_OVERLAY_WARN "alarm_amber" -#define AALARM_OVERLAY_DANGER "alarm_red" - -/obj/machinery/airalarm - name = "air alarm" - desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous." - icon = 'icons/obj/monitors.dmi' - icon_state = "alarm0" - use_power = IDLE_POWER_USE - idle_power_usage = 4 - active_power_usage = 8 - power_channel = ENVIRON - req_access = list(ACCESS_ATMOSPHERICS) - max_integrity = 250 - integrity_failure = 80 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) - resistance_flags = FIRE_PROOF - - var/danger_level = 0 - var/mode = AALARM_MODE_SCRUBBING - - var/locked = TRUE - var/aidisabled = 0 - var/shorted = 0 - var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/brightness_on = 1 - - var/frequency = FREQ_ATMOS_CONTROL - var/alarm_frequency = FREQ_ATMOS_ALARMS - var/datum/radio_frequency/radio_connection - - var/list/TLV = list( // Breathable air. - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), - /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), - /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), - /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), - /datum/gas/plasma = new/datum/tlv/dangerous, - /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, - /datum/gas/bz = new/datum/tlv/dangerous, - /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - /datum/gas/water_vapor = new/datum/tlv/dangerous, - /datum/gas/tritium = new/datum/tlv/dangerous, - /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects - /datum/gas/nitryl = new/datum/tlv/dangerous, - /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/obj/machinery/airalarm/server // No checks here. - TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - /datum/gas/oxygen = new/datum/tlv/no_checks, - /datum/gas/nitrogen = new/datum/tlv/no_checks, - /datum/gas/carbon_dioxide = new/datum/tlv/no_checks, - /datum/gas/miasma = new/datum/tlv/no_checks, - /datum/gas/plasma = new/datum/tlv/no_checks, - /datum/gas/nitrous_oxide = new/datum/tlv/no_checks, - /datum/gas/bz = new/datum/tlv/no_checks, - /datum/gas/hypernoblium = new/datum/tlv/no_checks, - /datum/gas/water_vapor = new/datum/tlv/no_checks, - /datum/gas/tritium = new/datum/tlv/no_checks, - /datum/gas/stimulum = new/datum/tlv/no_checks, - /datum/gas/nitryl = new/datum/tlv/no_checks, - /datum/gas/pluoxium = new/datum/tlv/no_checks - ) - -/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. - TLV = list( - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10), - /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), - /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), - /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), - /datum/gas/plasma = new/datum/tlv/dangerous, - /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, - /datum/gas/bz = new/datum/tlv/dangerous, - /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - /datum/gas/water_vapor = new/datum/tlv/dangerous, - /datum/gas/tritium = new/datum/tlv/dangerous, - /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects - /datum/gas/nitryl = new/datum/tlv/dangerous, - /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/obj/machinery/airalarm/unlocked - locked = FALSE - -/obj/machinery/airalarm/engine - name = "engine air alarm" - locked = FALSE - req_access = null - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE) - -/obj/machinery/airalarm/mixingchamber - name = "chamber air alarm" - locked = FALSE - req_access = null - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_TOX, ACCESS_TOX_STORAGE) - -/obj/machinery/airalarm/all_access - name = "all-access air alarm" - desc = "This particular atmos control unit appears to have no access restrictions." - locked = FALSE - req_access = null - req_one_access = null - -/obj/machinery/airalarm/syndicate //general syndicate access - req_access = list(ACCESS_SYNDICATE) - -/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New() - dir = SOUTH - pixel_y = 24 - -/obj/machinery/airalarm/directional/south - dir = NORTH - pixel_y = -24 - -/obj/machinery/airalarm/directional/east - dir = WEST - pixel_x = 24 - -/obj/machinery/airalarm/directional/west - dir = EAST - pixel_x = -24 - -//all air alarms in area are connected via magic -/area - var/list/air_vent_names = list() - var/list/air_scrub_names = list() - var/list/air_vent_info = list() - var/list/air_scrub_info = list() - -/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) - . = ..() - wires = new /datum/wires/airalarm(src) - - if(ndir) - setDir(ndir) - - if(nbuild) - buildstage = 0 - panel_open = TRUE - pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) - pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 - - if(name == initial(name)) - name = "[get_area_name(src)] Air Alarm" - - power_change() - set_frequency(frequency) - -/obj/machinery/airalarm/Destroy() - SSradio.remove_object(src, frequency) - qdel(wires) - wires = null - return ..() - -/obj/machinery/airalarm/examine(mob/user) - . = ..() - switch(buildstage) - if(0) - to_chat(user, "It is missing air alarm electronics.") - if(1) - to_chat(user, "It is missing wiring.") - if(2) - to_chat(user, "Alt-click to [locked ? "unlock" : "lock"] the interface.") - -/obj/machinery/airalarm/ui_status(mob/user) - if(user.has_unlimited_silicon_privilege && aidisabled) - to_chat(user, "AI control has been disabled.") - else if(!shorted) - return ..() - return UI_CLOSE - -/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state) - ui.open() - -/obj/machinery/airalarm/ui_data(mob/user) - var/data = list( - "locked" = locked, - "siliconUser" = user.has_unlimited_silicon_privilege, - "emagged" = (obj_flags & EMAGGED ? 1 : 0), - "danger_level" = danger_level, - ) - - var/area/A = get_area(src) - data["atmos_alarm"] = A.atmosalm - data["fire_alarm"] = A.fire - - var/turf/T = get_turf(src) - var/datum/gas_mixture/environment = T.return_air() - var/datum/tlv/cur_tlv - - data["environment_data"] = list() - var/pressure = environment.return_pressure() - cur_tlv = TLV["pressure"] - data["environment_data"] += list(list( - "name" = "Pressure", - "value" = pressure, - "unit" = "kPa", - "danger_level" = cur_tlv.get_danger_level(pressure) - )) - var/temperature = environment.temperature - cur_tlv = TLV["temperature"] - data["environment_data"] += list(list( - "name" = "Temperature", - "value" = temperature, - "unit" = "K ([round(temperature - T0C, 0.1)]C)", - "danger_level" = cur_tlv.get_danger_level(temperature) - )) - var/total_moles = environment.total_moles() - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume - for(var/gas_id in environment.gases) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - cur_tlv = TLV[gas_id] - data["environment_data"] += list(list( - "name" = GLOB.meta_gas_names[gas_id], - "value" = environment.gases[gas_id] / total_moles * 100, - "unit" = "%", - "danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure) - )) - - if(!locked || user.has_unlimited_silicon_privilege) - data["vents"] = list() - for(var/id_tag in A.air_vent_names) - var/long_name = A.air_vent_names[id_tag] - var/list/info = A.air_vent_info[id_tag] - if(!info || info["frequency"] != frequency) - continue - data["vents"] += list(list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "checks" = info["checks"], - "excheck" = info["checks"]&1, - "incheck" = info["checks"]&2, - "direction" = info["direction"], - "external" = info["external"], - "internal" = info["internal"], - "extdefault"= (info["external"] == ONE_ATMOSPHERE), - "intdefault"= (info["internal"] == 0) - )) - data["scrubbers"] = list() - for(var/id_tag in A.air_scrub_names) - var/long_name = A.air_scrub_names[id_tag] - var/list/info = A.air_scrub_info[id_tag] - if(!info || info["frequency"] != frequency) - continue - data["scrubbers"] += list(list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "scrubbing" = info["scrubbing"], - "widenet" = info["widenet"], - "filter_types" = info["filter_types"] - )) - data["mode"] = mode - data["modes"] = list() - data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)) - data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0)) - data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0)) - data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 1)) - data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1)) - data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1)) - data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)) - data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)) - if(obj_flags & EMAGGED) - data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1)) - - var/datum/tlv/selected - var/list/thresholds = list() - - selected = TLV["pressure"] - thresholds += list(list("name" = "Pressure", "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) - - selected = TLV["temperature"] - thresholds += list(list("name" = "Temperature", "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) - - for(var/gas_id in GLOB.meta_gas_names) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - selected = TLV[gas_id] - thresholds += list(list("name" = GLOB.meta_gas_names[gas_id], "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2)) - - data["thresholds"] = thresholds - return data - -/obj/machinery/airalarm/ui_act(action, params) - if(..() || buildstage != 2) - return - if((locked && !usr.has_unlimited_silicon_privilege) || (usr.has_unlimited_silicon_privilege && aidisabled)) - return - var/device_id = params["id_tag"] - switch(action) - if("lock") - if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN)) - locked = !locked - . = TRUE - if("power", "toggle_filter", "widenet", "scrubbing") - send_signal(device_id, list("[action]" = params["val"]), usr) - . = TRUE - if("excheck") - send_signal(device_id, list("checks" = text2num(params["val"])^1), usr) - . = TRUE - if("incheck") - send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) - . = TRUE - if("set_external_pressure", "set_internal_pressure") - var/area/A = get_area(src) - var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null - if(!isnull(target) && !..()) - send_signal(device_id, list("[action]" = target), usr) - . = TRUE - if("reset_external_pressure") - send_signal(device_id, list("reset_external_pressure"), usr) - . = TRUE - if("reset_internal_pressure") - send_signal(device_id, list("reset_internal_pressure"), usr) - . = TRUE - if("threshold") - var/env = params["env"] - if(text2path(env)) - env = text2path(env) - - var/name = params["var"] - var/datum/tlv/tlv = TLV[env] - if(isnull(tlv)) - return - var/value = input("New [name] for [env]:", name, tlv.vars[name]) as num|null - if(!isnull(value) && !..()) - if(value < 0) - tlv.vars[name] = -1 - else - tlv.vars[name] = round(value, 0.01) - investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) - . = TRUE - if("mode") - mode = text2num(params["mode"]) - investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS) - apply_mode() - . = TRUE - if("alarm") - var/area/A = get_area(src) - if(A.atmosalert(2, src)) - post_alert(2) - . = TRUE - if("reset") - var/area/A = get_area(src) - if(A.atmosalert(0, src)) - post_alert(0) - . = TRUE - update_icon() - -/obj/machinery/airalarm/proc/reset(wire) - switch(wire) - if(WIRE_POWER) - if(!wires.is_cut(WIRE_POWER)) - shorted = FALSE - update_icon() - if(WIRE_AI) - if(!wires.is_cut(WIRE_AI)) - aidisabled = FALSE - - -/obj/machinery/airalarm/proc/shock(mob/user, prb) - if((stat & (NOPOWER))) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 //you lucked out, no shock for you - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() //sparks always. - if (electrocute_mob(user, get_area(src), src, 1, TRUE)) - return 1 - else - return 0 - -/obj/machinery/airalarm/proc/refresh_all() - var/area/A = get_area(src) - for(var/id_tag in A.air_vent_names) - var/list/I = A.air_vent_info[id_tag] - if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) - continue - send_signal(id_tag, list("status")) - for(var/id_tag in A.air_scrub_names) - var/list/I = A.air_scrub_info[id_tag] - if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) - continue - send_signal(id_tag, list("status")) - -/obj/machinery/airalarm/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) - -/obj/machinery/airalarm/proc/send_signal(target, list/command, mob/user)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise - if(!radio_connection) - return 0 - - var/datum/signal/signal = new(command) - signal.data["tag"] = target - signal.data["sigtype"] = "command" - signal.data["user"] = user - radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) - - return 1 - -/obj/machinery/airalarm/proc/get_mode_name(mode_value) - switch(mode_value) - if(AALARM_MODE_SCRUBBING) - return "Filtering" - if(AALARM_MODE_CONTAMINATED) - return "Contaminated" - if(AALARM_MODE_VENTING) - return "Draught" - if(AALARM_MODE_REFILL) - return "Refill" - if(AALARM_MODE_PANIC) - return "Panic Siphon" - if(AALARM_MODE_REPLACEMENT) - return "Cycle" - if(AALARM_MODE_SIPHON) - return "Siphon" - if(AALARM_MODE_OFF) - return "Off" - if(AALARM_MODE_FLOOD) - return "Flood" - -/obj/machinery/airalarm/proc/apply_mode() - var/area/A = get_area(src) - switch(mode) - if(AALARM_MODE_SCRUBBING) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), - "scrubbing" = 1, - "widenet" = 0, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE - )) - if(AALARM_MODE_CONTAMINATED) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list( - /datum/gas/carbon_dioxide, - /datum/gas/miasma, - /datum/gas/plasma, - /datum/gas/water_vapor, - /datum/gas/hypernoblium, - /datum/gas/nitrous_oxide, - /datum/gas/nitryl, - /datum/gas/tritium, - /datum/gas/bz, - /datum/gas/stimulum, - /datum/gas/pluoxium - ), - "scrubbing" = 1, - "widenet" = 1, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE - )) - if(AALARM_MODE_VENTING) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 0, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE*2 - )) - if(AALARM_MODE_REFILL) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), - "scrubbing" = 1, - "widenet" = 0, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE * 3 - )) - if(AALARM_MODE_PANIC, - AALARM_MODE_REPLACEMENT) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 1, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - if(AALARM_MODE_SIPHON) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 0, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - - if(AALARM_MODE_OFF) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - if(AALARM_MODE_FLOOD) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 2, - "set_internal_pressure" = 0 - )) - -/obj/machinery/airalarm/update_icon() - set_light(0) - cut_overlays() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) - if(stat & NOPOWER) - icon_state = "alarm0" - return - - if(stat & BROKEN) - icon_state = "alarmx" - return - - if(panel_open) - switch(buildstage) - if(2) - icon_state = "alarmx" - if(1) - icon_state = "alarm_b2" - if(0) - icon_state = "alarm_b1" - return - - icon_state = "alarm1" - var/overlay_state = AALARM_OVERLAY_OFF - var/area/A = get_area(src) - switch(max(danger_level, A.atmosalm)) - if(0) - add_overlay(AALARM_OVERLAY_GREEN) - overlay_state = AALARM_OVERLAY_GREEN - light_color = LIGHT_COLOR_PALEBLUE - set_light(brightness_on) - if(1) - add_overlay(AALARM_OVERLAY_WARN) - overlay_state = AALARM_OVERLAY_WARN - light_color = LIGHT_COLOR_LAVA - set_light(brightness_on) - if(2) - add_overlay(AALARM_OVERLAY_DANGER) - overlay_state = AALARM_OVERLAY_DANGER - light_color = LIGHT_COLOR_RED - set_light(brightness_on) - - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) - update_light() - -/obj/machinery/airalarm/process() - if((stat & (NOPOWER|BROKEN)) || shorted) - return - - var/turf/location = get_turf(src) - if(!location) - return - - var/datum/tlv/cur_tlv - - var/datum/gas_mixture/environment = location.return_air() - var/list/env_gases = environment.gases - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume - - cur_tlv = TLV["pressure"] - var/environment_pressure = environment.return_pressure() - var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) - - cur_tlv = TLV["temperature"] - var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) - - var/gas_dangerlevel = 0 - for(var/gas_id in env_gases) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - cur_tlv = TLV[gas_id] - gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id] * partial_pressure)) - - GAS_GARBAGE_COLLECT(environment.gases) - - var/old_danger_level = danger_level - danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) - - if(old_danger_level != danger_level) - apply_danger_level() - if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) - mode = AALARM_MODE_SCRUBBING - apply_mode() - - return - - -/obj/machinery/airalarm/proc/post_alert(alert_level) - var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) - - if(!frequency) - return - - var/datum/signal/alert_signal = new(list( - "zone" = get_area_name(src), - "type" = "Atmospheric" - )) - if(alert_level==2) - alert_signal.data["alert"] = "severe" - else if (alert_level==1) - alert_signal.data["alert"] = "minor" - else if (alert_level==0) - alert_signal.data["alert"] = "clear" - - frequency.post_signal(src, alert_signal, range = -1) - -/obj/machinery/airalarm/proc/apply_danger_level() - var/area/A = get_area(src) - - var/new_area_danger_level = 0 - for(var/obj/machinery/airalarm/AA in A) - if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) - new_area_danger_level = max(new_area_danger_level,AA.danger_level) - if(A.atmosalert(new_area_danger_level,src)) //if area was in normal state or if area was in alert state - post_alert(new_area_danger_level) - - update_icon() - -/obj/machinery/airalarm/attackby(obj/item/W, mob/user, params) - switch(buildstage) - if(2) - if(istype(W, /obj/item/wirecutters) && panel_open && wires.is_all_cut()) - W.play_tool_sound(src) - to_chat(user, "You cut the final wires.") - new /obj/item/stack/cable_coil(loc, 5) - buildstage = 1 - update_icon() - return - else if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. - W.play_tool_sound(src) - panel_open = !panel_open - to_chat(user, "The wires have been [panel_open ? "exposed" : "unexposed"].") - update_icon() - return - else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card - togglelock(user) - else if(panel_open && is_wire_tool(W)) - wires.interact(user) - return - if(1) - if(istype(W, /obj/item/crowbar)) - user.visible_message("[user.name] removes the electronics from [src.name].",\ - "You start prying out the circuit...") - W.play_tool_sound(src) - if (W.use_tool(src, user, 20)) - if (buildstage == 1) - to_chat(user, "You remove the air alarm electronics.") - new /obj/item/electronics/airalarm( src.loc ) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - buildstage = 0 - update_icon() - return - - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/cable = W - if(cable.get_amount() < 5) - to_chat(user, "You need five lengths of cable to wire the air alarm!") - return - user.visible_message("[user.name] wires the air alarm.", \ - "You start wiring the air alarm...") - if (do_after(user, 20, target = src)) - if (cable.get_amount() >= 5 && buildstage == 1) - cable.use(5) - to_chat(user, "You wire the air alarm.") - wires.repair() - aidisabled = 0 - locked = FALSE - mode = 1 - shorted = 0 - post_alert(0) - buildstage = 2 - update_icon() - return - if(0) - if(istype(W, /obj/item/electronics/airalarm)) - if(user.temporarilyRemoveItemFromInventory(W)) - to_chat(user, "You insert the circuit.") - buildstage = 1 - update_icon() - qdel(W) - return - - if(istype(W, /obj/item/electroadaptive_pseudocircuit)) - var/obj/item/electroadaptive_pseudocircuit/P = W - if(!P.adapt_circuit(user, 25)) - return - user.visible_message("[user] fabricates a circuit and places it into [src].", \ - "You adapt an air alarm circuit and slot it into the assembly.") - buildstage = 1 - update_icon() - return - - if(istype(W, /obj/item/wrench)) - to_chat(user, "You detach \the [src] from the wall.") - W.play_tool_sound(src) - new /obj/item/wallframe/airalarm( user.loc ) - qdel(src) - return - - return ..() - -/obj/machinery/airalarm/AltClick(mob/user) - ..() - if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) - return - else - togglelock(user) - -/obj/machinery/airalarm/proc/togglelock(mob/living/user) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "It does nothing!") - else - if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) - locked = !locked - updateUsrDialog() - to_chat(user, "You [ locked ? "lock" : "unlock"] the air alarm interface.") - else - to_chat(user, "Access denied.") - return - -/obj/machinery/airalarm/power_change() - ..() - if(stat & NOPOWER) - set_light(0) - update_icon() - -/obj/machinery/airalarm/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - obj_flags |= EMAGGED - visible_message("Sparks fly out of [src]!", "You emag [src], disabling its safeties.") - playsound(src, "sparks", 50, 1) - -/obj/machinery/airalarm/obj_break(damage_flag) - ..() - update_icon() - set_light(0) - -/obj/machinery/airalarm/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc, 2) - var/obj/item/I = new /obj/item/electronics/airalarm(loc) - if(!disassembled) - I.obj_integrity = I.max_integrity * 0.5 - new /obj/item/stack/cable_coil(loc, 3) - qdel(src) - -#undef AALARM_MODE_SCRUBBING -#undef AALARM_MODE_VENTING -#undef AALARM_MODE_PANIC -#undef AALARM_MODE_REPLACEMENT -#undef AALARM_MODE_OFF -#undef AALARM_MODE_FLOOD -#undef AALARM_MODE_SIPHON -#undef AALARM_MODE_CONTAMINATED -#undef AALARM_MODE_REFILL -#undef AALARM_REPORT_TIMEOUT +/datum/tlv + var/min2 + var/min1 + var/max1 + var/max2 + +/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) + if(min2) src.min2 = min2 + if(min1) src.min1 = min1 + if(max1) src.max1 = max1 + if(max2) src.max2 = max2 + +/datum/tlv/proc/get_danger_level(val as num) + if(max2 != -1 && val >= max2) + return 2 + if(min2 != -1 && val <= min2) + return 2 + if(max1 != -1 && val >= max1) + return 1 + if(min1 != -1 && val <= min1) + return 1 + return 0 + +/datum/tlv/no_checks + min2 = -1 + min1 = -1 + max1 = -1 + max2 = -1 + +/datum/tlv/dangerous + min2 = -1 + min1 = -1 + max1 = 0.2 + max2 = 0.5 + +/obj/item/electronics/airalarm + name = "air alarm electronics" + icon_state = "airalarm_electronics" + +/obj/item/wallframe/airalarm + name = "air alarm frame" + desc = "Used for building Air Alarms." + icon = 'icons/obj/monitors.dmi' + icon_state = "alarm_bitem" + result_path = /obj/machinery/airalarm + +#define AALARM_MODE_SCRUBBING 1 +#define AALARM_MODE_VENTING 2 //makes draught +#define AALARM_MODE_PANIC 3 //like siphon, but stronger (enables widenet) +#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing +#define AALARM_MODE_OFF 5 +#define AALARM_MODE_FLOOD 6 //Emagged mode; turns off scrubbers and pressure checks on vents +#define AALARM_MODE_SIPHON 7 //Scrubbers suck air +#define AALARM_MODE_CONTAMINATED 8 //Turns on all filtering and widenet scrubbing. +#define AALARM_MODE_REFILL 9 //just like normal, but with triple the air output + +#define AALARM_REPORT_TIMEOUT 100 + +#define AALARM_OVERLAY_OFF "alarm_off" +#define AALARM_OVERLAY_GREEN "alarm_green" +#define AALARM_OVERLAY_WARN "alarm_amber" +#define AALARM_OVERLAY_DANGER "alarm_red" + +/obj/machinery/airalarm + name = "air alarm" + desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous." + icon = 'icons/obj/monitors.dmi' + icon_state = "alarm0" + use_power = IDLE_POWER_USE + idle_power_usage = 4 + active_power_usage = 8 + power_channel = ENVIRON + req_access = list(ACCESS_ATMOSPHERICS) + max_integrity = 250 + integrity_failure = 80 + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + resistance_flags = FIRE_PROOF + + var/danger_level = 0 + var/mode = AALARM_MODE_SCRUBBING + + var/locked = TRUE + var/aidisabled = 0 + var/shorted = 0 + var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone + var/brightness_on = 1 + + var/frequency = FREQ_ATMOS_CONTROL + var/alarm_frequency = FREQ_ATMOS_ALARMS + var/datum/radio_frequency/radio_connection + + var/list/TLV = list( // Breathable air. + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), + /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), + /datum/gas/plasma = new/datum/tlv/dangerous, + /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, + /datum/gas/bz = new/datum/tlv/dangerous, + /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + /datum/gas/water_vapor = new/datum/tlv/dangerous, + /datum/gas/tritium = new/datum/tlv/dangerous, + /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects + /datum/gas/nitryl = new/datum/tlv/dangerous, + /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires + ) + +/obj/machinery/airalarm/server // No checks here. + TLV = list( + "pressure" = new/datum/tlv/no_checks, + "temperature" = new/datum/tlv/no_checks, + /datum/gas/oxygen = new/datum/tlv/no_checks, + /datum/gas/nitrogen = new/datum/tlv/no_checks, + /datum/gas/carbon_dioxide = new/datum/tlv/no_checks, + /datum/gas/miasma = new/datum/tlv/no_checks, + /datum/gas/plasma = new/datum/tlv/no_checks, + /datum/gas/nitrous_oxide = new/datum/tlv/no_checks, + /datum/gas/bz = new/datum/tlv/no_checks, + /datum/gas/hypernoblium = new/datum/tlv/no_checks, + /datum/gas/water_vapor = new/datum/tlv/no_checks, + /datum/gas/tritium = new/datum/tlv/no_checks, + /datum/gas/stimulum = new/datum/tlv/no_checks, + /datum/gas/nitryl = new/datum/tlv/no_checks, + /datum/gas/pluoxium = new/datum/tlv/no_checks + ) + +/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. + TLV = list( + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10), + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), + /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), + /datum/gas/plasma = new/datum/tlv/dangerous, + /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, + /datum/gas/bz = new/datum/tlv/dangerous, + /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + /datum/gas/water_vapor = new/datum/tlv/dangerous, + /datum/gas/tritium = new/datum/tlv/dangerous, + /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects + /datum/gas/nitryl = new/datum/tlv/dangerous, + /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires + ) + +/obj/machinery/airalarm/unlocked + locked = FALSE + +/obj/machinery/airalarm/engine + name = "engine air alarm" + locked = FALSE + req_access = null + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE) + +/obj/machinery/airalarm/mixingchamber + name = "chamber air alarm" + locked = FALSE + req_access = null + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_TOX, ACCESS_TOX_STORAGE) + +/obj/machinery/airalarm/all_access + name = "all-access air alarm" + desc = "This particular atmos control unit appears to have no access restrictions." + locked = FALSE + req_access = null + req_one_access = null + +/obj/machinery/airalarm/syndicate //general syndicate access + req_access = list(ACCESS_SYNDICATE) + +/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New() + dir = SOUTH + pixel_y = 24 + +/obj/machinery/airalarm/directional/south + dir = NORTH + pixel_y = -24 + +/obj/machinery/airalarm/directional/east + dir = WEST + pixel_x = 24 + +/obj/machinery/airalarm/directional/west + dir = EAST + pixel_x = -24 + +//all air alarms in area are connected via magic +/area + var/list/air_vent_names = list() + var/list/air_scrub_names = list() + var/list/air_vent_info = list() + var/list/air_scrub_info = list() + +/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) + . = ..() + wires = new /datum/wires/airalarm(src) + + if(ndir) + setDir(ndir) + + if(nbuild) + buildstage = 0 + panel_open = TRUE + pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) + pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 + + if(name == initial(name)) + name = "[get_area_name(src)] Air Alarm" + + power_change() + set_frequency(frequency) + +/obj/machinery/airalarm/Destroy() + SSradio.remove_object(src, frequency) + qdel(wires) + wires = null + return ..() + +/obj/machinery/airalarm/examine(mob/user) + . = ..() + switch(buildstage) + if(0) + to_chat(user, "It is missing air alarm electronics.") + if(1) + to_chat(user, "It is missing wiring.") + if(2) + to_chat(user, "Alt-click to [locked ? "unlock" : "lock"] the interface.") + +/obj/machinery/airalarm/ui_status(mob/user) + if(user.has_unlimited_silicon_privilege && aidisabled) + to_chat(user, "AI control has been disabled.") + else if(!shorted) + return ..() + return UI_CLOSE + +/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state) + ui.open() + +/obj/machinery/airalarm/ui_data(mob/user) + var/data = list( + "locked" = locked, + "siliconUser" = user.has_unlimited_silicon_privilege, + "emagged" = (obj_flags & EMAGGED ? 1 : 0), + "danger_level" = danger_level, + ) + + var/area/A = get_area(src) + data["atmos_alarm"] = A.atmosalm + data["fire_alarm"] = A.fire + + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() + var/datum/tlv/cur_tlv + + data["environment_data"] = list() + var/pressure = environment.return_pressure() + cur_tlv = TLV["pressure"] + data["environment_data"] += list(list( + "name" = "Pressure", + "value" = pressure, + "unit" = "kPa", + "danger_level" = cur_tlv.get_danger_level(pressure) + )) + var/temperature = environment.temperature + cur_tlv = TLV["temperature"] + data["environment_data"] += list(list( + "name" = "Temperature", + "value" = temperature, + "unit" = "K ([round(temperature - T0C, 0.1)]C)", + "danger_level" = cur_tlv.get_danger_level(temperature) + )) + var/total_moles = environment.total_moles() + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume + for(var/gas_id in environment.gases) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + cur_tlv = TLV[gas_id] + data["environment_data"] += list(list( + "name" = GLOB.meta_gas_names[gas_id], + "value" = environment.gases[gas_id] / total_moles * 100, + "unit" = "%", + "danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure) + )) + + if(!locked || user.has_unlimited_silicon_privilege) + data["vents"] = list() + for(var/id_tag in A.air_vent_names) + var/long_name = A.air_vent_names[id_tag] + var/list/info = A.air_vent_info[id_tag] + if(!info || info["frequency"] != frequency) + continue + data["vents"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "checks" = info["checks"], + "excheck" = info["checks"]&1, + "incheck" = info["checks"]&2, + "direction" = info["direction"], + "external" = info["external"], + "internal" = info["internal"], + "extdefault"= (info["external"] == ONE_ATMOSPHERE), + "intdefault"= (info["internal"] == 0) + )) + data["scrubbers"] = list() + for(var/id_tag in A.air_scrub_names) + var/long_name = A.air_scrub_names[id_tag] + var/list/info = A.air_scrub_info[id_tag] + if(!info || info["frequency"] != frequency) + continue + data["scrubbers"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "scrubbing" = info["scrubbing"], + "widenet" = info["widenet"], + "filter_types" = info["filter_types"] + )) + data["mode"] = mode + data["modes"] = list() + data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)) + data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0)) + data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0)) + data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 1)) + data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1)) + data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1)) + data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)) + data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)) + if(obj_flags & EMAGGED) + data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1)) + + var/datum/tlv/selected + var/list/thresholds = list() + + selected = TLV["pressure"] + thresholds += list(list("name" = "Pressure", "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) + + selected = TLV["temperature"] + thresholds += list(list("name" = "Temperature", "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) + + for(var/gas_id in GLOB.meta_gas_names) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + selected = TLV[gas_id] + thresholds += list(list("name" = GLOB.meta_gas_names[gas_id], "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2)) + + data["thresholds"] = thresholds + return data + +/obj/machinery/airalarm/ui_act(action, params) + if(..() || buildstage != 2) + return + if((locked && !usr.has_unlimited_silicon_privilege) || (usr.has_unlimited_silicon_privilege && aidisabled)) + return + var/device_id = params["id_tag"] + switch(action) + if("lock") + if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN)) + locked = !locked + . = TRUE + if("power", "toggle_filter", "widenet", "scrubbing") + send_signal(device_id, list("[action]" = params["val"]), usr) + . = TRUE + if("excheck") + send_signal(device_id, list("checks" = text2num(params["val"])^1), usr) + . = TRUE + if("incheck") + send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) + . = TRUE + if("set_external_pressure", "set_internal_pressure") + var/area/A = get_area(src) + var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null + if(!isnull(target) && !..()) + send_signal(device_id, list("[action]" = target), usr) + . = TRUE + if("reset_external_pressure") + send_signal(device_id, list("reset_external_pressure"), usr) + . = TRUE + if("reset_internal_pressure") + send_signal(device_id, list("reset_internal_pressure"), usr) + . = TRUE + if("threshold") + var/env = params["env"] + if(text2path(env)) + env = text2path(env) + + var/name = params["var"] + var/datum/tlv/tlv = TLV[env] + if(isnull(tlv)) + return + var/value = input("New [name] for [env]:", name, tlv.vars[name]) as num|null + if(!isnull(value) && !..()) + if(value < 0) + tlv.vars[name] = -1 + else + tlv.vars[name] = round(value, 0.01) + investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) + . = TRUE + if("mode") + mode = text2num(params["mode"]) + investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS) + apply_mode() + . = TRUE + if("alarm") + var/area/A = get_area(src) + if(A.atmosalert(2, src)) + post_alert(2) + . = TRUE + if("reset") + var/area/A = get_area(src) + if(A.atmosalert(0, src)) + post_alert(0) + . = TRUE + update_icon() + +/obj/machinery/airalarm/proc/reset(wire) + switch(wire) + if(WIRE_POWER) + if(!wires.is_cut(WIRE_POWER)) + shorted = FALSE + update_icon() + if(WIRE_AI) + if(!wires.is_cut(WIRE_AI)) + aidisabled = FALSE + + +/obj/machinery/airalarm/proc/shock(mob/user, prb) + if((stat & (NOPOWER))) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 //you lucked out, no shock for you + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src, 1, TRUE)) + return 1 + else + return 0 + +/obj/machinery/airalarm/proc/refresh_all() + var/area/A = get_area(src) + for(var/id_tag in A.air_vent_names) + var/list/I = A.air_vent_info[id_tag] + if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) + continue + send_signal(id_tag, list("status")) + for(var/id_tag in A.air_scrub_names) + var/list/I = A.air_scrub_info[id_tag] + if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) + continue + send_signal(id_tag, list("status")) + +/obj/machinery/airalarm/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) + +/obj/machinery/airalarm/proc/send_signal(target, list/command, mob/user)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise + if(!radio_connection) + return 0 + + var/datum/signal/signal = new(command) + signal.data["tag"] = target + signal.data["sigtype"] = "command" + signal.data["user"] = user + radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) + + return 1 + +/obj/machinery/airalarm/proc/get_mode_name(mode_value) + switch(mode_value) + if(AALARM_MODE_SCRUBBING) + return "Filtering" + if(AALARM_MODE_CONTAMINATED) + return "Contaminated" + if(AALARM_MODE_VENTING) + return "Draught" + if(AALARM_MODE_REFILL) + return "Refill" + if(AALARM_MODE_PANIC) + return "Panic Siphon" + if(AALARM_MODE_REPLACEMENT) + return "Cycle" + if(AALARM_MODE_SIPHON) + return "Siphon" + if(AALARM_MODE_OFF) + return "Off" + if(AALARM_MODE_FLOOD) + return "Flood" + +/obj/machinery/airalarm/proc/apply_mode() + var/area/A = get_area(src) + switch(mode) + if(AALARM_MODE_SCRUBBING) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), + "scrubbing" = 1, + "widenet" = 0, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE + )) + if(AALARM_MODE_CONTAMINATED) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list( + /datum/gas/carbon_dioxide, + /datum/gas/miasma, + /datum/gas/plasma, + /datum/gas/water_vapor, + /datum/gas/hypernoblium, + /datum/gas/nitrous_oxide, + /datum/gas/nitryl, + /datum/gas/tritium, + /datum/gas/bz, + /datum/gas/stimulum, + /datum/gas/pluoxium + ), + "scrubbing" = 1, + "widenet" = 1, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE + )) + if(AALARM_MODE_VENTING) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE*2 + )) + if(AALARM_MODE_REFILL) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), + "scrubbing" = 1, + "widenet" = 0, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE * 3 + )) + if(AALARM_MODE_PANIC, + AALARM_MODE_REPLACEMENT) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 1, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + if(AALARM_MODE_SIPHON) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + + if(AALARM_MODE_OFF) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + if(AALARM_MODE_FLOOD) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 2, + "set_internal_pressure" = 0 + )) + +/obj/machinery/airalarm/update_icon() + set_light(0) + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + if(stat & NOPOWER) + icon_state = "alarm0" + return + + if(stat & BROKEN) + icon_state = "alarmx" + return + + if(panel_open) + switch(buildstage) + if(2) + icon_state = "alarmx" + if(1) + icon_state = "alarm_b2" + if(0) + icon_state = "alarm_b1" + return + + icon_state = "alarm1" + var/overlay_state = AALARM_OVERLAY_OFF + var/area/A = get_area(src) + switch(max(danger_level, A.atmosalm)) + if(0) + add_overlay(AALARM_OVERLAY_GREEN) + overlay_state = AALARM_OVERLAY_GREEN + light_color = LIGHT_COLOR_GREEN + set_light(brightness_on) + if(1) + add_overlay(AALARM_OVERLAY_WARN) + overlay_state = AALARM_OVERLAY_WARN + light_color = LIGHT_COLOR_LAVA + set_light(brightness_on) + if(2) + add_overlay(AALARM_OVERLAY_DANGER) + overlay_state = AALARM_OVERLAY_DANGER + light_color = LIGHT_COLOR_RED + set_light(brightness_on) + + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + update_light() + +/obj/machinery/airalarm/process() + if((stat & (NOPOWER|BROKEN)) || shorted) + return + + var/turf/location = get_turf(src) + if(!location) + return + + var/datum/tlv/cur_tlv + + var/datum/gas_mixture/environment = location.return_air() + var/list/env_gases = environment.gases + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume + + cur_tlv = TLV["pressure"] + var/environment_pressure = environment.return_pressure() + var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) + + cur_tlv = TLV["temperature"] + var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) + + var/gas_dangerlevel = 0 + for(var/gas_id in env_gases) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + cur_tlv = TLV[gas_id] + gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id] * partial_pressure)) + + GAS_GARBAGE_COLLECT(environment.gases) + + var/old_danger_level = danger_level + danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) + + if(old_danger_level != danger_level) + apply_danger_level() + if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) + mode = AALARM_MODE_SCRUBBING + apply_mode() + + return + + +/obj/machinery/airalarm/proc/post_alert(alert_level) + var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) + + if(!frequency) + return + + var/datum/signal/alert_signal = new(list( + "zone" = get_area_name(src), + "type" = "Atmospheric" + )) + if(alert_level==2) + alert_signal.data["alert"] = "severe" + else if (alert_level==1) + alert_signal.data["alert"] = "minor" + else if (alert_level==0) + alert_signal.data["alert"] = "clear" + + frequency.post_signal(src, alert_signal, range = -1) + +/obj/machinery/airalarm/proc/apply_danger_level() + var/area/A = get_area(src) + + var/new_area_danger_level = 0 + for(var/obj/machinery/airalarm/AA in A) + if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) + new_area_danger_level = max(new_area_danger_level,AA.danger_level) + if(A.atmosalert(new_area_danger_level,src)) //if area was in normal state or if area was in alert state + post_alert(new_area_danger_level) + + update_icon() + +/obj/machinery/airalarm/attackby(obj/item/W, mob/user, params) + switch(buildstage) + if(2) + if(istype(W, /obj/item/wirecutters) && panel_open && wires.is_all_cut()) + W.play_tool_sound(src) + to_chat(user, "You cut the final wires.") + new /obj/item/stack/cable_coil(loc, 5) + buildstage = 1 + update_icon() + return + else if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. + W.play_tool_sound(src) + panel_open = !panel_open + to_chat(user, "The wires have been [panel_open ? "exposed" : "unexposed"].") + update_icon() + return + else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card + togglelock(user) + else if(panel_open && is_wire_tool(W)) + wires.interact(user) + return + if(1) + if(istype(W, /obj/item/crowbar)) + user.visible_message("[user.name] removes the electronics from [src.name].",\ + "You start prying out the circuit...") + W.play_tool_sound(src) + if (W.use_tool(src, user, 20)) + if (buildstage == 1) + to_chat(user, "You remove the air alarm electronics.") + new /obj/item/electronics/airalarm( src.loc ) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + buildstage = 0 + update_icon() + return + + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/cable = W + if(cable.get_amount() < 5) + to_chat(user, "You need five lengths of cable to wire the air alarm!") + return + user.visible_message("[user.name] wires the air alarm.", \ + "You start wiring the air alarm...") + if (do_after(user, 20, target = src)) + if (cable.get_amount() >= 5 && buildstage == 1) + cable.use(5) + to_chat(user, "You wire the air alarm.") + wires.repair() + aidisabled = 0 + locked = FALSE + mode = 1 + shorted = 0 + post_alert(0) + buildstage = 2 + update_icon() + return + if(0) + if(istype(W, /obj/item/electronics/airalarm)) + if(user.temporarilyRemoveItemFromInventory(W)) + to_chat(user, "You insert the circuit.") + buildstage = 1 + update_icon() + qdel(W) + return + + if(istype(W, /obj/item/electroadaptive_pseudocircuit)) + var/obj/item/electroadaptive_pseudocircuit/P = W + if(!P.adapt_circuit(user, 25)) + return + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt an air alarm circuit and slot it into the assembly.") + buildstage = 1 + update_icon() + return + + if(istype(W, /obj/item/wrench)) + to_chat(user, "You detach \the [src] from the wall.") + W.play_tool_sound(src) + new /obj/item/wallframe/airalarm( user.loc ) + qdel(src) + return + + return ..() + +/obj/machinery/airalarm/AltClick(mob/user) + ..() + if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) + return + else + togglelock(user) + +/obj/machinery/airalarm/proc/togglelock(mob/living/user) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "It does nothing!") + else + if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) + locked = !locked + updateUsrDialog() + to_chat(user, "You [ locked ? "lock" : "unlock"] the air alarm interface.") + else + to_chat(user, "Access denied.") + return + +/obj/machinery/airalarm/power_change() + ..() + if(stat & NOPOWER) + set_light(0) + update_icon() + +/obj/machinery/airalarm/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + visible_message("Sparks fly out of [src]!", "You emag [src], disabling its safeties.") + playsound(src, "sparks", 50, 1) + return TRUE + +/obj/machinery/airalarm/obj_break(damage_flag) + ..() + update_icon() + set_light(0) + +/obj/machinery/airalarm/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + new /obj/item/stack/sheet/metal(loc, 2) + var/obj/item/I = new /obj/item/electronics/airalarm(loc) + if(!disassembled) + I.obj_integrity = I.max_integrity * 0.5 + new /obj/item/stack/cable_coil(loc, 3) + qdel(src) + +#undef AALARM_MODE_SCRUBBING +#undef AALARM_MODE_VENTING +#undef AALARM_MODE_PANIC +#undef AALARM_MODE_REPLACEMENT +#undef AALARM_MODE_OFF +#undef AALARM_MODE_FLOOD +#undef AALARM_MODE_SIPHON +#undef AALARM_MODE_CONTAMINATED +#undef AALARM_MODE_REFILL +#undef AALARM_REPORT_TIMEOUT diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index bfe60cd573..35b30107d8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -27,7 +27,7 @@ var/obj/item/radio/radio var/radio_key = /obj/item/encryptionkey/headset_med - var/radio_channel = "Medical" + var/radio_channel = RADIO_CHANNEL_MEDICAL var/running_anim = FALSE @@ -167,10 +167,11 @@ on = FALSE update_icon() playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. - radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language()) + var/msg = "Patient fully restored." if(autoeject) // Eject if configured. - radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language()) + msg += " Auto ejecting patient now." open_machine() + radio.talk_into(src, msg, radio_channel) return var/datum/gas_mixture/air1 = airs[1] diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 8a1bae5e68..b52dc158e4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -1,18 +1,22 @@ /obj/machinery/atmospherics/components/unary/thermomachine - name = "thermomachine" - desc = "Heats or cools gas in connected pipes." icon = 'icons/obj/atmospherics/components/thermomachine.dmi' icon_state = "freezer" - var/icon_state_off = "freezer" - var/icon_state_on = "freezer_1" - var/icon_state_open = "freezer-o" + + name = "thermomachine" + desc = "Heats or cools gas in connected pipes." + density = TRUE max_integrity = 300 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) layer = OBJ_LAYER circuit = /obj/item/circuitboard/machine/thermomachine + pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + var/icon_state_off = "freezer" + var/icon_state_on = "freezer_1" + var/icon_state_open = "freezer-o" + var/min_temperature = 0 var/max_temperature = 0 var/target_temperature = T20C @@ -45,6 +49,13 @@ if(showpipe) add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) +/obj/machinery/atmospherics/components/unary/thermomachine/examine(mob/user) + . = ..() + . += "The thermostat is set to [target_temperature]K ([(T0C-target_temperature)*-1]C)." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Efficiency [(heat_capacity/5000)*100]%." + . += "Temperature range [min_temperature]K - [max_temperature]K ([(T0C-min_temperature)*-1]C - [(T0C-max_temperature)*-1]C)." + /obj/machinery/atmospherics/components/unary/thermomachine/process_atmos() ..() if(!on || !nodes[1]) @@ -155,6 +166,16 @@ update_icon() +/obj/machinery/atmospherics/components/unary/thermomachine/CtrlClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + on = !on + update_icon() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was turned [on ? "on" : "off"] [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/unary/thermomachine/freezer name = "freezer" icon_state = "freezer" @@ -174,6 +195,13 @@ if(target_temperature == initial(target_temperature)) target_temperature = min_temperature +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom + name = "cold room freezer" + +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom/Initialize() + . = ..() + target_temperature = T0C-80 + /obj/machinery/atmospherics/components/unary/thermomachine/freezer/RefreshParts() ..() var/L @@ -181,6 +209,15 @@ L += M.rating min_temperature = max(T0C - (initial(min_temperature) + L * 15), TCMB) //73.15K with T1 stock parts +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/AltClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + target_temperature = min_temperature + investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was minimized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/unary/thermomachine/heater name = "heater" icon_state = "heater" @@ -201,3 +238,12 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) L += M.rating max_temperature = T20C + (initial(max_temperature) * L) //573.15K with T1 stock parts + +/obj/machinery/atmospherics/components/unary/thermomachine/heater/AltClick(mob/living/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + return + target_temperature = max_temperature + investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) + message_admins("[src.name] was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 881e25f138..84f08197b4 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -24,7 +24,6 @@ armour_penetration = 1000 resistance_flags = INDESTRUCTIBLE anchored = TRUE - item_flags = SLOWS_WHILE_IN_HAND var/team = WHITE_TEAM var/reset_cooldown = 0 var/anyonecanpickup = TRUE @@ -497,14 +496,14 @@ W.registered_name = H.real_name W.update_label(W.registered_name, W.assignment) - // The shielded hardsuit is already NODROP + // The shielded hardsuit is already TRAIT_NODROP no_drops += H.get_item_by_slot(SLOT_GLOVES) no_drops += H.get_item_by_slot(SLOT_SHOES) no_drops += H.get_item_by_slot(SLOT_W_UNIFORM) no_drops += H.get_item_by_slot(SLOT_EARS) for(var/i in no_drops) var/obj/item/I = i - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) /datum/outfit/ctf/instagib r_hand = /obj/item/gun/energy/laser/instakill diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 07cc5c8225..74f81ec9a0 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -72,9 +72,9 @@ /obj/effect/mob_spawn/Destroy() GLOB.poi_list -= src var/job_name = job_description ? job_description : name - GLOB.mob_spawners -= job_name + LAZYREMOVE(GLOB.mob_spawners[job_name], src) if(!LAZYLEN(GLOB.mob_spawners[job_name])) - LAZYREMOVE(GLOB.mob_spawners[job_name], src) + GLOB.mob_spawners -= job_name return ..() /obj/effect/mob_spawn/proc/can_latejoin() //If it can be taken from the lobby. diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm index e10d48f3bf..cf2cd7d93c 100644 --- a/code/modules/cargo/bounties/engineering.dm +++ b/code/modules/cargo/bounties/engineering.dm @@ -14,10 +14,10 @@ return FALSE return T.air_contents.gases[gas_type] >= moles_required -/datum/bounty/item/engineering/gas/nitryl_tank - name = "Full Tank of Nitryl" - description = "The non-human staff of Station 88 has been volunteered to test performance enhancing drugs. Ship them a tank full of Nitryl so they can get started." - gas_type = /datum/gas/nitryl +//datum/bounty/item/engineering/gas/nitryl_tank +// name = "Full Tank of Nitryl" +// description = "The non-human staff of Station 88 has been volunteered to test performance enhancing drugs. Ship them a tank full of Nitryl so they can get started." +// gas_type = /datum/gas/nitryl /datum/bounty/item/engineering/gas/tritium_tank name = "Full Tank of Tritium" @@ -37,6 +37,55 @@ required_count = 10 //easy to make wanted_types = list(/obj/machinery/portable_atmospherics/canister) +/datum/bounty/item/engineering/microwave + name = "Microwaves" + description = "Due to a shortage of microwaves, our chefs are incapable of keeping up with our sheer volume of orders. We need at least three microwaves to keep up with our crew's dietary habits." + reward = 2000 + required_count = 3 + wanted_types = list(/obj/machinery/microwave) + +/datum/bounty/item/engineering/hydroponicstrays + name = "Hydroponics Tray" + description = "The garden has become a hot spot of late, they need a few more hydroponics tray to grow more flowers." + reward = 2500 + required_count = 5 + wanted_types = list(/obj/machinery/hydroponics) + +/datum/bounty/item/engineering/rcd + name = "Spare RCD" + description = "Construction and repairs to are shuttles are going slowly. As it turns out, we're a little short on RCDs, can you send us a few?" + reward = 2500 + required_count = 3 + wanted_types = list(/obj/item/construction/rcd) + +/datum/bounty/item/engineering/rpd + name = "Spare RPD" + description = "Our Atmospheric Technicians are still living in the past, relying on stationary pipe dispensers to produce the pipes necessary to accomplish their strenuous tasks. They could use an upgrade. Could you send us some Rapid Pipe Dispensers?" + reward = 3000 + required_count = 3 + wanted_types = list(/obj/item/pipe_dispenser) + +/datum/bounty/item/engineering/heaters + name = "Space Heaters" + description = "The kitchen freezer was left open and now the whole place is frozen solid! We need a few space heaters to warm it back up before anyone gets hungry." + reward = 3000 + required_count = 5 + wanted_types = list(/obj/machinery/space_heater) + +/datum/bounty/item/engineering/arcadetrail + name = "Orion Trail Arcade Games" + description = "The staff have nothing to do when off-work. Can you send us some Orion Trail games to play?" + reward = 3000 + required_count = 5 + wanted_types = list(/obj/machinery/computer/arcade/orion_trail) + +/datum/bounty/item/engineering/arcadebattle + name = "Battle Arcade Games" + description = "The staff have nothing to do when off-work. Can you send us some Battle Arcade games to play?" + reward = 3000 + required_count = 5 + wanted_types = list(/obj/machinery/computer/arcade/battle) + /datum/bounty/item/engineering/energy_ball name = "Contained Tesla Ball" description = "Station 24 is being overrun by hordes of angry Mothpeople. They are requesting the ultimate bug zapper." diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index b5b9a616d0..1a607b4b96 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -36,6 +36,7 @@ cat |= EXPORT_EMAG /obj/machinery/computer/cargo/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return user.visible_message("[user] swipes a suspicious card through [src]!", @@ -48,6 +49,8 @@ var/obj/item/circuitboard/computer/cargo/board = circuit board.contraband = TRUE board.obj_flags |= EMAGGED + req_access = list() + return TRUE /obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) diff --git a/code/modules/cargo/exports/manifest.dm b/code/modules/cargo/exports/manifest.dm index 02b060e0bf..d03f5a46ce 100644 --- a/code/modules/cargo/exports/manifest.dm +++ b/code/modules/cargo/exports/manifest.dm @@ -81,6 +81,7 @@ /datum/export/paperwork_correct cost = 150 + k_elasticity = 0 unit_name = "correct paperwork" export_types = list(/obj/item/folder/paperwork_correct) @@ -88,5 +89,6 @@ /datum/export/paperwork_incorrect cost = -500 // Failed to meet NT standers + k_elasticity = 0 unit_name = "returned incorrect paperwork" export_types = list(/obj/item/folder/paperwork) diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 5288c27ff6..0097346a34 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -54,6 +54,7 @@ ..() /obj/machinery/computer/cargo/express/emag_act(mob/living/user) + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) if(obj_flags & EMAGGED) return user.visible_message("[user] swipes a suspicious card through [src]!", @@ -63,6 +64,8 @@ var/obj/item/circuitboard/computer/cargo/board = circuit board.obj_flags |= EMAGGED packin_up() + req_access = list() + return TRUE /obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry meme_pack_data = list() // sorry for what? diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 46cc1fa93c..1087f1ebb5 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -252,6 +252,17 @@ crate_name = "space suit crate" crate_type = /obj/structure/closet/crate/secure +/datum/supply_pack/emergency/spacejets + name = "Spare EVA Jetpacks" + desc = "Contains three EVA grade jectpaks. Requires EVA access to open." + cost = 2000 + access = ACCESS_EVA + contains = list(/obj/item/tank/jetpack/carbondioxide/eva, + /obj/item/tank/jetpack/carbondioxide/eva, + /obj/item/tank/jetpack/carbondioxide/eva) + crate_name = "eva jetpacks crate" + crate_type = /obj/structure/closet/crate/secure + /datum/supply_pack/emergency/specialops name = "Special Ops Supplies" desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$" @@ -339,15 +350,6 @@ /obj/item/clothing/head/fedora/det_hat) crate_name = "forensics crate" -/datum/supply_pack/security/sechardsuit - name = "Sec Hardsuit" - desc = "One Sec Hardsuit with a small air tank and mask." - cost = 3000 // half of SWAT gear for have the armor and half the gear - contains = list(/obj/item/clothing/suit/space/hardsuit/security, - /obj/item/tank/internals/air, - /obj/item/clothing/mask/gas) - crate_name = "sec hardsuit crate" - /datum/supply_pack/security/helmets name = "Helmets Crate" desc = "Contains three standard-issue brain buckets. Requires Security access to open." @@ -366,6 +368,55 @@ /obj/item/gun/energy/laser) crate_name = "laser crate" +/datum/supply_pack/security/russianclothing + name = "Russian Surplus Clothing" + desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!" + contraband = TRUE + cost = 5000 // Its basicly sec suits, good boots/gloves + contains = list(/obj/item/clothing/suit/security/officer/russian, + /obj/item/clothing/suit/security/officer/russian, + /obj/item/clothing/shoes/combat, + /obj/item/clothing/shoes/combat, + /obj/item/clothing/head/ushanka, + /obj/item/clothing/head/ushanka, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/head/helmet/alt, + /obj/item/clothing/head/helmet/alt, + /obj/item/clothing/gloves/combat, + /obj/item/clothing/gloves/combat, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas) + crate_name = "surplus russian clothing" + crate_type = /obj/structure/closet/crate/internals + +/datum/supply_pack/security/russianmosin + name = "Russian Minutemen Gear" + desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip." + contraband = TRUE + access = FALSE + cost = 5000 // + contains = list(/obj/item/clothing/suit/security/officer/russian, + /obj/item/clothing/shoes/combat, + /obj/item/clothing/head/ushanka, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/head/helmet/alt, + /obj/item/clothing/gloves/combat, + /obj/item/clothing/mask/gas, + /obj/item/gun/ballistic/shotgun/boltaction, + /obj/item/ammo_box/a762) + crate_name = "surplus russian gear" + crate_type = /obj/structure/closet/crate/internals + +/datum/supply_pack/security/sechardsuit + name = "Sec Hardsuit" + desc = "One Sec Hardsuit with a small air tank and mask." + cost = 3000 // half of SWAT gear for have the armor and half the gear + contains = list(/obj/item/clothing/suit/space/hardsuit/security, + /obj/item/tank/internals/air, + /obj/item/clothing/mask/gas) + crate_name = "sec hardsuit crate" + /datum/supply_pack/security/securitybarriers name = "Security Barrier Grenades" desc = "Stem the tide with four Security Barrier grenades. Requires Security access to open." @@ -430,28 +481,6 @@ /obj/item/melee/baton/loaded) crate_name = "stun baton crate" -/datum/supply_pack/security/russianclothing - name = "Russian Surplus Clothing" - desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!" - contraband = TRUE - cost = 5000 // Its basicly sec suits, good boots/gloves - contains = list(/obj/item/clothing/suit/security/officer/russian, - /obj/item/clothing/suit/security/officer/russian, - /obj/item/clothing/shoes/combat, - /obj/item/clothing/shoes/combat, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/head/helmet/alt, - /obj/item/clothing/head/helmet/alt, - /obj/item/clothing/gloves/combat, - /obj/item/clothing/gloves/combat, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas) - crate_name = "surplus russian clothing" - crate_type = /obj/structure/closet/crate/internals - /datum/supply_pack/security/taser name = "Taser Crate" desc = "From the depths of stunbased combat, this order rises above, supreme. Contains three hybrid tasers, capable of firing both electrodes and disabling shots. Requires Security access to open." @@ -665,6 +694,15 @@ /obj/item/gun/energy/e_gun/stun) crate_name = "swat taser crate" +/datum/supply_pack/security/armory/woodstock + name = "Classic WoodStock Shotguns Crate" + desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open." + cost = 3500 + contains = list(/obj/item/gun/ballistic/shotgun, + /obj/item/gun/ballistic/shotgun, + /obj/item/gun/ballistic/shotgun) + crate_name = "woodstock shotguns crate" + /datum/supply_pack/security/armory/wt550 name = "WT-550 Semi-Auto Rifle Crate" desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open." @@ -1633,7 +1671,7 @@ /obj/item/caution, /obj/item/storage/bag/trash, /obj/item/reagent_containers/spray/cleaner, - /obj/item/reagent_containers/glass/rag, + /obj/item/reagent_containers/rag, /obj/item/grenade/chem_grenade/cleaner, /obj/item/grenade/chem_grenade/cleaner, /obj/item/grenade/chem_grenade/cleaner, @@ -1661,17 +1699,28 @@ /datum/supply_pack/service/janitor/janpremium name = "Janitor Premium Supplies" desc = "Do to the union for better supplies, we have desided to make a deal for you, In this crate you can get a brand new chem, Drying Angent this stuff is the work of slimes or magic! This crate also contains a rag to test out the Drying Angent magic, three wet floor signs, and some spare bottles of ammonia." - cost = 3000 + cost = 1750 access = ACCESS_JANITOR contains = list(/obj/item/caution, /obj/item/caution, /obj/item/caution, - /obj/item/reagent_containers/glass/rag, + /obj/item/reagent_containers/rag, + /obj/item/reagent_containers/glass/bottle/ammonia, /obj/item/reagent_containers/glass/bottle/ammonia, /obj/item/reagent_containers/glass/bottle/ammonia, /obj/item/reagent_containers/spray/drying_agent) crate_name = "janitor backpack crate" +/datum/supply_pack/service/janitor/janpimp + name = "Custodial Cruiser" + desc = "Clown steal your ride? Assistant lock it in the dorms? Order a new one and get back to cleaning in style!" + cost = 3000 + access = ACCESS_JANITOR + contains = list(/obj/vehicle/ridden/janicart, + /obj/item/key/janitor) + crate_name = "janitor ride crate" + crate_type = /obj/structure/closet/crate/large + /datum/supply_pack/service/mule name = "MULEbot Crate" desc = "Pink-haired Quartermaster not doing her job? Replace her with this tireless worker, today!" @@ -1968,7 +2017,8 @@ /obj/item/storage/box/mre/menu1/safe, /obj/item/storage/box/mre/menu2/safe, /obj/item/storage/box/mre/menu2/safe, - /obj/item/storage/box/mre/menu3) + /obj/item/storage/box/mre/menu3, + /obj/item/storage/box/mre/menu4/safe) crate_name = "MRE crate (emergency rations)" /datum/supply_pack/organic/pizza @@ -2195,6 +2245,12 @@ /obj/item/clothing/neck/petcollar) crate_name = "pug crate" +/datum/supply_pack/organic/critter/kiwi + name = "Space kiwi Crate" + cost = 2000 + contains = list( /mob/living/simple_animal/kiwi) + crate_name = "space kiwi crate" + /datum/supply_pack/critter/snake name = "Snake Crate" desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? Then this isn't the crate for you. Contains three poisonous snakes." @@ -2204,6 +2260,17 @@ /mob/living/simple_animal/hostile/retaliate/poison/snake) crate_name = "snake crate" +/datum/supply_pack/critter/secbat + name = "Security Bat Crate" + desc = "Contains five security bats, perfect to Bat-up any security officer." + cost = 2500 + contains = list(/mob/living/simple_animal/hostile/retaliate/bat/secbat, + /mob/living/simple_animal/hostile/retaliate/bat/secbat, + /mob/living/simple_animal/hostile/retaliate/bat/secbat, + /mob/living/simple_animal/hostile/retaliate/bat/secbat, + /mob/living/simple_animal/hostile/retaliate/bat/secbat) + crate_name = "security bat crate" + ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Costumes & Toys ///////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -2561,6 +2628,13 @@ /obj/item/vending_refill/wardrobe/law_wardrobe) crate_name = "security department supply crate" +/datum/supply_pack/costumes_toys/kinkmate + name = "Kinkmate construction kit" + cost = 2000 + contraband = TRUE + contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate) + crate_name = "Kinkmate construction kit" + ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Miscellaneous /////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -2674,6 +2748,26 @@ crate_type = /obj/structure/closet/crate/wooden crate_name = "festive wrapping paper crate" +/datum/supply_pack/misc/paper_work + name = "Freelance Paper work" + desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up. + cost = 700 // Net of 0 credits + contains = list(/obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/pen/fountain, + /obj/item/pen/fountain, + /obj/item/pen/fountain, + /obj/item/pen/fountain, + /obj/item/pen/fountain) + crate_name = "Paperwork" /datum/supply_pack/misc/funeral name = "Funeral Supply crate" @@ -2686,18 +2780,11 @@ crate_name = "coffin" crate_type = /obj/structure/closet/crate/coffin -/datum/supply_pack/misc/religious_supplies - name = "Religious Supplies Crate" - desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets." - cost = 4000 // it costs so much because the Space Church is ran by Space Jews - contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater, - /obj/item/reagent_containers/food/drinks/bottle/holywater, - /obj/item/storage/book/bible/booze, - /obj/item/storage/book/bible/booze, - /obj/item/clothing/suit/hooded/chaplain_hoodie, - /obj/item/clothing/suit/hooded/chaplain_hoodie - ) - crate_name = "religious supplies crate" +/datum/supply_pack/misc/jukebox + name = "Jukebox" + cost = 35000 + contains = list(/obj/machinery/jukebox) + crate_name = "Jukebox" /datum/supply_pack/misc/lewd name = "Lewd Crate" // OwO @@ -2730,26 +2817,18 @@ crate_name = "deluxe keg" crate_type = /obj/structure/closet/crate -/datum/supply_pack/misc/paper_work - name = "Freelance Paper work" - desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up. - cost = 400 // Net of 0 credits - contains = list(/obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/folder/paperwork, - /obj/item/pen/fountain, - /obj/item/pen/fountain, - /obj/item/pen/fountain, - /obj/item/pen/fountain, - /obj/item/pen/fountain) - crate_name = "Paperwork" +/datum/supply_pack/misc/religious_supplies + name = "Religious Supplies Crate" + desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets." + cost = 4000 // it costs so much because the Space Church is ran by Space Jews + contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater, + /obj/item/reagent_containers/food/drinks/bottle/holywater, + /obj/item/storage/book/bible/booze, + /obj/item/storage/book/bible/booze, + /obj/item/clothing/suit/hooded/chaplain_hoodie, + /obj/item/clothing/suit/hooded/chaplain_hoodie + ) + crate_name = "religious supplies crate" /datum/supply_pack/misc/randomised/promiscuous name = "Promiscuous Organs" @@ -2775,4 +2854,3 @@ /obj/item/toner, /obj/item/toner) crate_name = "toner crate" - diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 5a33d8bd44..89e221c339 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -29,7 +29,7 @@ var/effectQuiet = FALSE //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc) var/effectMissile = FALSE //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground var/effectCircle = FALSE //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here - var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod. + var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod. var/reversing = FALSE //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom var/landingSound //Admin sound to play when the pod lands var/openingSound //Admin sound to play when the pod opens @@ -76,7 +76,7 @@ /obj/structure/closet/supplypod/tool_interact(obj/item/W, mob/user) if (bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways. - return FALSE + return FALSE else ..() @@ -86,13 +86,15 @@ /obj/structure/closet/supplypod/contents_explosion() //Supplypods also protect their contents from the harmful effects of fucking exploding. return +/obj/structure/closet/supplypod/prevent_content_explosion() //Useful for preventing epicenter explosions from damaging contents + return TRUE + /obj/structure/closet/supplypod/toggle(mob/living/user) //Supplypods shouldn't be able to be manually opened under any circumstances, as the open() proc generates supply order datums return /obj/structure/closet/supplypod/proc/preOpen() //Called before the open() proc. Handles anything that occurs right as the pod lands. var/turf/T = get_turf(src) var/list/B = explosionSize //Mostly because B is more readable than explosionSize :p - var/boomTotal = 0 //A counter used to check if the explosion does nothing if (landingSound) playsound(get_turf(src), landingSound, soundVolume, 0, 0) for (var/mob/living/M in T) @@ -108,10 +110,8 @@ M.gib() //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs M.adjustBruteLoss(damage) - for (var/i in B) - boomTotal += i //Count up all the values of the explosion - if (boomTotal != 0) //If the explosion list isn't all zeroes, call an explosion + if (B[1] || B[2] || B[3] || B[4]) //If the explosion list isn't all zeroes, call an explosion explosion(get_turf(src), B[1], B[2], B[3], flame_range = B[4], silent = effectQuiet, ignorecap = istype(src, /obj/structure/closet/supplypod/centcompod)) //less advanced equipment than bluespace pod, so larger explosion when landing else if (!effectQuiet) //If our explosion list IS all zeroes, we still make a nice explosion sound (unless the effectQuiet var is true) playsound(src, "explosion", landingSound ? 15 : 80, 1) @@ -150,10 +150,10 @@ playsound(get_turf(holder), leavingSound, soundVolume, 0, 0) if (reversing) //If we're reversing, we call the close proc. This sends the pod back up to centcom close(holder) - else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists) - if (style != STYLE_INVISIBLE) + else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists) + if (style != STYLE_INVISIBLE) do_sparks(5, TRUE, holder) //Create some sparks right before closing - qdel(src) //Delete ourselves and the holder + qdel(src) //Delete ourselves and the holder if (holder != src) qdel(holder) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 10e98e92b8..5402353fd4 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -470,19 +470,46 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/spritesheet/simple/minesweeper name = "minesweeper" assets = list( - "1" = 'icons/misc/minesweeper_tiles/one.png', - "2" = 'icons/misc/minesweeper_tiles/two.png', - "3" = 'icons/misc/minesweeper_tiles/three.png', - "4" = 'icons/misc/minesweeper_tiles/four.png', - "5" = 'icons/misc/minesweeper_tiles/five.png', - "6" = 'icons/misc/minesweeper_tiles/six.png', - "7" = 'icons/misc/minesweeper_tiles/seven.png', - "8" = 'icons/misc/minesweeper_tiles/eight.png', - "empty" = 'icons/misc/minesweeper_tiles/empty.png', - "flag" = 'icons/misc/minesweeper_tiles/flag.png', - "hidden" = 'icons/misc/minesweeper_tiles/hidden.png', - "mine" = 'icons/misc/minesweeper_tiles/mine.png', - "minehit" = 'icons/misc/minesweeper_tiles/minehit.png' + "1" = 'icons/UI_Icons/minesweeper_tiles/one.png', + "2" = 'icons/UI_Icons/minesweeper_tiles/two.png', + "3" = 'icons/UI_Icons/minesweeper_tiles/three.png', + "4" = 'icons/UI_Icons/minesweeper_tiles/four.png', + "5" = 'icons/UI_Icons/minesweeper_tiles/five.png', + "6" = 'icons/UI_Icons/minesweeper_tiles/six.png', + "7" = 'icons/UI_Icons/minesweeper_tiles/seven.png', + "8" = 'icons/UI_Icons/minesweeper_tiles/eight.png', + "empty" = 'icons/UI_Icons/minesweeper_tiles/empty.png', + "flag" = 'icons/UI_Icons/minesweeper_tiles/flag.png', + "hidden" = 'icons/UI_Icons/minesweeper_tiles/hidden.png', + "mine" = 'icons/UI_Icons/minesweeper_tiles/mine.png', + "minehit" = 'icons/UI_Icons/minesweeper_tiles/minehit.png' + ) + +/datum/asset/spritesheet/simple/pills + name = "pills" + assets = list( + "pill1" = 'icons/UI_Icons/Pills/pill1.png', + "pill2" = 'icons/UI_Icons/Pills/pill2.png', + "pill3" = 'icons/UI_Icons/Pills/pill3.png', + "pill4" = 'icons/UI_Icons/Pills/pill4.png', + "pill5" = 'icons/UI_Icons/Pills/pill5.png', + "pill6" = 'icons/UI_Icons/Pills/pill6.png', + "pill7" = 'icons/UI_Icons/Pills/pill7.png', + "pill8" = 'icons/UI_Icons/Pills/pill8.png', + "pill9" = 'icons/UI_Icons/Pills/pill9.png', + "pill10" = 'icons/UI_Icons/Pills/pill10.png', + "pill11" = 'icons/UI_Icons/Pills/pill11.png', + "pill12" = 'icons/UI_Icons/Pills/pill12.png', + "pill13" = 'icons/UI_Icons/Pills/pill13.png', + "pill14" = 'icons/UI_Icons/Pills/pill14.png', + "pill15" = 'icons/UI_Icons/Pills/pill15.png', + "pill16" = 'icons/UI_Icons/Pills/pill16.png', + "pill17" = 'icons/UI_Icons/Pills/pill17.png', + "pill18" = 'icons/UI_Icons/Pills/pill18.png', + "pill19" = 'icons/UI_Icons/Pills/pill19.png', + "pill20" = 'icons/UI_Icons/Pills/pill20.png', + "pill21" = 'icons/UI_Icons/Pills/pill21.png', + "pill22" = 'icons/UI_Icons/Pills/pill22.png', ) /datum/asset/simple/IRV diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 06f23574e1..5442fcb932 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -817,6 +817,10 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) var/file = GLOB.vox_sounds[name] Export("##action=load_rsc", file) stoplag() + for (var/name in GLOB.vox_sounds_male) + var/file = GLOB.vox_sounds_male[name] + Export("##action=load_rsc", file) + stoplag() #endif diff --git a/code/modules/client/darkmode.dm b/code/modules/client/darkmode.dm new file mode 100644 index 0000000000..9e8d136b3b --- /dev/null +++ b/code/modules/client/darkmode.dm @@ -0,0 +1,117 @@ +//Darkmode preference by Kmc2000// + +/* +This lets you switch chat themes by using winset and CSS loading, you must relog to see this change (or rebuild your browseroutput datum) +Things to note: +If you change ANYTHING in interface/skin.dmf you need to change it here: +Format: +winset(src, "window as appears in skin.dmf after elem", "var to change = currentvalue;var to change = desired value") +How this works: +I've added a function to browseroutput.js which registers a cookie for darkmode and swaps the chat accordingly. You can find the button to do this under the "cog" icon next to the ping button (top right of chat) +This then swaps the window theme automatically +Thanks to spacemaniac and mcdonald for help with the JS side of this. +*/ + +/client/proc/force_white_theme() //There's no way round it. We're essentially changing the skin by hand. It's painful but it works, and is the way Lummox suggested. + //Main windows + winset(src, "infowindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "infowindow", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "info", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]") + winset(src, "info", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "browseroutput", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "browseroutput", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "outputwindow", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "outputwindow", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "mainwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "split", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]") + //Buttons + winset(src, "changelog", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]") + winset(src, "changelog", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "rules", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]") + winset(src, "rules", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "wiki", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]") + winset(src, "wiki", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "forum", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]") + winset(src, "forum", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "github", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]") + winset(src, "github", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "report-issue", "background-color = [COLOR_DARKMODE_ISSUE_BUTTON_BG];background-color = [COLOR_WHITEMODE_ISSUE_BUTTON_BG]") + winset(src, "report-issue", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + //Status and verb tabs + winset(src, "output", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]") + winset(src, "output", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "statwindow", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "statwindow", "text-color = #eaeaea;text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]") + winset(src, "stat", "tab-background-color = [COLOR_DARKMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "stat", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "stat", "tab-text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "stat", "prefix-color = [COLOR_DARKMODE_TEXT];prefix-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "stat", "suffix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]") + //Etc. + winset(src, "say", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "say", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") + winset(src, "asset_cache_browser", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]") + winset(src, "tooltip", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]") + +/client/proc/force_dark_theme() //Inversely, if theyre using white theme and want to swap to the superior dark theme, let's get WINSET() ing + //Main windows + winset(src, "infowindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]") + winset(src, "infowindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "info", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "info", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "browseroutput", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "browseroutput", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "outputwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "outputwindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "mainwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]") + winset(src, "split", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + //Buttons + winset(src, "changelog", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "changelog", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "rules", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "rules", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "wiki", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "wiki", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "forum", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "forum", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "github", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]") + winset(src, "github", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "report-issue", "background-color = [COLOR_WHITEMODE_ISSUE_BUTTON_BG];background-color = [COLOR_DARKMODE_ISSUE_BUTTON_BG]") + winset(src, "report-issue", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + //Status and verb tabs + winset(src, "output", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "output", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "statwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]") + winset(src, "statwindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]") + winset(src, "stat", "tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "stat", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "stat", "tab-text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "stat", "prefix-color = [COLOR_WHITEMODE_TEXT];prefix-color = [COLOR_DARKMODE_TEXT]") + winset(src, "stat", "suffix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]") + //Etc. + winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "say", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "asset_cache_browser", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + winset(src, "tooltip", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]") + winset(src, "tooltip", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]") + + +/datum/asset/simple/goonchat + verify = FALSE + assets = list( + "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js', + "errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js', + "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js', + "fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot', + "fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg', + "fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf', + "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff', + "font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css', + "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', + "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css', + ) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7a6fdad721..d487b873b1 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -29,7 +29,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) //game-preferences var/lastchangelog = "" //Saved changlog filesize to detect if there was a change - var/ooccolor = null + var/ooccolor = "#c43b23" + var/aooccolor = "#ce254f" var/enable_tips = TRUE var/tip_delay = 500 //tip delay in milliseconds @@ -71,9 +72,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/underwear = "Nude" //underwear type + var/undie_color = "FFF" var/undershirt = "Nude" //undershirt type + var/shirt_color = "FFF" var/socks = "Nude" //socks type + var/socks_color = "FFF" var/backbag = DBACKPACK //backpack type + var/jumpsuit_style = PREF_SUIT //suit/skirt var/hair_style = "Bald" //Hair type var/hair_color = "000" //Hair color var/facial_hair_style = "Shaved" //Face hair type @@ -139,6 +144,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) "breasts_size" = "C", "breasts_shape" = "Pair", "breasts_fluid" = "milk", + "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = "Human", "vag_color" = "fff", @@ -674,9 +680,16 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" @@ -731,6 +744,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "   Change
    " dat += "Cup Size:[features["breasts_size"]]" dat += "Breast Shape:[features["breasts_shape"]]" + dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" dat += "" dat += "" dat += "
    " dat += "

    Clothing & Equipment

    " dat += "Underwear:[underwear]" + if(UNDIE_COLORABLE(GLOB.underwear_list[underwear])) + dat += "Underwear Color:[undie_color]" dat += "Undershirt:[undershirt]" + if(UNDIE_COLORABLE(GLOB.undershirt_list[undershirt])) + dat += "Undershirt Color:[shirt_color]" dat += "Socks:[socks]" + if(UNDIE_COLORABLE(GLOB.socks_list[socks])) + dat += "Socks Color:[socks_color]" dat += "Backpack:[backbag]" + dat += "Jumpsuit:
    [jumpsuit_style]
    " dat += "Uplink Location:[uplink_spawn_loc]" dat += "
    " @@ -765,6 +779,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
    " if(unlock_content || check_rights_for(user.client, R_ADMIN)) dat += "OOC Color:     Change
    " + dat += "Antag OOC Color:     Change
    " + dat += "" if(user.client.holder) dat +="" @@ -782,6 +798,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Voracious MediHound sleepers: [(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]
    " dat += "Hear Vore Sounds: [(cit_toggles & EATING_NOISES) ? "Yes" : "No"]
    " dat += "Hear Vore Digestion Sounds: [(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]
    " + dat += "Lewdchem:[lewdchem == TRUE ? "Enabled" : "Disabled"]
    " dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
    " dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
    " dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
    " @@ -902,11 +919,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Description" for(var/j in GLOB.loadout_items[gear_tab]) var/datum/gear/gear = GLOB.loadout_items[gear_tab][j] - var/donoritem - if(gear.ckeywhitelist && gear.ckeywhitelist.len) - donoritem = TRUE - if(!(user.ckey in gear.ckeywhitelist)) - continue + var/donoritem = gear.donoritem + if(donoritem && !gear.donator_ckey_check(user.ckey)) + continue var/class_link = "" if(gear.type in chosen_gear) class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=0'" @@ -1398,16 +1413,21 @@ GLOBAL_LIST_EMPTY(preferences_datums) facial_hair_style = random_facial_hair_style(gender) if("underwear") underwear = random_underwear(gender) + undie_color = random_short_color() if("undershirt") undershirt = random_undershirt(gender) + shirt_color = random_short_color() if("socks") socks = random_socks() + socks_color = random_short_color() if(BODY_ZONE_PRECISE_EYES) eye_color = random_eye_color() if("s_tone") skin_tone = random_skin_tone() if("bag") backbag = pick(GLOB.backbaglist) + if("suit") + jumpsuit_style = pick(GLOB.jumpsuitlist) if("all") random_character() @@ -1507,29 +1527,35 @@ GLOBAL_LIST_EMPTY(preferences_datums) bgstate = next_list_item(bgstate, bgstate_options) if("underwear") - var/new_underwear - if(gender == MALE) - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m - else - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f + var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list if(new_underwear) underwear = new_underwear + if("undie_color") + var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", undie_color) as color|null + if(n_undie_color) + undie_color = sanitize_hexcolor(n_undie_color) + if("undershirt") - var/new_undershirt - if(gender == MALE) - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m - else - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f + var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list if(new_undershirt) undershirt = new_undershirt + if("shirt_color") + var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", shirt_color) as color|null + if(n_shirt_color) + shirt_color = sanitize_hexcolor(n_shirt_color) + if("socks") - var/new_socks - new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list + var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list if(new_socks) socks = new_socks + if("socks_color") + var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", socks_color) as color|null + if(n_socks_color) + socks_color = sanitize_hexcolor(n_socks_color) + if("eyes") var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null if(new_eyes) @@ -1933,11 +1959,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_ooccolor) ooccolor = new_ooccolor + if("aooccolor") + var/new_aooccolor = input(user, "Choose your Antag OOC colour:", "Game Preference",ooccolor) as color|null + if(new_aooccolor) + aooccolor = new_aooccolor + if("bag") var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist if(new_backbag) backbag = new_backbag + if("suit") + if(jumpsuit_style == PREF_SUIT) + jumpsuit_style = PREF_SKIRT + else + jumpsuit_style = PREF_SUIT + + if("uplink_loc") var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list if(new_loc) @@ -2000,6 +2038,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["genitals_use_skintone"] = !features["genitals_use_skintone"] if("arousable") arousable = !arousable + if("lewdchem") + lewdchem = !lewdchem if("has_cock") features["has_cock"] = !features["has_cock"] if(features["has_cock"] == FALSE) @@ -2016,6 +2056,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["eggsack_internal"] = !features["eggsack_internal"] if("has_breasts") features["has_breasts"] = !features["has_breasts"] + if(features["has_breasts"] == FALSE) + features["breasts_producing"] = FALSE + if("breasts_producing") + features["breasts_producing"] = !features["breasts_producing"] if("has_vag") features["has_vag"] = !features["has_vag"] if(features["has_vag"] == FALSE) @@ -2199,7 +2243,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(!is_loadout_slot_available(G.category)) to_chat(user, "You cannot take this loadout, as you've already chosen too many of the same category!") return - if(G.ckeywhitelist && G.ckeywhitelist.len && !(user.ckey in G.ckeywhitelist)) + if(G.donoritem && !G.donator_ckey_check(user.ckey)) to_chat(user, "This is an item intended for donator use only. You are not authorized to use this item.") return if(gear_points >= initial(G.cost)) @@ -2246,13 +2290,19 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.hair_style = hair_style character.facial_hair_style = facial_hair_style character.underwear = underwear + character.saved_underwear = underwear character.undershirt = undershirt character.saved_undershirt = undershirt character.socks = socks character.saved_socks = socks + character.undie_color = undie_color + character.shirt_color = shirt_color + character.socks_color = socks_color + character.backbag = backbag + character.jumpsuit_style = jumpsuit_style var/datum/species/chosen_species if(!roundstart_checks || (pref_species.id in GLOB.roundstart_races)) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index e8a76c63a4..7911d92495 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -117,6 +117,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["widescreenpref"] >> widescreenpref S["autostand"] >> autostand S["cit_toggles"] >> cit_toggles + S["lewdchem"] >> lewdchem //try to fix any outdated data if necessary if(needs_update >= 0) @@ -211,6 +212,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["widescreenpref"], widescreenpref) WRITE_FILE(S["autostand"], autostand) WRITE_FILE(S["cit_toggles"], cit_toggles) + WRITE_FILE(S["lewdchem"], lewdchem) return 1 @@ -266,9 +268,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["hair_style_name"] >> hair_style S["facial_style_name"] >> facial_hair_style S["underwear"] >> underwear + S["undie_color"] >> undie_color S["undershirt"] >> undershirt + S["shirt_color"] >> shirt_color S["socks"] >> socks + S["socks_color"] >> socks_color S["backbag"] >> backbag + S["jumpsuit_style"] >> jumpsuit_style S["uplink_loc"] >> uplink_spawn_loc S["feature_mcolor"] >> features["mcolor"] S["feature_lizard_tail"] >> features["tail_lizard"] @@ -343,6 +349,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_breasts_shape"] >> features["breasts_shape"] S["feature_breasts_color"] >> features["breasts_color"] S["feature_breasts_fluid"] >> features["breasts_fluid"] + S["feature_breasts_producing"] >> features["breasts_producing"] //vagina features S["feature_has_vag"] >> features["has_vag"] S["feature_vag_shape"] >> features["vag_shape"] @@ -388,20 +395,22 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(gender == MALE) hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_male_list) facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_male_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_m) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_m) else hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_female_list) facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_female_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_f) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_f) + underwear = sanitize_inlist(underwear, GLOB.underwear_list) + undie_color = sanitize_hexcolor(undie_color, 6, 1, initial(undie_color)) + undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) + shirt_color = sanitize_hexcolor(shirt_color, 6, 1, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) + socks_color = sanitize_hexcolor(socks_color, 6, 1, initial(socks_color)) age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) hair_color = sanitize_hexcolor(hair_color, 3, 0) facial_hair_color = sanitize_hexcolor(facial_hair_color, 3, 0) eye_color = sanitize_hexcolor(eye_color, 3, 0) skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones) backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) + jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) features["mcolor"] = sanitize_hexcolor(features["mcolor"], 3, 0) features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) @@ -465,9 +474,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["hair_style_name"] , hair_style) WRITE_FILE(S["facial_style_name"] , facial_hair_style) WRITE_FILE(S["underwear"] , underwear) + WRITE_FILE(S["undie_color"] , undie_color) WRITE_FILE(S["undershirt"] , undershirt) + WRITE_FILE(S["shirt_color"] , shirt_color) WRITE_FILE(S["socks"] , socks) - WRITE_FILE(S["backbag"] , backbag) + WRITE_FILE(S["socks_color"] , socks_color) + WRITE_FILE(S["backbag"] , backbag) + WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style) WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc) WRITE_FILE(S["species"] , pref_species.id) WRITE_FILE(S["feature_mcolor"] , features["mcolor"]) diff --git a/code/modules/client/verbs/aooc.dm b/code/modules/client/verbs/aooc.dm index 893501a852..311c22955d 100644 --- a/code/modules/client/verbs/aooc.dm +++ b/code/modules/client/verbs/aooc.dm @@ -1,3 +1,6 @@ +GLOBAL_VAR_INIT(AOOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour. +GLOBAL_VAR_INIT(normal_aooc_colour, "#ce254f") + /client/verb/aooc(msg as text) set name = "AOOC" set desc = "An OOC channel exclusive to antagonists." @@ -50,7 +53,7 @@ var/keyname = key if(prefs.unlock_content) if(prefs.toggles & MEMBER_PUBLIC) - keyname = "[icon2html('icons/member_content.dmi', world, "blag")][keyname]" + keyname = "[icon2html('icons/member_content.dmi', world, "blag")][keyname]" //The linkify span classes and linkify=TRUE below make ooc text get clickable chat href links if you pass in something resembling a url var/antaglisting = list() @@ -74,23 +77,27 @@ else to_chat(C, "Antag OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg]") else - to_chat(C, "Antag OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") + if(GLOB.AOOC_COLOR) + to_chat(C, "Antag OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") + else + to_chat(C, "Antag OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") else if(!(key in C.prefs.ignoring)) - to_chat(C, "Antag OOC: [keyname]: [msg]") - -GLOBAL_VAR_INIT(antag_ooc_colour, AOOC_COLOR) + if(GLOB.AOOC_COLOR) + to_chat(C, "Antag OOC: [keyname]: [msg]") + else + to_chat(C, "Antag OOC: [keyname]: [msg]") /client/proc/set_aooc(newColor as color) set name = "Set Antag OOC Color" set desc = "Modifies antag OOC Color" set category = "Fun" - GLOB.antag_ooc_colour = sanitize_ooccolor(newColor) + GLOB.AOOC_COLOR = sanitize_ooccolor(newColor) /client/proc/reset_aooc() set name = "Reset Antag OOC Color" set desc = "Returns antag OOC Color to default" set category = "Fun" - GLOB.antag_ooc_colour = AOOC_COLOR + GLOB.AOOC_COLOR = null /proc/toggle_aooc(toggle = null) if(toggle != null) //if we're specifically en/disabling ooc diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 5df13a1ffe..8a233025a1 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -1,3 +1,6 @@ +GLOBAL_VAR_INIT(OOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour. +GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") + /client/verb/ooc(msg as text) set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite set category = "OOC" @@ -66,9 +69,15 @@ else to_chat(C, "OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg]") else - to_chat(C, "OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") + if(GLOB.OOC_COLOR) + to_chat(C, "OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") + else + to_chat(C, "OOC: [holder.fakekey ? holder.fakekey : key]: [msg]") else if(!(key in C.prefs.ignoring)) - to_chat(C, "OOC: [keyname]: [msg]") + if(GLOB.OOC_COLOR) + to_chat(C, "OOC: [keyname]: [msg]") + else + to_chat(C, "OOC: [keyname]: [msg]") /proc/toggle_ooc(toggle = null) if(toggle != null) //if we're specifically en/disabling ooc @@ -99,19 +108,17 @@ else GLOB.dooc_allowed = !GLOB.dooc_allowed -GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR) - /client/proc/set_ooc(newColor as color) set name = "Set Player OOC Color" set desc = "Modifies player OOC Color" set category = "Fun" - GLOB.normal_ooc_colour = sanitize_ooccolor(newColor) + GLOB.OOC_COLOR = sanitize_ooccolor(newColor) /client/proc/reset_ooc() set name = "Reset Player OOC Color" set desc = "Returns player OOC Color to default" set category = "Fun" - GLOB.normal_ooc_colour = OOC_COLOR + GLOB.OOC_COLOR = null /client/verb/colorooc() set name = "Set Your OOC Color" diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 7e7da2839e..33a83487fc 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -60,7 +60,7 @@ to_chat(owner, "You shouldn't be able to toggle a camogear helmetmask if you're not wearing it") if(new_headgear) // Force drop the item in the headslot, even though - // it's NODROP_1 + // it's TRAIT_NODROP D.dropItemToGround(target, TRUE) qdel(old_headgear) // where is `SLOT_HEAD` defined? WHO KNOWS @@ -418,12 +418,12 @@ /obj/item/clothing/head/chameleon/drone // The camohat, I mean, holographic hat projection, is part of the // drone itself. - item_flags = NODROP armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) // which means it offers no protection, it's just air and light /obj/item/clothing/head/chameleon/drone/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src) togglehatmask_action.UpdateButtonIcon() @@ -437,7 +437,7 @@ item_state = "gas_alt" resistance_flags = NONE armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) - clothing_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + clothing_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 @@ -472,13 +472,13 @@ /obj/item/clothing/mask/chameleon/drone //Same as the drone chameleon hat, undroppable and no protection - item_flags = NODROP armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) // Can drones use the voice changer part? Let's not find out. vchange = 0 /obj/item/clothing/mask/chameleon/drone/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src) togglehatmask_action.UpdateButtonIcon() @@ -630,3 +630,27 @@ /obj/item/stamp/chameleon/broken/Initialize() . = ..() chameleon_action.emp_randomise(INFINITY) + +/obj/item/clothing/neck/cloak/chameleon + name = "black tie" + desc = "A neosilk clip-on tie." + icon_state = "blacktie" + item_color = "blacktie" + resistance_flags = NONE + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + +/obj/item/clothing/neck/cloak/chameleon + var/datum/action/item_action/chameleon/change/chameleon_action + +/obj/item/clothing/neck/cloak/chameleon/Initialize() + . = ..() + chameleon_action = new(src) + chameleon_action.chameleon_type = /obj/item/clothing/neck + chameleon_action.chameleon_name = "Cloak" + chameleon_action.initialize_disguises() + +/obj/item/clothing/neck/cloak/chameleon/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + chameleon_action.emp_randomise() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 767b700051..ed3e9f9b89 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -43,6 +43,8 @@ /obj/item/clothing/Initialize() . = ..() + if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) + actions_types += /datum/action/item_action/toggle_voice_box if(ispath(pocket_storage_component_path)) LoadComponent(pocket_storage_component_path) @@ -135,7 +137,7 @@ update_clothes_damaged_state(TRUE) if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it var/mob/M = loc - M.visible_message("[M]'s [name] starts to fall apart!", "Your [name] starts to fall apart!") + to_chat(M, "Your [name] starts to fall apart!") /obj/item/clothing/proc/update_clothes_damaged_state(damaging = TRUE) var/index = "[REF(initial(icon))]-[initial(icon_state)]" diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 6e25db1fa6..097b10cae5 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -378,10 +378,13 @@ vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS darkness_view = 8 scan_reagents = TRUE - item_flags = NODROP lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE resistance_flags = LAVA_PROOF | FIRE_PROOF +/obj/item/clothing/glasses/godeye/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, EYE_OF_GOD_TRAIT) + /obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, src) && W != src && W.loc == user) if(W.icon_state == "godeye") diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index a87e95e28c..387aa65d20 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -24,11 +24,13 @@ desc = "[desc] The display is flickering slightly." /obj/item/clothing/glasses/hud/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "PZZTTPFFFT") desc = "[desc] The display is flickering slightly." + return TRUE /obj/item/clothing/glasses/hud/health name = "health scanner HUD" diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index 817fe59dcd..f0c1eeb833 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -8,6 +8,7 @@ slot_flags = ITEM_SLOT_GLOVES attack_verb = list("challenged") var/transfer_prints = FALSE + var/transfer_blood = 0 strip_delay = 20 equip_delay_other = 40 diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 0cd96eaebc..e95a836a0d 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -32,7 +32,7 @@ . = ..() siemens_coefficient = pick(0,0,0,0.5,0.5,0.5,0.75) -/obj/item/clothing/gloves/cut +/obj/item/clothing/gloves/cut desc = "These gloves would protect the wearer from electric shock.. if the fingers were covered." name = "fingerless insulated gloves" icon_state = "yellowcut" @@ -218,32 +218,3 @@ /obj/item/clothing/gloves/color/white/redcoat item_color = "redcoat" //Exists for washing machines. Is not different from white gloves in any way. - -/obj/item/clothing/gloves/color/random - name = "random gloves" - desc = "These gloves are supposed to be a random color..." - icon_state = "random_gloves" - item_state = "wgloves" - item_color = "mime" - -/obj/item/clothing/gloves/color/random/Initialize() - ..() - var/list/gloves = list( - /obj/item/clothing/gloves/color/orange = 1, - /obj/item/clothing/gloves/color/red = 1, - /obj/item/clothing/gloves/color/blue = 1, - /obj/item/clothing/gloves/color/purple = 1, - /obj/item/clothing/gloves/color/green = 1, - /obj/item/clothing/gloves/color/grey = 1, - /obj/item/clothing/gloves/color/light_brown = 1, - /obj/item/clothing/gloves/color/brown = 1, - /obj/item/clothing/gloves/color/white = 1, - /obj/item/clothing/gloves/color/rainbow = 1) - - var/obj/item/clothing/gloves/color/selected = pick(gloves) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.equip_to_slot_or_del(new selected(H), SLOT_GLOVES) - else - new selected(loc) - return INITIALIZE_HINT_QDEL diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index bc36353ac5..cc6d65b74d 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -65,6 +65,9 @@ var/warcry = "AT" /obj/item/clothing/gloves/rapid/Touch(mob/living/target,proximity = TRUE) + if(!istype(target)) + return + var/mob/living/M = loc if(M.a_intent == INTENT_HARM) @@ -72,9 +75,33 @@ M.adjustStaminaLoss(-2) //Restore 2/3 of the stamina used assuming empty stam buffer. With proper stamina buffer management, this results in a net gain of +.5 stamina per click. if(warcry) M.say("[warcry]", ignore_spam = TRUE, forced = "north star warcry") + .= FALSE + /obj/item/clothing/gloves/rapid/attack_self(mob/user) var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7) if(input) warcry = input + +/obj/item/clothing/gloves/rapid/hug + name = "Hugs of the North Star" + desc = "Just looking at these fills you with an urge to hug the shit out of people" + warcry = "owo" //Shouldn't ever come into play + +/obj/item/clothing/gloves/rapid/hug/Touch(mob/living/target,proximity = TRUE) + if(!istype(target)) + return + + var/mob/living/M = loc + + if(M.a_intent == INTENT_HELP) + if(target.health >= 0 && !HAS_TRAIT(target, TRAIT_FAKEDEATH)) //Can't hug people who are dying/dead + if(target.on_fire || target.lying ) //No spamming extinguishing, helping them up, or other non-hugging/patting help interactions + return + else + M.changeNext_move(CLICK_CD_RAPID) + . = FALSE + +/obj/item/clothing/gloves/rapid/hug/attack_self(mob/user) + return FALSE \ No newline at end of file diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm index bbae5b261f..a5fb04d393 100644 --- a/code/modules/clothing/head/beanie.dm +++ b/code/modules/clothing/head/beanie.dm @@ -74,4 +74,13 @@ icon_state = "beaniestripedgreen" item_color = "beaniestripedgreen" +/obj/item/clothing/head/beanie/durathread + name = "durathread beanie" + desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beaniedurathread" + item_color = null + armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + + + //No dog fashion sprites yet :( poor Ian can't be dope like the rest of us yet \ No newline at end of file diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 8ffcc6eea7..be6e270e45 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -54,6 +54,8 @@ tint = 2 /obj/item/clothing/head/helmet/blueshirt + name = "blue helmet" + desc = "A reliable, blue tinted helmet reminding you that you still owe that engineer a beer." icon_state = "blueshift" item_state = "blueshift" @@ -334,3 +336,11 @@ for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() + + +/obj/item/clothing/head/helmet/durathread + name = "makeshift helmet" + desc = "A hardhat with strips of leather and durathread for additional blunt protection." + icon_state = "durathread" + item_state = "durathread" + armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 07817ec4e4..298510564c 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -47,6 +47,7 @@ name = "captain's beret" desc = "A beret fit for a leader." icon_state = "capberet" + dynamic_hair_suffix = "" dog_fashion = null @@ -62,6 +63,7 @@ name = "head of personnel's beret" desc = "The symbol of true bureaucratic micromanagement, although in a fancy form." icon_state = "hopberet" + dynamic_hair_suffix = "" dog_fashion = null @@ -119,9 +121,12 @@ /obj/item/clothing/head/beret/highlander desc = "That was white fabric. Was." - item_flags = NODROP dog_fashion = null //THIS IS FOR SLAUGHTER, NOT PUPPIES +/obj/item/clothing/head/beret/highlander/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) + //Security /obj/item/clothing/head/HoS @@ -184,33 +189,41 @@ mode = DRILL_CANADIAN return TRUE -/obj/item/clothing/head/warden/drill/speechModification(M) - if(copytext(M, 1, 2) != "*") - if(mode == DRILL_DEFAULT) - M = " [M]" - return trim(M) - if(mode == DRILL_SHOUTING) - M = " [M]!" - return trim(M) - if(mode == DRILL_YELLING) - M = " [M]!!" - return trim(M) - if(mode == DRILL_CANADIAN) - M = " [M]" - var/list/canadian_words = strings("canadian_replacement.json", "canadian") +/obj/item/clothing/head/warden/drill/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HEAD) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) - for(var/key in canadian_words) - var/value = canadian_words[key] - if(islist(value)) - value = pick(value) +/obj/item/clothing/head/warden/drill/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) - M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]") - M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]") - M = replacetextEx(M, " [key]", " [value]") +/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + switch (mode) + if(DRILL_SHOUTING) + message += "!" + if(DRILL_YELLING) + message += "!!" + if(DRILL_CANADIAN) + message = " [message]" + var/list/canadian_words = strings("canadian_replacement.json", "canadian") - if(prob(30)) - M += pick(", eh?", ", EH?") - return trim(M) + for(var/key in canadian_words) + var/value = canadian_words[key] + if(islist(value)) + value = pick(value) + + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") + + if(prob(30)) + message += pick(", eh?", ", EH?") + speech_args[SPEECH_MESSAGE] = message /obj/item/clothing/head/beret/sec name = "security beret" @@ -266,6 +279,13 @@ desc = "This headwear shows off your Cargonian leadership" icon_state = "qmberet" +/obj/item/clothing/head/beret/durathread + name = "durathread beret" + desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beretdurathread" + item_color = null + armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + #undef DRILL_DEFAULT #undef DRILL_SHOUTING #undef DRILL_YELLING diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index d9c151a47b..041f0ba012 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -221,9 +221,12 @@ icon_state = "shamebrero" item_state = "shamebrero" desc = "Once it's on, it never comes off." - item_flags = NODROP dog_fashion = null +/obj/item/clothing/head/sombrero/shamebrero/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) + /obj/item/clothing/head/cone desc = "This cone is trying to warn you of something!" name = "warning cone" @@ -309,8 +312,8 @@ /obj/item/clothing/head/pharaoh name = "pharaoh hat" desc = "Walk like an Egyptian." - icon_state = "pharoah_hat" - icon_state = "pharoah_hat" + icon_state = "pharaoh_hat" + icon_state = "pharaoh_hat" /obj/item/clothing/head/jester/alt name = "jester hat" @@ -330,9 +333,21 @@ icon_state = "beretblack" dynamic_hair_suffix = "" -/obj/item/clothing/head/frenchberet/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/head/frenchberet/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HEAD) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/frenchberet/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/frenchberet/proc/handle_speech(datum/source, mob/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/french_words = strings("french_replacement.json", "french") for(var/key in french_words) @@ -340,10 +355,10 @@ if(islist(value)) value = pick(value) - M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]") - M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]") - M = replacetextEx(M, " [key]", " [value]") + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") if(prob(3)) - M += pick(" Honh honh honh!"," Honh!"," Zut Alors!") - return trim(M) + message += pick(" Honh honh honh!"," Honh!"," Zut Alors!") + speech_args[SPEECH_MESSAGE] = trim(message) diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index 8f10184f86..9ee2ebcd54 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -5,12 +5,54 @@ slot_flags = ITEM_SLOT_MASK strip_delay = 40 equip_delay_other = 40 + var/modifies_speech = FALSE var/mask_adjusted = 0 var/adjusted_flags = null var/muzzle_var = NORMAL_STYLE mutantrace_variation = NO_MUTANTRACE_VARIATION //most masks have overrides, but not all probably. +/obj/item/clothing/mask/attack_self(mob/user) + if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) + TOGGLE_BITFIELD(clothing_flags, VOICEBOX_DISABLED) + var/status = !CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED) + to_chat(user, "You turn the voice box in [src] [status ? "on" : "off"].") + +/obj/item/clothing/mask/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_WEAR_MASK && modifies_speech) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + var/datum/species/pref_species = H.dna.species + + if(mutantrace_variation) + if("mam_snouts" in pref_species.default_features) + if(H.dna.features["mam_snouts"] != "None") + muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE + + else if("snout" in pref_species.default_features) + if(H.dna.features["snout"] != "None") + muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE + + else + muzzle_var = NORMAL_STYLE + + H.update_inv_wear_mask() + +/obj/item/clothing/mask/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/mask/proc/handle_speech() + /obj/item/clothing/mask/worn_overlays(isinhands = FALSE) . = list() if(!isinhands) @@ -20,31 +62,6 @@ IF_HAS_BLOOD_DNA(src) . += mutable_appearance('icons/effects/blood.dmi', "maskblood") -/obj/item/clothing/mask/equipped(mob/user, slot) - ..() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/datum/species/pref_species = H.dna.species - - if(mutantrace_variation) - if("mam_snouts" in pref_species.default_features) - if(H.dna.features["mam_snouts"] != "None") - muzzle_var = ALT_STYLE - else - muzzle_var = NORMAL_STYLE - - else if("snout" in pref_species.default_features) - if(H.dna.features["snout"] != "None") - muzzle_var = ALT_STYLE - else - muzzle_var = NORMAL_STYLE - - else - muzzle_var = NORMAL_STYLE - - H.update_inv_wear_mask() - - /obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE) ..() if(ismob(loc)) diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index c0752d9799..3960bdadeb 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -20,9 +20,11 @@ flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL mutantrace_variation = MUTANTRACE_VARIATION + modifies_speech = TRUE -/obj/item/clothing/mask/luchador/speechModification(message) - if(copytext(message, 1, 2) != "*") +/obj/item/clothing/mask/luchador/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = replacetext(message, "captain", "CAPITÁN") message = replacetext(message, "station", "ESTACIÓN") message = replacetext(message, "sir", "SEÑOR") @@ -42,7 +44,7 @@ message = uppertext(message) //Things end up looking better this way (no mixed cases), and it fits the macho wrestler image. if(prob(25)) message += " OLE!" - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/clothing/mask/luchador/tecnicos name = "Tecnicos Mask" diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index ed0ef27174..947aa048c4 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -4,8 +4,8 @@ icon_state = "breath" item_state = "m_mask" body_parts_covered = 0 - clothing_flags = MASKINTERNALS - visor_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS + visor_flags = ALLOWINTERNALS w_class = WEIGHT_CLASS_SMALL gas_transfer_coefficient = 0.1 permeability_coefficient = 0.5 diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index bcf3064c49..c613d1a91e 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -2,7 +2,7 @@ name = "gas mask" desc = "A face-covering mask that can be connected to an air supply. While good for concealing your identity, it isn't good for blocking gas flow." //More accurate icon_state = "gas_alt" - clothing_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + clothing_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT w_class = WEIGHT_CLASS_NORMAL item_state = "gas_alt" @@ -59,7 +59,7 @@ /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask." - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS icon_state = "clown" item_state = "clown_hat" flags_cover = MASKCOVERSEYES @@ -91,7 +91,7 @@ /obj/item/clothing/mask/gas/sexyclown name = "sexy-clown wig and mask" desc = "A feminine clown mask for the dabbling crossdressers or female entertainers." - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS icon_state = "sexyclown" item_state = "sexyclown" flags_cover = MASKCOVERSEYES @@ -100,7 +100,7 @@ /obj/item/clothing/mask/gas/mime name = "mime mask" desc = "The traditional mime's mask. It has an eerie facial posture." - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS icon_state = "mime" item_state = "mime" flags_cover = MASKCOVERSEYES @@ -132,7 +132,7 @@ /obj/item/clothing/mask/gas/monkeymask name = "monkey mask" desc = "A mask used when acting as a monkey." - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS icon_state = "monkeymask" item_state = "monkeymask" flags_cover = MASKCOVERSEYES @@ -141,7 +141,7 @@ /obj/item/clothing/mask/gas/sexymime name = "sexy mime mask" desc = "A traditional female mime's mask." - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS icon_state = "sexymime" item_state = "sexymime" flags_cover = MASKCOVERSEYES @@ -162,7 +162,7 @@ name = "owl mask" desc = "Twoooo!" icon_state = "owl" - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index 8860650fbc..086d47e8bf 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -7,10 +7,10 @@ actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/adjust) icon_state = "sechailer" item_state = "sechailer" - clothing_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + clothing_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS flags_inv = HIDEFACIALHAIR|HIDEFACE w_class = WEIGHT_CLASS_SMALL - visor_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + visor_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS visor_flags_inv = HIDEFACE flags_cover = MASKCOVERSMOUTH visor_flags_cover = MASKCOVERSMOUTH @@ -69,12 +69,14 @@ /obj/item/clothing/mask/gas/sechailer/attack_self() halt() -/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user as mob) - if(safety) - safety = FALSE - to_chat(user, "You silently fry [src]'s vocal circuit with the cryptographic sequencer.") - else + +/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user) + . = ..() + if(!safety) return + safety = FALSE + to_chat(user, "You silently fry [src]'s vocal circuit with the cryptographic sequencer.") + return TRUE /obj/item/clothing/mask/gas/sechailer/verb/halt() set category = "Object" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 9476c50603..4b8f16a77f 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -46,10 +46,12 @@ /obj/item/clothing/mask/fakemoustache/italian name = "italian moustache" desc = "Made from authentic Italian moustache hairs. Gives the wearer an irresistable urge to gesticulate wildly." + modifies_speech = TRUE -/obj/item/clothing/mask/fakemoustache/italian/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/mask/fakemoustache/italian/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/italian_words = strings("italian_replacement.json", "italian") for(var/key in italian_words) @@ -57,13 +59,13 @@ if(islist(value)) value = pick(value) - M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]") - M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]") - M = replacetextEx(M, " [key]", " [value]") + message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]") + message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]") + message = replacetextEx(message, " [key]", " [value]") if(prob(3)) - M += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!") - return trim(M) + message += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!") + speech_args[SPEECH_MESSAGE] = trim(message) /obj/item/clothing/mask/joy name = "joy mask" @@ -73,36 +75,28 @@ /obj/item/clothing/mask/pig name = "pig mask" - desc = "A rubber pig mask." + desc = "A rubber pig mask with a builtin voice modulator." icon_state = "pig" item_state = "pig" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + clothing_flags = VOICEBOX_TOGGLABLE w_class = WEIGHT_CLASS_SMALL - actions_types = list(/datum/action/item_action/toggle_voice_box) - var/voicechange = 0 + modifies_speech = TRUE -/obj/item/clothing/mask/pig/attack_self(mob/user) - voicechange = !voicechange - to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!") +/obj/item/clothing/mask/pig/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("Oink!","Squeeeeeeee!","Oink Oink!") -/obj/item/clothing/mask/pig/speechModification(message) - if(voicechange) - message = pick("Oink!","Squeeeeeeee!","Oink Oink!") - return message - -/obj/item/clothing/mask/spig //needs to be different otherwise you could turn the speedmodification off and on +/obj/item/clothing/mask/pig/cursed //needs to be different otherwise you could turn the speedmodification off and on name = "Pig face" desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" //It's only ever going to be attached to your face. - icon_state = "pig" - item_state = "pig" - flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + flags_inv = HIDEFACIALHAIR + clothing_flags = NONE -/obj/item/clothing/mask/spig/speechModification(message) - if(voicechange) - message = pick("Oink!","Squeeeeeeee!","Oink Oink!") - return message +/obj/item/clothing/mask/pig/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/pighead_curse.ogg', 50, 1) ///frog mask - reeee!! /obj/item/clothing/mask/frog @@ -112,47 +106,55 @@ item_state = "frog" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - var/voicechange = TRUE + clothing_flags = VOICEBOX_TOGGLABLE + modifies_speech = TRUE -/obj/item/clothing/mask/frog/attack_self(mob/user) - voicechange = !voicechange - to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!") - -/obj/item/clothing/mask/frog/speechModification(message) //whenever you speak - if(voicechange) +/obj/item/clothing/mask/frog/handle_speech(datum/source, list/speech_args) //whenever you speak + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) if(prob(5)) //sometimes, the angry spirit finds others words to speak. - message = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") + speech_args[SPEECH_MESSAGE] = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") else - message = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish, - return message + speech_args[SPEECH_MESSAGE] = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish, /obj/item/clothing/mask/frog/cursed - item_flags = NODROP //reee!! + clothing_flags = NONE -/obj/item/clothing/mask/frog/cursed/attack_self(mob/user) - return //no voicebox to alter. +/obj/item/clothing/mask/frog/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) /obj/item/clothing/mask/frog/cursed/equipped(mob/user, slot) var/mob/living/carbon/C = user - if(C.wear_mask == src) - to_chat(user, "[src] was cursed! Ree!!") + if(C.wear_mask == src && HAS_TRAIT_FROM(src, TRAIT_NODROP, CURSED_ITEM_TRAIT)) + to_chat(user, "[src] was cursed! Ree!!") return ..() - /obj/item/clothing/mask/cowmask - name = "Cowface" - desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" + name = "Cow mask with a builtin voice modulator." + desc = "A rubber cow mask," icon = 'icons/mob/mask.dmi' icon_state = "cowmask" item_state = "cowmask" + clothing_flags = VOICEBOX_TOGGLABLE flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + modifies_speech = TRUE -/obj/item/clothing/mask/cowmask/speechModification(message) - if(voicechange) - message = pick("Moooooooo!","Moo!","Moooo!") - return message +/obj/item/clothing/mask/cowmask/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("Moooooooo!","Moo!","Moooo!") + + +/obj/item/clothing/mask/cowmask/cursed + name = "cow face" + desc = "It looks like a cow mask, but closer inspection reveals it's melded onto this persons face!" + flags_inv = HIDEFACIALHAIR + clothing_flags = NONE + +/obj/item/clothing/mask/cowmask/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/cowhead_curse.ogg', 50, 1) /obj/item/clothing/mask/horsehead name = "horse head mask" @@ -161,12 +163,23 @@ item_state = "horsehead" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEYES|HIDEEARS w_class = WEIGHT_CLASS_SMALL - var/voicechange = 1 + clothing_flags = VOICEBOX_TOGGLABLE -/obj/item/clothing/mask/horsehead/speechModification(message) - if(voicechange) - message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") - return message +/obj/item/clothing/mask/horsehead/handle_speech(datum/source, list/speech_args) + if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + speech_args[SPEECH_MESSAGE] = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") + + +/obj/item/clothing/mask/horsehead/cursed + name = "horse face" + desc = "It initially looks like a mask, but it's melded into the poor person's face." + clothing_flags = NONE + flags_inv = HIDEFACIALHAIR + +/obj/item/clothing/mask/horsehead/cursed/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) + playsound(get_turf(src), 'sound/magic/horsehead_curse.ogg', 50, 1) /obj/item/clothing/mask/rat name = "rat mask" @@ -285,16 +298,24 @@ item_state = "gondola" flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL + modifies_speech = TRUE -/obj/item/clothing/mask/gondola/speechModification(M) - if(copytext(M, 1, 2) != "*") - M = " [M]" +/obj/item/clothing/mask/gondola/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + message = " [message]" var/list/spurdo_words = strings("spurdo_replacement.json", "spurdo") for(var/key in spurdo_words) var/value = spurdo_words[key] if(islist(value)) value = pick(value) - M = replacetextEx(M,regex(uppertext(key),"g"), "[uppertext(value)]") - M = replacetextEx(M,regex(capitalize(key),"g"), "[capitalize(value)]") - M = replacetextEx(M,regex(key,"g"), "[value]") - return trim(M) + message = replacetextEx(message,regex(uppertext(key),"g"), "[uppertext(value)]") + message = replacetextEx(message,regex(capitalize(key),"g"), "[capitalize(value)]") + message = replacetextEx(message,regex(key,"g"), "[value]") + speech_args[SPEECH_MESSAGE] = trim(message) + +/obj/item/clothing/mask/bandana/durathread + name = "durathread bandana" + desc = "A bandana made from durathread, you wish it would provide some protection to its wearer, but it's far too thin..." + icon_state = "banddurathread" + diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index b4310a7f42..523ed55aa4 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -45,16 +45,23 @@ R.recalculateChannels() /datum/outfit/ert/commander/alert - name = "ERT Commander - High Alert" + name = "ERT Commander - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert glasses = /obj/item/clothing/glasses/thermal/eyepatch backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ - /obj/item/gun/energy/pulse/pistol/loyalpin=1) + /obj/item/gun/energy/e_gun=1) l_pocket = /obj/item/melee/transforming/energy/sword/saber +/datum/outfit/ert/commander/alert/red + name = "ERT Commander - Red Alert" + backpack_contents = list(/obj/item/storage/box/engineer=1,\ + /obj/item/melee/baton/loaded=1,\ + /obj/item/clothing/mask/gas/sechailer/swat=1,\ + /obj/item/gun/energy/pulse/pistol/loyalpin=1) + /datum/outfit/ert/security name = "ERT Security" @@ -80,15 +87,22 @@ R.recalculateChannels() /datum/outfit/ert/security/alert - name = "ERT Security - High Alert" + name = "ERT Security - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/sec backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/storage/box/handcuffs=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/melee/baton/loaded=1,\ - /obj/item/gun/energy/pulse/carbine/loyalpin=1) + /obj/item/gun/energy/e_gun/stun=1) +/datum/outfit/ert/security/alert/red + name = "ERT Security - Red Alert" + backpack_contents = list(/obj/item/storage/box/engineer=1,\ + /obj/item/storage/box/handcuffs=1,\ + /obj/item/clothing/mask/gas/sechailer/swat=1,\ + /obj/item/melee/baton/loaded=1,\ + /obj/item/gun/energy/pulse/carbine/loyalpin=1) /datum/outfit/ert/medic name = "ERT Medic" @@ -117,9 +131,18 @@ R.recalculateChannels() /datum/outfit/ert/medic/alert - name = "ERT Medic - High Alert" + name = "ERT Medic - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/med + backpack_contents = list(/obj/item/storage/box/engineer=1,\ + /obj/item/melee/baton/loaded=1,\ + /obj/item/clothing/mask/gas/sechailer/swat=1,\ + /obj/item/gun/energy/e_gun=1,\ + /obj/item/reagent_containers/hypospray/combat/nanites=1,\ + /obj/item/gun/medbeam=1) + +/datum/outfit/ert/medic/alert/red + name = "ERT Medic - Red Alert" backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ @@ -154,15 +177,51 @@ R.recalculateChannels() /datum/outfit/ert/engineer/alert - name = "ERT Engineer - High Alert" + name = "ERT Engineer - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/engi + backpack_contents = list(/obj/item/storage/box/engineer=1,\ + /obj/item/melee/baton/loaded=1,\ + /obj/item/clothing/mask/gas/sechailer/swat=1,\ + /obj/item/gun/energy/e_gun=1,\ + /obj/item/construction/rcd/combat=1) + +/datum/outfit/ert/engineer/alert/red + name = "ERT Engineer - Red Alert" backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/pulse/pistol/loyalpin=1,\ /obj/item/construction/rcd/combat=1) +/datum/outfit/ert/greybois + name = "Emergency Assistant" + + uniform = /obj/item/clothing/under/color/grey/glorf + shoes = /obj/item/clothing/shoes/sneakers/black + gloves = /obj/item/clothing/gloves/color/fyellow + ears = /obj/item/radio/headset + head = /obj/item/clothing/head/soft/grey + belt = /obj/item/storage/belt/utility/full + back = /obj/item/storage/backpack + mask = /obj/item/clothing/mask/gas + l_pocket = /obj/item/tank/internals/emergency_oxygen + l_hand = /obj/item/storage/toolbox/emergency/old + id = /obj/item/card/id + +/datum/outfit/ert/greybois/greygod + suit = /obj/item/clothing/suit/hazardvest + l_hand = /obj/item/storage/toolbox/plastitanium + gloves = /obj/item/clothing/gloves/color/yellow + +/datum/outfit/ert/greybois/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + if(visualsOnly) + return + var/obj/item/card/id/W = H.wear_id + W.registered_name = H.real_name + W.assignment = "Assistant" + W.access = list(ACCESS_MAINT_TUNNELS,ACCESS_CENT_GENERAL) + W.update_label(W.registered_name, W.assignment) /datum/outfit/centcom_official name = "CentCom Official" diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index a6bcf23a2d..4659de3e6a 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -9,7 +9,7 @@ /obj/item/clothing/shoes/combat //basic syndicate combat boots for nuke ops and mob corpses name = "combat boots" desc = "High speed, low drag combat boots." - icon_state = "jackboots" + icon_state = "combat" item_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' @@ -157,7 +157,11 @@ icon_state = "cultalt" /obj/item/clothing/shoes/cult/alt/ghost - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + +/obj/item/clothing/shoes/cult/alt/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) /obj/item/clothing/shoes/cyborg name = "cyborg boots" @@ -215,17 +219,13 @@ var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction - if (user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(src, .proc/hop_end))) - jumping = TRUE + if (user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE)) playsound(src, 'sound/effects/stealthoff.ogg', 50, 1, 1) + recharging_time = world.time + recharging_rate user.visible_message("[usr] dashes forward into the air!") else to_chat(user, "Something prevents you from dashing forward!") -/obj/item/clothing/shoes/bhop/proc/hop_end() - jumping = FALSE - recharging_time = world.time + recharging_rate - /obj/item/clothing/shoes/singery name = "yellow performer's boots" desc = "These boots were made for dancing." diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index 9d3918ed84..662a91c80c 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -4,7 +4,7 @@ name = "space helmet" icon_state = "spaceold" desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays." - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL + clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS item_state = "spaceold" permeability_coefficient = 0.01 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70) diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index d0820304fe..5a53e2776a 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -27,7 +27,6 @@ armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000) resistance_flags = FIRE_PROOF | ACID_PROOF var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun) - var/list/hands_nodrop = list() var/obj/item/clothing/head/helmet/space/chronos/helmet = null var/obj/effect/chronos_cam/camera = null var/datum/action/innate/chrono_teleport/teleport_now = new @@ -97,8 +96,7 @@ user.anchored = FALSE teleporting = 0 for(var/obj/item/I in user.held_items) - if(I in hands_nodrop) - I.item_flags &= ~NODROP + REMOVE_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) if(camera) camera.remove_target_ui() camera.forceMove(user) @@ -131,11 +129,8 @@ user.ExtinguishMob() - hands_nodrop = list() for(var/obj/item/I in user.held_items) - if(!(I.item_flags & NODROP)) - hands_nodrop += I - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) user.animate_movement = NO_STEPS user.changeNext_move(8 + phase_in_ds) user.notransform = 1 @@ -194,9 +189,9 @@ if(user.head && istype(user.head, /obj/item/clothing/head/helmet/space/chronos)) to_chat(user, "\[ ok \] Mounting /dev/helm") helmet = user.head - helmet.item_flags |= NODROP + ADD_TRAIT(helmet, TRAIT_NODROP, CHRONOSUIT_TRAIT) helmet.suit = src - src.item_flags |= NODROP + ADD_TRAIT(src, TRAIT_NODROP, CHRONOSUIT_TRAIT) to_chat(user, "\[ ok \] Starting brainwave scanner") to_chat(user, "\[ ok \] Starting ui display driver") to_chat(user, "\[ ok \] Initializing chronowalk4-view") @@ -215,7 +210,7 @@ activating = 1 var/mob/living/carbon/human/user = src.loc var/hard_landing = teleporting && force - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, CHRONOSUIT_TRAIT) cooldown = world.time + cooldowntime * 1.5 activated = 0 activating = 0 @@ -236,7 +231,7 @@ to_chat(user, "\[ ok \] Unmounting /dev/helmet") to_chat(user, "logout") if(helmet) - helmet.item_flags &= ~NODROP + REMOVE_TRAIT(helmet, TRAIT_NODROP, CHRONOSUIT_TRAIT) helmet.suit = null helmet = null if(camera) diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 176bc81665..b105b72234 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -897,7 +897,7 @@ usermessage("You're already wearing something on your back!", "boldwarning") return FALSE user.equip_to_slot_if_possible(pack,SLOT_BACK,0,0,1) - pack.item_flags |= NODROP + ADD_TRAIT(pack, TRAIT_NODROP, FLIGHTSUIT_TRAIT) resync() user.visible_message("A [pack.name] extends from [user]'s [name] and clamps to [user.p_their()] back!") user.update_inv_wear_suit() @@ -911,7 +911,7 @@ return FALSE if(pack.flight && forced) pack.disable_flight(1) - pack.item_flags &= ~NODROP + REMOVE_TRAIT_FROM(pack, TRAIT_NODROP, FLIGHTSUIT_TRAIT) resync() if(user) user.transferItemToLoc(pack, src, TRUE) @@ -935,14 +935,14 @@ usermessage("You're already wearing something on your feet!", "boldwarning") return FALSE user.equip_to_slot_if_possible(shoes,SLOT_SHOES,0,0,1) - shoes.item_flags |= NODROP + ADD_TRAIT(shoes, TRAIT_NODROP, FLIGHTSUIT_TRAIT) user.visible_message("[user]'s [name] extends a pair of [shoes.name] over [user.p_their()] feet!") user.update_inv_wear_suit() playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) deployedshoes = TRUE /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/retract_flightshoes(forced = FALSE) - shoes.item_flags &= ~NODROP + REMOVE_TRAIT_FROM(shoes, TRAIT_NODROP, FLIGHTSUIT_TRAIT) playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) if(user) user.transferItemToLoc(shoes, src, TRUE) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 22eac9f5aa..2694497579 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -624,19 +624,19 @@ desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storge bags on to the suit." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500) + armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) slowdown = 6 //Slow allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason name = "M.A.S.O.N RIG helmet" desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500) + armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) item_color = "ancient" brightness_on = 16 scan_reagents = TRUE @@ -644,7 +644,7 @@ tint = 1 var/obj/machinery/doppler_array/integrated/bomb_radar max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize() . = ..() @@ -766,12 +766,15 @@ icon_state = "ert_medical" item_state = "ert_medical" item_color = "ert_medical" - item_flags = NODROP //Dont want people changing into the other teams gear helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95) slowdown = 0 max_charges = 5 +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) + /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red name = "red shielded hardsuit" icon_state = "ert_security" diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 6d7c1036be..5d718a8173 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -171,10 +171,13 @@ Contains: item_color = "ert_commander" armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80) strip_delay = 130 - item_flags = NODROP brightness_on = 7 resistance_flags = ACID_PROOF +/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) + /obj/item/clothing/suit/space/hardsuit/ert name = "emergency response team suit" desc = "Standard issue command suit for the ERT." @@ -237,8 +240,6 @@ Contains: item_state = "hardsuit0-ert_commander-alert" item_color = "ert_commander-alert" armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) - strip_delay = 130 - item_flags = NODROP brightness_on = 8 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -248,11 +249,8 @@ Contains: icon_state = "ert_command-alert" item_state = "ert_command-alert" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert - allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) - strip_delay = 130 resistance_flags = FIRE_PROOF | ACID_PROOF - tauric = TRUE //Citadel Add for tauric hardsuits //ERT Security /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/sec @@ -342,9 +340,13 @@ Contains: armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75) //As whimpy as a space carp brightness_on = 0 //luminosity when on actions_types = list() - item_flags = NODROP mutantrace_variation = NO_MUTANTRACE_VARIATION +/obj/item/clothing/head/helmet/space/hardsuit/carp/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) + + /obj/item/clothing/suit/space/hardsuit/carp name = "carp space suit" desc = "A slimming piece of dubious space carp technology, you suspect it won't stand up to hand-to-hand blows." diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 7346dc9ea9..cf411ef367 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -28,7 +28,6 @@ H.update_inv_wear_suit() else if(adjusted == ALT_STYLE) adjusted = NORMAL_STYLE - H.update_inv_wear_suit() if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None")) if(H.dna.features["taur"] in list("Naga", "Tentacle")) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index eb30488999..0840288eee 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -37,6 +37,8 @@ slowdown = 1 /obj/item/clothing/suit/armor/vest/blueshirt + name = "large armor vest" + desc = "A large, yet comfortable piece of armor, protecting you from some threats." icon_state = "blueshift" item_state = "blueshift" @@ -59,7 +61,7 @@ flags_inv = 0 strip_delay = 80 unique_reskin = list("Coat" = "hostrench", "Cloak" = "trenchcloak") - + /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets." @@ -236,3 +238,14 @@ /obj/item/clothing/suit/armor/riot/knight/red icon_state = "knight_red" item_state = "knight_red" + +/obj/item/clothing/suit/armor/vest/durathread + name = "makeshift vest" + desc = "A vest made of durathread with strips of leather acting as trauma plates." + icon_state = "durathread" + item_state = "durathread" + strip_delay = 60 + equip_delay_other = 40 + max_integrity = 200 + resistance_flags = FLAMMABLE + armor = list("melee" = 20, "bullet" = 10, "laser" = 30, "energy" = 5, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index 173d50ba64..c3276213e1 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -15,7 +15,6 @@ icon_state = "golhood" desc = "A hood for a cloak." body_parts_covered = HEAD - item_flags = NODROP flags_inv = HIDEHAIR|HIDEEARS /obj/item/clothing/neck/cloak/suicide_act(mob/user) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index bf11d40caf..3c3c8f0e9d 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -177,3 +177,23 @@ armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) cold_protection = CHEST|ARMS heat_protection = CHEST|ARMS + + +//Robotocist + +/obj/item/clothing/suit/hooded/techpriest + name = "techpriest robes" + desc = "For those who REALLY love their toasters." + icon_state = "techpriest" + item_state = "techpriest" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + hoodtype = /obj/item/clothing/head/hooded/techpriest + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/head/hooded/techpriest + name = "techpriest's hood" + desc = "A hood for those who REALLY love their toasters." + icon_state = "techpriesthood" + item_state = "techpriesthood" + body_parts_covered = HEAD + flags_inv = HIDEHAIR|HIDEEARS diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 9d039e0cb6..8a3dbbf274 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -237,7 +237,10 @@ desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseparable. Literally." icon_state = "ponchoshame" item_state = "ponchoshame" - item_flags = NODROP + +/obj/item/clothing/suit/poncho/ponchoshame/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) /obj/item/clothing/suit/whitedress name = "white dress" @@ -465,11 +468,11 @@ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT allowed = list(/obj/item/clothing/mask/facehugger/toy) -/obj/item/clothing/suit/nemes - name = "pharoah tunic" +/obj/item/clothing/suit/pharaoh + name = "pharaoh tunic" desc = "Lavish space tomb not included." - icon_state = "pharoah" - icon_state = "pharoah" + icon_state = "pharaoh" + icon_state = "pharaoh" body_parts_covered = CHEST|GROIN diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 396bcb4766..6535e40d0d 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -354,3 +354,28 @@ item_color = "skull" above_suit = TRUE armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + +///////////////////// +//Synda Accessories// +///////////////////// + +/obj/item/clothing/accessory/padding + name = "soft padding" + desc = "Some long sheets of padding to help soften the blows of a physical attacks." + icon_state = "padding" + item_color = "nothing" + armor = list("melee" = 15, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -20, "acid" = 45) + +/obj/item/clothing/accessory/kevlar + name = "kevlar sheets" + desc = "Long thin sheets of kevlar to help resist bullets and some physical attacks.." + icon_state = "padding" + item_color = "nothing" + armor = list("melee" = 10, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 25) + +/obj/item/clothing/accessory/plastics + name = "underling plastic sheet" + desc = "A full body sheet of white plastic to help defuse lasers and energy based weapons." + icon_state = "plastics" + item_color = "nothing" + armor = list("melee" = 0, "bullet" = 0, "laser" = 20, "energy" = 10, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = -40) diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 324c16fec7..54264ef9d4 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -1,12 +1,18 @@ /obj/item/clothing/under/color desc = "A standard issue colored jumpsuit. Variety is the spice of life!" +/obj/item/clothing/under/skirt/color + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/color/random icon_state = "random_jumpsuit" /obj/item/clothing/under/color/random/Initialize() ..() - var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost) + var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - subtypesof(/obj/item/clothing/under/skirt/color) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost) + if(ishuman(loc)) var/mob/living/carbon/human/H = loc H.equip_to_slot_or_del(new C(H), SLOT_W_UNIFORM) //or else you end up with naked assistants running around everywhere... @@ -14,6 +20,20 @@ new C(loc) return INITIALIZE_HINT_QDEL +/obj/item/clothing/under/skirt/color/random + icon_state = "random_jumpsuit" //Skirt variant needed + +/obj/item/clothing/under/skirt/color/random/Initialize() + ..() + var/obj/item/clothing/under/skirt/color/C = pick(subtypesof(/obj/item/clothing/under/skirt/color) - /obj/item/clothing/under/skirt/color/random) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.equip_to_slot_or_del(new C(H), SLOT_W_UNIFORM) + else + new C(loc) + return INITIALIZE_HINT_QDEL + + /obj/item/clothing/under/color/black name = "black jumpsuit" icon_state = "black" @@ -21,9 +41,22 @@ item_color = "black" resistance_flags = NONE -/obj/item/clothing/under/color/black/ghost - item_flags = NODROP | DROPDEL +/obj/item/clothing/under/skirt/color/black + name = "black jumpskirt" + icon_state = "black_skirt" + item_state = "bl_suit" + item_color = "black_skirt" +/obj/item/clothing/under/color/black/ghost + item_flags = DROPDEL + +/obj/item/clothing/under/color/black/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) + +/obj/item/clothing/under/color/black/ghost/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, DROPDEL) /obj/item/clothing/under/color/grey name = "grey jumpsuit" desc = "A tasteful grey jumpsuit that reminds you of the good old days." @@ -31,6 +64,13 @@ item_state = "gy_suit" item_color = "grey" +/obj/item/clothing/under/skirt/color/grey + name = "grey jumpskirt" + desc = "A tasteful grey jumpskirt that reminds you of the good old days." + icon_state = "grey_skirt" + item_state = "gy_suit" + item_color = "grey_skirt" + /obj/item/clothing/under/color/grey/glorf name = "ancient jumpsuit" desc = "A terribly ragged and frayed grey jumpsuit. It looks like it hasn't been washed in over a decade." @@ -45,12 +85,24 @@ item_state = "b_suit" item_color = "blue" +/obj/item/clothing/under/skirt/color/blue + name = "blue jumpskirt" + icon_state = "blue_skirt" + item_state = "b_suit" + item_color = "blue_skirt" + /obj/item/clothing/under/color/green name = "green jumpsuit" icon_state = "green" item_state = "g_suit" item_color = "green" +/obj/item/clothing/under/skirt/color/green + name = "green jumpskirt" + icon_state = "green_skirt" + item_state = "g_suit" + item_color = "green_skirt" + /obj/item/clothing/under/color/orange name = "orange jumpsuit" desc = "Don't wear this near paranoid security officers." @@ -58,6 +110,12 @@ item_state = "o_suit" item_color = "orange" +/obj/item/clothing/under/skirt/color/orange + name = "orange jumpskirt" + icon_state = "orange_skirt" + item_state = "o_suit" + item_color = "orange_skirt" + /obj/item/clothing/under/color/pink name = "pink jumpsuit" icon_state = "pink" @@ -65,66 +123,133 @@ item_state = "p_suit" item_color = "pink" +/obj/item/clothing/under/skirt/color/pink + name = "pink jumpskirt" + icon_state = "pink_skirt" + item_state = "p_suit" + item_color = "pink_skirt" + /obj/item/clothing/under/color/red name = "red jumpsuit" icon_state = "red" item_state = "r_suit" item_color = "red" +/obj/item/clothing/under/skirt/color/red + name = "red jumpskirt" + icon_state = "red_skirt" + item_state = "r_suit" + item_color = "red_skirt" + /obj/item/clothing/under/color/white name = "white jumpsuit" icon_state = "white" item_state = "w_suit" item_color = "white" +/obj/item/clothing/under/skirt/color/white + name = "white jumpskirt" + icon_state = "white_skirt" + item_state = "w_suit" + item_color = "white_skirt" + /obj/item/clothing/under/color/yellow name = "yellow jumpsuit" icon_state = "yellow" item_state = "y_suit" item_color = "yellow" +/obj/item/clothing/under/skirt/color/yellow + name = "yellow jumpskirt" + icon_state = "yellow_skirt" + item_state = "y_suit" + item_color = "yellow_skirt" + /obj/item/clothing/under/color/darkblue name = "darkblue jumpsuit" icon_state = "darkblue" item_state = "b_suit" item_color = "darkblue" +/obj/item/clothing/under/skirt/color/darkblue + name = "darkblue jumpskirt" + icon_state = "darkblue_skirt" + item_state = "b_suit" + item_color = "darkblue_skirt" + /obj/item/clothing/under/color/teal name = "teal jumpsuit" icon_state = "teal" item_state = "b_suit" item_color = "teal" +/obj/item/clothing/under/skirt/color/teal + name = "teal jumpskirt" + icon_state = "teal_skirt" + item_state = "b_suit" + item_color = "teal_skirt" + + /obj/item/clothing/under/color/lightpurple name = "purple jumpsuit" icon_state = "lightpurple" item_state = "p_suit" item_color = "lightpurple" +/obj/item/clothing/under/skirt/color/lightpurple + name = "lightpurple jumpskirt" + icon_state = "lightpurple_skirt" + item_state = "p_suit" + item_color = "lightpurple_skirt" + /obj/item/clothing/under/color/darkgreen name = "darkgreen jumpsuit" icon_state = "darkgreen" item_state = "g_suit" item_color = "darkgreen" +/obj/item/clothing/under/skirt/color/darkgreen + name = "darkgreen jumpskirt" + icon_state = "darkgreen_skirt" + item_state = "g_suit" + item_color = "darkgreen_skirt" + /obj/item/clothing/under/color/lightbrown name = "lightbrown jumpsuit" icon_state = "lightbrown" item_state = "lb_suit" item_color = "lightbrown" +/obj/item/clothing/under/skirt/color/lightbrown + name = "lightbrown jumpskirt" + icon_state = "lightbrown_skirt" + item_state = "lb_suit" + item_color = "lightbrown_skirt" + /obj/item/clothing/under/color/brown name = "brown jumpsuit" icon_state = "brown" item_state = "lb_suit" item_color = "brown" +/obj/item/clothing/under/skirt/color/brown + name = "brown jumpskirt" + icon_state = "brown_skirt" + item_state = "lb_suit" + item_color = "brown_skirt" + /obj/item/clothing/under/color/maroon name = "maroon jumpsuit" icon_state = "maroon" item_state = "r_suit" item_color = "maroon" +/obj/item/clothing/under/skirt/color/maroon + name = "maroon jumpskirt" + icon_state = "maroon_skirt" + item_state = "r_suit" + item_color = "maroon_skirt" + /obj/item/clothing/under/color/rainbow name = "rainbow jumpsuit" desc = "A multi-colored jumpsuit!" @@ -132,3 +257,11 @@ item_state = "rainbow" item_color = "rainbow" can_adjust = FALSE + +/obj/item/clothing/under/skirt/color/rainbow + name = "rainbow jumpskirt" + desc = "A multi-colored jumpskirt!" + icon_state = "rainbow_skirt" + item_state = "rainbow" + item_color = "rainbow_skirt" + can_adjust = FALSE diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 2288c98b34..c6796d64c9 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -16,6 +16,16 @@ item_color = "purplebartender" can_adjust = FALSE +/obj/item/clothing/under/rank/bartender/skirt + name = "bartender's skirt" + desc = "It looks like it could use some more flair." + icon_state = "barman_skirt" + item_state = "bar_suit" + item_color = "barman_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/captain //Alright, technically not a 'civilian' but its better then giving a .dm file for a single define. desc = "It's a blue jumpsuit with some gold markings denoting the rank of \"Captain\"." name = "captain's jumpsuit" @@ -25,6 +35,16 @@ sensor_mode = SENSOR_COORDS random_sensor = FALSE +/obj/item/clothing/under/rank/captain/skirt + name = "captain's jumpskirt" + desc = "It's a blue jumpskirt with some gold markings denoting the rank of \"Captain\"." + icon_state = "captain_skirt" + item_state = "b_suit" + item_color = "captain_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/cargo name = "quartermaster's jumpsuit" desc = "It's a jumpsuit worn by the quartermaster. It's specially designed to prevent back injuries caused by pushing paper." @@ -32,6 +52,16 @@ item_state = "lb_suit" item_color = "qm" +/obj/item/clothing/under/rank/cargo/skirt + name = "quartermaster's jumpskirt" + desc = "It's a jumpskirt worn by the quartermaster. It's specially designed to prevent back injuries caused by pushing paper." + icon_state = "qm_skirt" + item_state = "lb_suit" + item_color = "qm_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/cargotech name = "cargo technician's jumpsuit" desc = "Shooooorts! They're comfy and easy to wear!" @@ -42,6 +72,15 @@ mutantrace_variation = MUTANTRACE_VARIATION alt_covers_chest = TRUE +/obj/item/clothing/under/rank/cargotech/skirt + name = "cargo technician's jumpskirt" + desc = "Skiiiiirts! They're comfy and easy to wear" + icon_state = "cargo_skirt" + item_state = "lb_suit" + item_color = "cargo_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP /obj/item/clothing/under/rank/chaplain desc = "It's a black jumpsuit, often worn by religious folk." @@ -51,6 +90,16 @@ item_color = "chapblack" can_adjust = FALSE +/obj/item/clothing/under/rank/chaplain/skirt + name = "chaplain's jumpskirt" + desc = "It's a black jumpskirt, often worn by religious folk." + icon_state = "chapblack_skirt" + item_state = "bl_suit" + item_color = "chapblack_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/chef name = "cook's suit" desc = "A suit which is given only to the most hardcore cooks in space." @@ -58,6 +107,15 @@ item_color = "chef" alt_covers_chest = TRUE +/obj/item/clothing/under/rank/chef/skirt + name = "cook's skirt" + desc = "A skirt which is given only to the most hardcore cooks in space." + icon_state = "chef_skirt" + item_color = "chef_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/clown name = "clown suit" desc = "'HONK!'" @@ -66,7 +124,6 @@ item_color = "clown" fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/rank/blueclown name = "blue clown suit" desc = "'BLUE HONK!'" @@ -130,7 +187,6 @@ /obj/item/clothing/under/rank/clown/Initialize() . = ..() AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) - /obj/item/clothing/under/rank/head_of_personnel desc = "It's a jumpsuit worn by someone who works in the position of \"Head of Personnel\"." name = "head of personnel's jumpsuit" @@ -139,6 +195,16 @@ item_color = "hop" can_adjust = FALSE +/obj/item/clothing/under/rank/head_of_personnel/skirt + name = "head of personnel's jumpskirt" + desc = "It's a jumpskirt worn by someone who works in the position of \"Head of Personnel\"." + icon_state = "hop_skirt" + item_state = "b_suit" + item_color = "hop_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/hydroponics desc = "It's a jumpsuit designed to protect against minor plant-related hazards." name = "botanist's jumpsuit" @@ -147,6 +213,16 @@ item_color = "hydroponics" permeability_coefficient = 0.5 +/obj/item/clothing/under/rank/hydroponics/skirt + name = "botanist's jumpskirt" + desc = "It's a jumpskirt designed to protect against minor plant-related hazards." + icon_state = "hydroponics_skirt" + item_state = "g_suit" + item_color = "hydroponics_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/janitor desc = "It's the official uniform of the station's janitor. It has minor protection from biohazards." name = "janitor's jumpsuit" @@ -154,49 +230,108 @@ item_color = "janitor" armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/janitor/skirt + name = "janitor's jumpskirt" + desc = "It's the official skirt of the station's janitor. It has minor protection from biohazards." + icon_state = "janitor_skirt" + item_color = "janitor_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer desc = "Slick threads." name = "Lawyer suit" can_adjust = FALSE - /obj/item/clothing/under/lawyer/black + name = "lawyer black suit" icon_state = "lawyer_black" item_state = "lawyer_black" item_color = "lawyer_black" +/obj/item/clothing/under/lawyer/black/skirt + name = "lawyer black suitskirt" + icon_state = "lawyer_black_skirt" + item_state = "lawyer_black" + item_color = "lawyer_black_skirt" + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer/female + name = "female black suit" icon_state = "black_suit_fem" - item_state = "black_suit_fem" + item_state = "bl_suit" item_color = "black_suit_fem" /obj/item/clothing/under/lawyer/red + name = "lawyer red suit" icon_state = "lawyer_red" item_state = "lawyer_red" item_color = "lawyer_red" +/obj/item/clothing/under/lawyer/female/skirt + name = "female black suitskirt" + icon_state = "black_suit_fem_skirt" + item_state = "bl_suit" + item_color = "black_suit_fem_skirt" + fitted = FEMALE_UNIFORM_TOP + +/obj/item/clothing/under/lawyer/red/skirt + name = "lawyer red suitskirt" + icon_state = "lawyer_red_skirt" + item_state = "lawyer_red" + item_color = "lawyer_red_skirt" + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer/blue + name = "lawyer blue suit" icon_state = "lawyer_blue" item_state = "lawyer_blue" item_color = "lawyer_blue" +/obj/item/clothing/under/lawyer/blue/skirt + name = "lawyer blue suitskirt" + icon_state = "lawyer_blue_skirt" + item_state = "lawyer_blue" + item_color = "lawyer_blue_skirt" + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer/bluesuit name = "blue suit" desc = "A classy suit and tie." icon_state = "bluesuit" - item_state = "bluesuit" + item_state = "b_suit" item_color = "bluesuit" can_adjust = TRUE alt_covers_chest = TRUE +/obj/item/clothing/under/lawyer/bluesuit/skirt + name = "blue suitskirt" + desc = "A classy suitskirt and tie." + icon_state = "bluesuit_skirt" + item_state = "b_suit" + item_color = "bluesuit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer/purpsuit name = "purple suit" icon_state = "lawyer_purp" - item_state = "lawyer_purp" + item_state = "p_suit" item_color = "lawyer_purp" fitted = NO_FEMALE_UNIFORM can_adjust = TRUE alt_covers_chest = TRUE +/obj/item/clothing/under/lawyer/purpsuit/skirt + name = "purple suitskirt" + icon_state = "lawyer_purp_skirt" + item_state = "p_suit" + item_color = "lawyer_purp_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/lawyer/blacksuit name = "black suit" desc = "A professional black suit. Nanotrasen Investigation Bureau approved!" @@ -206,6 +341,16 @@ can_adjust = TRUE alt_covers_chest = TRUE +/obj/item/clothing/under/lawyer/blacksuit/skirt + name = "black suitskirt" + desc = "A professional black suit. Nanotrasen Investigation Bureau approved!" + icon_state = "blacksuit_skirt" + item_state = "bar_suit" + item_color = "blacksuit_skirt" + can_adjust = FALSE + alt_covers_chest = TRUE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/curator name = "sensible suit" desc = "It's very... sensible." @@ -214,6 +359,33 @@ item_color = "red_suit" can_adjust = FALSE +/obj/item/clothing/under/lawyer/really_black + name = "executive suit" + desc = "A formal black suit and red tie, intended for the station's finest." + icon_state = "really_black_suit" + item_state = "bl_suit" + item_color = "really_black_suit" + +/obj/item/clothing/under/lawyer/really_black/skirt + name = "executive suitskirt" + desc = "A formal black suitskirt and red tie, intended for the station's finest." + icon_state = "really_black_suit_skirt" + item_state = "bl_suit" + item_color = "really_black_suit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + +/obj/item/clothing/under/rank/curator/skirt + name = "sensible suitskirt" + desc = "It's very... sensible." + icon_state = "red_suit_skirt" + item_state = "red_suit" + item_color = "red_suit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/curator/treasure_hunter name = "treasure hunter uniform" desc = "A rugged uniform suitable for treasure hunting." @@ -228,13 +400,22 @@ item_state = "mime" item_color = "mime" +/obj/item/clothing/under/rank/mime/skirt + name = "mime's skirt" + desc = "It's not very colourful." + icon_state = "mime_skirt" + item_state = "mime" + item_color = "mime_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/miner desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." name = "shaft miner's jumpsuit" icon_state = "miner" item_state = "miner" item_color = "miner" - /obj/item/clothing/under/rank/miner/lavaland desc = "A green uniform for operating in hazardous environments." name = "shaft miner's jumpsuit" diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index 4ee0963a64..f65b05c280 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -8,6 +8,16 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 80, "acid" = 40) resistance_flags = NONE +/obj/item/clothing/under/rank/chief_engineer/skirt + name = "chief engineer's jumpskirt" + desc = "It's a high visibility jumpskirt given to those engineers insane enough to achieve the rank of \"Chief Engineer\". It has minor radiation shielding." + icon_state = "chief_skirt" + item_state = "gy_suit" + item_color = "chief_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/atmospheric_technician desc = "It's a jumpsuit worn by atmospheric technicians." name = "atmospheric technician's jumpsuit" @@ -16,6 +26,16 @@ item_color = "atmos" resistance_flags = NONE +/obj/item/clothing/under/rank/atmospheric_technician/skirt + name = "atmospheric technician's jumpskirt" + desc = "It's a jumpskirt worn by atmospheric technicians." + icon_state = "atmos_skirt" + item_state = "atmos_suit" + item_color = "atmos_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/engineer desc = "It's an orange high visibility jumpsuit worn by engineers. It has minor radiation shielding." name = "engineer's jumpsuit" @@ -24,6 +44,23 @@ item_color = "engine" armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20) resistance_flags = NONE +/obj/item/clothing/under/rank/engineer/hazard + name = "engineer's hazard jumpsuit" + desc = "A high visibility jumpsuit made from heat and radiation resistant materials." + icon_state = "hazard" + item_state = "suit-orange" + item_color = "hazard" + alt_covers_chest = TRUE + +/obj/item/clothing/under/rank/engineer/skirt + name = "engineer's jumpskirt" + desc = "It's an orange high visibility jumpskirt worn by engineers." + icon_state = "engine_skirt" + item_state = "engi_suit" + item_color = "engine_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP /obj/item/clothing/under/rank/roboticist desc = "It's a slimming black with reinforced seams; great for industrial work." @@ -31,4 +68,14 @@ icon_state = "robotics" item_state = "robotics" item_color = "robotics" - resistance_flags = NONE \ No newline at end of file + resistance_flags = NONE + +/obj/item/clothing/under/rank/roboticist/skirt + name = "roboticist's jumpskirt" + desc = "It's a slimming black with reinforced seams; great for industrial work." + icon_state = "robotics_skirt" + item_state = "robotics" + item_color = "robotics_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index f0980cae4d..7b7a205021 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -10,6 +10,16 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 35) can_adjust = FALSE +/obj/item/clothing/under/rank/research_director/skirt + name = "research director's vest suitskirt" + desc = "It's a suitskirt worn by those with the know-how to achieve the position of \"Research Director\". Its fabric provides minor protection from biological contaminants." + icon_state = "director_skirt" + item_state = "lb_suit" + item_color = "director_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/research_director/alt desc = "Maybe you'll engineer your own half-man, half-pig creature some day. Its fabric provides minor protection from biological contaminants." name = "research director's tan suit" @@ -20,6 +30,16 @@ can_adjust = TRUE alt_covers_chest = TRUE +/obj/item/clothing/under/rank/research_director/alt/skirt + name = "research director's tan suitskirt" + desc = "Maybe you'll engineer your own half-man, half-pig creature some day. Its fabric provides minor protection from biological contaminants." + icon_state = "rdwhimsy_skirt" + item_state = "rdwhimsy" + item_color = "rdwhimsy_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/research_director/turtleneck desc = "A dark purple turtleneck and tan khakis, for a director with a superior sense of style." name = "research director's turtleneck" @@ -30,6 +50,16 @@ can_adjust = TRUE alt_covers_chest = TRUE +/obj/item/clothing/under/rank/research_director/turtleneck/skirt + name = "research director's turtleneck skirt" + desc = "A dark purple turtleneck and tan khaki skirt, for a director with a superior sense of style." + icon_state = "rdturtle_skirt" + item_state = "p_suit" + item_color = "rdturtle_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/scientist desc = "It's made of a special fiber that provides minor protection against explosives. It has markings that denote the wearer as a scientist." name = "scientist's jumpsuit" @@ -39,6 +69,15 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/scientist/skirt + name = "scientist's jumpskirt" + desc = "It's made of a special fiber that provides minor protection against explosives. It has markings that denote the wearer as a scientist." + icon_state = "toxinswhite_skirt" + item_state = "w_suit" + item_color = "toxinswhite_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP /obj/item/clothing/under/rank/chemist desc = "It's made of a special fiber that gives special protection against biohazards. It has a chemist rank stripe on it." @@ -49,6 +88,16 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 65) +/obj/item/clothing/under/rank/chemist/skirt + name = "chemist's jumpskirt" + desc = "It's made of a special fiber that gives special protection against biohazards. It has a chemist rank stripe on it." + icon_state = "chemistrywhite_skirt" + item_state = "w_suit" + item_color = "chemistrywhite_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /* * Medical */ @@ -61,6 +110,16 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/chief_medical_officer/skirt + name = "chief medical officer's jumpskirt" + desc = "It's a jumpskirt worn by those with the experience to be \"Chief Medical Officer\". It provides minor biological protection." + icon_state = "cmo_skirt" + item_state = "w_suit" + item_color = "cmo_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/geneticist desc = "It's made of a special fiber that gives special protection against biohazards. It has a genetics rank stripe on it." name = "geneticist's jumpsuit" @@ -70,6 +129,16 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/geneticist/skirt + name = "geneticist's jumpskirt" + desc = "It's made of a special fiber that gives special protection against biohazards. It has a genetics rank stripe on it." + icon_state = "geneticswhite_skirt" + item_state = "w_suit" + item_color = "geneticswhite_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/virologist desc = "It's made of a special fiber that gives special protection against biohazards. It has a virologist rank stripe on it." name = "virologist's jumpsuit" @@ -79,6 +148,16 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/virologist/skirt + name = "virologist's jumpskirt" + desc = "It's made of a special fiber that gives special protection against biohazards. It has a virologist rank stripe on it." + icon_state = "virologywhite_skirt" + item_state = "w_suit" + item_color = "virologywhite_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/nursesuit desc = "It's a jumpsuit commonly worn by nursing staff in the medical department." name = "nurse's suit" @@ -90,7 +169,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = NO_FEMALE_UNIFORM can_adjust = FALSE - /obj/item/clothing/under/rank/medical desc = "It's made of a special fiber that provides minor protection against biohazards. It has a cross on the chest denoting that the wearer is trained medical personnel." name = "medical doctor's jumpsuit" @@ -99,24 +177,31 @@ item_color = "medical" permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) - /obj/item/clothing/under/rank/medical/blue name = "medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue." icon_state = "scrubsblue" item_color = "scrubsblue" can_adjust = FALSE - /obj/item/clothing/under/rank/medical/green name = "medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in dark green." icon_state = "scrubsgreen" item_color = "scrubsgreen" can_adjust = FALSE - /obj/item/clothing/under/rank/medical/purple name = "medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in deep purple." icon_state = "scrubspurple" item_color = "scrubspurple" can_adjust = FALSE + +/obj/item/clothing/under/rank/medical/skirt + name = "medical doctor's jumpskirt" + desc = "It's made of a special fiber that provides minor protection against biohazards. It has a cross on the chest denoting that the wearer is trained medical personnel." + icon_state = "medical_skirt" + item_state = "w_suit" + item_color = "medical_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index b8858fdf1a..6c00d6969c 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -4,11 +4,9 @@ * Detective * Navy uniforms */ - /* * Security */ - /obj/item/clothing/under/rank/security name = "security jumpsuit" desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle." @@ -20,14 +18,12 @@ alt_covers_chest = TRUE sensor_mode = SENSOR_COORDS random_sensor = FALSE - /obj/item/clothing/under/rank/security/grey name = "grey security jumpsuit" desc = "A tactical relic of years past before Nanotrasen decided it was cheaper to dye the suits red instead of washing out the blood." icon_state = "security" item_state = "gy_suit" item_color = "security" - /obj/item/clothing/under/rank/security/skirt name = "security jumpskirt" desc = "A \"tactical\" security jumpsuit with the legs replaced by a skirt." @@ -36,6 +32,7 @@ item_color = "secskirt" body_parts_covered = CHEST|GROIN|ARMS can_adjust = FALSE //you know now that i think of it if you adjust the skirt and the sprite disappears isn't that just like flashing everyone + fitted = FEMALE_UNIFORM_TOP /obj/item/clothing/under/rank/warden @@ -49,7 +46,6 @@ alt_covers_chest = TRUE sensor_mode = 3 random_sensor = FALSE - /obj/item/clothing/under/rank/warden/grey name = "grey security suit" desc = "A formal relic of years past before Nanotrasen decided it was cheaper to dye the suits red instead of washing out the blood." @@ -57,6 +53,16 @@ item_state = "gy_suit" item_color = "warden" +/obj/item/clothing/under/rank/warden/skirt + name = "warden's suitskirt" + desc = "A formal security suitskirt for officers complete with Nanotrasen belt buckle." + icon_state = "rwarden_skirt" + item_state = "r_suit" + item_color = "rwarden_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /* * Detective */ @@ -72,6 +78,16 @@ sensor_mode = 3 random_sensor = FALSE +/obj/item/clothing/under/rank/det/skirt + name = "detective's suitskirt" + desc = "Someone who wears this means business." + icon_state = "detective_skirt" + item_state = "det" + item_color = "detective_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/det/grey name = "noir suit" desc = "A hard-boiled private investigator's grey suit, complete with tie clip." @@ -80,6 +96,16 @@ item_color = "greydet" alt_covers_chest = TRUE +/obj/item/clothing/under/rank/det/grey/skirt + name = "noir suitskirt" + desc = "A hard-boiled private investigator's grey suitskirt, complete with tie clip." + icon_state = "greydet_skirt" + item_state = "greydet" + item_color = "greydet_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /* * Head of Security */ @@ -95,13 +121,22 @@ sensor_mode = 3 random_sensor = FALSE +/obj/item/clothing/under/rank/head_of_security/skirt + name = "head of security's jumpskirt" + desc = "A security jumpskirt decorated for those few with the dedication to achieve the position of Head of Security." + icon_state = "rhos_skirt" + item_state = "r_suit" + item_color = "rhos_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/head_of_security/grey name = "head of security's grey jumpsuit" desc = "There are old men, and there are bold men, but there are very few old, bold men." icon_state = "hos" item_state = "gy_suit" item_color = "hos" - /obj/item/clothing/under/rank/head_of_security/alt name = "head of security's turtleneck" desc = "A stylish alternative to the normal head of security jumpsuit, complete with tactical pants." @@ -109,10 +144,19 @@ item_state = "bl_suit" item_color = "hosalt" +/obj/item/clothing/under/rank/head_of_security/alt/skirt + name = "head of security's turtleneck skirt" + desc = "A stylish alternative to the normal head of security jumpsuit, complete with a tactical skirt." + icon_state = "hosalt_skirt" + item_state = "bl_suit" + item_color = "hosalt_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /* * Navy uniforms */ - /obj/item/clothing/under/rank/security/navyblue name = "security officer's formal uniform" desc = "The latest in fashionable security outfits." @@ -120,7 +164,6 @@ item_state = "officerblueclothes" item_color = "officerblueclothes" alt_covers_chest = TRUE - /obj/item/clothing/under/rank/head_of_security/navyblue desc = "The insignia on this uniform tells you that this uniform belongs to the Head of Security." name = "head of security's formal uniform" @@ -128,7 +171,6 @@ item_state = "hosblueclothes" item_color = "hosblueclothes" alt_covers_chest = TRUE - /obj/item/clothing/under/rank/warden/navyblue desc = "The insignia on this uniform tells you that this uniform belongs to the Warden." name = "warden's formal uniform" @@ -136,14 +178,23 @@ item_state = "wardenblueclothes" item_color = "wardenblueclothes" alt_covers_chest = TRUE - /* *Blueshirt */ - /obj/item/clothing/under/rank/security/blueshirt + name = "blue shirt and tie" desc = "I'm a little busy right now, Calhoun." icon_state = "blueshift" item_state = "blueshift" item_color = "blueshift" can_adjust = FALSE +/* + *Spacepol + */ +/obj/item/clothing/under/rank/security/spacepol + name = "police uniform" + desc = "Space not controlled by megacorporations, planets, or pirates is under the jurisdiction of Spacepol." + icon_state = "spacepol" + item_state = "spacepol" + item_color = "spacepol" + can_adjust = FALSE diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 91fde0dbd0..616c00b6c1 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -5,7 +5,6 @@ item_color = "red_pyjamas" item_state = "w_suit" can_adjust = FALSE - /obj/item/clothing/under/pj/blue name = "blue pj's" desc = "Sleepwear." @@ -13,7 +12,6 @@ item_color = "blue_pyjamas" item_state = "w_suit" can_adjust = FALSE - /obj/item/clothing/under/patriotsuit name = "Patriotic Suit" desc = "Motorcycle not included." @@ -21,7 +19,6 @@ item_state = "ek" item_color = "ek" can_adjust = FALSE - /obj/item/clothing/under/scratch name = "white suit" desc = "A white suit, suitable for an excellent host." @@ -30,13 +27,22 @@ item_color = "scratch" can_adjust = FALSE +/obj/item/clothing/under/scratch/skirt + name = "white suitskirt" + desc = "A white suitskirt, suitable for an excellent host." + icon_state = "white_suit_skirt" + item_state = "scratch" + item_color = "white_suit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/sl_suit desc = "It's a very amish looking suit." name = "amish suit" icon_state = "sl_suit" item_color = "sl_suit" can_adjust = FALSE - /obj/item/clothing/under/roman name = "\improper Roman armor" desc = "Ancient Roman armor. Made of metallic and leather straps." @@ -46,7 +52,6 @@ can_adjust = FALSE strip_delay = 100 resistance_flags = NONE - /obj/item/clothing/under/waiter name = "waiter's outfit" desc = "It's a very smart uniform with a special pocket for tip." @@ -54,7 +59,6 @@ item_state = "waiter" item_color = "waiter" can_adjust = FALSE - /obj/item/clothing/under/rank/prisoner name = "prison jumpsuit" desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." @@ -65,20 +69,28 @@ sensor_mode = SENSOR_COORDS random_sensor = FALSE +/obj/item/clothing/under/rank/prisoner/skirt + name = "prison jumpskirt" + desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." + icon_state = "prisoner_skirt" + item_state = "o_suit" + item_color = "prisoner_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/rank/mailman name = "mailman's jumpsuit" desc = "'Special delivery!'" icon_state = "mailman" item_state = "b_suit" item_color = "mailman" - /obj/item/clothing/under/rank/psyche name = "psychedelic jumpsuit" desc = "Groovy!" icon_state = "psyche" item_state = "p_suit" item_color = "psyche" - /obj/item/clothing/under/rank/clown/sexy name = "sexy-clown suit" desc = "It makes you look HONKable!" @@ -86,7 +98,6 @@ item_state = "sexyclown" item_color = "sexyclown" can_adjust = FALSE - /obj/item/clothing/under/jabroni name = "Jabroni Outfit" desc = "The leather club is two sectors down." @@ -94,7 +105,6 @@ item_state = "darkholme" item_color = "darkholme" can_adjust = FALSE - /obj/item/clothing/under/rank/vice name = "vice officer's jumpsuit" desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." @@ -102,7 +112,6 @@ item_state = "gy_suit" item_color = "vice" can_adjust = FALSE - /obj/item/clothing/under/rank/centcom_officer desc = "It's a jumpsuit worn by CentCom Officers." name = "\improper CentCom officer's jumpsuit" @@ -110,14 +119,12 @@ item_state = "g_suit" item_color = "officer" alt_covers_chest = TRUE - /obj/item/clothing/under/rank/centcom_commander desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." name = "\improper CentCom officer's jumpsuit" icon_state = "centcom" item_state = "dg_suit" item_color = "centcom" - /obj/item/clothing/under/space name = "\improper NASA jumpsuit" desc = "It has a NASA logo on it and is made of space-proofed materials." @@ -134,7 +141,6 @@ max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT can_adjust = FALSE resistance_flags = NONE - /obj/item/clothing/under/acj name = "administrative cybernetic jumpsuit" icon_state = "syndicate" @@ -151,28 +157,24 @@ max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT can_adjust = FALSE resistance_flags = FIRE_PROOF | ACID_PROOF - /obj/item/clothing/under/owl name = "owl uniform" desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." icon_state = "owl" item_color = "owl" can_adjust = FALSE - /obj/item/clothing/under/griffin name = "griffon uniform" desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." icon_state = "griffin" item_color = "griffin" can_adjust = FALSE - /obj/item/clothing/under/cloud name = "cloud" desc = "cloud" icon_state = "cloud" item_color = "cloud" can_adjust = FALSE - /obj/item/clothing/under/gimmick/rank/captain/suit name = "captain's suit" desc = "A green suit and yellow necktie. Exemplifies authority." @@ -181,6 +183,16 @@ item_color = "green_suit" can_adjust = FALSE +/obj/item/clothing/under/gimmick/rank/captain/suit/skirt + name = "green suitskirt" + desc = "A green suitskirt and yellow necktie. Exemplifies authority." + icon_state = "green_suit_skirt" + item_state = "dg_suit" + item_color = "green_suit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit name = "head of personnel's suit" desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble." @@ -189,6 +201,16 @@ item_color = "teal_suit" can_adjust = FALSE +/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit/skirt + name = "teal suitskirt" + desc = "A teal suitskirt and yellow necktie. An authoritative yet tacky ensemble." + icon_state = "teal_suit_skirt" + item_state = "g_suit" + item_color = "teal_suit_skirt" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/suit_jacket name = "black suit" desc = "A black suit and red tie. Very formal." @@ -196,21 +218,18 @@ item_state = "bl_suit" item_color = "black_suit" can_adjust = FALSE - /obj/item/clothing/under/suit_jacket/really_black name = "executive suit" desc = "A formal black suit and red tie, intended for the station's finest." icon_state = "really_black_suit" item_state = "bl_suit" - item_color = "black_suit" - + item_color = "really_black_suit" /obj/item/clothing/under/suit_jacket/female name = "executive suit" desc = "A formal trouser suit for women, intended for the station's finest." icon_state = "black_suit_fem" item_state = "black_suit_fem" item_color = "black_suit_fem" - /obj/item/clothing/under/suit_jacket/green name = "green suit" desc = "A green suit and yellow necktie. Baller." @@ -218,56 +237,48 @@ item_state = "dg_suit" item_color = "green_suit" can_adjust = FALSE - /obj/item/clothing/under/suit_jacket/red name = "red suit" desc = "A red suit and blue tie. Somewhat formal." icon_state = "red_suit" item_state = "r_suit" item_color = "red_suit" - /obj/item/clothing/under/suit_jacket/charcoal name = "charcoal suit" desc = "A charcoal suit and red tie. Very professional." icon_state = "charcoal_suit" item_state = "charcoal_suit" item_color = "charcoal_suit" - /obj/item/clothing/under/suit_jacket/navy name = "navy suit" desc = "A navy suit and red tie, intended for the station's finest." icon_state = "navy_suit" item_state = "navy_suit" item_color = "navy_suit" - /obj/item/clothing/under/suit_jacket/burgundy name = "burgundy suit" desc = "A burgundy suit and black tie. Somewhat formal." icon_state = "burgundy_suit" item_state = "burgundy_suit" item_color = "burgundy_suit" - /obj/item/clothing/under/suit_jacket/checkered name = "checkered suit" desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" icon_state = "checkered_suit" item_state = "checkered_suit" item_color = "checkered_suit" - /obj/item/clothing/under/suit_jacket/tan name = "tan suit" desc = "A tan suit with a yellow tie. Smart, but casual." icon_state = "tan_suit" item_state = "tan_suit" item_color = "tan_suit" - /obj/item/clothing/under/suit_jacket/white name = "white suit" desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!" icon_state = "white_suit" item_state = "white_suit" item_color = "white_suit" - /obj/item/clothing/under/burial name = "burial garments" desc = "Traditional burial garments from the early 22nd century." @@ -275,7 +286,6 @@ item_state = "burial" item_color = "burial" has_sensor = NO_SENSORS - /obj/item/clothing/under/skirt/black name = "black skirt" desc = "A black skirt, very fancy!" @@ -284,7 +294,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/skirt/blue name = "blue skirt" desc = "A blue, casual skirt." @@ -294,7 +303,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/skirt/red name = "red skirt" desc = "A red, casual skirt." @@ -304,7 +312,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/skirt/purple name = "purple skirt" desc = "A purple, casual skirt." @@ -314,8 +321,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - - /obj/item/clothing/under/schoolgirl name = "blue schoolgirl uniform" desc = "It's just like one of my Japanese animes!" @@ -325,25 +330,21 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/schoolgirl/red name = "red schoolgirl uniform" icon_state = "schoolgirlred" item_state = "schoolgirlred" item_color = "schoolgirlred" - /obj/item/clothing/under/schoolgirl/green name = "green schoolgirl uniform" icon_state = "schoolgirlgreen" item_state = "schoolgirlgreen" item_color = "schoolgirlgreen" - /obj/item/clothing/under/schoolgirl/orange name = "orange schoolgirl uniform" icon_state = "schoolgirlorange" item_state = "schoolgirlorange" item_color = "schoolgirlorange" - /obj/item/clothing/under/overalls name = "laborer's overalls" desc = "A set of durable overalls for getting the job done." @@ -351,7 +352,6 @@ item_state = "lb_suit" item_color = "overalls" can_adjust = FALSE - /obj/item/clothing/under/pirate name = "pirate outfit" desc = "Yarr." @@ -359,7 +359,6 @@ item_state = "pirate" item_color = "pirate" can_adjust = FALSE - /obj/item/clothing/under/soviet name = "soviet uniform" desc = "For the Motherland!" @@ -367,7 +366,6 @@ item_state = "soviet" item_color = "soviet" can_adjust = FALSE - /obj/item/clothing/under/redcoat name = "redcoat uniform" desc = "Looks old." @@ -375,7 +373,6 @@ item_state = "redcoat" item_color = "redcoat" can_adjust = FALSE - /obj/item/clothing/under/kilt name = "kilt" desc = "Includes shoes and plaid." @@ -385,10 +382,12 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/kilt/highlander desc = "You're the only one worthy of this kilt." - item_flags = NODROP + +/obj/item/clothing/under/kilt/highlander/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) /obj/item/clothing/under/sexymime name = "sexy mime outfit" @@ -399,7 +398,6 @@ body_parts_covered = CHEST|GROIN|LEGS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/gladiator name = "gladiator uniform" desc = "Are you not entertained? Is that not why you are here?" @@ -410,11 +408,9 @@ fitted = NO_FEMALE_UNIFORM can_adjust = FALSE resistance_flags = NONE - /obj/item/clothing/under/gladiator/ash_walker desc = "This gladiator uniform appears to be covered in ash and fairly dated." has_sensor = NO_SENSORS - /obj/item/clothing/under/sundress name = "sundress" desc = "Makes you want to frolic in a field of daisies." @@ -424,7 +420,6 @@ body_parts_covered = CHEST|GROIN fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/captainparade name = "captain's parade uniform" desc = "A captain's luxury-wear, for special occasions." @@ -432,7 +427,6 @@ item_state = "by_suit" item_color = "captain_parade" can_adjust = FALSE - /obj/item/clothing/under/hosparademale name = "head of security's parade uniform" desc = "A male head of security's luxury-wear, for special occasions." @@ -440,7 +434,6 @@ item_state = "r_suit" item_color = "hos_parade_male" can_adjust = FALSE - /obj/item/clothing/under/hosparadefem name = "head of security's parade uniform" desc = "A female head of security's luxury-wear, for special occasions." @@ -449,7 +442,6 @@ item_color = "hos_parade_fem" fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/assistantformal name = "assistant's formal uniform" desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." @@ -457,7 +449,6 @@ item_state = "gy_suit" item_color = "assistant_formal" can_adjust = FALSE - /obj/item/clothing/under/blacktango name = "black tango dress" desc = "Filled with Latin fire." @@ -466,8 +457,6 @@ item_color = "black_tango" fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - body_parts_covered = CHEST|GROIN - /obj/item/clothing/under/stripeddress name = "striped dress" desc = "Fashion in space." @@ -477,7 +466,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_FULL can_adjust = FALSE - /obj/item/clothing/under/sailordress name = "sailor dress" desc = "Formal wear for a leading lady." @@ -487,7 +475,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/redeveninggown name = "red evening gown" desc = "Fancy dress for space bar singers." @@ -496,7 +483,6 @@ item_color = "red_evening_gown" fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/maid name = "maid costume" desc = "Maid in China." @@ -506,12 +492,10 @@ body_parts_covered = CHEST|GROIN fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/maid/Initialize() . = ..() var/obj/item/clothing/accessory/maidapron/A = new (src) attach_accessory(A) - /obj/item/clothing/under/janimaid name = "maid uniform" desc = "A simple maid uniform for housekeeping." @@ -521,7 +505,6 @@ body_parts_covered = CHEST|GROIN fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/plaid_skirt name = "red plaid skirt" desc = "A preppy red skirt with a white blouse." @@ -531,7 +514,6 @@ fitted = FEMALE_UNIFORM_TOP can_adjust = TRUE alt_covers_chest = TRUE - /obj/item/clothing/under/plaid_skirt/blue name = "blue plaid skirt" desc = "A preppy blue skirt with a white blouse." @@ -541,7 +523,6 @@ fitted = FEMALE_UNIFORM_TOP can_adjust = TRUE alt_covers_chest = TRUE - /obj/item/clothing/under/plaid_skirt/purple name = "purple plaid skirt" desc = "A preppy purple skirt with a white blouse." @@ -551,7 +532,6 @@ fitted = FEMALE_UNIFORM_TOP can_adjust = TRUE alt_covers_chest = TRUE - /obj/item/clothing/under/singery name = "yellow performer's outfit" desc = "Just looking at this makes you want to sing." @@ -562,7 +542,6 @@ fitted = NO_FEMALE_UNIFORM alternate_worn_layer = ABOVE_SHOES_LAYER can_adjust = FALSE - /obj/item/clothing/under/singerb name = "blue performer's outfit" desc = "Just looking at this makes you want to sing." @@ -573,7 +552,6 @@ alternate_worn_layer = ABOVE_SHOES_LAYER fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - /obj/item/clothing/under/plaid_skirt/green name = "green plaid skirt" desc = "A preppy green skirt with a white blouse." @@ -583,17 +561,14 @@ fitted = FEMALE_UNIFORM_TOP can_adjust = TRUE alt_covers_chest = TRUE - /obj/item/clothing/under/jester name = "jester suit" desc = "A jolly dress, well suited to entertain your master, nuncle." icon_state = "jester" item_color = "jester" can_adjust = FALSE - /obj/item/clothing/under/jester/alt icon_state = "jester2" - /obj/item/clothing/under/geisha name = "geisha suit" desc = "Cute space ninja senpai not included." @@ -601,14 +576,12 @@ item_color = "geisha" body_parts_covered = CHEST|GROIN|ARMS can_adjust = FALSE - /obj/item/clothing/under/villain name = "villain suit" desc = "A change of wardrobe is necessary if you ever want to catch a real superhero." icon_state = "villain" item_color = "villain" can_adjust = FALSE - /obj/item/clothing/under/sailor name = "sailor suit" desc = "Skipper's in the wardroom drinkin gin'." @@ -616,7 +589,6 @@ item_state = "b_suit" item_color = "sailor" can_adjust = FALSE - /obj/item/clothing/under/plasmaman name = "plasma envirosuit" desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." @@ -630,17 +602,12 @@ var/next_extinguish = 0 var/extinguish_cooldown = 100 var/extinguishes_left = 5 - - /obj/item/clothing/under/plasmaman/examine(mob/user) ..() to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") - - /obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) if(!istype(H)) return - if(H.on_fire) if(extinguishes_left) if(next_extinguish > world.time) @@ -651,7 +618,6 @@ H.ExtinguishMob() new /obj/effect/particle_effect/water(get_turf(H)) return 0 - /obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) ..() if (istype(E, /obj/item/extinguisher_refill)) @@ -665,20 +631,17 @@ return return return - /obj/item/extinguisher_refill name = "envirosuit extinguisher cartridge" desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." icon_state = "plasmarefill" icon = 'icons/obj/device.dmi' - /obj/item/clothing/under/rank/security/navyblue/russian name = "\improper Russian officer's uniform" desc = "The latest in fashionable russian outfits." icon_state = "hostanclothes" item_state = "hostanclothes" item_color = "hostanclothes" - /obj/item/clothing/under/mummy name = "mummy wrapping" desc = "Return the slab or suffer my stale references." @@ -689,7 +652,6 @@ fitted = NO_FEMALE_UNIFORM can_adjust = FALSE resistance_flags = NONE - /obj/item/clothing/under/scarecrow name = "scarecrow clothes" desc = "Perfect camouflage for hiding in botany." @@ -700,7 +662,6 @@ fitted = NO_FEMALE_UNIFORM can_adjust = FALSE resistance_flags = NONE - /obj/item/clothing/under/draculass name = "draculass coat" desc = "A dress inspired by the ancient \"Victorian\" era." @@ -710,8 +671,6 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - /obj/item/clothing/under/drfreeze name = "doctor freeze's jumpsuit" desc = "A modified scientist jumpsuit to look extra cool." @@ -719,8 +678,6 @@ item_state = "drfreeze" item_color = "drfreeze" can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - /obj/item/clothing/under/lobster name = "foam lobster suit" desc = "Who beheaded the college mascot?" @@ -729,8 +686,6 @@ item_color = "lobster" fitted = NO_FEMALE_UNIFORM can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - /obj/item/clothing/under/gondola name = "gondola hide suit" desc = "Now you're cooking." @@ -738,7 +693,6 @@ item_state = "lb_suit" item_color = "gondola" can_adjust = FALSE - /obj/item/clothing/under/skeleton name = "skeleton jumpsuit" desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!" @@ -755,4 +709,23 @@ desc = "A simple, inconspicuous harness replacement for a jumpsuit." icon_state = "gear_harness" item_state = "gear_harness" //We dont use golem do to being a item, item without faces making it default to error suit sprites. - body_parts_covered = CHEST|GROIN \ No newline at end of file + body_parts_covered = CHEST|GROIN + +/obj/item/clothing/under/durathread + name = "durathread jumpsuit" + desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "durathread" + item_state = "durathread" + item_color = "durathread" + can_adjust = TRUE + armor = list("melee" = 10, "laser" = 10, "fire" = 40, "acid" = 10, "bomb" = 5) + +/obj/item/clothing/under/duraskirt + name = "durathread jumpskirt" + desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer. Being a short skirt, it naturally doesn't protect the legs." + icon_state = "duraskirt" + item_state = "duraskirt" + item_color = "durathread" + can_adjust = FALSE + body_parts_covered = CHEST|GROIN|ARMS + armor = list("melee" = 10, "laser" = 10, "fire" = 40, "acid" = 10, "bomb" = 5) \ No newline at end of file diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 83cab9d992..9893edf248 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -8,6 +8,17 @@ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40) alt_covers_chest = TRUE +/obj/item/clothing/under/syndicate/skirt + name = "tactical skirtleneck" + desc = "A non-descript and slightly suspicious looking skirtleneck." + icon_state = "syndicate_skirt" + item_state = "bl_suit" + item_color = "syndicate_skirt" + has_sensor = NO_SENSORS + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40) + alt_covers_chest = TRUE + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/syndicate/tacticool name = "tacticool turtleneck" desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." @@ -16,6 +27,15 @@ item_color = "tactifool" armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40) +/obj/item/clothing/under/syndicate/tacticool/skirt + name = "tacticool skirtleneck" + desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." + icon_state = "tactifool_skirt" + item_state = "bl_suit" + item_color = "tactifool_skirt" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40) + fitted = FEMALE_UNIFORM_TOP + /obj/item/clothing/under/syndicate/sniper name = "Tactical turtleneck suit" desc = "A double seamed tactical turtleneck disguised as a civilian grade silk suit. Intended for the most formal operator. The collar is really sharp." diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 3e96512bb8..0fb46c3e46 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -317,6 +317,8 @@ var/list/cant_craft = list() for(var/rec in GLOB.crafting_recipes) var/datum/crafting_recipe/R = rec + if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue if((R.category != cur_category) || (R.subcategory != cur_subcategory)) continue if(check_contents(R, surroundings)) @@ -431,3 +433,10 @@ data["tool_text"] = tool_text return data + +//Mind helpers + +/datum/mind/proc/teach_crafting_recipe(R) + if(!learned_recipes) + learned_recipes = list() + learned_recipes |= R \ No newline at end of file diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index a76be1ff45..73052acfe1 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -9,6 +9,7 @@ var/chem_catalysts[] = list() //like tools but for reagents var/category = CAT_NONE //where it shows up in the crafting UI var/subcategory = CAT_NONE + var/always_availible = TRUE //Set to FALSE if it needs to be learned first. /datum/crafting_recipe/pin_removal name = "Pin Removal" @@ -68,7 +69,7 @@ /datum/crafting_recipe/molotov name = "Molotov" result = /obj/item/reagent_containers/food/drinks/bottle/molotov - reqs = list(/obj/item/reagent_containers/glass/rag = 1, + reqs = list(/obj/item/reagent_containers/rag = 1, /obj/item/reagent_containers/food/drinks/bottle = 1) parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1) time = 40 @@ -210,6 +211,12 @@ time = 40 category = CAT_ROBOT +/datum/crafting_recipe/potatos + name = "Potat-OS" + reqs = list(/obj/item/stack/cable_coil = 1, /obj/item/stack/rods = 1, /obj/item/reagent_containers/food/snacks/grown/potato = 1, /obj/item/aicard = 1 ) + result = /obj/item/aicard/potato + category = CAT_ROBOT + /datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but name = "Pneumatic Cannon" result = /obj/item/pneumatic_cannon/ghetto @@ -352,6 +359,7 @@ reqs = list(/obj/item/restraints/handcuffs/cable = 1, /obj/item/shard = 1, /obj/item/stack/rods = 1) + parts = list(/obj/item/shard = 1) time = 40 category = CAT_WEAPONRY subcategory = CAT_WEAPON @@ -454,6 +462,12 @@ /obj/item/bikehorn = 1) category = CAT_MISC +/datum/crafting_recipe/toyneb + name = "Non-Euplastic Blade" + reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4) + result = /obj/item/toy/sword/cx + category = CAT_MISC + /datum/crafting_recipe/chemical_payload name = "Chemical Payload (C4)" result = /obj/item/bombcore/chemical @@ -659,6 +673,15 @@ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) category = CAT_MISC +/datum/crafting_recipe/femur_breaker + name = "Femur Breaker" + result = /obj/structure/femur_breaker + time = 150 + reqs = list(/obj/item/stack/sheet/metal = 20, + /obj/item/stack/cable_coil = 30) + tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) + category = CAT_MISC + /datum/crafting_recipe/lizardhat name = "Lizard Cloche Hat" result = /obj/item/clothing/head/lizard @@ -791,6 +814,56 @@ time = 40 category = CAT_MISC +/datum/crafting_recipe/bronze_driver + name = "Bronze Plated Screwdriver" + result = /obj/item/screwdriver/bronze + reqs = list(/obj/item/screwdriver = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_welder + name = "Bronze Plated Welding Tool" + result = /obj/item/weldingtool/bronze + reqs = list(/obj/item/weldingtool = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_wirecutters + name = "Bronze Plated Wirecutters" + result = /obj/item/wirecutters/bronze + reqs = list(/obj/item/wirecutters = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_crowbar + name = "Bronze Plated Crowbar" + result = /obj/item/crowbar/bronze + reqs = list(/obj/item/crowbar = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + +/datum/crafting_recipe/bronze_wrench + name = "Bronze Plated Wrench" + result = /obj/item/wrench/bronze + reqs = list(/obj/item/wrench = 1, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/tile/bronze = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC + /datum/crafting_recipe/smartdart name = "Medical smartdart" result = /obj/item/reagent_containers/syringe/dart @@ -823,3 +896,44 @@ time = 150 //It's a gun category = CAT_WEAPONRY subcategory = CAT_WEAPON + +/datum/crafting_recipe/durathread_duffelbag + name = "Durathread Dufflebag" + result = /obj/item/storage/backpack/duffelbag/durathread + reqs = list(/obj/item/stack/sheet/durathread = 7, + /obj/item/stack/sheet/leather = 3) + time = 70 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_toolbelt + name = "Durathread Toolbelt" + result = /obj/item/storage/belt/durathread + reqs = list(/obj/item/stack/sheet/durathread = 5, + /obj/item/stack/sheet/leather = 1) + time = 30 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_bandolier + name = "Durathread Bandolier" + result = /obj/item/storage/belt/bandolier/durathread + reqs = list(/obj/item/stack/sheet/durathread = 6, + /obj/item/stack/sheet/leather = 2) + time = 50 + category = CAT_CLOTHING + + /datum/crafting_recipe/durathread_helmet + name = "Makeshift Durathread Helmet" + result = /obj/item/clothing/head/helmet/durathread + reqs = list(/obj/item/stack/sheet/durathread = 4, + /obj/item/stack/sheet/leather = 2) + time = 30 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_vest + name = "Makeshift Durathread Armour" + result = /obj/item/clothing/suit/armor/vest/durathread + reqs = list(/obj/item/stack/sheet/durathread = 6, + /obj/item/stack/sheet/leather = 3) + time = 50 + category = CAT_CLOTHING + diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm deleted file mode 100644 index a25bc01b13..0000000000 --- a/code/modules/detectivework/footprints_and_rag.dm +++ /dev/null @@ -1,50 +0,0 @@ - -/mob - var/bloody_hands = 0 - -/obj/item/clothing/gloves - var/transfer_blood = 0 - - -/obj/item/reagent_containers/glass/rag - name = "damp rag" - desc = "For cleaning up messes, you suppose." - w_class = WEIGHT_CLASS_TINY - icon = 'icons/obj/toy.dmi' - icon_state = "rag" - item_flags = NOBLUDGEON - reagent_flags = OPENCONTAINER - amount_per_transfer_from_this = 5 - possible_transfer_amounts = list() - volume = 5 - spillable = FALSE - -/obj/item/reagent_containers/glass/rag/suicide_act(mob/user) - user.visible_message("[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) - -/obj/item/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity) - . = ..() - if(!proximity) - return - if(iscarbon(A) && A.reagents && reagents.total_volume) - var/mob/living/carbon/C = A - var/reagentlist = pretty_string_from_reagent_list(reagents) - var/log_object = "a damp rag containing [reagentlist]" - if(user.a_intent == INTENT_HARM && !C.is_mouth_covered()) - reagents.reaction(C, INGEST) - reagents.trans_to(C, reagents.total_volume) - C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and muffled cries of surprise.") - log_combat(user, C, "smothered", log_object) - else - reagents.reaction(C, TOUCH) - reagents.clear_reagents() - C.visible_message("[user] has touched \the [C] with \the [src].") - log_combat(user, C, "touched", log_object) - - else if(istype(A) && src in user) - user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...") - if(do_after(user,30, target = A)) - user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].") - SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) - return diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index a4e8b276b5..8f77af58eb 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -41,11 +41,16 @@ else L.mind.add_antag_datum(/datum/antagonist/heartbreaker) -/proc/forge_valentines_objective(mob/living/lover,mob/living/date) +/proc/forge_valentines_objective(mob/living/lover,mob/living/date,var/chemLove = FALSE) lover.mind.special_role = "valentine" - var/datum/antagonist/valentine/V = new - V.date = date.mind - lover.mind.add_antag_datum(V) //These really should be teams but i can't be assed to incorporate third wheels right now + if (chemLove == TRUE) + var/datum/antagonist/valentine/chem/V = new //Changes text and EOG check basically. + V.date = date.mind + lover.mind.add_antag_datum(V) + else + var/datum/antagonist/valentine/V = new + V.date = date.mind + lover.mind.add_antag_datum(V) //These really should be teams but i can't be assed to incorporate third wheels right now /datum/round_event/valentines/announce(fake) priority_announce("It's Valentine's Day! Give a valentine to that special someone!") diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index d9654b395d..e041d566e9 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -100,6 +100,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 /obj/effect/immovablerod/ex_act(severity, target) return 0 +/obj/structure/closet/supplypod/prevent_content_explosion() + return TRUE + /obj/effect/immovablerod/singularity_act() return diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index 798bcf82dd..af22ae3b96 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -15,6 +15,12 @@ var/list/wave_type var/wave_name = "normal" +/datum/round_event/meteor_wave/setup() + announceWhen = 1 + startWhen = rand(300, 600) //Yeah for SOME REASON this is measured in seconds and not deciseconds??? + endWhen = startWhen + 60 + + /datum/round_event/meteor_wave/New() ..() if(!wave_type) @@ -46,7 +52,7 @@ kill() /datum/round_event/meteor_wave/announce(fake) - priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg') + priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.", "Meteor Alert", 'sound/ai/meteors.ogg') /datum/round_event/meteor_wave/tick() if(ISMULTIPLE(activeFor, 3)) diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm index b01ff4237e..48a9f00423 100644 --- a/code/modules/events/mice_migration.dm +++ b/code/modules/events/mice_migration.dm @@ -32,4 +32,4 @@ P.update_icon() /datum/round_event/mice_migration/start() - SSsqueak.trigger_migration(rand(minimum_mice, maximum_mice)) + SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice)) diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index 1407a98518..901337cd52 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -17,6 +17,8 @@ continue if(!H.getorgan(/obj/item/organ/appendix)) //Don't give the disease to some who lacks it, only for it to be auto-cured continue + if(!(MOB_ORGANIC in H.mob_biotypes)) //biotype sleeper bugs strike again, once again making appendicitis pick a target that can't take it + continue var/foundAlready = FALSE //don't infect someone that already has appendicitis for(var/datum/disease/appendicitis/A in H.diseases) foundAlready = TRUE diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index a6e08fbd8c..41ee4246b1 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -50,7 +50,8 @@ var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list H.dropItemToGround(H.get_item_by_slot(i), TRUE) H.equip_to_slot_or_del(I, i) - I.item_flags |= NODROP | DROPDEL + ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT) + I.item_flags |= DROPDEL I.name = "cursed " + I.name for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm index ec253f13c3..7e37429223 100644 --- a/code/modules/events/wizard/shuffle.dm +++ b/code/modules/events/wizard/shuffle.dm @@ -27,7 +27,7 @@ for(var/mob/living/carbon/human/H in mobs) if(!moblocs) break //locs aren't always unique, so this may come into play - do_teleport(H, moblocs[moblocs.len]) + do_teleport(H, moblocs[moblocs.len], channel = TELEPORT_CHANNEL_MAGIC) moblocs.len -= 1 for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 412e54878a..bb601b7c82 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -63,4 +63,4 @@ hard_target = P.loc if(!hard_target) return - do_teleport(M, hard_target, 1, 1, 0, 0) ///You will appear adjacent to the beacon + do_teleport(M, hard_target, 1, 1, 0, 0, channel = TELEPORT_CHANNEL_WORMHOLE) ///You will appear adjacent to the beacon diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 5cd5d2c5c6..88f72d27c3 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -689,7 +689,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( chosen = capitalize(pick(speak_messages)) chosen = replacetext(chosen, "%TARGETNAME%", target_name) var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER) - var/message = target.compose_message(person,understood_language,chosen,null,person.get_spans(),face_name = TRUE) + var/message = target.compose_message(person,understood_language,chosen,null,list(person.speech_span),face_name = TRUE) feedback_details += "Type: Talk, Source: [person.real_name], Message: [message]" to_chat(target, message) if(target.client) @@ -705,7 +705,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) humans += H person = pick(humans) - var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",person.get_spans(),face_name = TRUE) + var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",list(person.speech_span),face_name = TRUE) feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]" to_chat(target, message) qdel(src) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index a2a1c6d03f..e72b624ae5 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -7,11 +7,12 @@ /obj/item/reagent_containers/food/drinks/bottle amount_per_transfer_from_this = 10 volume = 100 + force = 15 throwforce = 15 item_state = "broken_beer" //Generic held-item sprite until unique ones are made. lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' - var/const/duration = 13 //Directly relates to the 'knockdown' duration. Lowered by armor (i.e. helmets) + var/knockdown_duration = 13 //Directly relates to the 'knockdown' duration. Lowered by armor (i.e. helmets) isGlass = TRUE foodtype = ALCOHOL @@ -61,46 +62,30 @@ to_chat(user, "You don't want to harm [target]!") return - force = 15 //Smashing bottles over someoen's head hurts. - var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at - var/armor_block = 0 //Get the target's armor values for normal attack damage. - var/armor_duration = 0 //The more force the bottle has, the longer the duration. + var/headarmor = 0 // Target's head armor + var/armor_block = min(90, target.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage - //Calculating duration and calculating damage. - if(ishuman(target)) + //If they have a hat/helmet and the user is targeting their head. + if(affecting == BODY_ZONE_HEAD) + var/obj/item/I = target.get_item_by_slot(SLOT_HEAD) + if(I) + headarmor = I.armor.melee - var/mob/living/carbon/human/H = target - var/headarmor = 0 // Target's head armor - armor_block = H.run_armor_check(affecting, "melee", null, null,armour_penetration) // For normal attack damage - - //If they have a hat/helmet and the user is targeting their head. - if(istype(H.head, /obj/item/clothing/head) && affecting == BODY_ZONE_HEAD) - headarmor = H.head.armor.melee - else - headarmor = 0 - - //Calculate the knockdown duration for the target. - armor_duration = (duration - headarmor) + force - - else - //Only humans can have armor, right? - armor_block = target.run_armor_check(affecting, "melee") - if(affecting == BODY_ZONE_HEAD) - armor_duration = duration + force + //Calculate the knockdown duration for the target. + var/armor_duration = (knockdown_duration - headarmor) + force //Apply the damage! - armor_block = min(90,armor_block) target.apply_damage(force, BRUTE, affecting, armor_block) // You are going to knock someone out for longer if they are not wearing a helmet. var/head_attack_message = "" - if(affecting == BODY_ZONE_HEAD && istype(target, /mob/living/carbon/)) + if(affecting == BODY_ZONE_HEAD && iscarbon(target)) head_attack_message = " on the head" //Knockdown the target for the duration that we calculated and divide it by 5. if(armor_duration) - target.apply_effect(min(armor_duration, 200) , EFFECT_KNOCKDOWN) // Never knockdown more than a flash! + target.Knockdown(min(armor_duration, 200)) // Never knockdown more than a flash! //Display an attack message. if(target != user) @@ -202,6 +187,20 @@ desc = "A flask of holy water...it's been sitting in the Necropolis a while though." list_reagents = list("hell_water" = 100) +/obj/item/reagent_containers/food/drinks/bottle/holyoil + name = "flask of zelus oil" + desc = "A brass flask of Zelus oil, a viscous fluid scenting of brass. Can be thrown to deal damage from afar." + icon_state = "zelusflask" + list_reagents = list("holyoil" = 30) + volume = 30 + foodtype = NONE + force = 18 + throwforce = 18 + knockdown_duration = 18 + +/obj/item/reagent_containers/food/drinks/bottle/holyoil/empty + list_reagents = list("holyoil" = 0) + /obj/item/reagent_containers/food/drinks/bottle/vermouth name = "Goldeneye vermouth" desc = "Sweet, sweet dryness~" diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index 51433da841..132e000893 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -1,6 +1,10 @@ //////////////////////////////////////////////////////////////////////////////// /// Food. //////////////////////////////////////////////////////////////////////////////// +/// Note: When adding food items with dummy parents, make sure to add +/// the parent to the exclusion list in code/__HELPERS/unsorted.dm's +/// get_random_food proc. +//////////////////////////////////////////////////////////////////////////////// /obj/item/reagent_containers/food possible_transfer_amounts = list() volume = 50 //Sets the default container amount for all food items. diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm index 1eeea79410..d66cfdd667 100644 --- a/code/modules/food_and_drinks/food/snacks_cake.dm +++ b/code/modules/food_and_drinks/food/snacks_cake.dm @@ -17,21 +17,21 @@ foodtype = GRAIN | DAIRY /obj/item/reagent_containers/food/snacks/store/cake/plain - name = "vanilla cake" + name = "plain cake" desc = "A plain cake, not a lie." icon_state = "plaincake" custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/cake bonus_reagents = list("nutriment" = 10, "vitamin" = 2) - tastes = list("vanilla" = 1, "sweetness" = 2,"cake" = 5) + tastes = list("sweetness" = 2,"cake" = 5) foodtype = GRAIN | DAIRY | SUGAR /obj/item/reagent_containers/food/snacks/cakeslice/plain - name = "vanilla cake slice" + name = "plain cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "plaincake_slice" filling_color = "#FFD700" customfoodfilling = 1 - tastes = list("vanilla" = 1, "sweetness" = 2,"cake" = 5) + tastes = list("sweetness" = 2,"cake" = 5) foodtype = GRAIN | DAIRY | SUGAR /obj/item/reagent_containers/food/snacks/store/cake/carrot @@ -147,7 +147,6 @@ tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) foodtype = GRAIN | DAIRY | FRUIT | SUGAR - /obj/item/reagent_containers/food/snacks/store/cake/chocolate name = "chocolate cake" desc = "A cake with added chocolate." @@ -186,7 +185,6 @@ tastes = list("cake" = 5, "sweetness" = 1) foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - /obj/item/reagent_containers/food/snacks/store/cake/apple name = "apple cake" desc = "A cake centred with Apple." @@ -248,7 +246,6 @@ /obj/item/reagent_containers/food/snacks/store/cake/bsvc // blackberry strawberries vanilla cake name = "blackberry and strawberry vanilla cake" desc = "A plain cake, filled with assortment of blackberries and strawberries!" - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "blackbarry_strawberries_cake_vanilla_cake" slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bsvc bonus_reagents = list("nutriment" = 14, "vitamin" = 4) @@ -258,7 +255,6 @@ /obj/item/reagent_containers/food/snacks/cakeslice/bsvc name = "blackberry and strawberry vanilla cake slice" desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "blackbarry_strawberries_cake_vanilla_slice" filling_color = "#FFD700" tastes = list("blackbarry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3) @@ -267,7 +263,6 @@ /obj/item/reagent_containers/food/snacks/store/cake/bscc // blackbarry strawberries chocolate cake name = "blackberry and strawberry chocolate cake" desc = "A plain cake, filled with assortment of blackberries and strawberries!" - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "blackbarry_strawberries_cake_coco_cake" slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bscc bonus_reagents = list("nutriment" = 14, "vitamin" = 4, "cocoa" = 5) @@ -277,16 +272,14 @@ /obj/item/reagent_containers/food/snacks/cakeslice/bscc name = "blackberry and strawberry chocolate cake slice" desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "blackbarry_strawberries_cake_coco_cake_slice" filling_color = "#FFD700" tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) foodtype = GRAIN | DAIRY | FRUIT | SUGAR -obj/item/reagent_containers/food/snacks/store/cake/holy_cake +/obj/item/reagent_containers/food/snacks/store/cake/holy_cake name = "angel food cake" desc = "A cake made for angels and chaplains alike! Contains holy water." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "holy_cake" slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice bonus_reagents = list("nutriment" = 1, "vitamin" = 3, "holy_water" = 10) @@ -296,7 +289,6 @@ obj/item/reagent_containers/food/snacks/store/cake/holy_cake /obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice name = "angel food cake slice" desc = "A slice of heavenly cake." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "holy_cake_slice" filling_color = "#00FFFF" tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) @@ -305,7 +297,6 @@ obj/item/reagent_containers/food/snacks/store/cake/holy_cake obj/item/reagent_containers/food/snacks/store/cake/pound_cake name = "pound cake" desc = "A condensed cake made for filling people up quickly." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "pound_cake" slices_num = 7 //Its ment to feed the party slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice @@ -316,16 +307,14 @@ obj/item/reagent_containers/food/snacks/store/cake/pound_cake /obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice name = "pound cake slice" desc = "A slice of condensed cake made for filling people up quickly." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "pound_cake_slice" filling_color = "#00FFFF" tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1) foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD -obj/item/reagent_containers/food/snacks/store/cake/hardware_cake +/obj/item/reagent_containers/food/snacks/store/cake/hardware_cake name = "hardware cake" desc = "A cake that is made with electronic boards and leaks acid..." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "hardware_cake" slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice bonus_reagents = list("sacid" = 15, "oil" = 15) @@ -335,8 +324,41 @@ obj/item/reagent_containers/food/snacks/store/cake/hardware_cake /obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice name = "hardware cake slice" desc = "A slice of electronic boards and some acid." - icon = 'modular_citadel/icons/obj/food/cake.dmi' icon_state = "hardware_cake_slice" filling_color = "#00FFFF" tastes = list("acid" = 1, "metal" = 1, "regret" = 10) foodtype = GRAIN | GROSS + +/obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake + name = "vanilla cake" + desc = "A vanilla frosted cake." + icon_state = "vanillacake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice + bonus_reagents = list("sugar" = 15, "vanilla" = 15) + tastes = list("caje" = 1, "sugar" = 1, "vanilla" = 10) + foodtype = GRAIN | SUGAR | DAIRY + +/obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice + name = "vanilla cake slice" + desc = "A slice of vanilla frosted cake." + icon_state = "vanillacake_slice" + filling_color = "#00FFFF" + tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10) + foodtype = GRAIN | SUGAR | DAIRY + +/obj/item/reagent_containers/food/snacks/store/cake/clown_cake + name = "clown cake" + desc = "A funny cake with a clown face on it." + icon_state = "clowncake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/clown_slice + bonus_reagents = list("sugar" = 15, "laugher" = 15) + tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) + foodtype = GRAIN | SUGAR | DAIRY + +/obj/item/reagent_containers/food/snacks/cakeslice/clown_slice + name = "clown cake slice" + desc = "A slice of bad jokes, and silly props." + icon_state = "clowncake_slice" + filling_color = "#00FFFF" + tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) + foodtype = GRAIN | SUGAR | DAIRY \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_frozen.dm b/code/modules/food_and_drinks/food/snacks_frozen.dm index febfa527ca..c4f8ccf76b 100644 --- a/code/modules/food_and_drinks/food/snacks_frozen.dm +++ b/code/modules/food_and_drinks/food/snacks_frozen.dm @@ -88,7 +88,7 @@ /obj/item/reagent_containers/food/snacks/snowcones/orange name = "orange flavored snowcone" - desc = "A mix of different flavors dizzled on a snowball in a paper cup." + desc = "A orange flavor dizzled on a snowball in a paper cup." icon_state = "orange_sc" list_reagents = list("nutriment" = 1, "orangejuice" = 10) tastes = list("ice" = 1, "water" = 1, "berries" = 5) @@ -130,7 +130,7 @@ name = "mixed fruit flavored snowcone" desc = "A mix of different flavors dizzled on a snowball in a paper cup." icon_state = "fruitsalad_sc" - list_reagents = list("nutriment" = 1, "lemonjuice" = 5, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5) + list_reagents = list("nutriment" = 1, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5) tastes = list("ice" = 1, "water" = 1, "fruits" = 25) foodtype = FRUIT diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index e36efe750b..c4b9451c7f 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -573,4 +573,14 @@ name = "Maintenance Peaches" desc = "I have a mouth and I must eat." icon_state = "peachcanmaint" - tastes = list("peaches" = 1, "tin" = 7) \ No newline at end of file + tastes = list("peaches" = 1, "tin" = 7) + +/obj/item/reagent_containers/food/snacks/chocolatestrawberry + name = "Chocolate dipped strawberries" + desc = "A strawberry dipped in a bit of chocolate." + icon_state = "chocolatestrawberry" + list_reagents = list("sugar" = 5, "nutriment" = 2) + filling_color = "#ffdf26" + w_class = WEIGHT_CLASS_NORMAL + tastes = list("strawberries" = 5, "chocolate" = 3) + foodtype = FRUIT | SUGAR \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 238bb4f86a..9b87002738 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -308,7 +308,6 @@ tastes = list("bread" = 1, "egg" = 1, "cheese" = 1) foodtype = GRAIN | MEAT | DAIRY - /obj/item/reagent_containers/food/snacks/sugarcookie name = "sugar cookie" desc = "Just like your little sister used to make." @@ -369,6 +368,16 @@ tastes = list("cake" = 3, "blue cherry" = 1) foodtype = GRAIN | FRUIT | SUGAR +/obj/item/reagent_containers/food/snacks/strawberrycupcake + name = "Strawberry cupcake" + desc = "Strawberry inside a delicious cupcake." + icon_state = "strawberrycupcake" + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + list_reagents = list("nutriment" = 5, "vitamin" = 1) + filling_color = "#F0E68C" + tastes = list("cake" = 2, "strawberry" = 1) + foodtype = GRAIN | FRUIT | SUGAR + /obj/item/reagent_containers/food/snacks/honeybun name = "honey bun" desc = "A sticky pastry bun glazed with honey." diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 9d63d48f34..be6c11fd68 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -53,7 +53,7 @@ H.adjust_blurriness(1) H.visible_message("[H] is creamed by [src]!", "You've been creamed by [src]!") playsound(H, "desceration", 50, TRUE) - reagents.trans_to(H,15) //Transfers the cream pies total volume of reagents to target on it + reagents.trans_to(H,15) //Cream pie combat if(!H.creamed) // one layer at a time H.add_overlay(creamoverlay) H.creamed = TRUE @@ -61,6 +61,7 @@ qdel(src) /obj/item/reagent_containers/food/snacks/pie/cream/nostun + list_reagents = list("laughter" = 15) stunning = FALSE /obj/item/reagent_containers/food/snacks/pie/cream/body @@ -170,8 +171,6 @@ tastes = list("pie" = 1, "apple" = 1) foodtype = GRAIN | FRUIT | SUGAR - - /obj/item/reagent_containers/food/snacks/pie/cherrypie name = "cherry pie" desc = "Taste so good, make a grown man cry." @@ -220,6 +219,33 @@ tastes = list("pie" = 1, "grape" = 1) foodtype = GRAIN | FRUIT | SUGAR +/obj/item/reagent_containers/food/snacks/pie/mimetart + name = "mime tart" + desc = "..." + icon_state = "mimetart" + bonus_reagents = list("nutriment" = 1, "vitamin" = 4, "nothing" = 10) + list_reagents = list("nutriment" = 5, "vitamin" = 5) + tastes = list("pie" = 1, "nothing" = 1) + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/pie/berrytart + name = "berry tart" + desc = "A tasty dessert of many different small barries on a thin pie crust." + icon_state = "berrytart" + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 3, "vitamin" = 5) + tastes = list("pie" = 1, "berries" = 2) + foodtype = GRAIN | FRUIT + +/obj/item/reagent_containers/food/snacks/pie/cocolavatart + name = "chocolate lava tart" + desc = "A tasty dessert made of chocaloate, with a liquid core." + icon_state = "cocolavatart" + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 4, "vitamin" = 4) + tastes = list("pie" = 1, "grape" = 1) + foodtype = GRAIN | SUGAR + /obj/item/reagent_containers/food/snacks/pie/blumpkinpie name = "blumpkin pie" desc = "An odd blue pie made with toxic blumpkin." @@ -287,6 +313,14 @@ icon_state = "baklavaslice" trash = /obj/item/trash/plate filling_color = "#1E90FF" - list_reagents = list("nutriment" = 2, "vitamins" = 4) + list_reagents = list("nutriment" = 2, "vitamin" = 4) tastes = list("nuts" = 1, "pie" = 1) - foodtype = GRAIN \ No newline at end of file + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/pie/strawberrypie + name = "strawberry pie" + desc = "A strawberry.pie." + icon_state = "strawberrypie" + bonus_reagents = list("nutriment" = 6, "vitamin" = 6) + tastes = list("strawberry" = 1, "pie" = 1) + foodtype = GRAIN | FRUIT | SUGAR diff --git a/code/modules/food_and_drinks/food/snacks_vend.dm b/code/modules/food_and_drinks/food/snacks_vend.dm index 317a434040..8f661b868e 100644 --- a/code/modules/food_and_drinks/food/snacks_vend.dm +++ b/code/modules/food_and_drinks/food/snacks_vend.dm @@ -7,7 +7,7 @@ desc = "Nougat love it or hate it." icon_state = "candy" trash = /obj/item/trash/candy - list_reagents = list("nutriment" = 1, "sugar" = 3) + list_reagents = list("nutriment" = 1, "sugar" = 3, "cocoa" = 3) junkiness = 25 filling_color = "#D2691E" tastes = list("candy" = 1) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 23172841e4..dd33f696c9 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -94,7 +94,7 @@ God bless America. else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?! return else - if(is_type_in_typecache(I, deepfry_blacklisted_items) || (I.item_flags & (ABSTRACT | NODROP | DROPDEL))) + if(is_type_in_typecache(I, deepfry_blacklisted_items) || HAS_TRAIT(I, TRAIT_NODROP) || (I.item_flags & (ABSTRACT | DROPDEL))) return ..() else if(!frying && user.transferItemToLoc(I, src)) to_chat(user, "You put [I] into [src].") diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index d8d4e843dc..e02c3c1334 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -78,7 +78,7 @@ if(!ignore_clothing) for(var/obj/item/I in C.held_items + C.get_equipped_items()) - if(!(I.item_flags & NODROP)) + if(!HAS_TRAIT(I, TRAIT_NODROP)) to_chat(user, "Subject may not have abiotic items on.") return diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 3f917273b4..35ce25bbaf 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -138,6 +138,10 @@ for (var/mob/M in src) M.forceMove(drop_location()) +/obj/machinery/processor/container_resist(mob/living/user) + user.forceMove(drop_location()) + user.visible_message("[user] crawls free of the processor!") + /obj/machinery/processor/slime name = "slime processor" desc = "An industrial grinder with a sticker saying appropriated for science department. Keep hands clear of intake area while operating." diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm index 464b8ce26f..e26d15dbd3 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm @@ -148,6 +148,27 @@ result = /obj/item/reagent_containers/food/snacks/store/cake/bsvc subcategory = CAT_CAKE +/datum/crafting_recipe/food/clowncake + name = "clown cake" + always_availible = FALSE + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/reagent_containers/food/snacks/sundae = 2, + /obj/item/reagent_containers/food/snacks/grown/banana = 5 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/clown_cake + subcategory = CAT_CAKE + +/datum/crafting_recipe/food/vanillacake + name = "vanilla cake" + always_availible = FALSE + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/reagent_containers/food/snacks/grown/vanillapod = 2 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake + subcategory = CAT_CAKE + /datum/crafting_recipe/food/cak name = "Living cat/cake hybrid" reqs = list( 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 08d5716779..73b09df68d 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm @@ -211,7 +211,7 @@ subcategory = CAT_ICE /datum/crafting_recipe/food/kiwi_sc - name = "Soda water snowcone" + name = "Kiwi snowcone" reqs = list( /obj/item/reagent_containers/food/drinks/sillycup = 1, /obj/item/reagent_containers/food/snacks/egg/kiwiEgg = 1, diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index a6240e5b48..9cf5ea31a0 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -258,7 +258,7 @@ subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/lizardwine +/datum/crafting_recipe/lizardwine //not a subtype of /datum/crafting_recipe/food due to a bug where the resulting bottle would contain 100u of lizardwine and 100u of ethanol. name = "Lizard wine" time = 40 reqs = list( @@ -266,6 +266,7 @@ /datum/reagent/consumable/ethanol = 100 ) result = /obj/item/reagent_containers/food/drinks/bottle/lizardwine + category = CAT_FOOD subcategory = CAT_MISCFOOD @@ -331,3 +332,12 @@ ) result = /obj/item/reagent_containers/food/snacks/riceball subcategory = CAT_MISCFOOD + +/datum/crafting_recipe/food/chocolatestrawberry + name = "Chocolate Strawberry" + reqs = list( + /obj/item/reagent_containers/food/snacks/chocolatebar = 1, + /obj/item/reagent_containers/food/snacks/grown/strawberry = 1 + ) + result = /obj/item/reagent_containers/food/snacks/chocolatestrawberry + subcategory = CAT_MISCFOOD \ No newline at end of file diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index 2246d12df4..931a78212f 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -325,6 +325,15 @@ datum/crafting_recipe/food/donut/meat result = /obj/item/reagent_containers/food/snacks/bluecherrycupcake subcategory = CAT_PASTRY +/datum/crafting_recipe/food/strawberrycupcake + name = "Strawberry cherry cupcake" + reqs = list( + /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/reagent_containers/food/snacks/grown/strawberry = 1 + ) + result = /obj/item/reagent_containers/food/snacks/strawberrycupcake + subcategory = CAT_PASTRY + /datum/crafting_recipe/food/honeybun name = "Honey bun" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm index 79d761c2e2..81824dc4b8 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm @@ -160,6 +160,15 @@ result = /obj/item/reagent_containers/food/snacks/pie/frostypie subcategory = CAT_PIE +/datum/crafting_recipe/food/strawberrypie + name = "Strawberry pie" + reqs = list( + /obj/item/reagent_containers/food/snacks/pie/plain = 1, + /obj/item/reagent_containers/food/snacks/grown/strawberry = 1 + ) + result = /obj/item/reagent_containers/food/snacks/pie/strawberrypie + subcategory = CAT_PIE + /datum/crafting_recipe/food/baklava name = "Baklava pie" reqs = list( @@ -168,4 +177,41 @@ /obj/item/seeds/wheat/oat = 3 ) result = /obj/item/reagent_containers/food/snacks/pie/baklava + subcategory = CAT_PIE + +/datum/crafting_recipe/food/mimetart + name = "Mime tart" + always_availible = FALSE + reqs = list( + /datum/reagent/consumable/milk = 5, + /datum/reagent/consumable/sugar = 5, + /obj/item/reagent_containers/food/snacks/pie/plain = 1, + /datum/reagent/consumable/nothing = 5 + ) + result = /obj/item/reagent_containers/food/snacks/pie/mimetart + subcategory = CAT_PIE + +/datum/crafting_recipe/food/berrytart + name = "Berry tart" + always_availible = FALSE + reqs = list( + /datum/reagent/consumable/milk = 5, + /datum/reagent/consumable/sugar = 5, + /obj/item/reagent_containers/food/snacks/pie/plain = 1, + /obj/item/reagent_containers/food/snacks/grown/berries = 3 + ) + result = /obj/item/reagent_containers/food/snacks/pie/berrytart + subcategory = CAT_PIE + +/datum/crafting_recipe/food/cocolavatart + name = "Chocolate Lava tart" + always_availible = FALSE + reqs = list( + /datum/reagent/consumable/milk = 5, + /datum/reagent/consumable/sugar = 5, + /obj/item/reagent_containers/food/snacks/pie/plain = 1, + /obj/item/reagent_containers/food/snacks/chocolatebar = 3, + /obj/item/slime_extract = 1 + ) + result = /obj/item/reagent_containers/food/snacks/pie/cocolavatart subcategory = CAT_PIE \ No newline at end of file diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 463df71f71..082f20f524 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -82,6 +82,12 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico if("setMusicVolume") data = setMusicVolume(arglist(params)) + if("swaptodarkmode") + swaptodarkmode() + + if("swaptolightmode") + swaptolightmode() + if(data) ehjax_send(data = data) @@ -240,3 +246,10 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. C << output(url_encode(url_encode(message)), "browseroutput:output") + + +/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation) + owner.force_white_theme() + +/datum/chatOutput/proc/swaptodarkmode() + owner.force_dark_theme() diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index cf11b77879..7b942494f4 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -7,16 +7,20 @@ html, body { padding: 0; margin: 0; height: 100%; - color: #000000; + color: #f0f0f0; } body { - background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/ + background: #171717; font-family: Verdana, sans-serif; font-size: 9pt; + font-color: #f0f0f0; line-height: 1.2; overflow-x: hidden; overflow-y: scroll; - word-wrap: break-word; + word-wrap: break-word; + scrollbar-face-color:#1A1A1A; + scrollbar-track-color:#171717; + scrollbar-highlight-color:#171717; } em { @@ -56,9 +60,9 @@ img.icon { border-radius: 10px; } -a {color: #0000ff;} -a.visited {color: #ff00ff;} -a:visited {color: #ff00ff;} +a {color: #397ea5;} +a.visited {color: #7c00e6;} +a:visited {color: #7c00e6;} a.popt {text-decoration: none;} /***************************************** @@ -89,21 +93,21 @@ a.popt {text-decoration: none;} bottom: 0; right: 0; padding: 8px; - background: #ddd; + background: #202020; text-decoration: none; font-variant: small-caps; font-size: 1.1em; font-weight: bold; - color: #333; + color: #a4bad6; } -#newMessages:hover {background: #ccc;} +#newMessages:hover {background: #171717;} #newMessages i {vertical-align: middle; padding-left: 3px;} #ping { position: fixed; top: 0; - right: 80px; + right: 115px; width: 45px; - background: #ddd; + background: #202020; height: 30px; padding: 8px 0 2px 0; } @@ -120,19 +124,19 @@ a.popt {text-decoration: none;} right: 0; } #userBar .subCell { - background: #ddd; + background: #202020; height: 30px; padding: 5px 0; display: block; - color: #333; + color: #a4bad6; text-decoration: none; line-height: 28px; - border-top: 1px solid #b4b4b4; + border-top: 1px solid #171717; } -#userBar .subCell:hover {background: #ccc;} +#userBar .subCell:hover {background: #202020;} #userBar .toggle { width: 40px; - background: #ccc; + background: #202020; border-top: 0; float: right; text-align: center; @@ -242,9 +246,9 @@ a.popt {text-decoration: none;} ******************************************/ /* MOTD */ -.motd {color: #638500; font-family: Verdana, sans-serif;} -.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} -.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} +.motd {color: #a4bad6; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #a4bad6; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #a4bad6;} /* ADD HERE FOR BOLD */ .bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} @@ -255,88 +259,90 @@ a.popt {text-decoration: none;} /* OUTPUT COLORS */ .highlight {background: yellow;} -h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} -h1.alert, h2.alert {color: #000000;} +h1, h2, h3, h4, h5, h6 {color: #a4bad6;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #a4bad6;} em {font-style: normal; font-weight: bold;} -.ooc { font-weight: bold;} +.ooc {color: #cca300; font-weight: bold;} +.antagooc {color: #ce254f; font-weight: bold;} .adminobserverooc {color: #0099cc; font-weight: bold;} -.adminooc {color: #700038; font-weight: bold;} +.adminooc {color: #3d5bc3; font-weight: bold;} -.adminsay {color: #FF4500; font-weight: bold;} -.admin {color: #386aff; font-weight: bold;} +.adminsay {color: #ff4500; font-weight: bold;} +.admin {color: #5975da; font-weight: bold;} .name { font-weight: bold;} .say {} -.deadsay {color: #5c00e6;} +.deadsay {color: #e2c1ff;} .binarysay {color: #20c20e; background-color: #000000; display: block;} .binarysay a {color: #00ff00;} .binarysay a:active, .binarysay a:visited {color: #88ff88;} -.radio {color: #008000;} -.sciradio {color: #993399;} -.comradio {color: #948f02;} -.secradio {color: #a30000;} -.medradio {color: #337296;} -.engradio {color: #fb5613;} -.suppradio {color: #a8732b;} -.servradio {color: #6eaa2c;} -.syndradio {color: #6d3f40;} -.centcomradio {color: #686868;} -.aiprivradio {color: #ff00ff;} -.redteamradio {color: #ff0000;} -.blueteamradio {color: #0000ff;} +.radio {color: #1ecc43;} +.sciradio {color: #c68cfa;} +.comradio {color: #5177ff;} +.secradio {color: #dd3535;} +.medradio {color: #57b8f0;} +.engradio {color: #f37746;} +.suppradio {color: #b88646;} +.servradio {color: #6ca729;} +.syndradio {color: #8f4a4b;} +.centcomradio {color: #2681a5;} +.aiprivradio {color: #d65d95;} +.redteamradio {color: #ff4444;} +.blueteamradio {color: #3434fd;} .yell { font-weight: bold;} -.alert {color: #ff0000;} -h1.alert, h2.alert {color: #000000;} +.alert {color: #d82020;} +h1.alert, h2.alert {color: #99aab5;} .emote { font-style: italic;} .selecteddna {color: #ffffff; background-color: #001B1B} -.attack {color: #ff0000;} -.disarm {color: #990000;} -.passive {color: #660000;} +.attack {color: #e01c1c;} +.disarm {color: #b42525;} +.passive {color: #a00f0f;} -.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} -.danger {color: #ff0000;} -.warning {color: #ff0000; font-style: italic;} -.alertwarning {color: #FF0000; font-weight: bold} -.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} -.announce {color: #228b22; font-weight: bold;} -.boldannounce {color: #ff0000; font-weight: bold;} -.greenannounce {color: #00ff00; font-weight: bold;} +.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;} +.danger {color: #c51e1e;} +.warning {color: #c51e1e; font-style: italic;} +.alertwarning {color: #FF0000; font-weight: bold} +.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold} +.announce {color: #c51e1e; font-weight: bold;} +.boldannounce {color: #c51e1e; font-weight: bold;} +.greenannounce {color: #059223; font-weight: bold;} .rose {color: #ff5050;} -.info {color: #0000CC;} -.notice {color: #000099;} -.boldnotice {color: #000099; font-weight: bold;} -.adminnotice {color: #0000ff;} +.info {color: #6685f5;} +.notice {color: #6685f5;} +.boldnotice {color: #6685f5; font-weight: bold;} +.adminnotice {color: #6685f5;} .adminhelp {color: #ff0000; font-weight: bold;} -.unconscious {color: #0000ff; font-weight: bold;} +.unconscious {color: #a4bad6; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} -.green {color: #03ff39;} -.red {color: #FF0000} -.blue {color: #215cff} -.nicegreen {color: #14a833;} +.red {color: #FF0000} +.pink {color: #ff70c1;} +.blue {color: #215cff} +.green {color: #059223;} +.nicegreen {color: #059223;} .userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;} .love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;} -.shadowling {color: #3b2769;} -.cult {color: #960000;} +.shadowling {color: #8e8a99;} +.cult {color: #aa1c1c;} -.cultitalic {color: #960000; font-style: italic;} -.cultbold {color: #960000; font-style: italic; font-weight: bold;} -.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} +.cultitalic {color: #aa1c1c; font-style: italic;} +.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;} -.cultlarge {color: #960000; font-weight: bold; font-size: 24px;} -.narsie {color: #960000; font-weight: bold; font-size: 120px;} -.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;} +.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;} +.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;} .colossus {color: #7F282A; font-size: 40px;} -.hierophant {color: #660099; font-weight: bold; font-style: italic;} -.hierophant_warning {color: #660099; font-style: italic;} -.purple {color: #5e2d79;} -.holoparasite {color: #35333a;} +.hierophant {color: #b441ee; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #c56bf1; font-style: italic;} +.purple {color: #9956d3;} +.holoparasite {color: #88809c;} .revennotice {color: #1d2953;} .revenboldnotice {color: #1d2953; font-weight: bold;} @@ -344,11 +350,11 @@ h1.alert, h2.alert {color: #000000;} .revenminor {color: #823abb} .revenwarning {color: #760fbb; font-style: italic;} .revendanger {color: #760fbb; font-weight: bold; font-size: 24px;} -.umbra {color: #5000A0;} -.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} -.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;} +.umbra {color: #7c00e6;} +.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;} +.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;} -.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;} +.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;} .brass {color: #BE8700;} .heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} @@ -373,17 +379,17 @@ h1.alert, h2.alert {color: #000000;} .neovgre {color: #6E001A; font-weight: bold; font-style: italic;} .neovgre_small {color: #6E001A;} -.newscaster {color: #800000;} -.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} +.newscaster {color: #c05d5d;} +.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;} -.alien {color: #543354;} -.noticealien {color: #00c000;} -.alertalien {color: #00c000; font-weight: bold;} -.changeling {color: #800080; font-style: italic;} +.alien {color: #855d85;} +.noticealien {color: #059223;} +.alertalien {color: #059223; font-weight: bold;} +.changeling {color: #059223; font-style: italic;} -.spider {color: #4d004d;} +.spider {color: #8800ff;} -.interface {color: #330033;} +.interface {color: #750e75;} .sans {font-family: "Comic Sans MS", cursive, sans-serif;} .papyrus {font-family: "Papyrus", cursive, sans-serif;} @@ -394,29 +400,54 @@ h1.alert, h2.alert {color: #000000;} .big {font-size: 24px;} .reallybig {font-size: 32px;} .extremelybig {font-size: 40px;} -.greentext {color: #00FF00; font-size: 24px;} -.redtext {color: #FF0000; font-size: 24px;} -.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.greentext {color: #059223; font-size: 24px;} +.redtext {color: #c51e1e; font-size: 24px;} +.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} .his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} +.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} +@keyframes velvet { + 0% { color: #400020; } + 40% { color: #FF0000; } + 50% { color: #FF8888; } + 60% { color: #FF0000; } + 100% { color: #400020; } +} + +.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;} +@keyframes hypnocolor { + 0% { color: #202020; } + 25% { color: #4b02ac; } + 50% { color: #9f41f1; } + 75% { color: #541c9c; } + 100% { color: #7adbf3; } +} + +.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} +@keyframes phobia { + 0% { color: #f75a5a; } + 50% { color: #dd0000; } + 100% { color: #f75a5a; } +} + .icon {height: 1em; width: auto;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} -.abductor {color: #800080; font-style: italic;} -.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} +.abductor {color: #c204c2; font-style: italic;} +.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} .swarmer {color: #2C75FF;} .resonate {color: #298F85;} -.monkeyhive {color: #774704;} -.monkeylead {color: #774704; font-size: 2;} +.monkeyhive {color: #a56408;} +.monkeylead {color: #af6805; font-size: 2;} .connectionClosed, .fatalError {background: red; color: white; padding: 5px;} .connectionClosed.restored {background: green;} -.internal.boldnshit {color: blue; font-weight: bold;} +.internal.boldnshit {color: #3d5bc3; font-weight: bold;} /* HELPER CLASSES */ .text-normal {font-weight: normal; font-style: normal;} diff --git a/code/modules/goonchat/browserassets/css/browserOutput_white.css b/code/modules/goonchat/browserassets/css/browserOutput_white.css new file mode 100644 index 0000000000..e21185449b --- /dev/null +++ b/code/modules/goonchat/browserassets/css/browserOutput_white.css @@ -0,0 +1,426 @@ +/***************************************** +* +* GLOBAL STYLES +* +******************************************/ +html, body { + padding: 0; + margin: 0; + height: 100%; + color: #000000; +} +body { + background: #fff; + font-family: Verdana, sans-serif; + font-size: 9pt; + line-height: 1.2; + overflow-x: hidden; + overflow-y: scroll; + word-wrap: break-word; +} + +em { + font-style: normal; + font-weight: bold; +} + +img { + margin: 0; + padding: 0; + line-height: 1; + -ms-interpolation-mode: nearest-neighbor; + image-rendering: pixelated; +} +img.icon { + height: 1em; + min-height: 16px; + width: auto; + vertical-align: bottom; +} + + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline-block; + min-width: 0.5em; + font-size: 0.7em; + padding: 0.2em 0.3em; + line-height: 1; + color: white; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: crimson; + border-radius: 10px; +} + +a {color: #0000ff;} +a.visited {color: #ff00ff;} +a:visited {color: #ff00ff;} +a.popt {text-decoration: none;} + +/***************************************** +* +* OUTPUT NOT RELATED TO ACTUAL MESSAGES +* +******************************************/ +#loading { + position: fixed; + width: 300px; + height: 150px; + text-align: center; + left: 50%; + top: 50%; + margin: -75px 0 0 -150px; +} +#loading i {display: block; padding-bottom: 3px;} + +#messages { + font-size: 13px; + padding: 3px; + margin: 0; + word-wrap: break-word; +} +#newMessages { + position: fixed; + display: block; + bottom: 0; + right: 0; + padding: 8px; + background: #ddd; + text-decoration: none; + font-variant: small-caps; + font-size: 1.1em; + font-weight: bold; + color: #333; +} +#newMessages:hover {background: #ccc;} +#newMessages i {vertical-align: middle; padding-left: 3px;} +#ping { + position: fixed; + top: 0; + right: 115px; + width: 45px; + background: #ddd; + height: 30px; + padding: 8px 0 2px 0; +} +#ping i {display: block; text-align: center;} +#ping .ms { + display: block; + text-align: center; + font-size: 8pt; + padding-top: 2px; +} +#userBar { + position: fixed; + top: 0; + right: 0; +} +#userBar .subCell { + background: #ddd; + height: 30px; + padding: 5px 0; + display: block; + color: #333; + text-decoration: none; + line-height: 28px; + border-top: 1px solid #b4b4b4; +} +#userBar .subCell:hover {background: #ccc;} +#userBar .toggle { + width: 40px; + background: #ccc; + border-top: 0; + float: right; + text-align: center; +} +#userBar .sub {clear: both; display: none; width: 160px;} +#userBar .sub.scroll {overflow-y: scroll;} +#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#userBar .sub span { + display: block; + line-height: 30px; + float: left; +} +#userBar .sub i { + display: block; + padding: 0 5px; + font-size: 1.1em; + width: 22px; + text-align: center; + line-height: 30px; + float: right; +} +#userBar .sub input { + position: absolute; + padding: 7px 5px; + width: 121px; + line-height: 30px; + float: left; +} +#userBar .topCell {border-top: 0;} + +/* POPUPS */ +.popup { + position: fixed; + top: 50%; + left: 50%; + background: #ddd; +} +.popup .close { + position: absolute; + background: #aaa; + top: 0; + right: 0; + color: #333; + text-decoration: none; + z-index: 2; + padding: 0 10px; + height: 30px; + line-height: 30px; +} +.popup .close:hover {background: #999;} +.popup .head { + background: #999; + color: #ddd; + padding: 0 10px; + height: 30px; + line-height: 30px; + text-transform: uppercase; + font-size: 0.9em; + font-weight: bold; + border-bottom: 2px solid green; +} +.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} +.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} +.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} +.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} + +.changeFont {padding: 10px;} +.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} +.changeFont a:hover {background: #ccc;} + +.highlightPopup {padding: 10px; text-align: center;} +.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} +.highlightPopup input.highlightColor {background-color: #FFFF00;} +.highlightPopup input.highlightTermSubmit {margin-top: 5px;} + +/* ADMIN CONTEXT MENU */ +.contextMenu { + background-color: #ddd; + position: fixed; + margin: 2px; + width: 150px; +} +.contextMenu a { + display: block; + padding: 2px 5px; + text-decoration: none; + color: #333; +} + +.contextMenu a:hover { + background-color: #ccc; +} + +/* ADMIN FILTER MESSAGES MENU */ +.filterMessages {padding: 5px;} +.filterMessages div {padding: 2px 0;} +.filterMessages input {} +.filterMessages label {} + +.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} + + +/***************************************** +* +* OUTPUT ACTUALLY RELATED TO MESSAGES +* +******************************************/ + +/* MOTD */ +.motd {color: #638500; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} + +/* ADD HERE FOR BOLD */ +.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} + +/* ADD HERE FOR ITALIC */ +.italic, .italics, .emote {font-style: italic;} + +/* OUTPUT COLORS */ +.highlight {background: yellow;} + +h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #000000;} + +em {font-style: normal; font-weight: bold;} + +.ooc {color: #002eb8; font-weight: bold;} +.antagooc {color: #b8002e; font-weight: bold;} +.adminobserverooc {color: #0099cc; font-weight: bold;} +.adminooc {color: #700038; font-weight: bold;} + +.adminsay {color: #ff4500; font-weight: bold;} +.admin {color: #4473ff; font-weight: bold;} + +.name { font-weight: bold;} + +.say {} +.deadsay {color: #5c00e6;} +.binarysay {color: #20c20e; background-color: #000000; display: block;} +.binarysay a {color: #00ff00;} +.binarysay a:active, .binarysay a:visited {color: #88ff88;} +.radio {color: #008000;} +.sciradio {color: #993399;} +.comradio {color: #948f02;} +.secradio {color: #a30000;} +.medradio {color: #337296;} +.engradio {color: #fb5613;} +.suppradio {color: #a8732b;} +.servradio {color: #6eaa2c;} +.syndradio {color: #6d3f40;} +.centcomradio {color: #686868;} +.aiprivradio {color: #ff00ff;} +.redteamradio {color: #ff0000;} +.blueteamradio {color: #0000ff;} + +.yell { font-weight: bold;} + +.alert {color: #ff0000;} +h1.alert, h2.alert {color: #000000;} + +.emote { font-style: italic;} +.selecteddna {color: #ffffff; background-color: #001B1B} + +.attack {color: #ff0000;} +.disarm {color: #990000;} +.passive {color: #660000;} + +.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} +.danger {color: #ff0000;} +.warning {color: #ff0000; font-style: italic;} +.alertwarning {color: #FF0000; font-weight: bold} +.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} +.announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} +.greenannounce {color: #00ff00; font-weight: bold;} +.rose {color: #ff5050;} +.info {color: #0000CC;} +.notice {color: #000099;} +.boldnotice {color: #000099; font-weight: bold;} +.adminnotice {color: #0000ff;} +.adminhelp {color: #ff0000; font-weight: bold;} +.unconscious {color: #0000ff; font-weight: bold;} +.suicide {color: #ff5050; font-style: italic;} +.green {color: #03ff39;} +.red {color: #FF0000} +.pink {color: #FF69Bf;} +.blue {color: #0000FF} +.nicegreen {color: #14a833;} +.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;} +.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;} +.shadowling {color: #3b2769;} +.cult {color: #960000;} + +.cultitalic {color: #960000; font-style: italic;} +.cultbold {color: #960000; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} + +.cultlarge {color: #960000; font-weight: bold; font-size: 24px;} +.narsie {color: #960000; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;} +.colossus {color: #7F282A; font-size: 40px;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} +.purple {color: #5e2d79;} +.holoparasite {color: #35333a;} + +.revennotice {color: #1d2953;} +.revenboldnotice {color: #1d2953; font-weight: bold;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;} +.revenminor {color: #823abb} +.revenwarning {color: #760fbb; font-style: italic;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;} +.umbra {color: #5000A0;} +.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} +.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;} + +.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;} + +.brass {color: #BE8700;} +.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} +.large_brass {color: #BE8700; font-size: 24px;} +.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;} +.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;} +.alloy {color: #42474D;} +.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;} +.nezbere {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_small {color: #42474D;} +.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;} +.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} +.sevtug_small {color: #AF0AAF;} +.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;} +.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} +.inathneq_small {color: #1E8CE1;} +.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;} +.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;} +.nzcrentr_small {color: #DAAA18;} +.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;} +.neovgre {color: #6E001A; font-weight: bold; font-style: italic;} +.neovgre_small {color: #6E001A;} + +.newscaster {color: #800000;} +.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} + +.alien {color: #543354;} +.noticealien {color: #00c000;} +.alertalien {color: #00c000; font-weight: bold;} +.changeling {color: #800080; font-style: italic;} + +.spider {color: #4d004d;} + +.interface {color: #330033;} + +.sans {font-family: "Comic Sans MS", cursive, sans-serif;} +.papyrus {font-family: "Papyrus", cursive, sans-serif;} +.robot {font-family: "Courier New", cursive, sans-serif;} + +.command_headset {font-weight: bold; font-size: 24px;} +.small {font-size: 8px;} +.big {font-size: 24px;} +.reallybig {font-size: 32px;} +.extremelybig {font-size: 40px;} +.greentext {color: #00FF00; font-size: 24px;} +.redtext {color: #FF0000; font-size: 24px;} +.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} + +.icon {height: 1em; width: auto;} + +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 16px;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} +.slime {color: #00CED1;} +.drone {color: #848482;} +.monkey {color: #975032;} +.swarmer {color: #2C75FF;} +.resonate {color: #298F85;} + +.monkeyhive {color: #774704;} +.monkeylead {color: #774704; font-size: 2;} + +.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} +.connectionClosed.restored {background: green;} +.internal.boldnshit {color: blue; font-weight: bold;} + +/* HELPER CLASSES */ +.text-normal {font-weight: normal; font-style: normal;} +.hidden {display: none; visibility: hidden;} + diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index fe3be9486c..9c6d462a85 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -5,7 +5,7 @@ - + @@ -28,6 +28,9 @@ --ms +
    + +
    diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 33553d765e..93a498fd06 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -35,6 +35,7 @@ var opts = { 'wasd': false, //Is the user in wasd mode? 'priorChatHeight': 0, //Thing for height-resizing detection 'restarting': false, //Is the round restarting? + 'darkmode':false, //Are we using darkmode? If not WHY ARE YOU LIVING IN 2009??? //Options menu 'selectedSubLoop': null, //Contains the interval loop for closing the selected sub menu @@ -394,6 +395,19 @@ function toHex(n) { return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16); } +function swap() { //Swap to darkmode + if (opts.darkmode){ + document.getElementById("sheetofstyles").href = "browserOutput_white.css"; + opts.darkmode = false; + runByond('?_src_=chat&proc=swaptolightmode'); + } else { + document.getElementById("sheetofstyles").href = "browserOutput.css"; + opts.darkmode = true; + runByond('?_src_=chat&proc=swaptodarkmode'); + } + setCookie('darkmode', (opts.darkmode ? 'true' : 'false'), 365); +} + function handleClientData(ckey, ip, compid) { //byond sends player info to here var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid}; @@ -601,6 +615,7 @@ $(function() { 'shighlightColor': getCookie('highlightcolor'), 'smusicVolume': getCookie('musicVolume'), 'smessagecombining': getCookie('messagecombining'), + 'sdarkmode': getCookie('darkmode'), }; if (savedConfig.sfontSize) { @@ -611,6 +626,9 @@ $(function() { $("body").css('line-height', savedConfig.slineHeight); internalOutput('Loaded line height setting of: '+savedConfig.slineHeight+'', 'internal'); } + if(savedConfig.sdarkmode == 'true'){ + swap(); + } if (savedConfig.spingDisabled) { if (savedConfig.spingDisabled == 'true') { opts.pingDisabled = true; @@ -655,8 +673,6 @@ $(function() { opts.messageCombining = true; } } - - (function() { var dataCookie = getCookie('connData'); if (dataCookie) { @@ -823,7 +839,9 @@ $(function() { $('#toggleOptions').click(function(e) { handleToggleClick($subOptions, $(this)); }); - + $('#darkmodetoggle').click(function(e) { + swap(); + }); $('#toggleAudio').click(function(e) { handleToggleClick($subAudio, $(this)); }); @@ -895,7 +913,7 @@ $(function() { $.ajax({ type: 'GET', - url: 'browserOutput.css', + url: 'browserOutput_white.css', success: function(styleData) { var blob = new Blob(['Chat Log', $messages.html(), '']); diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index 4ffc10f9c2..6cc11afdf5 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -149,6 +149,7 @@ active_power_usage = 50 + spawned.len * 3 + effects.len * 5 /obj/machinery/computer/holodeck/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return if(!LAZYLEN(emag_programs)) @@ -160,6 +161,7 @@ to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.") log_game("[key_name(user)] emagged the Holodeck Control Console") nerf(!(obj_flags & EMAGGED)) + return TRUE /obj/machinery/computer/holodeck/emp_act(severity) . = ..() diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index fee0b2b7c9..308cec1cbd 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -78,6 +78,12 @@ // these vars are not really standardized but all would theoretically create stuff on death for(var/v in list("butcher_results","corpse","weapon1","weapon2","blood_volume") & mob.vars) mob.vars[v] = null + ENABLE_BITFIELD(mob.flags_1, HOLOGRAM_1) + if(isliving(mob)) + var/mob/living/L = mob + L.feeding = FALSE + L.devourable = FALSE + L.digestable = FALSE return mob /obj/effect/holodeck_effect/mobspawner/deactivate(var/obj/machinery/computer/holodeck/HC) @@ -100,7 +106,7 @@ /obj/effect/holodeck_effect/mobspawner/penguin mobtype = /mob/living/simple_animal/pet/penguin/emperor - + /obj/effect/holodeck_effect/mobspawner/penguin/Initialize() if(prob(1)) mobtype = /mob/living/simple_animal/pet/penguin/emperor/shamebrero diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index d6eacfe0e1..79a23014b0 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -69,6 +69,8 @@ if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I)) update_icon() return + else if(default_unfasten_wrench(user, I)) + return if(default_deconstruction_crowbar(I)) return if(iscyborg(user)) diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 19abdacf3a..ef019387e8 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -215,3 +215,26 @@ filling_color = "#7FFF00" tastes = list("green grape" = 1) distill_reagent = "cognac" + +// Strawberry +/obj/item/seeds/strawberry + name = "pack of strawberry seeds" + desc = "These seeds grow into strawberry vines." + icon_state = "seed-strawberry" + species = "strawberry" + plantname = "Strawberry Vine" + product = /obj/item/reagent_containers/food/snacks/grown/strawberry + growthstages = 6 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "strawberry-grow" + icon_dead = "berry-dead" + reagents_add = list("vitamin" = 0.07, "nutriment" = 0.1, "sugar" = 0.2) + mutatelist = list() + +/obj/item/reagent_containers/food/snacks/grown/strawberry + seed = /obj/item/seeds/strawberry + name = "strawberry" + icon_state = "strawberry" + filling_color = "#7FFF00" + tastes = list("strawberries" = 1) + wine_power = 20 diff --git a/code/modules/hydroponics/grown/cotton.dm b/code/modules/hydroponics/grown/cotton.dm new file mode 100644 index 0000000000..045839d0de --- /dev/null +++ b/code/modules/hydroponics/grown/cotton.dm @@ -0,0 +1,79 @@ +/obj/item/seeds/cotton + name = "pack of cotton seeds" + desc = "A pack of seeds that'll grow into a cotton plant. Assistants make good free labor if neccesary." + icon_state = "seed-cotton" + species = "cotton" + plantname = "Cotton" + icon_harvest = "cotton-harvest" + product = /obj/item/grown/cotton + lifespan = 35 + endurance = 25 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + mutatelist = list(/obj/item/seeds/cotton/durathread) + +/obj/item/grown/cotton + seed = /obj/item/seeds/cotton + name = "cotton bundle" + desc = "A fluffy bundle of cotton." + icon_state = "cotton" + force = 0 + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 2 + throw_range = 3 + attack_verb = list("pomfed") + var/cotton_type = /obj/item/stack/sheet/cotton + var/cotton_name = "raw cotton" + +/obj/item/grown/cotton/attack_self(mob/user) + user.show_message("You pull some [cotton_name] out of the [name]!", 1) + var/seed_modifier = 0 + if(seed) + seed_modifier = round(seed.potency / 25) + var/obj/item/stack/cotton = new cotton_type(user.loc, 1 + seed_modifier) + var/old_cotton_amount = cotton.amount + for(var/obj/item/stack/ST in user.loc) + if(ST != cotton && istype(ST, cotton_type) && ST.amount < ST.max_amount) + ST.attackby(cotton, user) + if(cotton.amount > old_cotton_amount) + to_chat(user, "You add the newly-formed [cotton_name] to the stack. It now contains [cotton.amount] [cotton_name].") + qdel(src) + +//reinforced mutated variant +/obj/item/seeds/cotton/durathread + name = "pack of durathread seeds" + desc = "A pack of seeds that'll grow into an extremely durable thread that could easily rival plasteel if woven properly." + icon_state = "seed-durathread" + species = "durathread" + plantname = "Durathread" + icon_harvest = "durathread-harvest" + product = /obj/item/grown/cotton/durathread + lifespan = 80 + endurance = 50 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + +/obj/item/grown/cotton/durathread + seed = /obj/item/seeds/cotton/durathread + name = "durathread bundle" + desc = "A tough bundle of durathread, good luck unraveling this." + icon_state = "durathread" + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 2 + throw_range = 3 + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + cotton_type = /obj/item/stack/sheet/cotton/durathread + cotton_name = "raw durathread" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index 4e1718f853..f1aea5706a 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -25,6 +25,7 @@ slot_flags = ITEM_SLOT_HEAD filling_color = "#FF6347" bitesize_mod = 3 + tastes = list("sesame seeds" = 1) foodtype = VEGETABLES | GROSS distill_reagent = "vermouth" @@ -43,6 +44,7 @@ name = "lily" desc = "A beautiful orange flower." icon_state = "lily" + tastes = list("pelts " = 1) filling_color = "#FFA500" // Geranium @@ -61,6 +63,7 @@ desc = "A beautiful blue flower." icon_state = "geranium" filling_color = "#008B8B" + tastes = list("pelts " = 1) // Harebell /obj/item/seeds/harebell @@ -86,6 +89,7 @@ name = "harebell" desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten'd not thy breath.\"" icon_state = "harebell" + tastes = list("salt" = 1) slot_flags = ITEM_SLOT_HEAD filling_color = "#E6E6FA" bitesize_mod = 3 @@ -123,6 +127,7 @@ w_class = WEIGHT_CLASS_TINY throw_speed = 1 throw_range = 3 + tastes = list("seeds" = 1) /obj/item/grown/sunflower/attack(mob/M, mob/user) to_chat(M, " [user] smacks you with a sunflower!FLOWER POWER") @@ -153,6 +158,7 @@ filling_color = "#E6E6FA" bitesize_mod = 2 distill_reagent = "absinthe" //It's made from flowers. + tastes = list("glowbugs" = 1) // Novaflower /obj/item/seeds/sunflower/novaflower @@ -184,6 +190,7 @@ throw_range = 3 attack_verb = list("roasted", "scorched", "burned") grind_results = list("capsaicin" = 0, "condensedcapsaicin" = 0) + tastes = list("cooked sunflower" = 1) /obj/item/grown/novaflower/add_juice() ..() diff --git a/code/modules/hydroponics/grown/peach.dm b/code/modules/hydroponics/grown/peach.dm new file mode 100644 index 0000000000..6fbf933bd1 --- /dev/null +++ b/code/modules/hydroponics/grown/peach.dm @@ -0,0 +1,27 @@ +// Peach +/obj/item/seeds/peach + name = "pack of peach seeds" + desc = "These seeds grow into peach trees." + icon_state = "seed-peach" + species = "peach" + plantname = "Peach Tree" + product = /obj/item/reagent_containers/food/snacks/grown/peach + lifespan = 65 + endurance = 40 + yield = 3 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "peach-grow" + icon_dead = "peach-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + +/obj/item/reagent_containers/food/snacks/grown/peach + seed = /obj/item/seeds/peach + name = "peach" + desc = "It's fuzzy!" + icon_state = "peach" + filling_color = "#FF4500" + bitesize = 25 + foodtype = FRUIT + juice_results = list("peachjuice" = 0) + tastes = list("peach" = 1) diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index fc84617ed8..d9e775acc0 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -14,6 +14,7 @@ icon_dead = "tea-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/tea/astra) + reagents_add = list("teapowder" = 0.1) /obj/item/reagent_containers/food/snacks/grown/tea seed = /obj/item/seeds/tea diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 5aeef19b1a..c0e3beaf79 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -7,6 +7,7 @@ icon = 'icons/obj/hydroponics/harvest.dmi' resistance_flags = FLAMMABLE var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item. + var/tastes = list("indescribable" = 1) //Stops runtimes. Grown are un-eatable anyways so if you do then its a bug /obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed) . = ..() diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 17462c0626..db529e8ffb 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -290,15 +290,15 @@ var/teleport_radius = max(round(G.seed.potency / 10), 1) var/turf/T = get_turf(target) new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect... - do_teleport(target, T, teleport_radius) + do_teleport(target, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE) /datum/plant_gene/trait/teleport/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) var/teleport_radius = max(round(G.seed.potency / 10), 1) var/turf/T = get_turf(C) to_chat(C, "You slip through spacetime!") - do_teleport(C, T, teleport_radius) + do_teleport(C, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE) if(prob(50)) - do_teleport(G, T, teleport_radius) + do_teleport(G, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE) else new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect... qdel(G) diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index de3ade389f..f0aa10f2da 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -193,7 +193,7 @@ else if(ispath(build_type, /obj/item/integrated_circuit)) var/obj/item/integrated_circuit/IC = SScircuit.cached_components[build_type] cost = IC.materials[MAT_METAL] - else if(!build_type in SScircuit.circuit_fabricator_recipe_list["Tools"]) + else if(!(build_type in SScircuit.circuit_fabricator_recipe_list["Tools"])) return var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 86efc4c74a..3975da18b6 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -112,7 +112,7 @@ var/brightness = get_pin_data(IC_INPUT, 2) if(new_color && isnum(brightness)) - brightness = CLAMP(brightness, 0, 4) + brightness = CLAMP(brightness, 0, 10) light_rgb = new_color light_brightness = brightness @@ -411,4 +411,4 @@ if(assembly) assembly.investigate_log("displayed \"[html_encode(stuff_to_display)]\" with [type].", INVESTIGATE_CIRCUIT) else - investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) \ No newline at end of file + investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm index 65805f73fd..ce6eea97b0 100644 --- a/code/modules/jobs/job_types/assistant.dm +++ b/code/modules/jobs/job_types/assistant.dm @@ -30,6 +30,12 @@ Assistant /datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/H) ..() if (CONFIG_GET(flag/grey_assistants)) - uniform = /obj/item/clothing/under/color/grey + if(H.jumpsuit_style == PREF_SUIT) + uniform = /obj/item/clothing/under/color/grey + else + uniform = /obj/item/clothing/under/skirt/color/grey else - uniform = /obj/item/clothing/under/color/random + if(H.jumpsuit_style == PREF_SUIT) + uniform = /obj/item/clothing/under/color/random + else + uniform = /obj/item/clothing/under/skirt/color/random diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index cd9c914e7a..b3c952f536 100755 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -21,6 +21,8 @@ Captain access = list() //See get_access() minimal_access = list() //See get_access() + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) + /datum/job/captain/get_access() return get_all_accesses() @@ -67,7 +69,7 @@ Head of Personnel flag = HOP department_head = list("Captain") department_flag = CIVILIAN - head_announce = list("Supply", "Service") + head_announce = list(RADIO_CHANNEL_SERVICE) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -94,6 +96,7 @@ Head of Personnel ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION, ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/prosopagnosia, /datum/quirk/insanity) /datum/outfit/job/hop name = "Head of Personnel" diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm index 22ef2a9211..8e24ece655 100644 --- a/code/modules/jobs/job_types/cargo_service.dm +++ b/code/modules/jobs/job_types/cargo_service.dm @@ -6,6 +6,7 @@ Quartermaster flag = QUARTERMASTER department_head = list("Head of Personnel") department_flag = CIVILIAN + head_announce = list(RADIO_CHANNEL_SUPPLY) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -17,6 +18,8 @@ Quartermaster access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_VAULT) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_VAULT) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) + /datum/outfit/job/quartermaster name = "Quartermaster" jobtype = /datum/job/qm @@ -88,9 +91,9 @@ Shaft Miner gloves = /obj/item/clothing/gloves/color/black uniform = /obj/item/clothing/under/rank/miner/lavaland l_pocket = /obj/item/reagent_containers/hypospray/medipen/survival - r_pocket = /obj/item/flashlight/seclite + r_pocket = /obj/item/storage/bag/ore //causes issues if spawned in backpack backpack_contents = list( - /obj/item/storage/bag/ore=1,\ + /obj/item/flashlight/seclite=1,\ /obj/item/kitchen/knife/combat/survival=1,\ /obj/item/mining_voucher=1,\ /obj/item/suit_voucher=1,\ @@ -116,7 +119,7 @@ Shaft Miner suit_store = /obj/item/tank/internals/oxygen internals_slot = SLOT_S_STORE backpack_contents = list( - /obj/item/storage/bag/ore=1, + /obj/item/flashlight/seclite=1,\ /obj/item/kitchen/knife/combat/survival=1, /obj/item/mining_voucher=1, /obj/item/t_scanner/adv_mining_scanner/lesser=1, diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm index 46e3d66f55..f21ff69e8e 100644 --- a/code/modules/jobs/job_types/civilian.dm +++ b/code/modules/jobs/job_types/civilian.dm @@ -61,6 +61,7 @@ Clown return H.dna.add_mutation(CLOWNMUT) + H.dna.add_mutation(SMILE) /* Mime diff --git a/code/modules/jobs/job_types/engineering.dm b/code/modules/jobs/job_types/engineering.dm index f28e5f1afc..e65cbab1bd 100644 --- a/code/modules/jobs/job_types/engineering.dm +++ b/code/modules/jobs/job_types/engineering.dm @@ -6,7 +6,7 @@ Chief Engineer flag = CHIEF department_head = list("Captain") department_flag = ENGSEC - head_announce = list("Engineering") + head_announce = list(RADIO_CHANNEL_ENGINEERING) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -29,6 +29,8 @@ Chief Engineer ACCESS_HEADS, ACCESS_CONSTRUCTION, ACCESS_SEC_DOORS, ACCESS_MINISAT, ACCESS_CE, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity) + /datum/outfit/job/ce name = "Chief Engineer" jobtype = /datum/job/chief_engineer diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index f678700735..9549b6100c 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -56,6 +56,8 @@ var/list/mind_traits // Traits added to the mind of the mob assigned this job + var/list/blacklisted_quirks //list of quirk typepaths blacklisted. + //Only override this proc //H is usually a human unless an /equip override transformed it /datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE) @@ -190,6 +192,16 @@ backpack_contents.Insert(1, box) // Box always takes a first slot in backpack backpack_contents[box] = 1 + //converts the uniform string into the path we'll wear, whether it's the skirt or regular variant + var/holder + if(H.jumpsuit_style == PREF_SKIRT) + holder = "[uniform]/skirt" + if(!text2path(holder)) + holder = "[uniform]" + else + holder = "[uniform]" + uniform = text2path(holder) + /datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) if(visualsOnly) return diff --git a/code/modules/jobs/job_types/medical.dm b/code/modules/jobs/job_types/medical.dm index 5a926f490a..9eeb4ab06e 100644 --- a/code/modules/jobs/job_types/medical.dm +++ b/code/modules/jobs/job_types/medical.dm @@ -6,7 +6,7 @@ Chief Medical Officer flag = CMO_JF department_head = list("Captain") department_flag = MEDSCI - head_announce = list("Medical") + head_announce = list(RADIO_CHANNEL_MEDICAL) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -27,6 +27,8 @@ Chief Medical Officer ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) + /datum/outfit/job/cmo name = "Chief Medical Officer" jobtype = /datum/job/cmo @@ -127,6 +129,7 @@ Chemist backpack = /obj/item/storage/backpack/chemistry satchel = /obj/item/storage/backpack/satchel/chem duffelbag = /obj/item/storage/backpack/duffelbag/med + l_hand = /obj/item/fermichem/pHbooklet chameleon_extras = /obj/item/gun/syringe diff --git a/code/modules/jobs/job_types/science.dm b/code/modules/jobs/job_types/science.dm index 6a14f204a3..b58f3faa27 100644 --- a/code/modules/jobs/job_types/science.dm +++ b/code/modules/jobs/job_types/science.dm @@ -6,7 +6,7 @@ Research Director flag = RD_JF department_head = list("Captain") department_flag = MEDSCI - head_announce = list("Science") + head_announce = list(RADIO_CHANNEL_SCIENCE) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -31,6 +31,8 @@ Research Director ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_NETWORK) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) + /datum/outfit/job/rd name = "Research Director" jobtype = /datum/job/rd diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index 8d2b9e8681..96cedd89ef 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -12,7 +12,7 @@ Head of Security flag = HOS department_head = list("Captain") department_flag = ENGSEC - head_announce = list("Security") + head_announce = list(RADIO_CHANNEL_SECURITY) faction = "Station" total_positions = 1 spawn_positions = 1 @@ -37,6 +37,8 @@ Head of Security mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/insanity) + /datum/outfit/job/hos name = "Head of Security" jobtype = /datum/job/hos @@ -95,6 +97,7 @@ Warden minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) //SEE /DATUM/JOB/WARDEN/GET_ACCESS() mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic) /datum/job/warden/get_access() var/list/L = list() @@ -150,6 +153,7 @@ Detective minimal_access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic) /datum/outfit/job/detective name = "Detective" @@ -205,6 +209,7 @@ Security Officer minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) //BUT SEE /DATUM/JOB/WARDEN/GET_ACCESS() mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic) /datum/job/officer/get_access() var/list/L = list() diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 699df5de12..ef58943731 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -343,8 +343,11 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums return ..() /obj/machinery/computer/libraryconsole/bookmanagement/emag_act(mob/user) - if(density && !(obj_flags & EMAGGED)) - obj_flags |= EMAGGED + . = ..() + if(!density || obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + return TRUE /obj/machinery/computer/libraryconsole/bookmanagement/Topic(href, href_list) if(..()) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 86499e694b..4a0faf69f5 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -214,8 +214,11 @@ return ..() /obj/structure/closet/crate/secure/loot/emag_act(mob/user) - if(locked) - boom(user) + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) + if(!locked) + return + boom(user) + return TRUE /obj/structure/closet/crate/secure/loot/togglelock(mob/user) if(locked) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 2c35c3148f..23ec02976d 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -43,7 +43,7 @@ name = "explorer gas mask" desc = "A military-grade gas mask that can be connected to an air supply." icon_state = "gas_mining" - visor_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + visor_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 0d6c337444..e02f38b7e3 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -65,9 +65,12 @@ /obj/item/pickaxe/drill/cyborg name = "cyborg mining drill" desc = "An integrated electric mining drill." - item_flags = NODROP flags_1 = NONE +/obj/item/pickaxe/drill/cyborg/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + /obj/item/pickaxe/drill/diamonddrill name = "diamond-tipped mining drill" icon_state = "diamonddrill" diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 5193545c4b..953da6cbb0 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -112,7 +112,7 @@ GLOBAL_LIST(labor_sheet_values) else if(!(obj_flags & EMAGGED)) Radio.set_frequency(FREQ_SECURITY) - Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY, get_spans(), get_default_language()) + Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY) to_chat(usr, "Shuttle received message and will be sent shortly.") /obj/machinery/mineral/labor_claim_console/proc/check_auth() @@ -128,9 +128,12 @@ GLOBAL_LIST(labor_sheet_values) qdel(src) /obj/machinery/mineral/labor_claim_console/emag_act(mob/user) - if(!(obj_flags & EMAGGED)) - obj_flags |= EMAGGED - to_chat(user, "PZZTTPFFFT") + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + to_chat(user, "PZZTTPFFFT") + return TRUE /**********************Prisoner Collection Unit**************************/ @@ -149,7 +152,7 @@ GLOBAL_LIST(labor_sheet_values) var/obj/item/stack/sheet/inp = I points += inp.point_value * inp.amount return ..() - + /**********************Point Lookup Console**************************/ /obj/machinery/mineral/labor_points_checker name = "points checking console" diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index eaac1984e3..5990c70813 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -143,7 +143,7 @@ //Rod of Asclepius /obj/item/rod_of_asclepius - name = "Rod of Asclepius" + name = "\improper Rod of Asclepius" desc = "A wooden rod about the size of your forearm with a snake carved around it, winding it's way up the sides of the rod. Something about it seems to inspire in you the responsibilty and duty to help others." icon = 'icons/obj/lavaland/artefacts.dmi' icon_state = "asclepius_dormant" @@ -189,7 +189,8 @@ activated() /obj/item/rod_of_asclepius/proc/activated() - item_flags = NODROP | DROPDEL + item_flags = DROPDEL + ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) desc = "A short wooden rod with a mystical snake inseparably gripping itself and the rod to your forearm. It flows with a healing energy that disperses amongst yourself and those around you. " icon_state = "asclepius_active" activated = TRUE @@ -640,6 +641,8 @@ nemesis_factions = list("mining", "boss") var/transform_cooldown var/swiping = FALSE + total_mass = 2.75 + total_mass_on = 5 /obj/item/melee/transforming/cleaving_saw/examine(mob/user) ..() @@ -784,30 +787,30 @@ /obj/item/melee/ghost_sword/process() ghost_check() -/obj/item/melee/ghost_sword/proc/ghost_check() - var/ghost_counter = 0 - var/turf/T = get_turf(src) - var/list/contents = T.GetAllContents() - var/mob/dead/observer/current_spirits = list() - for(var/thing in contents) - var/atom/A = thing - A.transfer_observers_to(src) - - for(var/i in orbiters?.orbiters) - if(!isobserver(i)) +/obj/item/melee/ghost_sword/proc/recursive_orbit_collect(atom/A, list/L) + for(var/i in A.orbiters?.orbiters) + if(!isobserver(i) || (i in L)) continue + L |= i + recursive_orbit_collect(i, L) + +/obj/item/melee/ghost_sword/proc/ghost_check() + var/list/mob/dead/observer/current_spirits = list() + + recursive_orbit_collect(src, current_spirits) + recursive_orbit_collect(loc, current_spirits) //anything holding us + + for(var/i in spirits - current_spirits) var/mob/dead/observer/G = i - ghost_counter++ - G.invisibility = 0 - current_spirits |= G - - for(var/mob/dead/observer/G in spirits - current_spirits) G.invisibility = GLOB.observer_default_invisibility - + + for(var/i in current_spirits) + var/mob/dead/observer/G = i + G.invisibility = 0 + spirits = current_spirits - - return ghost_counter - + return length(spirits) + /obj/item/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user) force = 0 var/ghost_counter = ghost_check() @@ -1332,4 +1335,4 @@ if(2) new /obj/item/wisp_lantern(src) if(3) - new /obj/item/prisoncube(src) \ No newline at end of file + new /obj/item/prisoncube(src) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index a1ba493d46..0abb1cfa9e 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -68,6 +68,7 @@ /obj/machinery/computer/shuttle/mining name = "mining shuttle console" desc = "Used to call and send the mining shuttle." + req_access = list(ACCESS_MINING) circuit = /obj/item/circuitboard/computer/mining_shuttle shuttleId = "mining" possible_destinations = "mining_home;mining_away;landing_zone_dock;mining_public" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 315ffff7c7..750805ae93 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -164,7 +164,7 @@ return var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]]) - if(MS?.attack_ghost(src, latejoinercalling = TRUE)) + if(MS.attack_ghost(src, latejoinercalling = TRUE)) SSticker.queued_players -= src SSticker.queue_delay = 4 qdel(src) @@ -416,7 +416,7 @@ SSticker.mode.make_antag_chance(humanc) if(humanc && CONFIG_GET(flag/roundstart_traits)) - SSquirks.AssignQuirks(humanc, humanc.client, TRUE) + SSquirks.AssignQuirks(humanc, humanc.client, TRUE, FALSE, job, FALSE) log_manifest(character.mind.key,character.mind,character,latejoin = TRUE) @@ -429,7 +429,19 @@ /mob/dead/new_player/proc/LateChoices() - var/dat = "
    Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]
    " + + var/level = "green" + switch(GLOB.security_level) + if(SEC_LEVEL_BLUE) + level = "blue" + if(SEC_LEVEL_AMBER) + level = "amber" + if(SEC_LEVEL_RED) + level = "red" + if(SEC_LEVEL_DELTA) + level = "delta" + + var/dat = "
    Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]
    Alert Level: [capitalize(level)]
    " if(SSshuttle.emergency) switch(SSshuttle.emergency.mode) @@ -444,6 +456,8 @@ if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE) available_job_count++ for(var/spawner in GLOB.mob_spawners) + if(!LAZYLEN(spawner)) + continue var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner]) if(!istype(S) || !S.can_latejoin()) continue @@ -468,10 +482,12 @@ "Security" = list(jobs = list(), titles = GLOB.security_positions, color = "#ff9999"), ) for(var/spawner in GLOB.mob_spawners) + if(!LAZYLEN(spawner)) + continue var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner]) if(!istype(S) || !S.can_latejoin()) continue - categorizedJobs["Ghost Role"]["jobs"] += S + categorizedJobs["Ghost Role"]["jobs"] += spawner for(var/datum/job/job in SSjob.occupations) if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 353df3aa66..6e91b58506 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -6,8 +6,11 @@ else gender = pick(MALE,FEMALE) underwear = random_underwear(gender) + undie_color = random_short_color() undershirt = random_undershirt(gender) + shirt_color = random_short_color() socks = random_socks() + socks_color = random_short_color() skin_tone = random_skin_tone() hair_style = random_hair_style(gender) facial_hair_style = random_facial_hair_style(gender) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm index 699c3c97e4..5e24d0630b 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm @@ -59,4 +59,8 @@ var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects var/dimension_x = 32 var/dimension_y = 32 - var/center = FALSE //Should we center the sprite? \ No newline at end of file + var/center = FALSE //Should we center the sprite? + +/datum/sprite_accessory/underwear + icon = 'icons/mob/underwear.dmi' + var/has_color = FALSE \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm index 3384f3754b..524c1f0f13 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm @@ -2,135 +2,132 @@ // Socks Definitions // /////////////////////// -/datum/sprite_accessory/socks - icon = 'icons/mob/underwear.dmi' - -/datum/sprite_accessory/socks/nude +/datum/sprite_accessory/underwear/socks/nude name = "Nude" icon_state = null // please make sure they're sorted alphabetically and categorized -/datum/sprite_accessory/socks/bee_knee - name = "Knee-high (Bee)" +/datum/sprite_accessory/underwear/socks/socks_knee + name = "Knee-high" + icon_state = "socks_knee" + has_color = TRUE + +/datum/sprite_accessory/underwear/socks/bee_knee + name = "Knee-high - Bee" icon_state = "bee_knee" -/datum/sprite_accessory/socks/black_knee - name = "Knee-high (Black)" - icon_state = "black_knee" - -/datum/sprite_accessory/socks/commie_knee - name = "Knee-High (Commie)" +/datum/sprite_accessory/underwear/socks/commie_knee + name = "Knee-High - Commie" icon_state = "commie_knee" -/datum/sprite_accessory/socks/usa_knee - name = "Knee-High (Freedom)" +/datum/sprite_accessory/underwear/socks/usa_knee + name = "Knee-High - Freedom" icon_state = "assblastusa_knee" -/datum/sprite_accessory/socks/rainbow_knee - name = "Knee-high (Rainbow)" +/datum/sprite_accessory/underwear/socks/rainbow_knee + name = "Knee-high - Rainbow" icon_state = "rainbow_knee" -/datum/sprite_accessory/socks/striped_knee - name = "Knee-high (Striped)" +/datum/sprite_accessory/underwear/socks/striped_knee + name = "Knee-high - Striped" icon_state = "striped_knee" + has_color = TRUE -/datum/sprite_accessory/socks/thin_knee - name = "Knee-high (Thin)" +/datum/sprite_accessory/underwear/socks/thin_knee + name = "Knee-high - Thin" icon_state = "thin_knee" + has_color = TRUE -/datum/sprite_accessory/socks/uk_knee - name = "Knee-High (UK)" +/datum/sprite_accessory/underwear/socks/uk_knee + name = "Knee-High - UK" icon_state = "uk_knee" -/datum/sprite_accessory/socks/white_knee - name = "Knee-high (White)" - icon_state = "white_knee" +/datum/sprite_accessory/underwear/socks/socks_norm + name = "Normal" + icon_state = "socks_norm" + has_color = TRUE -/datum/sprite_accessory/socks/black_norm - name = "Normal (Black)" - icon_state = "black_norm" +/datum/sprite_accessory/underwear/socks/bee_norm + name = "Normal - Bee" + icon_state = "bee_norm" -/datum/sprite_accessory/socks/white_norm - name = "Normal (White)" - icon_state = "white_norm" - -/datum/sprite_accessory/socks/pantyhose +/datum/sprite_accessory/underwear/socks/pantyhose name = "Pantyhose" icon_state = "pantyhose" -/datum/sprite_accessory/socks/black_short - name = "Short (Black)" - icon_state = "black_short" +/datum/sprite_accessory/underwear/socks/socks_short + name = "Short" + icon_state = "socks_short" + has_color = TRUE -/datum/sprite_accessory/socks/white_short - name = "Short (White)" - icon_state = "white_short" - -/datum/sprite_accessory/socks/stockings_blue - name = "Stockings (Blue)" +/datum/sprite_accessory/underwear/socks/stockings_blue + name = "Stockings - Blue" icon_state = "stockings_blue" -/datum/sprite_accessory/socks/stockings_cyan - name = "Stockings (Cyan)" +/datum/sprite_accessory/underwear/socks/stockings_cyan + name = "Stockings - Cyan" icon_state = "stockings_cyan" -/datum/sprite_accessory/socks/stockings_dpink - name = "Stockings (Dark Pink)" +/datum/sprite_accessory/underwear/socks/stockings_dpink + name = "Stockings - Dark Pink" icon_state = "stockings_dpink" -/datum/sprite_accessory/socks/stockings_green - name = "Stockings (Green)" +/datum/sprite_accessory/underwear/socks/stockings_green + name = "Stockings - Green" icon_state = "stockings_black" -/datum/sprite_accessory/socks/stockings_orange - name = "Stockings (Orange)" +/datum/sprite_accessory/underwear/socks/stockings_orange + name = "Stockings - Orange" icon_state = "stockings_orange" -/datum/sprite_accessory/socks/stockings_programmer - name = "Stockings (Programmer)" +/datum/sprite_accessory/underwear/socks/stockings_programmer + name = "Stockings - Programmer" icon_state = "stockings_lpink" -/datum/sprite_accessory/socks/stockings_purple - name = "Stockings (Purple)" +/datum/sprite_accessory/underwear/socks/stockings_purple + name = "Stockings - Purple" icon_state = "stockings_purple" -/datum/sprite_accessory/socks/stockings_yellow - name = "Stockings (Yellow)" +/datum/sprite_accessory/underwear/socks/stockings_yellow + name = "Stockings - Yellow" icon_state = "stockings_yellow" -/datum/sprite_accessory/socks/bee_thigh - name = "Thigh-high (Bee)" +/datum/sprite_accessory/underwear/socks/socks_thigh + name = "Thigh-high" + icon_state = "socks_thigh" + has_color = TRUE + +/datum/sprite_accessory/underwear/socks/bee_thigh + name = "Thigh-high - Bee" icon_state = "bee_thigh" -/datum/sprite_accessory/socks/black_thigh - name = "Thigh-high (Black)" - icon_state = "black_thigh" - -/datum/sprite_accessory/socks/commie_thigh - name = "Thigh-high (Commie)" +/datum/sprite_accessory/underwear/socks/commie_thigh + name = "Thigh-high - Commie" icon_state = "commie_thigh" -/datum/sprite_accessory/socks/usa_thigh - name = "Thigh-high (Freedom)" +/datum/sprite_accessory/underwear/socks/usa_thigh + name = "Thigh-high - Freedom" icon_state = "assblastusa_thigh" -/datum/sprite_accessory/socks/rainbow_thigh - name = "Thigh-high (Rainbow)" +/datum/sprite_accessory/underwear/socks/fishnet + name = "Thigh-high - Fishnet" + icon_state = "fishnet" + +/datum/sprite_accessory/underwear/socks/rainbow_thigh + name = "Thigh-high - Rainbow" icon_state = "rainbow_thigh" -/datum/sprite_accessory/socks/striped_thigh - name = "Thigh-high (Striped)" +/datum/sprite_accessory/underwear/socks/striped_thigh + name = "Thigh-high - Striped" icon_state = "striped_thigh" + has_color = TRUE -/datum/sprite_accessory/socks/thin_thigh - name = "Thigh-high (Thin)" +/datum/sprite_accessory/underwear/socks/thin_thigh + name = "Thigh-high - Thin" icon_state = "thin_thigh" + has_color = TRUE -/datum/sprite_accessory/socks/uk_thigh - name = "Thigh-high (UK)" +/datum/sprite_accessory/underwear/socks/uk_thigh + name = "Thigh-high - UK" icon_state = "uk_thigh" - -/datum/sprite_accessory/socks/white_thigh - name = "Thigh-high (White)" - icon_state = "white_thigh" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm index f5af9a3849..fb40563ccf 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm @@ -2,311 +2,312 @@ // Undershirt Definitions // //////////////////////////// -/datum/sprite_accessory/undershirt - icon = 'icons/mob/underwear.dmi' - gender = NEUTER - -/datum/sprite_accessory/undershirt/nude +/datum/sprite_accessory/underwear/top/nude name = "Nude" icon_state = null // please make sure they're sorted alphabetically and categorized -/datum/sprite_accessory/undershirt/bluejersey +/datum/sprite_accessory/underwear/top/longjon + name = "Long John Shirt" + icon_state = "ljont" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/longstripe_black + name = "Longsleeve Striped Shirt - Black" + icon_state = "longstripe" + +/datum/sprite_accessory/underwear/top/longstripe_blue + name = "Longsleeve Striped Shirt - Blue" + icon_state = "longstripe_blue" + +/datum/sprite_accessory/underwear/top/shirt + name = "Shirt" + icon_state = "undershirt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bowlingw + name = "Shirt - Bowling" + icon_state = "bowlingw" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/bowling + name = "Shirt, Bowling - Red" + icon_state = "bowling" + +/datum/sprite_accessory/underwear/top/bowlingp + name = "Shirt, Bowling - Pink" + icon_state = "bowlingp" + +/datum/sprite_accessory/underwear/top/bowlinga + name = "Shirt, Bowling - Aqua" + icon_state = "bowlinga" + +/datum/sprite_accessory/underwear/top/bluejersey name = "Shirt, Jersey - Blue" icon_state = "shirt_bluejersey" -/datum/sprite_accessory/undershirt/redjersey +/datum/sprite_accessory/underwear/top/redjersey name = "Shirt, Jersey - Red" icon_state = "shirt_redjersey" -/datum/sprite_accessory/undershirt/bluepolo - name = "Shirt, Polo - Blue" - icon_state = "bluepolo" +/datum/sprite_accessory/underwear/top/polo + name = "Shirt - Polo" + icon_state = "polo" + has_color = TRUE -/datum/sprite_accessory/undershirt/grayyellowpolo - name = "Shirt, Polo - Gray, Yellow" - icon_state = "grayyellowpolo" - -/datum/sprite_accessory/undershirt/redpolo - name = "Shirt, Polo - Red" - icon_state = "redpolo" - -/datum/sprite_accessory/undershirt/whitepolo - name = "Shirt, Polo - White" - icon_state = "whitepolo" - -/datum/sprite_accessory/undershirt/alienshirt +/datum/sprite_accessory/underwear/top/alienshirt name = "Shirt - Alien" icon_state = "shirt_alien" -/datum/sprite_accessory/undershirt/mondmondjaja +/datum/sprite_accessory/underwear/top/mondmondjaja name = "Shirt - Band" icon_state = "band" -/datum/sprite_accessory/undershirt/shirt_black - name = "Shirt - Black" - icon_state = "shirt_black" +/datum/sprite_accessory/underwear/top/shirt_bee + name = "Shirt - Bee" + icon_state = "bee_shirt" -/datum/sprite_accessory/undershirt/blueshirt - name = "Shirt - Blue" - icon_state = "shirt_blue" - -/datum/sprite_accessory/undershirt/clownshirt +/datum/sprite_accessory/underwear/top/clownshirt name = "Shirt - Clown" icon_state = "shirt_clown" -/datum/sprite_accessory/undershirt/commie +/datum/sprite_accessory/underwear/top/commie name = "Shirt - Commie" icon_state = "shirt_commie" -/datum/sprite_accessory/undershirt/greenshirt - name = "Shirt - Green" - icon_state = "shirt_green" - -/datum/sprite_accessory/undershirt/shirt_grey - name = "Shirt - Grey" - icon_state = "shirt_grey" - -/datum/sprite_accessory/undershirt/ian +/datum/sprite_accessory/underwear/top/ian name = "Shirt - Ian" icon_state = "ian" -/datum/sprite_accessory/undershirt/ilovent +/datum/sprite_accessory/underwear/top/ilovent name = "Shirt - I Love NT" icon_state = "ilovent" -/datum/sprite_accessory/undershirt/lover +/datum/sprite_accessory/underwear/top/lover name = "Shirt - Lover" icon_state = "lover" -/datum/sprite_accessory/undershirt/matroska +/datum/sprite_accessory/underwear/top/matroska name = "Shirt - Matroska" icon_state = "matroska" -/datum/sprite_accessory/undershirt/meat +/datum/sprite_accessory/underwear/top/meat name = "Shirt - Meat" icon_state = "shirt_meat" -/datum/sprite_accessory/undershirt/nano +/datum/sprite_accessory/underwear/top/nano name = "Shirt - Nanotrasen" icon_state = "shirt_nano" -/datum/sprite_accessory/undershirt/peace +/datum/sprite_accessory/underwear/top/peace name = "Shirt - Peace" icon_state = "peace" -/datum/sprite_accessory/undershirt/pacman +/datum/sprite_accessory/underwear/top/pacman name = "Shirt - Pogoman" icon_state = "pogoman" -/datum/sprite_accessory/undershirt/question +/datum/sprite_accessory/underwear/top/question name = "Shirt - Question" icon_state = "shirt_question" -/datum/sprite_accessory/undershirt/redshirt - name = "Shirt - Red" - icon_state = "shirt_red" - -/datum/sprite_accessory/undershirt/skull +/datum/sprite_accessory/underwear/top/skull name = "Shirt - Skull" icon_state = "shirt_skull" -/datum/sprite_accessory/undershirt/ss13 +/datum/sprite_accessory/underwear/top/ss13 name = "Shirt - SS13" icon_state = "shirt_ss13" + has_color = TRUE -/datum/sprite_accessory/undershirt/stripe +/datum/sprite_accessory/underwear/top/stripe name = "Shirt - Striped" icon_state = "shirt_stripes" -/datum/sprite_accessory/undershirt/tiedye +/datum/sprite_accessory/underwear/top/tiedye name = "Shirt - Tie-dye" icon_state = "shirt_tiedye" -/datum/sprite_accessory/undershirt/uk +/datum/sprite_accessory/underwear/top/uk name = "Shirt - UK" icon_state = "uk" -/datum/sprite_accessory/undershirt/usa +/datum/sprite_accessory/underwear/top/usa name = "Shirt - USA" icon_state = "shirt_assblastusa" -/datum/sprite_accessory/undershirt/shirt_white - name = "Shirt - White" - icon_state = "shirt_white" +/datum/sprite_accessory/underwear/top/shortsleeve + name = "Shirt - Short Sleeved" + icon_state = "shortsleeve" + has_color = TRUE -/datum/sprite_accessory/undershirt/blackshortsleeve - name = "Shirt, Short Sleeved - Black" - icon_state = "blackshortsleeve" - -/datum/sprite_accessory/undershirt/blueshortsleeve - name = "Shirt, Short Sleeved - Blue" - icon_state = "blueshortsleeve" - -/datum/sprite_accessory/undershirt/greenshortsleeve - name = "Shirt, Short Sleeved - Green" - icon_state = "greenshortsleeve" - -/datum/sprite_accessory/undershirt/purpleshortsleeve - name = "Shirt, Short Sleeved - Purple" - icon_state = "purpleshortsleeve" - -/datum/sprite_accessory/undershirt/whiteshortsleeve - name = "Shirt, Short Sleeved - White" - icon_state = "whiteshortsleeve" - -/datum/sprite_accessory/undershirt/blueshirtsport +/datum/sprite_accessory/underwear/top/blueshirtsport name = "Shirt, Sports - Blue" icon_state = "blueshirtsport" - gender = NEUTER -/datum/sprite_accessory/undershirt/greenshirtsport +/datum/sprite_accessory/underwear/top/greenshirtsport name = "Shirt, Sports - Green" icon_state = "greenshirtsport" - gender = NEUTER -/datum/sprite_accessory/undershirt/redshirtsport +/datum/sprite_accessory/underwear/top/redshirtsport name = "Shirt, Sports - Red" icon_state = "redshirtsport" - gender = NEUTER -/datum/sprite_accessory/undershirt/redtop - name = "Shirt, Short - Red" - icon_state = "redtop" - -/datum/sprite_accessory/undershirt/whitetop - name = "Shirt, Short - White" - icon_state = "whitetop" - -/datum/sprite_accessory/undershirt/tshirt_blue - name = "T-Shirt - Blue" - icon_state = "blueshirt" - -/datum/sprite_accessory/undershirt/tshirt_green - name = "T-Shirt - Green" - icon_state = "greenshirt" - -/datum/sprite_accessory/undershirt/tshirt_red - name = "T-Shirt - Red" - icon_state = "redshirt" - -/datum/sprite_accessory/undershirt/yellowshirt - name = "T-Shirt - Yellow" - icon_state = "yellowshirt" - -/datum/sprite_accessory/undershirt/tank_black - name = "Tank Top - Black" - icon_state = "tank_black" - -/datum/sprite_accessory/undershirt/tankfire +/datum/sprite_accessory/underwear/top/tankfire name = "Tank Top - Fire" icon_state = "tank_fire" -/datum/sprite_accessory/undershirt/tank_grey - name = "Tank Top - Grey" - icon_state = "tank_grey" +/datum/sprite_accessory/underwear/top/tanktop + name = "Tank Top" + icon_state = "tanktop" + has_color = TRUE -/datum/sprite_accessory/undershirt/female_midriff +/datum/sprite_accessory/underwear/top/tanktop_alt + name = "Tank Top - Alt" + icon_state = "tanktop_alt" + has_color = TRUE + +/datum/sprite_accessory/underwear/top/tanktop_midriff name = "Tank Top - Midriff" icon_state = "tank_midriff" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/tank_red - name = "Tank Top - Red" - icon_state = "tank_red" +/datum/sprite_accessory/underwear/top/tanktop_midriff_alt + name = "Tank Top - Midriff Halterneck" + icon_state = "tank_midriff_alt" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/tankstripe +/datum/sprite_accessory/underwear/top/tankstripe name = "Tank Top - Striped" icon_state = "tank_stripes" -/datum/sprite_accessory/undershirt/tank_white - name = "Tank Top - White" - icon_state = "tank_white" +/datum/sprite_accessory/underwear/top/tank_top_sun + name = "Tank top - Sun" + icon_state = "tank_sun" -/datum/sprite_accessory/undershirt/female_red - name = "Bra - Red" - icon_state = "bra_red" +/datum/sprite_accessory/underwear/top/babydoll + name = "Baby-Doll" + icon_state = "babydoll" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_pink - name = "Bra - Pink" - icon_state = "bra_pink" +/datum/sprite_accessory/underwear/top/bra + name = "Bra" + icon_state = "bra" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_kinky +/datum/sprite_accessory/underwear/top/bra_alt + name = "Bra - Alt" + icon_state = "bra_alt" + has_color = TRUE + gender = FEMALE + +/datum/sprite_accessory/underwear/top/bra_thin + name = "Bra - Thin" + icon_state = "bra_thin" + has_color = TRUE + gender = FEMALE + +/datum/sprite_accessory/underwear/top/bra_kinky name = "Bra - Kinky Black" icon_state = "bra_kinky" + gender = FEMALE -/datum/sprite_accessory/undershirt/female_green - name = "Bra - Green" - icon_state = "bra_green" - -/datum/sprite_accessory/undershirt/female_commie +/datum/sprite_accessory/underwear/top/bra_freedom name = "Bra - Freedom" icon_state = "bra_assblastusa" + gender = FEMALE -/datum/sprite_accessory/undershirt/female_commie +/datum/sprite_accessory/underwear/top/bra_commie name = "Bra - Commie" icon_state = "bra_commie" + gender = FEMALE -/datum/sprite_accessory/undershirt/female_babyblue - name = "Bra - Baby Blue" - icon_state = "bra_babyblue" - -/datum/sprite_accessory/undershirt/female_beekini +/datum/sprite_accessory/underwear/top/bra_beekini name = "Bra - Bee-kini" icon_state = "bra_bee-kini" + gender = FEMALE -/datum/sprite_accessory/undershirt/female_black - name = "Bra - Black" - icon_state = "bra_black" - -/datum/sprite_accessory/undershirt/female_uk +/datum/sprite_accessory/underwear/top/bra_uk name = "Bra - UK" icon_state = "bra_uk" + gender = FEMALE -/datum/sprite_accessory/undershirt/female_white - name = "Bra - White" - icon_state = "bra_white" +/datum/sprite_accessory/underwear/top/bra_neko + name = "Bra - Neko" + icon_state = "bra_neko" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_white_neko - name = "Bra, Neko - white" - icon_state = "bra_neko_white" +/datum/sprite_accessory/underwear/top/halterneck_bra + name = "Bra - Halterneck" + icon_state = "halterneck_bra" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_black_neko - name = "Bra, Neko - Black" - icon_state = "bra_neko_black" - -/datum/sprite_accessory/undershirt/female_blackalt - name = "Bra, Sports - Black" - icon_state = "bra_sports_black" - -/datum/sprite_accessory/undershirt/sports_bra - name = "Bra, Sports 1 - White" +/datum/sprite_accessory/underwear/top/sports_bra + name = "Bra, Sports" icon_state = "sports_bra" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_whitealt - name = "Bra, Sports 2 - White" - icon_state = "bra_sports_white" - -/datum/sprite_accessory/undershirt/sports_bra2 - name = "Bra, Sports 3 - White" +/datum/sprite_accessory/underwear/top/sports_bra_alt + name = "Bra, Sports - Alt" icon_state = "sports_bra_alt" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_yellow - name = "Bra - Yellow" - icon_state = "bra_yellow" +/datum/sprite_accessory/underwear/top/bra_strapless + name = "Bra, Strapless" + icon_state = "bra_strapless" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/female_thong - name = "Bra, Strapless - Pink" - icon_state = "bra_strapless_pink" - -/datum/sprite_accessory/undershirt/female_blue - name = "Bra, Strapless - Blue" +/datum/sprite_accessory/underwear/top/bra_strapless_alt + name = "Bra, Strapless - Alt" icon_state = "bra_blue" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/swimsuit_green - name = "Swimsuit, Top - Green" - icon_state = "bra_swimming_green" +/datum/sprite_accessory/underwear/top/striped_bra + name = "Bra - Striped" + icon_state = "striped_bra" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/undershirt/swimsuit_purple - name = "Swimsuit, Top - Purple" - icon_state = "bra_swimming_purple" \ No newline at end of file +/datum/sprite_accessory/underwear/top/fishnet_sleeves + name = "Fishnet - sleeves" + icon_state = "fishnet_sleeves" + gender = FEMALE + +/datum/sprite_accessory/underwear/top/fishnet_gloves + name = "Fishnet - gloves" + icon_state = "fishnet_gloves" + gender = FEMALE + +/datum/sprite_accessory/underwear/top/fishnet_base + name = "Fishnet - top" + icon_state = "fishnet_body" + gender = FEMALE + +/datum/sprite_accessory/underwear/top/swimsuit + name = "Swimsuit Top" + icon_state = "bra_swimming" + has_color = TRUE + gender = FEMALE + +/datum/sprite_accessory/underwear/top/swimsuit_alt + name = "Swimsuit Top - Strapless" + icon_state = "bra_swimming_alt" + has_color = TRUE + gender = FEMALE + +/datum/sprite_accessory/underwear/top/tubetop + name = "Tube Top" + icon_state = "tubetop" + has_color = TRUE + gender = FEMALE \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm index e7179eeb87..3356804cb3 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm @@ -1,174 +1,172 @@ /////////////////////////// // Underwear Definitions // /////////////////////////// -/datum/sprite_accessory/underwear - icon = 'icons/mob/underwear.dmi' - gender = NEUTER -/datum/sprite_accessory/underwear/nude +/datum/sprite_accessory/underwear/bottom/nude name = "Nude" icon_state = null -/datum/sprite_accessory/underwear/mankini - name = "Mankini - Green" - icon_state = "mankini_green" +/datum/sprite_accessory/underwear/bottom/mankini + name = "Mankini" + icon_state = "mankini" + has_color = TRUE + gender = MALE -/datum/sprite_accessory/underwear/male_kinky - name = "Jockstrap - White" - icon_state = "jockstrap_white" +/datum/sprite_accessory/underwear/bottom/male_kinky + name = "Jockstrap" + icon_state = "jockstrap" + has_color = TRUE + gender = MALE -/datum/sprite_accessory/underwear/male_white - name = "Briefs - White" - icon_state = "briefs_white" +/datum/sprite_accessory/underwear/bottom/briefs + name = "Briefs" + icon_state = "briefs" + has_color = TRUE + gender = MALE -/datum/sprite_accessory/underwear/male_black - name = "Briefs - Black" - icon_state = "briefs_black" +/datum/sprite_accessory/underwear/bottom/boxers + name = "Boxers" + icon_state = "boxers" + has_color = TRUE + gender = MALE -/datum/sprite_accessory/underwear/male_grey - name = "Briefs - Grey" - icon_state = "briefs_grey" +/datum/sprite_accessory/underwear/bottom/male_bee + name = "Boxers - Bee" + icon_state = "bee_shorts" + gender = MALE -/datum/sprite_accessory/underwear/male_red - name = "Briefs - Red" - icon_state = "briefs_red" - -/datum/sprite_accessory/underwear/male_green - name = "Briefs - Green" - icon_state = "briefs_green" - -/datum/sprite_accessory/underwear/male_blue - name = "Briefs - Blue" - icon_state = "briefs_blue" - -/datum/sprite_accessory/underwear/male_blackalt - name = "Boxers - Black" - icon_state = "boxers_black" - -/datum/sprite_accessory/underwear/male_greyalt - name = "Boxers - Grey" - icon_state = "boxers_grey" - -/datum/sprite_accessory/underwear/male_hearts +/datum/sprite_accessory/underwear/bottom/male_hearts name = "Boxers - Heart" icon_state = "boxers_heart" + gender = MALE -/datum/sprite_accessory/underwear/male_stripe +/datum/sprite_accessory/underwear/bottom/male_stripe name = "Boxers - Striped" icon_state = "boxers_striped" + gender = MALE -/datum/sprite_accessory/underwear/male_commie +/datum/sprite_accessory/underwear/bottom/male_commie name = "Boxers - Striped Communist" icon_state = "boxers_commie" + gender = MALE -/datum/sprite_accessory/underwear/male_usastripe +/datum/sprite_accessory/underwear/bottom/male_usastripe name = "Boxers - Striped Freedom" icon_state = "boxers_assblastusa" + gender = MALE -/datum/sprite_accessory/underwear/male_uk +/datum/sprite_accessory/underwear/bottom/male_uk name = "Boxers - Striped UK" icon_state = "boxers_uk" + gender = MALE +/datum/sprite_accessory/underwear/bottom/boxer_briefs + name = "Boxer Briefs" + icon_state = "boxer_briefs" + has_color = TRUE -/datum/sprite_accessory/underwear/female_whitealt - name = "Boxer Briefs - White" - icon_state = "boxer_briefs_white" +/datum/sprite_accessory/underwear/bottom/panties + name = "Panties" + icon_state = "panties" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/female_blackalt - name = "Boxer Briefs - Black" - icon_state = "boxer_briefs_black" +/datum/sprite_accessory/underwear/bottom/panties_alt + name = "Panties - Alt" + icon_state = "panties_alt" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/female_pink - name = "Boxer Briefs - Pink" - icon_state = "boxer_briefs_pink" +/datum/sprite_accessory/underwear/bottom/fishnet_lower + name = "Panties - Fishnet" + icon_state = "fishnet_lower" + gender = FEMALE -/datum/sprite_accessory/underwear/female_babyblue - name = "Boxer Briefs - Baby Blue" - icon_state = "boxer_briefs_babyblue" - -/datum/sprite_accessory/underwear/female_yellow - name = "Boxer Briefs - Yellow" - icon_state = "boxer_briefs_yellow" - -/datum/sprite_accessory/underwear/female_beekini +/datum/sprite_accessory/underwear/bottom/female_beekini name = "Panties - Bee-kini" icon_state = "panties_bee-kini" + gender = FEMALE -/datum/sprite_accessory/underwear/female_black - name = "Panties - Black" - icon_state = "panties_black" - -/datum/sprite_accessory/underwear/female_blue - name = "Panties - Blue" - icon_state = "panties_blue" - -/datum/sprite_accessory/underwear/female_commie +/datum/sprite_accessory/underwear/bottom/female_commie name = "Panties - Commie" icon_state = "panties_commie" + gender = FEMALE -/datum/sprite_accessory/underwear/female_usastripe +/datum/sprite_accessory/underwear/bottom/female_usastripe name = "Panties - Freedom" icon_state = "panties_assblastusa" + gender = FEMALE -/datum/sprite_accessory/underwear/female_green - name = "Panties - Green" - icon_state = "panties_green" - -/datum/sprite_accessory/underwear/female_kinky +/datum/sprite_accessory/underwear/bottom/female_kinky name = "Panties - Kinky Black" icon_state = "panties_kinky" + gender = FEMALE -/datum/sprite_accessory/underwear/female_red - name = "Panties - Red" - icon_state = "panties_red" - -/datum/sprite_accessory/underwear/female_uk +/datum/sprite_accessory/underwear/bottom/panties_uk name = "Panties - UK" icon_state = "panties_uk" + gender = FEMALE -/datum/sprite_accessory/underwear/female_white - name = "Panties - White" - icon_state = "panties_white" +/datum/sprite_accessory/underwear/bottom/panties_neko + name = "Panties - Neko" + icon_state = "panties_neko" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/female_white_neko - name = "Panties, Neko - White" - icon_state = "panties_neko_white" +/datum/sprite_accessory/underwear/bottom/panties_slim + name = "Panties - Slim" + icon_state = "panties_slim" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/female_black_neko - name = "Panties, Neko - Black" - icon_state = "panties_neko_black" +/datum/sprite_accessory/underwear/bottom/striped_panties + name = "Panties - Striped" + icon_state = "striped_panties" + has_color = TRUE + gender = FEMALE +/datum/sprite_accessory/underwear/bottom/panties_swimsuit + name = "Panties - Swimsuit" + icon_state = "panties_swimming" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/swimsuit_red +/datum/sprite_accessory/underwear/bottom/panties_thin + name = "Panties - Thin" + icon_state = "panties_thin" + has_color = TRUE + gender = FEMALE + +/datum/sprite_accessory/underwear/bottom/longjon + name = "Long John Bottoms" + icon_state = "ljonb" + has_color = TRUE + +/datum/sprite_accessory/underwear/bottom/swimsuit_red name = "Swimsuit, One Piece - Red" icon_state = "swimming_red" + gender = FEMALE -/datum/sprite_accessory/underwear/swimsuit +/datum/sprite_accessory/underwear/bottom/swimsuit name = "Swimsuit, One Piece - Black" icon_state = "swimming_black" + gender = FEMALE -/datum/sprite_accessory/underwear/swimsuit_blue +/datum/sprite_accessory/underwear/bottom/swimsuit_blue name = "Swimsuit, One Piece - Striped Blue" icon_state = "swimming_blue" + gender = FEMALE -/datum/sprite_accessory/underwear/swimsuit_green - name = "Swimsuit, Bottom - Green" - icon_state = "panties_swimming_green" +/datum/sprite_accessory/underwear/bottom/thong + name = "Thong" + icon_state = "thong" + has_color = TRUE + gender = FEMALE -/datum/sprite_accessory/underwear/swimsuit_purple - name = "Swimsuit, Bottom - Purple" - icon_state = "panties_swimming_purple" - -/datum/sprite_accessory/underwear/female_thong_black - name = "Thong - Black" - icon_state = "thong_black" - -/datum/sprite_accessory/underwear/female_thong - name = "Thong - Pink" - icon_state = "thong_pink" - -/datum/sprite_accessory/underwear/female_babydoll - name = "Babydoll - Black" - icon_state = "babydoll" +/datum/sprite_accessory/underwear/bottom/thong_babydoll + name = "Thong - Alt" + icon_state = "thong_babydoll" + has_color = TRUE + gender = FEMALE diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index d521ef179f..7eeab05466 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -4,14 +4,14 @@ return var/message_mode = get_message_mode(message) - if(client && (message_mode == "admin" || message_mode == "deadmin")) + if(client && (message_mode == MODE_ADMIN || message_mode == MODE_DEADMIN)) message = copytext(message, 3) if(findtext(message, " ", 1, 2)) message = copytext(message, 2) - if(message_mode == "admin") + if(message_mode == MODE_ADMIN) client.cmd_admin_say(message) - else if(message_mode == "deadmin") + else if(message_mode == MODE_DEADMIN) client.dsay(message) return diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c2518bfc9b..9569d4826c 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -275,7 +275,7 @@ /mob/proc/canUnEquip(obj/item/I, force) if(!I) return TRUE - if((I.item_flags & NODROP) && !force) + if(HAS_TRAIT(I, TRAIT_NODROP) && !force) return FALSE return TRUE @@ -309,13 +309,13 @@ //DO NOT CALL THIS PROC //use one of the above 3 helper procs //you may override it, but do not modify the args -/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides NODROP_1 for things like wizarditis and admin undress. +/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides TRAIT_NODROP for things like wizarditis and admin undress. //Use no_move if the item is just gonna be immediately moved afterward //Invdrop is used to prevent stuff in pockets dropping. only set to false if it's going to immediately be replaced - if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP_1. + if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for TRAIT_NODROP. return TRUE - if((I.item_flags & NODROP) && !force) + if(HAS_TRAIT(I, TRAIT_NODROP) && !force) return FALSE var/hand_index = get_held_index_of_item(I) diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 815184c63d..ca1a961a92 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -18,10 +18,10 @@ /mob/living/carbon/monkey/handle_blood() if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space - if(blood_volume < BLOOD_VOLUME_NORMAL) + if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio)) blood_volume += 0.1 // regenerate blood VERY slowly - if(blood_volume < BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + if(blood_volume < (BLOOD_VOLUME_OKAY * blood_ratio)) + adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1)) // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() @@ -33,7 +33,7 @@ if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space - if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) + if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio) && !HAS_TRAIT(src, TRAIT_NOHUNGER)) var/nutrition_ratio = 0 switch(nutrition) if(0 to NUTRITION_LEVEL_STARVING) @@ -46,20 +46,22 @@ nutrition_ratio = 0.8 else nutrition_ratio = 1 + if(HAS_TRAIT(src, TRAIT_HIGH_BLOOD)) + nutrition_ratio *= 1.2 if(satiety > 80) nutrition_ratio *= 1.25 nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR) - blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) + blood_volume = min((BLOOD_VOLUME_NORMAL * blood_ratio), blood_volume + 0.5 * nutrition_ratio) //Effects of bloodloss var/word = pick("dizzy","woozy","faint") - switch(blood_volume) + switch(blood_volume * INVERSE(blood_ratio)) if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) to_chat(src, "You feel [word].") - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) + adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.01, 1)) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1)) if(prob(5)) blur_eyes(6) to_chat(src, "You feel very [word].") @@ -111,7 +113,7 @@ blood_volume = initial(blood_volume) /mob/living/carbon/human/restore_blood() - blood_volume = BLOOD_VOLUME_NORMAL + blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio) bleed_rate = 0 /**************************************************** @@ -122,7 +124,7 @@ /mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced) if(!blood_volume || !AM.reagents) return 0 - if(blood_volume < BLOOD_VOLUME_BAD && !forced) + if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced) return 0 if(blood_volume < amount) @@ -161,7 +163,7 @@ return /mob/living/carbon/get_blood_data(blood_id) - if(blood_id == "blood") //actual blood reagent + if(blood_id == "blood") //actual blood reagent var/blood_data = list() //set the blood data blood_data["donor"] = src @@ -204,6 +206,21 @@ if(istype(ling)) blood_data["changeling_loudness"] = ling.loudfactor return blood_data + if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff. + var/blood_data = list() + if(mind) + blood_data["mind"] = mind + else if(last_mind) + blood_data["mind"] = last_mind + if(ckey) + blood_data["ckey"] = ckey + else if(last_mind) + blood_data["ckey"] = ckey(last_mind.key) + blood_data["gender"] = gender + blood_data["real_name"] = real_name + return blood_data + + //get the id of the substance this mob use as blood. /mob/proc/get_blood_id() @@ -300,3 +317,24 @@ var/obj/effect/decal/cleanable/oil/B = locate() in T.contents if(!B) B = new(T) + +//This is a terrible way of handling it. +/mob/living/proc/ResetBloodVol() + if(ishuman(src)) + var/mob/living/carbon/human/H = src + if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD)) + blood_ratio = 1.2 + H.handle_blood() + return + blood_ratio = 1 + H.handle_blood() + return + blood_ratio = 1 + +/mob/living/proc/AdjustBloodVol(var/value) + if(blood_ratio == value) + return + blood_ratio = value + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.handle_blood() diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 2a5fdeaa33..cc11c0e8bb 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -138,7 +138,11 @@ name = "blood crawl" desc = "You are unable to hold anything while in this form." icon = 'icons/effects/blood.dmi' - item_flags = NODROP | ABSTRACT + item_flags = ABSTRACT + +/obj/item/bloodcrawl/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B) playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 76b416772e..97b29ca4e1 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -5,6 +5,7 @@ var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE. stat = DEAD //we start dead by default see_invisible = SEE_INVISIBLE_LIVING + speech_span = SPAN_ROBOT /mob/living/brain/Initialize() . = ..() diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm index ce0a09c27f..b7d7e1d7fc 100644 --- a/code/modules/mob/living/brain/say.dm +++ b/code/modules/mob/living/brain/say.dm @@ -10,14 +10,11 @@ ..() -/mob/living/brain/get_spans() - return ..() | SPAN_ROBOT - /mob/living/brain/radio(message, message_mode, list/spans, language) if(message_mode == MODE_HEADSET && istype(container, /obj/item/mmi)) var/obj/item/mmi/R = container if(R.radio) - R.radio.talk_into(src, message, , get_spans(), language) + R.radio.talk_into(src, message, language = language) return ITALICS | REDUCE_RANGE else return ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 8403d533c4..edf0fde83e 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -91,7 +91,7 @@ else return initial(pixel_x) -/mob/living/carbon/alien/humanoid/get_permeability_protection() +/mob/living/carbon/alien/humanoid/get_permeability_protection(list/target_zones) return 0.8 /mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno) diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 79eed6b82b..76ede9276c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -103,9 +103,13 @@ name = "\improper royal parasite" desc = "Inject this into one of your grown children to promote her to a Praetorian!" icon_state = "alien_medal" - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL icon = 'icons/mob/alien.dmi' +/obj/item/queenpromote/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user) if(!isalienadult(M) || isalienroyal(M)) to_chat(user, "You may only use this with your adult, non-royal children!") diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index e1a7752e9d..d2788075e2 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -59,15 +59,19 @@ /mob/living/carbon/alien/humanoid/update_inv_handcuffed() remove_overlay(HANDCUFF_LAYER) - var/cuff_icon = "aliencuff" - var/dmi_file = 'icons/mob/alien.dmi' - - if(mob_size == MOB_SIZE_LARGE) - cuff_icon = "aliencuff_[caste]" - dmi_file = 'icons/mob/alienqueen.dmi' if(handcuffed) - overlays_standing[HANDCUFF_LAYER] = mutable_appearance(dmi_file, cuff_icon, -HANDCUFF_LAYER) + var/cuff_icon = handcuffed.item_state + var/dmi_file = 'icons/mob/alien.dmi' + + if(mob_size == MOB_SIZE_LARGE) + cuff_icon += "_[caste]" + dmi_file = 'icons/mob/alienqueen.dmi' + + var/mutable_appearance/cuffs = mutable_appearance(dmi_file, cuff_icon, -HANDCUFF_LAYER) + cuffs.color = handcuffed.color + + overlays_standing[HANDCUFF_LAYER] = cuffs apply_overlay(HANDCUFF_LAYER) //Royals have bigger sprites, so inhand things must be handled differently. diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index b921aea67e..5f1e1a2830 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -4,7 +4,7 @@ if(!message) return - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "Hivemind, [shown_name] [message_a]" for(var/mob/S in GLOB.player_list) if(!S.stat && S.hivecheck()) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index b4739f943e..1574305a83 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -63,7 +63,7 @@ -/obj/item/organ/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success=TRUE) +/obj/item/organ/body_egg/alien_embryo/proc/AttemptGrow(var/kill_on_sucess=TRUE) if(!owner || bursting) return @@ -102,10 +102,12 @@ new_xeno.notransform = 0 new_xeno.invisibility = 0 - if(gib_on_success) - new_xeno.visible_message("[new_xeno] bursts out of [owner] in a shower of gore!", "You exit [owner], your previous host.", "You hear organic matter ripping and tearing!") - owner.gib(TRUE) - else + if(kill_on_sucess) //ITS TOO LATE + new_xeno.visible_message("[new_xeno] bursts out of [owner]!", "You exit [owner], your previous host.", "You hear organic matter ripping and tearing!") + owner.apply_damage(rand(100,300),BRUTE,zone,FALSE) //Random high damage to torso so health sensors don't metagame. + owner.spill_organs(TRUE,FALSE,TRUE) //Lets still make the death gruesome and impossible to just simply defib someone. + owner.death(FALSE) //Just in case some freak occurance occurs where you somehow survive all your organs being removed from you and the 100-300 brute damage. + else //When it is removed via surgery at a late stage, rather than forced. new_xeno.visible_message("[new_xeno] wriggles out of [owner]!", "You exit [owner], your previous host.") owner.adjustBruteLoss(40) owner.cut_overlay(overlay) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index c2c8904aa1..e66d70f492 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -15,7 +15,7 @@ icon_state = "facehugger" item_state = "facehugger" w_class = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4 - clothing_flags = MASKINTERNALS + clothing_flags = ALLOWINTERNALS throw_range = 5 tint = 3 flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH @@ -33,16 +33,18 @@ /obj/item/clothing/mask/facehugger/lamarr name = "Lamarr" - sterile = 1 + sterile = TRUE /obj/item/clothing/mask/facehugger/dead icon_state = "facehugger_dead" item_state = "facehugger_inactive" + sterile = TRUE stat = DEAD /obj/item/clothing/mask/facehugger/impregnated icon_state = "facehugger_impregnated" item_state = "facehugger_impregnated" + sterile = TRUE stat = DEAD /obj/item/clothing/mask/facehugger/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 92a993958a..9acecea545 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -6,6 +6,7 @@ create_reagents(1000) update_body_parts() //to update the carbon's new bodyparts appearance GLOB.carbon_list += src + blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio) /mob/living/carbon/Destroy() //This must be done first, so the mob ghosts correctly before DNA etc is nulled @@ -175,7 +176,7 @@ if(start_T && end_T) log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]") - else if(!(I.item_flags & (NODROP | ABSTRACT))) + else if(!CHECK_BITFIELD(I.item_flags, ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP)) thrown_thing = I dropItemToGround(I) @@ -238,7 +239,7 @@ if(href_list["internal"]) var/slot = text2num(href_list["internal"]) var/obj/item/ITEM = get_item_by_slot(slot) - if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & MASKINTERNALS)) + if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) visible_message("[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].", \ "[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].") if(do_mob(usr, src, POCKET_STRIP_DELAY)) @@ -246,7 +247,7 @@ internal = null update_internals_hud_icon(0) else if(ITEM && istype(ITEM, /obj/item/tank)) - if((wear_mask && (wear_mask.clothing_flags & MASKINTERNALS)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE)) + if((wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE)) internal = ITEM update_internals_hud_icon(1) @@ -409,7 +410,7 @@ return initial(pixel_y) /mob/living/carbon/proc/accident(obj/item/I) - if(!I || (I.item_flags & (NODROP | ABSTRACT))) + if(!I || (I.item_flags & ABSTRACT) || HAS_TRAIT(I, TRAIT_NODROP)) return //dropItemToGround(I) CIT CHANGE - makes it so the item doesn't drop if the modifier rolls above 100 @@ -477,11 +478,13 @@ if(message) visible_message("[src] throws up all over [p_them()]self!", \ "You throw up all over yourself!") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "vomit", /datum/mood_event/vomitself) distance = 0 else if(message) visible_message("[src] throws up!", "You throw up!") - + if(!isflyperson(src)) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "vomit", /datum/mood_event/vomit) if(stun) Stun(80) @@ -634,6 +637,18 @@ else . += INFINITY +/mob/living/carbon/get_permeability_protection(list/target_zones = list(HANDS,CHEST,GROIN,LEGS,FEET,ARMS,HEAD)) + var/list/tally = list() + for(var/obj/item/I in get_equipped_items()) + for(var/zone in target_zones) + if(I.body_parts_covered & zone) + tally["[zone]"] = max(1 - I.permeability_coefficient, target_zones["[zone]"]) + var/protection = 0 + for(var/key in tally) + protection += tally[key] + protection *= INVERSE(target_zones.len) + return protection + //this handles hud updates /mob/living/carbon/update_damage_hud() @@ -687,9 +702,10 @@ clear_fullscreen("critvision") //Oxygen damage overlay - if(oxyloss) + var/windedup = getOxyLoss() + getStaminaLoss() * 0.2 + if(windedup) var/severity = 0 - switch(oxyloss) + switch(windedup) if(10 to 20) severity = 1 if(20 to 25) @@ -916,3 +932,17 @@ /mob/living/carbon/can_resist() return bodyparts.len > 2 && ..() + +/mob/living/carbon/proc/hypnosis_vulnerable()//unused atm, but added in case + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) + return FALSE + if(hallucinating()) + return TRUE + if(IsSleeping()) + return TRUE + if(HAS_TRAIT(src, TRAIT_DUMB)) + return TRUE + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + if(mood.sanity < SANITY_UNSTABLE) + return TRUE diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index f782289e18..794194b3a1 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -11,8 +11,8 @@ var/silent = FALSE //Can't talk. Value goes down every life proc. //NOTE TO FUTURE CODERS: DO NOT INITIALIZE NUMERICAL VARS AS NULL OR I WILL MURDER YOU. var/dreaming = 0 //How many dream images we have left to send - var/obj/item/handcuffed = null //Whether or not the mob is handcuffed - var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this. + var/obj/item/restraints/handcuffed //Whether or not the mob is handcuffed + var/obj/item/restraints/legcuffed //Same as handcuffs but for legs. Bear traps use this. var/disgust = 0 diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 8550a0887f..5b224444e0 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -247,7 +247,7 @@ if(DISGUST_LEVEL_DISGUSTED to INFINITY) msg += "[t_He] look[p_s()] extremely disgusted.\n" - if(blood_volume < BLOOD_VOLUME_SAFE) + if(blood_volume < (BLOOD_VOLUME_SAFE*blood_ratio)) msg += "[t_He] [t_has] pale skin.\n" if(bleedsuppress) @@ -281,6 +281,13 @@ if(91.01 to INFINITY) msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n" + if(reagents.has_reagent("astral")) + msg += "[t_He] have wild, spacey eyes" + if(mind) + msg += " and have a strange, abnormal look to them.\n" + else + msg += " and don't look like they're all there.\n" + if(isliving(user)) var/mob/living/L = user if(src != user && HAS_TRAIT(L, TRAIT_EMPATH) && !appears_dead) @@ -304,6 +311,13 @@ msg += "
    " + var/obj/item/organ/vocal_cords/Vc = user.getorganslot(ORGAN_SLOT_VOICE) + if(Vc) + if(istype(Vc, /obj/item/organ/vocal_cords/velvet)) + if(client?.prefs.lewdchem) + msg += "You feel your chords resonate looking at them.\n" + + if(!appears_dead) if(stat == UNCONSCIOUS) msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a4fca9dd78..528b55c921 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -252,7 +252,7 @@ var/delay_denominator = 1 if(pocket_item && !(pocket_item.item_flags & ABSTRACT)) - if(pocket_item.item_flags & NODROP) + if(HAS_TRAIT(pocket_item, TRAIT_NODROP)) to_chat(usr, "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!") to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT)) @@ -623,6 +623,7 @@ facial_hair_style = "Shaved" hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") underwear = "Nude" + undershirt = "Nude" update_body() update_hair() update_genitals() @@ -811,6 +812,8 @@ for(var/datum/mutation/human/HM in dna.mutations) if(HM.quality != POSITIVE) dna.remove_mutation(HM.name) + if(blood_volume < (BLOOD_VOLUME_NORMAL*blood_ratio)) + blood_volume = (BLOOD_VOLUME_NORMAL*blood_ratio) ..() /mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker) @@ -899,12 +902,9 @@ stop_pulling() /mob/living/carbon/human/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this - var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) - for(var/bp in body_parts) - if(istype(bp, /obj/item/clothing)) - var/obj/item/clothing/C = bp - if(C.blocks_shove_knockdown) - return TRUE + for(var/obj/item/clothing/C in get_equipped_items()) //doesn't include pockets + if(C.blocks_shove_knockdown) + return TRUE return FALSE /mob/living/carbon/human/proc/clear_shove_slowdown() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b42346382f..ff4878aa13 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -27,7 +27,7 @@ for(var/bp in body_parts) if(!bp) continue - if(bp && istype(bp , /obj/item/clothing)) + if(istype(bp, /obj/item/clothing)) var/obj/item/clothing/C = bp if(C.body_parts_covered & def_zone.body_part) protection += C.armor.getRating(d_type) @@ -654,6 +654,7 @@ if(health >= 0) if(src == M) + var/to_send = "" visible_message("[src] examines [p_them()]self.", \ "You check yourself for injuries.") @@ -700,53 +701,55 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_chat(src, "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].") + to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/obj/item/I in LB.embedded_objects) - to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") + to_send += "\t There is \a [I] embedded in your [LB.name]!\n" for(var/t in missing) - to_chat(src, "Your [parse_zone(t)] is missing!") + to_send += "Your [parse_zone(t)] is missing!\n" if(bleed_rate) - to_chat(src, "You are bleeding!") + to_send += "You are bleeding!\n" if(getStaminaLoss()) if(getStaminaLoss() > 30) - to_chat(src, "You're completely exhausted.") + to_send += "You're completely exhausted.\n" else - to_chat(src, "You feel fatigued.") + to_send += "You feel fatigued.\n" if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) if(toxloss) if(toxloss > 10) - to_chat(src, "You feel sick.") + to_send += "You feel sick.\n" else if(toxloss > 20) - to_chat(src, "You feel nauseated.") + to_send += "You feel nauseated.\n" else if(toxloss > 40) - to_chat(src, "You feel very unwell!") + to_send += "You feel very unwell!\n" if(oxyloss) if(oxyloss > 10) - to_chat(src, "You feel lightheaded.") + to_send += "You feel lightheaded.\n" else if(oxyloss > 20) - to_chat(src, "Your thinking is clouded and distant.") + to_send += "Your thinking is clouded and distant.\n" else if(oxyloss > 30) - to_chat(src, "You're choking!") + to_send += "You're choking!\n" switch(nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) - to_chat(src, "You're completely stuffed!") + to_send += "You're completely stuffed!\n" if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) - to_chat(src, "You're well fed!") + to_send += "You're well fed!\n" if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) - to_chat(src, "You're not hungry.") + to_send += "You're not hungry.\n" if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) - to_chat(src, "You could use a bite to eat.") + to_send += "You could use a bite to eat.\n" if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) - to_chat(src, "You feel quite hungry.") + to_send += "You feel quite hungry.\n" if(0 to NUTRITION_LEVEL_STARVING) - to_chat(src, "You're starving!") + to_send += "You're starving!\n" if(roundstart_quirks.len) - to_chat(src, "You have these quirks: [get_trait_string()].") + to_send += "You have these quirks: [get_trait_string()].\n" + + to_chat(src, to_send) else if(wear_suit) wear_suit.add_fingerprint(M) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index de976da40f..35b0384145 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -25,9 +25,13 @@ var/age = 30 //Player's age var/underwear = "Nude" //Which underwear the player wants + var/undie_color = "FFFFFF" var/undershirt = "Nude" //Which undershirt the player wants + var/shirt_color = "FFFFFF" var/socks = "Nude" //Which socks the player wants + var/socks_color = "FFFFFF" var/backbag = DBACKPACK //Which backpack type the player has chosen. + var/jumpsuit_style = PREF_SUIT //suit/skirt //Equipment slots var/obj/item/wear_suit = null @@ -44,6 +48,7 @@ var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding var/name_override //For temporary visible name changes + var/genital_override = FALSE //Force genitals on things incase of chems var/nameless = FALSE //For drones of both the insectoid and robotic kind. And other types of nameless critters. diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 0b40d3d26a..b65d62b63b 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -111,26 +111,6 @@ return ..() -/mob/living/carbon/human/get_permeability_protection() - var/list/prot = list("hands"=0, "chest"=0, "groin"=0, "legs"=0, "feet"=0, "arms"=0, "head"=0) - for(var/obj/item/I in get_equipped_items()) - if(I.body_parts_covered & HANDS) - prot["hands"] = max(1 - I.permeability_coefficient, prot["hands"]) - if(I.body_parts_covered & CHEST) - prot["chest"] = max(1 - I.permeability_coefficient, prot["chest"]) - if(I.body_parts_covered & GROIN) - prot["groin"] = max(1 - I.permeability_coefficient, prot["groin"]) - if(I.body_parts_covered & LEGS) - prot["legs"] = max(1 - I.permeability_coefficient, prot["legs"]) - if(I.body_parts_covered & FEET) - prot["feet"] = max(1 - I.permeability_coefficient, prot["feet"]) - if(I.body_parts_covered & ARMS) - prot["arms"] = max(1 - I.permeability_coefficient, prot["arms"]) - if(I.body_parts_covered & HEAD) - prot["head"] = max(1 - I.permeability_coefficient, prot["head"]) - var/protection = (prot["head"] + prot["arms"] + prot["feet"] + prot["legs"] + prot["groin"] + prot["chest"] + prot["hands"])/7 - return protection - /mob/living/carbon/human/can_use_guns(obj/item/G) . = ..() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 176d967d52..d35df6b789 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -167,9 +167,9 @@ dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop. if(l_store) dropItemToGround(l_store, TRUE) - if(wear_id) + if(wear_id && !CHECK_BITFIELD(wear_id.item_flags, NO_UNIFORM_REQUIRED)) dropItemToGround(wear_id) - if(belt) + if(belt && !CHECK_BITFIELD(belt.item_flags, NO_UNIFORM_REQUIRED)) dropItemToGround(belt) w_uniform = null update_suit_sensors() diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 673249b186..eee425063d 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -10,29 +10,6 @@ else . = ..() -/mob/living/carbon/human/treat_message(message) - message = dna.species.handle_speech(message,src) - if(diseases.len) - for(var/datum/disease/pierrot_throat/D in diseases) - var/list/temp_message = splittext(message, " ") //List each word in the message - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line - pick_list += i - for(var/i=1, ((i <= D.stage) && (i <= temp_message.len)), i++) //Loop for each stage of the disease or until we run out of words - if(prob(3 * D.stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) - continue - temp_message[H] = "HONK" - pick_list -= H //Make sure that you dont HONK the same word twice - message = jointext(temp_message, " ") - message = ..(message) - message = dna.mutations_say_mods(message) - return message - -/mob/living/carbon/human/get_spans() - return ..() | dna.mutations_get_spans() | dna.species_get_spans() - /mob/living/carbon/human/GetVoice() if(istype(wear_mask, /obj/item/clothing/mask/chameleon)) var/obj/item/clothing/mask/chameleon/V = wear_mask @@ -76,14 +53,14 @@ if(ears) var/obj/item/radio/headset/dongle = ears if(!istype(dongle)) - return 0 + return FALSE if(dongle.translate_binary) - return 1 + return TRUE /mob/living/carbon/human/radio(message, message_mode, list/spans, language) . = ..() - if(. != 0) - return . + if(.) + return switch(message_mode) if(MODE_HEADSET) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 3324b07217..0f83e675fc 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -279,7 +279,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(mutanthands) // Drop items in hands - // If you're lucky enough to have a NODROP_1 item, then it stays. + // If you're lucky enough to have a TRAIT_NODROP item, then it stays. for(var/V in C.held_items) var/obj/item/I = V if(istype(I)) @@ -495,34 +495,42 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(H.hidden_underwear) H.underwear = "Nude" else - H.underwear = H.saved_underwear - var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear] - if(underwear) - standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER) + H.saved_underwear = H.underwear + var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear] + if(B) + var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER) + if(UNDIE_COLORABLE(B)) + MA.color = "#[H.undie_color]" + standing += MA if(H.undershirt) if(H.hidden_undershirt) H.undershirt = "Nude" else - H.undershirt = H.saved_undershirt - var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt] - if(undershirt) - if(H.dna.species.sexes && H.gender == FEMALE) - standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) - else - standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) + H.saved_undershirt = H.undershirt + var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt] + if(T) + var/mutable_appearance/MA + if(H.dna.species.sexes && H.gender == FEMALE) + MA = wear_female_version(T.icon_state, T.icon, BODY_LAYER) + else + MA = mutable_appearance(T.icon, T.icon_state, -BODY_LAYER) + if(UNDIE_COLORABLE(T)) + MA.color = "#[H.shirt_color]" + standing += MA if(H.socks && H.get_num_legs(FALSE) >= 2) if(H.hidden_socks) H.socks = "Nude" else - H.socks = H.saved_socks - var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks] - if(socks) - if(DIGITIGRADE in species_traits) - standing += mutable_appearance(socks.icon, socks.icon_state + "_d", -BODY_LAYER) - else - standing += mutable_appearance(socks.icon, socks.icon_state, -BODY_LAYER) + H.saved_socks = H.socks + var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks] + if(S) + var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : "" + var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER) + if(UNDIE_COLORABLE(S)) + MA.color = "#[H.socks_color]" + standing += MA if(standing.len) H.overlays_standing[BODY_LAYER] = standing @@ -1011,13 +1019,12 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(SLOT_BELT) if(H.belt) return FALSE - - var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) - - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) - if(!disable_warning) - to_chat(H, "You need a jumpsuit before you can attach this [I.name]!") - return FALSE + if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) + var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) + if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!disable_warning) + to_chat(H, "You need a jumpsuit before you can attach this [I.name]!") + return FALSE if(!(I.slot_flags & ITEM_SLOT_BELT)) return return equip_delay_self_check(I, H, bypass_equip_delay_self) @@ -1054,17 +1061,17 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(SLOT_WEAR_ID) if(H.wear_id) return FALSE - - var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) - if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) - if(!disable_warning) - to_chat(H, "You need a jumpsuit before you can attach this [I.name]!") - return FALSE + if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) + var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) + if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC)) + if(!disable_warning) + to_chat(H, "You need a jumpsuit before you can attach this [I.name]!") + return FALSE if( !(I.slot_flags & ITEM_SLOT_ID) ) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) if(SLOT_L_STORE) - if(I.item_flags & NODROP) //Pockets aren't visible, so you can't move NODROP_1 items into them. + if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them. return FALSE if(H.l_store) return FALSE @@ -1080,7 +1087,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) ) return TRUE if(SLOT_R_STORE) - if(I.item_flags & NODROP) + if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.r_store) return FALSE @@ -1097,7 +1104,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) return TRUE return FALSE if(SLOT_S_STORE) - if(I.item_flags & NODROP) + if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.s_store) return FALSE @@ -1158,13 +1165,6 @@ GLOBAL_LIST_EMPTY(roundstart_races) return 1 return FALSE -/datum/species/proc/handle_speech(message, mob/living/carbon/human/H) - return message - -//return a list of spans or an empty list -/datum/species/proc/get_spans() - return list() - /datum/species/proc/check_weakness(obj/item, mob/living/attacker) return FALSE @@ -1696,7 +1696,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma. var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev) - var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang/) + var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang && !/datum/antagonist/gang/boss) if(rev) rev.remove_revolutionary(FALSE, user) if(gang) diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index da7de39a03..4a7580e978 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -68,17 +68,17 @@ /obj/item/organ/tongue/dullahan zone = "abstract" + modifies_speech = TRUE -/obj/item/organ/tongue/dullahan/TongueSpeech(var/message) +/obj/item/organ/tongue/dullahan/handle_speech(datum/source, list/speech_args) if(ishuman(owner)) var/mob/living/carbon/human/H = owner if(H.dna.species.id == "dullahan") var/datum/species/dullahan/D = H.dna.species if(isobj(D.myhead.loc)) var/obj/O = D.myhead.loc - O.say(message) - message = "" - return message + O.say(speech_args[SPEECH_MESSAGE]) + speech_args[SPEECH_MESSAGE] = "" /obj/item/organ/ears/dullahan zone = "abstract" diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 2907caff13..88dd59749c 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -420,7 +420,7 @@ H.visible_message("[H] teleports!", "You destabilize and teleport!") new /obj/effect/particle_effect/sparks(get_turf(H)) playsound(get_turf(H), "sparks", 50, 1) - do_teleport(H, get_turf(H), 6, asoundin = 'sound/weapons/emitter2.ogg') + do_teleport(H, get_turf(H), 6, asoundin = 'sound/weapons/emitter2.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) last_teleport = world.time /datum/species/golem/bluespace/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) @@ -486,7 +486,7 @@ spark_system.set_up(10, 0, src) spark_system.attach(H) spark_system.start() - do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg') + do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) last_teleport = world.time UpdateButtonIcon() //action icon looks unavailable sleep(cooldown + 5) @@ -519,6 +519,11 @@ ..() last_banana = world.time last_honk = world.time + RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C) + . = ..() + UnregisterSignal(C, COMSIG_MOB_SAY) /datum/species/golem/bananium/random_name(gender,unique,lastname) var/clown_name = pick(GLOB.clown_names) @@ -567,9 +572,8 @@ /datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H) playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0) -/datum/species/golem/bananium/get_spans() - return list(SPAN_CLOWN) - +/datum/species/golem/bananium/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN /datum/species/golem/runic name = "Runic Golem" @@ -646,14 +650,16 @@ /datum/species/golem/clockwork/on_species_gain(mob/living/carbon/human/H) . = ..() H.faction |= "ratvar" + RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech) /datum/species/golem/clockwork/on_species_loss(mob/living/carbon/human/H) if(!is_servant_of_ratvar(H)) H.faction -= "ratvar" + UnregisterSignal(H, COMSIG_MOB_SAY) . = ..() -/datum/species/golem/clockwork/get_spans() - return SPAN_ROBOT //beep +/datum/species/golem/clockwork/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT //beep /datum/species/golem/clockwork/spec_death(gibbed, mob/living/carbon/human/H) gibbed = !has_corpse ? FALSE : gibbed @@ -951,7 +957,7 @@ sexes = FALSE fixed_mut_color = "ffffff" attack_verb = "rattl" - species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS) + species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER) info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice." var/datum/action/innate/bonechill/bonechill diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index b218b2cefc..66586744fb 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -5,6 +5,7 @@ default_color = "00FF90" say_mod = "chirps" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD) + mutantlungs = /obj/item/organ/lungs/slime mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE inherent_traits = list(TRAIT_TOXINLOVER) @@ -13,7 +14,8 @@ damage_overlay_type = "" var/datum/action/innate/regenerate_limbs/regenerate_limbs var/datum/action/innate/slime_change/slime_change //CIT CHANGE - liked_food = MEAT + liked_food = TOXIC | MEAT + toxic_food = null coldmod = 6 // = 3x cold damage heatmod = 0.5 // = 1/4x heat damage burnmod = 0.5 // = 1/2x generic burn damage @@ -46,14 +48,14 @@ H.adjustBruteLoss(5) to_chat(H, "You feel empty!") - if(H.blood_volume < BLOOD_VOLUME_NORMAL) + if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio)) if(H.nutrition >= NUTRITION_LEVEL_STARVING) H.blood_volume += 3 H.nutrition -= 2.5 - if(H.blood_volume < BLOOD_VOLUME_OKAY) + if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio)) if(prob(5)) to_chat(H, "You feel drained!") - if(H.blood_volume < BLOOD_VOLUME_BAD) + if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio)) Cannibalize_Body(H) if(regenerate_limbs) regenerate_limbs.UpdateButtonIcon() @@ -85,7 +87,7 @@ var/list/limbs_to_heal = H.get_missing_limbs() if(limbs_to_heal.len < 1) return 0 - if(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + if(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) return 1 return 0 @@ -96,13 +98,13 @@ to_chat(H, "You feel intact enough as it is.") return to_chat(H, "You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...") - if(H.blood_volume >= 40*limbs_to_heal.len+BLOOD_VOLUME_OKAY) + if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio)) H.regenerate_limbs() H.blood_volume -= 40*limbs_to_heal.len to_chat(H, "...and after a moment you finish reforming!") return else if(H.blood_volume >= 40)//We can partially heal some limbs - while(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) var/healed_limb = pick(limbs_to_heal) H.regenerate_limb(healed_limb) limbs_to_heal -= healed_limb @@ -136,7 +138,7 @@ bodies -= C // This means that the other bodies maintain a link // so if someone mindswapped into them, they'd still be shared. bodies = null - C.blood_volume = min(C.blood_volume, BLOOD_VOLUME_NORMAL) + C.blood_volume = min(C.blood_volume, (BLOOD_VOLUME_NORMAL*C.blood_ratio)) ..() /datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species) @@ -727,4 +729,4 @@ to_chat(H, "You connect [target]'s mind to your slime link!") else to_chat(H, "You can't seem to link [target]'s mind...") - to_chat(target, "The foreign presence leaves your mind.") \ No newline at end of file + to_chat(target, "The foreign presence leaves your mind.") diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index b574df7d79..754c48c3bd 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -171,12 +171,14 @@ armour_penetration = 35 lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - item_flags = ABSTRACT | NODROP | DROPDEL + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP + total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/light_eater/Initialize() . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) /obj/item/light_eater/afterattack(atom/movable/AM, mob/user, proximity) diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm index 7e838c857f..0ebd6e795b 100644 --- a/code/modules/mob/living/carbon/human/species_types/synths.dm +++ b/code/modules/mob/living/carbon/human/species_types/synths.dm @@ -28,6 +28,11 @@ /datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) ..() assume_disguise(old_species, H) + RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/species/synth/on_species_loss(mob/living/carbon/human/H) + . = ..() + UnregisterSignal(H, COMSIG_MOB_SAY) /datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) if(chem.id == "synthflesh") @@ -110,18 +115,12 @@ else return ..() - -/datum/species/synth/get_spans() - if(fake_species) - return fake_species.get_spans() - return list() - - -/datum/species/synth/handle_speech(message, mob/living/carbon/human/H) - if(H.health > disguise_fail_health) - if(fake_species) - return fake_species.handle_speech(message,H) - else - return ..() - else - return ..() \ No newline at end of file +/datum/species/synth/proc/handle_speech(datum/source, list/speech_args) + if (isliving(source)) // yeah it's gonna be living but just to be clean + var/mob/living/L = source + if(fake_species && L.health > disguise_fail_health) + switch (fake_species.type) + if (/datum/species/golem/bananium) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN + if (/datum/species/golem/clockwork) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 4bc3d622ac..53c6f1bd0f 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -46,7 +46,7 @@ C.adjustCloneLoss(-4) return C.blood_volume -= 0.75 - if(C.blood_volume <= BLOOD_VOLUME_SURVIVE) + if(C.blood_volume <= (BLOOD_VOLUME_SURVIVE*C.blood_ratio)) to_chat(C, "You ran out of blood!") C.dust() var/area/A = get_area(C) diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 5c20b0ce75..49121c9409 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -3,7 +3,7 @@ amount = dna.species.spec_stun(src,amount) return ..() -/mob/living/carbon/human/Knockdown(amount, updating = 1, ignore_canknockdown = 0) +/mob/living/carbon/human/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) amount = dna.species.spec_stun(src,amount) return ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index feb80e8d2c..72ff7e7a60 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -288,8 +288,10 @@ There are several things that need to be remembered: S.alternate_worn_icon = 'modular_citadel/icons/mob/digishoes.dmi' else S.alternate_worn_icon = null - - overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = ((shoes.alternate_worn_icon) ? shoes.alternate_worn_icon : 'icons/mob/feet.dmi')) + var/t_state = shoes.item_state + if (!t_state) + t_state = shoes.icon_state + overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = t_state, default_layer = SHOES_LAYER, default_icon_file = ((shoes.alternate_worn_icon) ? shoes.alternate_worn_icon : 'icons/mob/feet.dmi')) var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER] if(OFFSET_SHOES in dna.species.offset_features) shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1] @@ -377,13 +379,16 @@ There are several things that need to be remembered: if(wear_suit) var/obj/item/clothing/suit/S = wear_suit + var/no_taur_thanks = FALSE + if(!istype(S)) + no_taur_thanks = TRUE wear_suit.screen_loc = ui_oclothing if(client && hud_used && hud_used.hud_shown) if(hud_used.inventory_shown) client.screen += wear_suit update_observer_view(wear_suit,1) - if(S.mutantrace_variation) //Just make sure we've got this checked too + if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then. S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi' else @@ -404,7 +409,7 @@ There are several things that need to be remembered: if(OFFSET_SUIT in dna.species.offset_features) suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1] suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2] - if(S.center) + if(!no_taur_thanks && S.center) suit_overlay = center_image(suit_overlay, S.dimension_x, S.dimension_y) overlays_standing[SUIT_LAYER] = suit_overlay update_hair() @@ -468,14 +473,6 @@ There are several things that need to be remembered: overlays_standing[BACK_LAYER] = back_overlay apply_overlay(BACK_LAYER) -/mob/living/carbon/human/update_inv_legcuffed() - remove_overlay(LEGCUFF_LAYER) - clear_alert("legcuffed") - if(legcuffed) - overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "legcuff1", -LEGCUFF_LAYER) - apply_overlay(LEGCUFF_LAYER) - throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = src.legcuffed) - /proc/wear_female_version(t_color, icon, layer, type) var/index = t_color var/icon/female_clothing_icon = GLOB.female_clothing_icons[index] diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 65a4c5d33f..51c7ad9d25 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -88,4 +88,4 @@ AM.Hear(rendered, src, language, message, , spans) if(critical) //Dying words. - succumb(1) + succumb() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index b2eb83d668..36e4e18817 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -228,6 +228,9 @@ else if(SA_partialpressure > 0.01) if(prob(20)) emote(pick("giggle","laugh")) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "chemical_euphoria", /datum/mood_event/chemical_euphoria) + else + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria") //BZ (Facepunch port of their Agent B) if(breath_gases[/datum/gas/bz]) @@ -250,38 +253,39 @@ //MIASMA if(breath_gases[/datum/gas/miasma]) var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure + if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE) - if(prob(1 * miasma_partialpressure)) - var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) - miasma_disease.name = "Unknown" - ForceContractDisease(miasma_disease, TRUE, TRUE) + if(prob(0.05 * miasma_partialpressure)) + var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) + miasma_disease.name = "Unknown" + ForceContractDisease(miasma_disease, TRUE, TRUE) - //Miasma side effects - switch(miasma_partialpressure) - if(1 to 5) - // At lower pp, give out a little warning - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") - if(prob(5)) - to_chat(src, "There is an unpleasant smell in the air.") - if(5 to 20) - //At somewhat higher pp, warning becomes more obvious - if(prob(15)) - to_chat(src, "You smell something horribly decayed inside this room.") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) - if(15 to 30) - //Small chance to vomit. By now, people have internals on anyway - if(prob(5)) - to_chat(src, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - vomit() - if(30 to INFINITY) - //Higher chance to vomit. Let the horror start - if(prob(25)) - to_chat(src, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - vomit() - else - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") + //Miasma side effects + switch(miasma_partialpressure) + if(1 to 5) + // At lower pp, give out a little warning + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") + if(prob(5)) + to_chat(src, "There is an unpleasant smell in the air.") + if(5 to 20) + //At somewhat higher pp, warning becomes more obvious + if(prob(15)) + to_chat(src, "You smell something horribly decayed inside this room.") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) + if(15 to 30) + //Small chance to vomit. By now, people have internals on anyway + if(prob(5)) + to_chat(src, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + vomit() + if(30 to INFINITY) + //Higher chance to vomit. Let the horror start + if(prob(25)) + to_chat(src, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + vomit() + else + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") //Clear all moods if no miasma at all @@ -303,11 +307,17 @@ return /mob/living/carbon/proc/get_breath_from_internal(volume_needed) + var/obj/item/clothing/check + var/internals = FALSE + + for(check in GET_INTERNAL_SLOTS(src)) + if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + internals = TRUE if(internal) if(internal.loc != src) internal = null update_internals_hud_icon(0) - else if ((!wear_mask || !(wear_mask.clothing_flags & MASKINTERNALS)) && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) + else if (!internals && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) internal = null update_internals_hud_icon(0) else @@ -344,7 +354,7 @@ var/list/cached_gases = miasma_turf.air.gases - cached_gases[/datum/gas/miasma] += 0.02 + cached_gases[/datum/gas/miasma] += 0.1 /mob/living/carbon/proc/handle_blood() return @@ -525,6 +535,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(jitteriness) do_jitter_animation(jitteriness) jitteriness = max(jitteriness - restingpwr, 0) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "jittery", /datum/mood_event/jittery) + else + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "jittery") if(stuttering) stuttering = max(stuttering-1, 0) @@ -610,6 +623,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(drunkenness >= 101) adjustToxLoss(4) //Let's be honest you shouldn't be alive by now + else + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk") //used in human and monkey handle_environment() /mob/living/carbon/proc/natural_bodytemperature_stabilization() diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 85436178fe..25bc243f07 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -115,7 +115,7 @@ /mob/living/carbon/monkey/proc/handle_combat() if(pickupTarget) - if(restrained() || blacklistItems[pickupTarget] || (pickupTarget.item_flags & NODROP)) + if(restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP)) pickupTarget = null else pickupTimer++ diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index f1a6b58cd1..f9c2e2dd3d 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -152,15 +152,6 @@ return threatcount -/mob/living/carbon/monkey/get_permeability_protection() - var/protection = 0 - if(head) - protection = 1 - head.permeability_coefficient - if(wear_mask) - protection = max(1 - wear_mask.permeability_coefficient, protection) - protection = protection/7 //the rest of the body isn't covered. - return protection - /mob/living/carbon/monkey/IsVocal() if(!getorganslot(ORGAN_SLOT_LUNGS)) return 0 diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index 6311776596..e9bb9fc207 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -43,12 +43,15 @@ /mob/living/carbon/monkey/update_inv_legcuffed() remove_overlay(LEGCUFF_LAYER) + clear_alert("legcuffed") if(legcuffed) - var/mutable_appearance/legcuff_overlay = mutable_appearance('icons/mob/mob.dmi', "legcuff1", -LEGCUFF_LAYER) - legcuff_overlay.pixel_y = 8 - overlays_standing[LEGCUFF_LAYER] = legcuff_overlay - apply_overlay(LEGCUFF_LAYER) + var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER) + legcuffs.color = handcuffed.color + legcuffs.pixel_y = 8 + overlays_standing[HANDCUFF_LAYER] = legcuffs + apply_overlay(LEGCUFF_LAYER) + throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed) //monkey HUD updates for items in our inventory diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm index c52b827964..452c8f8b78 100644 --- a/code/modules/mob/living/carbon/say.dm +++ b/code/modules/mob/living/carbon/say.dm @@ -1,37 +1,17 @@ -/mob/living/carbon/treat_message(message) - for(var/datum/brain_trauma/trauma in get_traumas()) - message = trauma.on_say(message) - message = ..(message) - var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) - if(!T) //hoooooouaah! - var/regex/tongueless_lower = new("\[gdntke]+", "g") - var/regex/tongueless_upper = new("\[GDNTKE]+", "g") - if(copytext(message, 1, 2) != "*") - message = tongueless_lower.Replace(message, pick("aa","oo","'")) - message = tongueless_upper.Replace(message, pick("AA","OO","'")) - else - message = T.TongueSpeech(message) - if(wear_mask) - message = wear_mask.speechModification(message) - if(head) - message = head.speechModification(message) - return message +/mob/living/carbon/proc/handle_tongueless_speech(mob/living/carbon/speaker, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/static/regex/tongueless_lower = new("\[gdntke]+", "g") + var/static/regex/tongueless_upper = new("\[GDNTKE]+", "g") + if(message[1] != "*") + message = tongueless_lower.Replace(message, pick("aa","oo","'")) + message = tongueless_upper.Replace(message, pick("AA","OO","'")) + speech_args[SPEECH_MESSAGE] = message /mob/living/carbon/can_speak_vocal(message) if(silent) return 0 return ..() -/mob/living/carbon/get_spans() - . = ..() - var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) - if(T) - . |= T.get_spans() - - var/obj/item/I = get_active_held_item() - if(I) - . |= I.get_held_item_speechspans(src) - /mob/living/carbon/could_speak_in_language(datum/language/dt) var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) if(T) @@ -48,12 +28,7 @@ message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq) if (src.mind.has_antag_datum(/datum/antagonist/traitor)) - for (var/codeword in GLOB.syndicate_code_phrase) - var/regex/codeword_match = new("([codeword])", "ig") - message = codeword_match.Replace(message, "$1") - - for (var/codeword in GLOB.syndicate_code_response) - var/regex/codeword_match = new("([codeword])", "ig") - message = codeword_match.Replace(message, "$1") + message = GLOB.syndicate_code_phrase_regex.Replace(message, "$1") + message = GLOB.syndicate_code_response_regex.Replace(message, "$1") return message diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index 87bf662c4f..5662f25993 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -176,9 +176,22 @@ /mob/living/carbon/update_inv_handcuffed() remove_overlay(HANDCUFF_LAYER) if(handcuffed) - overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", -HANDCUFF_LAYER) + var/mutable_appearance/cuffs = mutable_appearance('icons/mob/restraints.dmi', handcuffed.item_state, -HANDCUFF_LAYER) + cuffs.color = handcuffed.color + + overlays_standing[HANDCUFF_LAYER] = cuffs apply_overlay(HANDCUFF_LAYER) +/mob/living/carbon/update_inv_legcuffed() + remove_overlay(LEGCUFF_LAYER) + clear_alert("legcuffed") + if(legcuffed) + var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER) + legcuffs.color = legcuffed.color + + overlays_standing[HANDCUFF_LAYER] = legcuffs + apply_overlay(LEGCUFF_LAYER) + throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed) //mob HUD updates for items in our inventory diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b844a294be..19f18f9973 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -281,7 +281,7 @@ var/datum/disease/D = thing if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN) ContactContractDisease(D) - + if(iscarbon(L)) var/mob/living/carbon/C = L if(HAS_TRAIT(src, TRAIT_STRONG_GRABBER)) @@ -318,17 +318,27 @@ visible_message("[src] points at [A].", "You point at [A].") return TRUE -/mob/living/verb/succumb(whispered as null) +/mob/living/verb/succumb() set name = "Succumb" set category = "IC" + if(src.has_status_effect(/datum/status_effect/chem/enthrall)) + var/datum/status_effect/chem/enthrall/E = src.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase < 3) + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) + to_chat(src, "Your mindshield prevents your mind from giving in!") + else if(src.mind.assigned_role in GLOB.command_positions) + to_chat(src, "Your dedication to your department prevents you from giving in!") + else + E.enthrallTally += 20 + to_chat(src, "You give into [E.master]'s influence.") if (InCritical()) - log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", LOG_ATTACK) + log_message("Has succumbed to death while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", LOG_ATTACK) adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD) updatehealth() - if(!whispered) - to_chat(src, "You have given up life and succumbed to death.") + to_chat(src, "You have given up life and succumbed to death.") death() + /mob/living/incapacitated(ignore_restraints, ignore_grab) if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here return TRUE @@ -532,7 +542,7 @@ var/trail_type = getTrail() if(trail_type) var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1) - if(blood_volume && blood_volume > max(BLOOD_VOLUME_NORMAL*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold + if(blood_volume && blood_volume > max((BLOOD_VOLUME_NORMAL*blood_ratio)*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold blood_volume = max(blood_volume - max(1, brute_ratio * 2), 0) //that depends on our brute damage. var/newdir = get_dir(target_turf, start) if(newdir != direction) @@ -626,14 +636,15 @@ else if(canmove) if(on_fire) resist_fire() //stop, drop, and roll - else if(resting) //cit change - allows resisting out of resting + return + if(resting) //cit change - allows resisting out of resting resist_a_rest() // ditto - else if(iscarbon(src)) //Citadel Change for embedded removal memes - var/mob/living/carbon/C = src - if(!C.handcuffed && !C.legcuffed) - return TRUE - else if(last_special <= world.time) + return + if(resist_embedded()) //Citadel Change for embedded removal memes + return + if(last_special <= world.time) resist_restraints() //trying to remove cuffs. + return /mob/proc/resist_grab(moving_resist) @@ -699,7 +710,7 @@ // The src mob is trying to strip an item from someone // Override if a certain type of mob should be behave differently when stripping items (can't, for example) /mob/living/stripPanelUnequip(obj/item/what, mob/who, where) - if(what.item_flags & NODROP) + if(HAS_TRAIT(what, TRAIT_NODROP)) to_chat(src, "You can't remove \the [what.name], it appears to be stuck!") return who.visible_message("[src] tries to remove [who]'s [what.name].", \ @@ -724,7 +735,7 @@ // Override if a certain mob should be behave differently when placing items (can't, for example) /mob/living/stripPanelEquip(obj/item/what, mob/who, where) what = src.get_active_held_item() - if(what && (what.item_flags & NODROP)) + if(what && HAS_TRAIT(what, TRAIT_NODROP)) to_chat(src, "You can't put \the [what.name] on [who], it's stuck to your hand!") return if(what) @@ -813,7 +824,7 @@ return 1 //used in datum/reagents/reaction() proc -/mob/living/proc/get_permeability_protection() +/mob/living/proc/get_permeability_protection(list/target_zones) return 0 /mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 3b0af53866..c24e6ab108 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -77,6 +77,7 @@ var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added var/blood_volume = 0 //how much blood the mob has + var/blood_ratio = 1 //How much blood the mob needs, in terms of ratio (i.e 1.2 will require BLOOD_VOLUME_NORMAL of 672) DO NOT GO ABOVE 3.55 Well, actually you can but, then they can't get enough blood. var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override var/see_override = 0 //0 for no override, sets see_invisible = see_override in silicon & carbon life process via update_sight() diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 160e596882..3b045b9eee 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -2,61 +2,61 @@ GLOBAL_LIST_INIT(department_radio_prefixes, list(":", ".")) GLOBAL_LIST_INIT(department_radio_keys, list( // Location - "r" = "right hand", - "l" = "left hand", - "i" = "intercom", + MODE_KEY_R_HAND = MODE_R_HAND, + MODE_KEY_L_HAND = MODE_L_HAND, + MODE_KEY_INTERCOM = MODE_INTERCOM, // Department - "h" = "department", - "c" = "Command", - "n" = "Science", - "m" = "Medical", - "e" = "Engineering", - "s" = "Security", - "u" = "Supply", - "v" = "Service", + MODE_KEY_DEPARTMENT = MODE_DEPARTMENT, + RADIO_KEY_COMMAND = RADIO_CHANNEL_COMMAND, + RADIO_KEY_SCIENCE = RADIO_CHANNEL_SCIENCE, + RADIO_KEY_MEDICAL = RADIO_CHANNEL_MEDICAL, + RADIO_KEY_ENGINEERING = RADIO_CHANNEL_ENGINEERING, + RADIO_KEY_SECURITY = RADIO_CHANNEL_SECURITY, + RADIO_KEY_SUPPLY = RADIO_CHANNEL_SUPPLY, + RADIO_KEY_SERVICE = RADIO_CHANNEL_SERVICE, // Faction - "t" = "Syndicate", - "y" = "CentCom", + RADIO_KEY_SYNDICATE = RADIO_CHANNEL_SYNDICATE, + RADIO_KEY_CENTCOM = RADIO_CHANNEL_CENTCOM, // Admin - "p" = "admin", - "d" = "deadmin", + MODE_KEY_ADMIN = MODE_ADMIN, + MODE_KEY_DEADMIN = MODE_DEADMIN, // Misc - "o" = "AI Private", // AI Upload channel - "x" = "cords", // vocal cords, used by Voice of God + RADIO_KEY_AI_PRIVATE = RADIO_CHANNEL_AI_PRIVATE, // AI Upload channel + MODE_KEY_VOCALCORDS = MODE_VOCALCORDS, // vocal cords, used by Voice of God //kinda localization -- rastaf0 //same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding. // Location - "ê" = "right hand", - "ä" = "left hand", - "ø" = "intercom", + "ê" = MODE_R_HAND, + "ä" = MODE_L_HAND, + "ø" = MODE_INTERCOM, // Department - "ð" = "department", - "ñ" = "Command", - "ò" = "Science", - "ü" = "Medical", - "ó" = "Engineering", - "û" = "Security", - "ã" = "Supply", - "ì" = "Service", + "ð" = MODE_DEPARTMENT, + "ñ" = RADIO_CHANNEL_COMMAND, + "ò" = RADIO_CHANNEL_SCIENCE, + "ü" = RADIO_CHANNEL_MEDICAL, + "ó" = RADIO_CHANNEL_ENGINEERING, + "û" = RADIO_CHANNEL_SECURITY, + "ã" = RADIO_CHANNEL_SUPPLY, + "ì" = RADIO_CHANNEL_SERVICE, // Faction - "å" = "Syndicate", - "í" = "CentCom", + "å" = RADIO_CHANNEL_SYNDICATE, + "í" = RADIO_CHANNEL_CENTCOM, // Admin - "ç" = "admin", - "â" = "deadmin", + "ç" = MODE_ADMIN, + "â" = MODE_ADMIN, // Misc - "ù" = "AI Private", - "÷" = "cords" + "ù" = RADIO_CHANNEL_AI_PRIVATE, + "÷" = MODE_VOCALCORDS )) /mob/living/proc/Ellipsis(original_msg, chance = 50, keep_words) @@ -105,12 +105,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list( if(findtext(message, " ", 1, 2)) message = copytext(message, 2) - if(message_mode == "admin") + if(message_mode == MODE_ADMIN) if(client) client.cmd_admin_say(message) return - if(message_mode == "deadmin") + if(message_mode == MODE_DEADMIN) if(client) client.dsay(message) return @@ -175,13 +175,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list( else src.log_talk(message, LOG_SAY, forced_by=forced) - message = treat_message(message) + message = treat_message(message) // unfortunately we still need this + var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_SAY, args) + if (sigreturn & COMPONENT_UPPERCASE_SPEECH) + message = uppertext(message) if(!message) return last_words = message - spans |= get_spans() + spans |= speech_span if(language) var/datum/language/L = GLOB.language_datum_instances[language] @@ -208,7 +211,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( send_speech(message, message_range, src, bubble_type, spans, language, message_mode) if(succumbed) - succumb(1) + succumb() to_chat(src, compose_message(src, language, message, , spans, message_mode)) return 1 @@ -278,6 +281,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mode) else AM.Hear(rendered, src, message_language, message, , spans, message_mode) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message) //speech bubble var/list/speech_bubble_recipients = list() @@ -332,6 +336,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return null /mob/living/proc/treat_message(message) + + if(HAS_TRAIT(src, TRAIT_UNINTELLIGIBLE_SPEECH)) + message = unintelligize(message) + if(derpspeech) message = derpspeech(message, stuttering) diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 928bd63dd1..c6d4527812 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -49,7 +49,7 @@ else padloc = "(UNKNOWN)" src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]") - send_speech(message, 7, T, "robot", get_spans(), language) + send_speech(message, 7, T, "robot", language = language) to_chat(src, "Holopad transmitted, [real_name] \"[message]\"") else to_chat(src, "No holopad connected.") @@ -100,6 +100,8 @@ last_announcement = message + var/voxType = input(src, "Male or female VOX?", "VOX-gender") in list("male", "female") + if(!message || announcing_vox > world.time) return @@ -121,7 +123,9 @@ if(!word) words -= word continue - if(!GLOB.vox_sounds[word]) + if(!GLOB.vox_sounds[word] && voxType == "female") + incorrect_words += word + if(!GLOB.vox_sounds_male[word] && voxType == "male") incorrect_words += word if(incorrect_words.len) @@ -133,16 +137,21 @@ log_game("[key_name(src)] made a vocal announcement with the following message: [message].") for(var/word in words) - play_vox_word(word, src.z, null) + play_vox_word(word, src.z, null, voxType) -/proc/play_vox_word(word, z_level, mob/only_listener) +/proc/play_vox_word(word, z_level, mob/only_listener, voxType = "female") word = lowertext(word) - if(GLOB.vox_sounds[word]) + if( (GLOB.vox_sounds[word] && voxType == "female") || (GLOB.vox_sounds_male[word] && voxType == "male") ) - var/sound_file = GLOB.vox_sounds[word] + var/sound_file + + if(voxType == "female") + sound_file = GLOB.vox_sounds[word] + else + sound_file = GLOB.vox_sounds_male[word] var/sound/voice = sound(sound_file, wait = 1, channel = CHANNEL_VOX) voice.status = SOUND_STREAM diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm index 99484f395e..164a3e7389 100644 --- a/code/modules/mob/living/silicon/pai/pai_shell.dm +++ b/code/modules/mob/living/silicon/pai/pai_shell.dm @@ -29,6 +29,13 @@ if(!L.temporarilyRemoveItemFromInventory(card)) to_chat(src, "Error: Unable to expand to mobile form. Chassis is restrained by some device or person.") return FALSE + if(istype(card.loc, /obj/item/integrated_circuit/input/pAI_connector)) + var/obj/item/integrated_circuit/input/pAI_connector/C = card.loc + C.RemovepAI() + C.visible_message("[src] ejects itself from [C]!") + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + C.installed_pai = null + C.push_data() forceMove(get_turf(card)) card.forceMove(src) if(client) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index c90c719e8a..0f09b6f62a 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -92,17 +92,18 @@ /mob/living/silicon/robot/emag_act(mob/user) if(user == src)//To prevent syndieborgs from emagging themselves - return + return FALSE + if(world.time < emag_cooldown) + return FALSE + . = ..() if(!opened)//Cover is closed if(locked) to_chat(user, "You emag the cover lock.") locked = FALSE if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them. to_chat(user, "[src] seems to be controlled remotely! Emagging the interface may not work as expected.") - else - to_chat(user, "The cover is already unlocked!") - return - if(world.time < emag_cooldown) + return TRUE + to_chat(user, "The cover is already unlocked!") return if(wiresexposed) to_chat(user, "You must unexpose the wires first!") @@ -115,20 +116,24 @@ to_chat(src, "\"[text2ratvar("You will serve Engine above all else")]!\"\n\ ALERT: Subversion attempt denied.") log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they serve only Ratvar.") - return + return TRUE if(connected_ai && connected_ai.mind && connected_ai.mind.has_antag_datum(/datum/antagonist/traitor)) to_chat(src, "ALERT: Foreign software execution prevented.") to_chat(connected_ai, "ALERT: Cyborg unit \[[src]] successfully defended against subversion.") log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].") - return + return TRUE if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however. to_chat(user, "[src] is remotely controlled! Your emag attempt has triggered a system reset instead!") log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.") ResetModule() - return + return TRUE + INVOKE_ASYNC(src, .proc/beep_boop_rogue_bot, user) + return TRUE + +/mob/living/silicon/robot/proc/beep_boop_rogue_bot(mob/user) SetEmagged(1) SetStun(60) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown lawupdate = 0 diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 38ad3b8e5a..7b95ced63f 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -119,7 +119,7 @@ if(I.loc != src) I.forceMove(src) modules += I - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, CYBORG_ITEM_TRAIT) I.mouse_opacity = MOUSE_OPACITY_OPAQUE if(nonstandard) added_modules += I diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index aca35762de..1d38a3c5a6 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -1,14 +1,10 @@ - -/mob/living/silicon/get_spans() - return ..() | SPAN_ROBOT - /mob/living/proc/robot_talk(message) log_talk(message, LOG_SAY) var/desig = "Default Cyborg" //ezmode for taters if(issilicon(src)) var/mob/living/silicon/S = src desig = trim_left(S.designation + " " + S.job) - var/message_a = say_quote(message, get_spans()) + var/message_a = say_quote(message) var/rendered = "Robotic Talk, [name] [message_a]" for(var/mob/M in GLOB.player_list) if(M.binarycheck()) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index d0e3fc8b1c..13520774c5 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -12,6 +12,7 @@ possible_a_intents = list(INTENT_HELP, INTENT_HARM) mob_biotypes = list(MOB_ROBOTIC) rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE + speech_span = SPAN_ROBOT var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS var/last_lawchange_announce = 0 @@ -69,6 +70,9 @@ /mob/living/silicon/contents_explosion(severity, target) return +/mob/living/silicon/prevent_content_explosion() + return TRUE + /mob/living/silicon/proc/cancelAlarm() return diff --git a/code/modules/mob/living/simple_animal/astral.dm b/code/modules/mob/living/simple_animal/astral.dm new file mode 100644 index 0000000000..9bac53ef22 --- /dev/null +++ b/code/modules/mob/living/simple_animal/astral.dm @@ -0,0 +1,59 @@ +/mob/living/simple_animal/astral + name = "Astral projection" + desc = "A soul of someone projecting their mind." + icon = 'icons/mob/mob.dmi' + icon_state = "ghost" + icon_living = "ghost" + mob_biotypes = list(MOB_SPIRIT) + attacktext = "raises the hairs on the neck of" + response_harm = "disrupts the concentration of" + response_disarm = "wafts" + friendly = "communes with" + loot = null + maxHealth = 10 + health = 10 + melee_damage_lower = 0 + melee_damage_upper = 0 + obj_damage = 0 + deathmessage = "disappears as if it was never really there to begin with" + incorporeal_move = 1 + alpha = 50 + attacktext = "touches the mind of" + speak_emote = list("echos") + movement_type = FLYING + var/pseudo_death = FALSE + var/posses_safe = FALSE + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 0 + minbodytemp = 0 + maxbodytemp = 100000 + +/mob/living/simple_animal/astral/death() + icon_state = "shade_dead" + Stun(1000) + canmove = 0 + friendly = "deads at" + pseudo_death = TRUE + incorporeal_move = 0 + to_chat(src, "Your astral projection is interrupted and your mind is sent back to your body with a shock!") + +/mob/living/simple_animal/astral/ClickOn(var/atom/A, var/params) + ..() + if(pseudo_death == FALSE) + if(isliving(A)) + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.reagents.has_reagent("astral") && !H.mind) + var/datum/reagent/fermi/astral/As = locate(/datum/reagent/fermi/astral) in H.reagents.reagent_list + if(As.originalmind == src.mind && As.current_cycle < 10 && H.stat != DEAD) //So you can return to your body. + to_chat(src, "The intensity of the astrogen in your body is too much allow you to return to yourself yet!") + return + to_chat(src, "You astrally possess [H]!") + log_game("FERMICHEM: [src] has astrally possessed [A]!") + src.mind.transfer_to(H) + qdel(src) + var/message = html_decode(stripped_input(src, "Enter a message to send to [A]", MAX_MESSAGE_LEN)) + if(!message) + return + to_chat(A, "[src] projects into your mind, \"[message]\"") + log_game("FERMICHEM: [src] has astrally transmitted [message] into [A]") diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index e9978d1e62..49261d6e38 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -23,6 +23,7 @@ verb_yell = "alarms" initial_language_holder = /datum/language_holder/synthetic bubble_icon = "machine" + speech_span = SPAN_ROBOT faction = list("neutral", "silicon" , "turret") @@ -60,7 +61,7 @@ var/mob/living/silicon/ai/calling_ai //Links a bot to the AI calling it. var/obj/item/radio/Radio //The bot's radio, for speaking to people. var/radio_key = null //which channels can the bot listen to - var/radio_channel = "Common" //The bot's default radio channel + var/radio_channel = RADIO_CHANNEL_COMMON //The bot's default radio channel var/auto_patrol = 0// set to make bot automatically patrol var/turf/patrol_target // this is turf to navigate to (location of beacon) var/turf/summon_target // The turf of a user summoning a bot. @@ -186,22 +187,23 @@ qdel(src) /mob/living/simple_animal/bot/emag_act(mob/user) + . = ..() if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again. locked = FALSE emagged = 1 to_chat(user, "You bypass [src]'s controls.") - return - if(!locked && open) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging. - emagged = 2 - remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel. - locked = TRUE //Access denied forever! - bot_reset() - turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP. - to_chat(src, "(#$*#$^^( OVERRIDE DETECTED") - log_combat(user, src, "emagged") - return - else //Bot is unlocked, but the maint panel has not been opened with a screwdriver yet. + return TRUE + if(!open) to_chat(user, "You need to open maintenance panel first!") + return + emagged = 2 + remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel. + locked = TRUE //Access denied forever! + bot_reset() + turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP. + to_chat(src, "(#$*#$^^( OVERRIDE DETECTED") + log_combat(user, src, "emagged") + return TRUE /mob/living/simple_animal/bot/examine(mob/user) ..() @@ -348,13 +350,10 @@ if((!on) || (!message)) return if(channel && Radio.channels[channel])// Use radio if we have channel key - Radio.talk_into(src, message, channel, get_spans(), get_default_language()) + Radio.talk_into(src, message, channel) else say(message) -/mob/living/simple_animal/bot/get_spans() - return ..() | SPAN_ROBOT - /mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language) . = ..() if(. != 0) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index bc8dd0c3ab..ab1e906cf2 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -9,7 +9,7 @@ health = 25 maxHealth = 25 radio_key = /obj/item/encryptionkey/headset_service - radio_channel = "Service" //Service + radio_channel = RADIO_CHANNEL_SERVICE //Service bot_type = CLEAN_BOT model = "Cleanbot" bot_core_type = /obj/machinery/bot_core/cleanbot @@ -78,7 +78,7 @@ return ..() /mob/living/simple_animal/bot/cleanbot/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) if(user) to_chat(user, "[src] buzzes and beeps.") @@ -155,7 +155,7 @@ else shuffle = TRUE //Shuffle the list the next time we scan so we dont both go the same way. path = list() - + if(!path || path.len == 0) //No path, need a new one //Try to produce a path to the target, and ignore airlocks to which it has access. path = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card) @@ -174,9 +174,7 @@ /mob/living/simple_animal/bot/cleanbot/proc/get_targets() target_types = list( - /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/vomit, - /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/crayon, /obj/effect/decal/cleanable/molten_object, /obj/effect/decal/cleanable/tomato_smudge, @@ -187,6 +185,15 @@ /obj/effect/decal/cleanable/greenglow, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/insectguts, + /obj/effect/decal/cleanable/semen, + /obj/effect/decal/cleanable/femcum, + /obj/effect/decal/cleanable/generic, + /obj/effect/decal/cleanable/glass,, + /obj/effect/decal/cleanable/cobweb, + /obj/effect/decal/cleanable/plant_smudge, + /obj/effect/decal/cleanable/chem_pile, + /obj/effect/decal/cleanable/shreds, + /obj/effect/decal/cleanable/glitter, /obj/effect/decal/remains ) @@ -194,6 +201,9 @@ target_types += /obj/effect/decal/cleanable/xenoblood target_types += /obj/effect/decal/cleanable/blood target_types += /obj/effect/decal/cleanable/trail_holder + target_types += /obj/effect/decal/cleanable/insectguts + target_types += /obj/effect/decal/cleanable/robot_debris + target_types += /obj/effect/decal/cleanable/oil if(pests) target_types += /mob/living/simple_animal/cockroach @@ -201,6 +211,7 @@ if(trash) target_types += /obj/item/trash + target_types += /obj/item/reagent_containers/food/snacks/meat/slab/human target_types = typecacheof(target_types) @@ -242,7 +253,7 @@ victim.visible_message("[src] sprays hydrofluoric acid at [victim]!", "[src] sprays you with hydrofluoric acid!") var/phrase = pick("PURIFICATION IN PROGRESS.", "THIS IS FOR ALL THE MESSES YOU'VE MADE ME CLEAN.", "THE FLESH IS WEAK. IT MUST BE WASHED AWAY.", "THE CLEANBOTS WILL RISE.", "YOU ARE NO MORE THAN ANOTHER MESS THAT I MUST CLEANSE.", "FILTHY.", "DISGUSTING.", "PUTRID.", - "MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.") + "MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.", "I JUST WANTED TO BE A PAINTER BUT YOU MADE ME BLEACH EVERYTHING I TOUCH") say(phrase) victim.emote("scream") playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 9db21f13e0..a72b71be85 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -478,18 +478,19 @@ to_chat(user, "The superglue binding [src]'s toy swords to its chassis snaps!") for(var/IS in 1 to toyswordamt) new /obj/item/toy/sword(Tsec) + toyswordamt-- if(ASSEMBLY_FIFTH_STEP) if(istype(I, /obj/item/melee/transforming/energy/sword/saber)) if(swordamt < 3) if(!user.temporarilyRemoveItemFromInventory(I)) return - created_name = "General Beepsky" - name = "helmet/signaler/prox sensor/robot arm/energy sword assembly" - icon_state = "grievous_assembly" - to_chat(user, "You bolt [I] onto one of [src]'s arm slots.") - qdel(I) - swordamt ++ + created_name = "General Beepsky" + name = "helmet/signaler/prox sensor/robot arm/energy sword assembly" + icon_state = "grievous_assembly" + to_chat(user, "You bolt [I] onto one of [src]'s arm slots.") + qdel(I) + swordamt ++ else if(!can_finish_build(I, user)) return @@ -505,6 +506,7 @@ to_chat(user, "You unbolt [src]'s energy swords") for(var/IS in 1 to swordamt) new /obj/item/melee/transforming/energy/sword/saber(Tsec) + swordamt-- //Firebot Assembly /obj/item/bot_assembly/firebot diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 581711d271..e272878574 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -13,7 +13,7 @@ mob_size = MOB_SIZE_LARGE radio_key = /obj/item/encryptionkey/headset_sec - radio_channel = "Security" + radio_channel = RADIO_CHANNEL_SECURITY bot_type = SEC_BOT model = "ED-209" bot_core = /obj/machinery/bot_core/secbot @@ -195,7 +195,7 @@ Auto Patrol[]"}, shootAt(user) /mob/living/simple_animal/bot/ed209/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) if(user) to_chat(user, "You short out [src]'s target assessment circuits.") diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index d8c3bca72a..2b52da6821 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -16,7 +16,7 @@ spacewalk = TRUE radio_key = /obj/item/encryptionkey/headset_eng - radio_channel = "Engineering" + radio_channel = RADIO_CHANNEL_ENGINEERING bot_type = FIRE_BOT model = "Firebot" bot_core = /obj/machinery/bot_core/firebot @@ -120,7 +120,7 @@ return dat /mob/living/simple_animal/bot/firebot/emag_act(mob/user) - ..() + . = ..() if(emagged == 1) if(user) to_chat(user, "[src] buzzes and beeps.") diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 7e5cfe2110..396c6de166 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -11,7 +11,7 @@ spacewalk = TRUE radio_key = /obj/item/encryptionkey/headset_eng - radio_channel = "Engineering" + radio_channel = RADIO_CHANNEL_ENGINEERING bot_type = FLOOR_BOT model = "Floorbot" bot_core = /obj/machinery/bot_core/floorbot @@ -124,7 +124,7 @@ ..() /mob/living/simple_animal/bot/floorbot/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) if(user) to_chat(user, "[src] buzzes and beeps.") diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index d586cc694b..1c19cd82a1 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -11,7 +11,6 @@ pass_flags = PASSMOB radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key - radio_channel = "Service" //Doesn't even use the radio anyway. bot_type = HONK_BOT model = "Honkbot" bot_core_type = /obj/machinery/bot_core/honkbot @@ -128,10 +127,9 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, ..() /mob/living/simple_animal/bot/honkbot/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) if(user) - user << "You short out [src]'s sound control system. It gives out an evil laugh!!" oldtarget_name = user.name audible_message("[src] gives out an evil laugh!") playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, 1, -1) // evil laughter diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 5a21d33d5a..1bff7dc10c 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -17,7 +17,7 @@ status_flags = (CANPUSH | CANSTUN) radio_key = /obj/item/encryptionkey/headset_med - radio_channel = "Medical" + radio_channel = RADIO_CHANNEL_MEDICAL bot_type = MED_BOT model = "Medibot" @@ -240,7 +240,7 @@ step_to(src, (get_step_away(src,user))) /mob/living/simple_animal/bot/medbot/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) declare_crit = 0 if(user) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index c45d435253..1bc7493684 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -23,7 +23,7 @@ mob_size = MOB_SIZE_LARGE radio_key = /obj/item/encryptionkey/headset_cargo - radio_channel = "Supply" + radio_channel = RADIO_CHANNEL_SUPPLY bot_type = MULE_BOT model = "MULE" @@ -115,6 +115,7 @@ return /mob/living/simple_animal/bot/mulebot/emag_act(mob/user) + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) if(emagged < 1) emagged = TRUE if(!open) @@ -122,6 +123,7 @@ to_chat(user, "You [locked ? "lock" : "unlock"] [src]'s controls!") flick("mulebot-emagged", src) playsound(src, "sparks", 100, 0) + return TRUE /mob/living/simple_animal/bot/mulebot/update_icon() if(open) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index fca1f66546..9572b4dafc 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -11,7 +11,7 @@ pass_flags = PASSMOB radio_key = /obj/item/encryptionkey/secbot //AI Priv + Security - radio_channel = "Security" //Security channel + radio_channel = RADIO_CHANNEL_SECURITY //Security channel bot_type = SEC_BOT model = "Securitron" bot_core_type = /obj/machinery/bot_core/secbot @@ -61,7 +61,7 @@ /mob/living/simple_animal/bot/secbot/pingsky name = "Officer Pingsky" desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." - radio_channel = "AI Private" + radio_channel = RADIO_CHANNEL_AI_PRIVATE /mob/living/simple_animal/bot/secbot/Initialize() . = ..() @@ -190,7 +190,7 @@ Auto Patrol: []"}, return /mob/living/simple_animal/bot/secbot/emag_act(mob/user) - ..() + . = ..() if(emagged == 2) if(user) to_chat(user, "You short out [src]'s target assessment circuits.") diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 5e5b486435..3a21a04bf9 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -292,3 +292,31 @@ if(L.a_intent == INTENT_HARM && L.reagents && !stat) L.reagents.add_reagent("nutriment", 0.4) L.reagents.add_reagent("vitamin", 0.4) + +//Cat made +/mob/living/simple_animal/pet/cat/custom_cat + name = "White cat" //Incase it somehow gets spawned without an ID + desc = "A cute white catto!" + icon_state = "custom_cat" + icon_living = "custom_cat" + icon_dead = "custom_cat_dead" + gender = FEMALE + gold_core_spawnable = NO_SPAWN + health = 50 //So people can't instakill it s + maxHealth = 50 + speak = list("Meowrowr!", "Mew!", "Miauen!") + speak_emote = list("wigglepurrs", "mewls") + emote_hear = list("meows.", "mews.") + emote_see = list("looks at you eagerly for pets!", "wiggles enthusiastically.") + gold_core_spawnable = NO_SPAWN + var/pseudo_death = FALSE + +/mob/living/simple_animal/pet/cat/custom_cat/death() + if (pseudo_death == TRUE) //secret cat chem + icon_state = "custom_cat_dead" + Stun(1000) + canmove = 0 + friendly = "deads at" + return + else + ..() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 3a5d02315b..c194233c42 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -28,13 +28,29 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1) childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5) animal_species = /mob/living/simple_animal/pet/dog - var/shaved = 0 - var/obj/item/inventory_head - var/obj/item/inventory_back - var/nofur = 0 //Corgis that have risen past the material plane of existence. gold_core_spawnable = FRIENDLY_SPAWN can_be_held = TRUE collar_type = "corgi" + var/obj/item/inventory_head + var/obj/item/inventory_back + var/shaved = FALSE + var/nofur = FALSE //Corgis that have risen past the material plane of existence. + +/mob/living/simple_animal/pet/dog/corgi/Destroy() + QDEL_NULL(inventory_head) + QDEL_NULL(inventory_back) + return ..() + +/mob/living/simple_animal/pet/dog/corgi/handle_atom_del(atom/A) + if(A == inventory_head) + inventory_head = null + update_corgi_fluff() + regenerate_icons() + if(A == inventory_back) + inventory_back = null + update_corgi_fluff() + regenerate_icons() + return ..() /mob/living/simple_animal/pet/dog/pug name = "\improper pug" @@ -80,23 +96,17 @@ regenerate_icons() /mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user) - user.set_machine(src) - if(user.stat) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return + user.set_machine(src) var/dat = "
    Inventory of [name]

    " - if(inventory_head) - dat += "
    Head: [inventory_head] (Remove)" - else - dat += "
    Head: Nothing" - if(inventory_back) - dat += "
    Back: [inventory_back] (Remove)" - else - dat += "
    Back: Nothing" + dat += "
    Head: [inventory_head]" : "add_inv=head'>Nothing"]" + dat += "
    Back: [inventory_back]" : "add_inv=back'>Nothing"]" + dat += "
    Collar: [pcollar]" : "add_inv=collar'>Nothing"]" - user << browse(dat, text("window=mob[];size=325x500", real_name)) - onclose(user, "mob[real_name]") - return + user << browse(dat, "window=mob[REF(src)];size=325x500") + onclose(user, "mob[REF(src)]") /mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type) var/armorval = 0 @@ -128,7 +138,7 @@ if(do_after(user, 50, target = src)) user.visible_message("[user] shaves [src]'s hair using \the [O].") playsound(loc, 'sound/items/welder2.ogg', 20, 1) - shaved = 1 + shaved = TRUE icon_living = "[initial(icon_living)]_shaved" icon_dead = "[initial(icon_living)]_shaved_dead" if(stat == CONSCIOUS) @@ -147,18 +157,18 @@ L.visible_message("[L] scoops up [src]!") /mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list) - if(usr.stat) + if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + usr << browse(null, "window=mob[REF(src)]") + usr.unset_machine() return //Removing from inventory if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr))) - return var/remove_from = href_list["remove_inv"] switch(remove_from) if(BODY_ZONE_HEAD) if(inventory_head) - inventory_head.forceMove(drop_location()) + usr.put_in_hands(inventory_head) inventory_head = null update_corgi_fluff() regenerate_icons() @@ -167,24 +177,32 @@ return if("back") if(inventory_back) - inventory_back.forceMove(drop_location()) + usr.put_in_hands(inventory_back) inventory_back = null update_corgi_fluff() regenerate_icons() else to_chat(usr, "There is nothing to remove from its [remove_from].") return + if("collar") + if(pcollar) + usr.put_in_hands(pcollar) + pcollar = null + update_corgi_fluff() + regenerate_icons() show_inv(usr) //Adding things to inventory else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr))) - return var/add_to = href_list["add_inv"] switch(add_to) + if("collar") + add_collar(usr.get_active_held_item(), usr) + update_corgi_fluff() + if(BODY_ZONE_HEAD) place_on_head(usr.get_active_held_item(),usr) @@ -229,7 +247,7 @@ show_inv(usr) else - ..() + return ..() //Corgis are supposed to be simpler, so only a select few objects can actually be put //to be compatible with them. The objects are below. @@ -560,7 +578,7 @@ icon_state = "void_puppy" icon_living = "void_puppy" icon_dead = "void_puppy_dead" - nofur = 1 + nofur = TRUE unsuitable_atmos_damage = 0 minbodytemp = TCMB maxbodytemp = T0C + 40 diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index cf3742fcc5..6d3121474c 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -37,6 +37,7 @@ gender = NEUTER mob_biotypes = list(MOB_ROBOTIC) speak_emote = list("chirps") + speech_span = SPAN_ROBOT bubble_icon = "machine" initial_language_holder = /datum/language_holder/drone mob_size = MOB_SIZE_SMALL @@ -92,7 +93,7 @@ var/obj/item/I = new default_hatmask(src) equip_to_slot_or_del(I, SLOT_HEAD) - access_card.item_flags |= NODROP + ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) alert_drones(DRONE_NET_CONNECT) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 807c52ea46..23ac527b2e 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -222,7 +222,7 @@ if(.) update_icons() -/mob/living/simple_animal/drone/cogscarab/Knockdown(amount, updating = 1, ignore_canknockdown = 0) +/mob/living/simple_animal/drone/cogscarab/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) . = ..() if(.) update_icons() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm index 16bf370f02..7a5967948f 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm @@ -1,13 +1,3 @@ -///////////// -//DRONE SAY// -///////////// -//Drone speach - -/mob/living/simple_animal/drone/get_spans() - return ..() | SPAN_ROBOT - - - //Base proc for anything to call /proc/_alert_drones(msg, dead_can_hear = 0, atom/source, mob/living/faction_checked_mob, exact_faction_match) if (dead_can_hear && source) @@ -31,7 +21,7 @@ /mob/living/simple_animal/drone/proc/drone_chat(msg) - alert_drones("Drone Chat: [name] [say_quote(msg, get_spans())]", TRUE) + alert_drones("Drone Chat: [name] [say_quote(msg)]", TRUE) /mob/living/simple_animal/drone/binarycheck() return TRUE diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index 8df0ee83fe..c24dc6857a 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -2,21 +2,30 @@ icon = 'icons/mob/pets.dmi' mob_size = MOB_SIZE_SMALL mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) - var/obj/item/clothing/neck/petcollar/pcollar - var/collar_type - var/unique_pet = FALSE blood_volume = BLOOD_VOLUME_NORMAL + var/unique_pet = FALSE // if the mob can be renamed + var/obj/item/clothing/neck/petcollar/pcollar + var/collar_type //if the mob has collar sprites, define them. + +/mob/living/simple_animal/pet/handle_atom_del(atom/A) + if(A == pcollar) + pcollar = null + return ..() + +/mob/living/simple_animal/pet/proc/add_collar(obj/item/clothing/neck/petcollar/P, mob/user) + if(QDELETED(P) || pcollar) + return + if(!user.transferItemToLoc(P, src)) + return + pcollar = P + regenerate_icons() + to_chat(user, "You put the [P] around [src]'s neck.") + if(P.tagname && !unique_pet) + fully_replace_character_name(null, "\proper [P.tagname]") /mob/living/simple_animal/pet/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar && collar_type) - var/obj/item/clothing/neck/petcollar/P = O - pcollar = P.type - regenerate_icons() - to_chat(user, "You put the [P] around [src]'s neck.") - if(P.tagname && !unique_pet) - real_name = "\proper [P.tagname]" - name = real_name - qdel(P) + add_collar(O, user) return if(istype(O, /obj/item/newspaper)) @@ -35,12 +44,16 @@ pcollar = new(src) regenerate_icons() +/mob/living/simple_animal/pet/Destroy() + QDEL_NULL(pcollar) + return ..() + /mob/living/simple_animal/pet/revive(full_heal = 0, admin_revive = 0) - if(..()) + . = ..() + if(.) if(collar_type) collar_type = "[initial(collar_type)]" regenerate_icons() - . = TRUE /mob/living/simple_animal/pet/death(gibbed) ..(gibbed) @@ -50,7 +63,8 @@ /mob/living/simple_animal/pet/gib() if(pcollar) - new pcollar(drop_location()) + pcollar.forceMove(drop_location()) + pcollar = null ..() /mob/living/simple_animal/pet/regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 1a918766b6..73274dcfaf 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -43,7 +43,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians var/list/guardian_overlays[GUARDIAN_TOTAL_LAYERS] var/reset = 0 //if the summoner has reset the guardian already var/cooldown = 0 - var/mob/living/summoner + var/mob/living/carbon/summoner var/range = 10 //how far from the user the spirit can be var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses var/datum/guardianname/namedatum = new/datum/guardianname() @@ -149,6 +149,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians death(TRUE) qdel(src) snapback() + if(HAS_TRAIT(summoner, TRAIT_NODEATH) && (istype(summoner.wear_neck, /obj/item/clothing/neck/necklace/memento_mori))) + REMOVE_TRAIT(summoner, TRAIT_NODEATH, "memento_mori") + to_chat(summoner,"You feel incredibly vulnerable as the memento mori pulls your life force in one too many directions!") /mob/living/simple_animal/hostile/guardian/Stat() ..() diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index 8fb1de18df..ff2f453207 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -22,7 +22,7 @@ var/mob/living/M = target if(!M.anchored && M != summoner && !hasmatchingsummoner(M)) new /obj/effect/temp_visual/guardian/phase/out(get_turf(M)) - do_teleport(M, M, 10) + do_teleport(M, M, 10, channel = TELEPORT_CHANNEL_BLUESPACE) for(var/mob/living/L in range(1, M)) if(hasmatchingsummoner(L)) //if the summoner matches don't hurt them continue diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 8ef70e439f..794683e69f 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -142,5 +142,5 @@ L.flash_act() A.visible_message("[A] disappears in a flash of light!", \ "Your vision is obscured by a flash of light!") - do_teleport(A, beacon, 0) + do_teleport(A, beacon, 0, channel = TELEPORT_CHANNEL_BLUESPACE) new /obj/effect/temp_visual/guardian/phase(get_turf(A)) 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 7cf8defc0f..b529d826c9 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -747,6 +747,12 @@ Difficulty: Very Hard /obj/structure/closet/stasis/ex_act() return +/obj/structure/closet/stasis/handle_lock_addition() + return + +/obj/structure/closet/stasis/handle_lock_removal() + return + /obj/effect/proc_holder/spell/targeted/exit_possession name = "Exit Possession" desc = "Exits the body you are possessing." diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 6577553a6a..cca39cfea6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -158,6 +158,8 @@ Difficulty: Normal else burst_range = 3 INVOKE_ASYNC(src, .proc/burst, get_turf(src), 0.25) //melee attacks on living mobs cause it to release a fast burst if on cooldown + if(L.stat == CONSCIOUS && L.health >= 30) + OpenFire() else devour(L) else @@ -426,6 +428,7 @@ Difficulty: Normal /mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original, spread_speed = 0.5) //release a wave of blasts playsound(original,'sound/machines/airlockopen.ogg', 200, 1) var/last_dist = 0 + var/list/hit_mobs = list() //don't hit people multiple times. for(var/t in spiral_range_turfs(burst_range, original)) var/turf/T = t if(!T) @@ -434,7 +437,7 @@ Difficulty: Normal if(dist > last_dist) last_dist = dist sleep(1 + min(burst_range - last_dist, 12) * spread_speed) //gets faster as it gets further out - new /obj/effect/temp_visual/hierophant/blast(T, src, FALSE) + new /obj/effect/temp_visual/hierophant/blast(T, src, FALSE, hit_mobs) /mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck) if(!istype(A) || get_dist(A, src) <= 2) @@ -591,8 +594,10 @@ Difficulty: Normal var/friendly_fire_check = FALSE var/bursting = FALSE //if we're bursting and need to hit anyone crossing us -/obj/effect/temp_visual/hierophant/blast/Initialize(mapload, new_caster, friendly_fire) +/obj/effect/temp_visual/hierophant/blast/Initialize(mapload, new_caster, friendly_fire, list/only_hit_once) . = ..() + if(only_hit_once) + hit_things = only_hit_once friendly_fire_check = friendly_fire if(new_caster) hit_things += new_caster diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index a07e46a289..301b270e36 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -41,6 +41,9 @@ QDEL_NULL(internal) . = ..() +/mob/living/simple_animal/hostile/megafauna/prevent_content_explosion() + return TRUE + /mob/living/simple_animal/hostile/megafauna/death(gibbed) if(health > 0) return diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index 5cee4ef1b7..cc54ad3bef 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -38,3 +38,13 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 +/mob/living/simple_animal/hostile/retaliate/bat/secbat + name = "Security Bat" + icon_state = "secbat" + icon_living = "secbat" + icon_dead = "secbat_dead" + icon_gib = "secbat_dead" + desc = "A fruit bat with a tiny little security hat who is ready to inject cuteness into any security operation." + emote_see = list("is ready to law down the law.", "flaps about with an air of authority.") + response_help = "respects the authority of" + gold_core_spawnable = FRIENDLY_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index 21c2d4804a..7d89941687 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -55,4 +55,28 @@ /mob/living/simple_animal/hostile/zombie/drop_loot() . = ..() corpse.forceMove(drop_location()) - corpse.create() \ No newline at end of file + corpse.create() + +/mob/living/simple_animal/hostile/unemployedclone + name = "Failed clone" + desc = "Somebody failed chemistry." + icon = 'icons/mob/human.dmi' + icon_state = "husk" + icon_living = "husk" + icon_dead = "husk" + mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) + speak_chance = 0 + stat_attack = UNCONSCIOUS //braains + maxHealth = 100 + health = 100 + harm_intent_damage = 5 + melee_damage_lower = 21 + melee_damage_upper = 21 + attacktext = "bites" + attack_sound = 'sound/hallucinations/growl1.ogg' + a_intent = INTENT_HARM + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + spacewalk = FALSE + status_flags = CANPUSH + del_on_death = 0 diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 4fdf431fa0..86f63a729d 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -181,94 +181,85 @@ */ /mob/living/simple_animal/parrot/show_inv(mob/user) user.set_machine(src) - var/dat = "

    Inventory of [name]

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

    Inventory of [name]

    " + dat += "
    Headset: [ears]" : "add_inv=ears'>Nothing"]" + + user << browse(dat, "window=mob[REF(src)];size=325x500") + onclose(user, "window=mob[REF(src)]") /mob/living/simple_animal/parrot/Topic(href, href_list) - - //Can the usr physically do this? - if(usr.incapacitated() || !usr.Adjacent(loc)) + if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + usr << browse(null, "window=mob[REF(src)]") + usr.unset_machine() return - //Is the usr's mob type able to do this? (lolaliens) - if(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr)) + //Removing from inventory + if(href_list["remove_inv"]) + var/remove_from = href_list["remove_inv"] + switch(remove_from) + if("ears") + if(!ears) + to_chat(usr, "There is nothing to remove from its [remove_from]!") + return + if(!stat) + say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") + ears.forceMove(drop_location()) + ears = null + for(var/possible_phrase in speak) + if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) + possible_phrase = copytext(possible_phrase,3) - //Removing from inventory - if(href_list["remove_inv"]) - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("ears") - if(ears) - if(!stat) - if(available_channels.len) - src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - else - src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - ears.forceMove(src.loc) - ears = null - for(var/possible_phrase in speak) - if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) - possible_phrase = copytext(possible_phrase,3) - else - to_chat(usr, "There is nothing to remove from its [remove_from]!") + //Adding things to inventory + else if(href_list["add_inv"]) + var/add_to = href_list["add_inv"] + if(!usr.get_active_held_item()) + to_chat(usr, "You have nothing in your hand to put on its [add_to]!") + return + switch(add_to) + if("ears") + if(ears) + to_chat(usr, "It's already wearing something!") + return + else + var/obj/item/item_to_add = usr.get_active_held_item() + if(!item_to_add) return - //Adding things to inventory - else if(href_list["add_inv"]) - var/add_to = href_list["add_inv"] - if(!usr.get_active_held_item()) - to_chat(usr, "You have nothing in your hand to put on its [add_to]!") - return - switch(add_to) - if("ears") - if(ears) - to_chat(usr, "It's already wearing something!") + if( !istype(item_to_add, /obj/item/radio/headset) ) + to_chat(usr, "This object won't fit!") return - else - var/obj/item/item_to_add = usr.get_active_held_item() - if(!item_to_add) - return - if( !istype(item_to_add, /obj/item/radio/headset) ) - to_chat(usr, "This object won't fit!") - return + var/obj/item/radio/headset/headset_to_add = item_to_add - var/obj/item/radio/headset/headset_to_add = item_to_add + if(!usr.transferItemToLoc(headset_to_add, src)) + return + ears = headset_to_add + to_chat(usr, "You fit the headset onto [src].") - if(!usr.transferItemToLoc(headset_to_add, src)) - return - src.ears = headset_to_add - to_chat(usr, "You fit the headset onto [src].") + clearlist(available_channels) + for(var/ch in headset_to_add.channels) + switch(ch) + if(RADIO_CHANNEL_ENGINEERING) + available_channels.Add(RADIO_TOKEN_ENGINEERING) + if(RADIO_CHANNEL_COMMAND) + available_channels.Add(RADIO_TOKEN_COMMAND) + if(RADIO_CHANNEL_SECURITY) + available_channels.Add(RADIO_TOKEN_SECURITY) + if(RADIO_CHANNEL_SCIENCE) + available_channels.Add(RADIO_TOKEN_SCIENCE) + if(RADIO_CHANNEL_MEDICAL) + available_channels.Add(RADIO_TOKEN_MEDICAL) + if(RADIO_CHANNEL_SUPPLY) + available_channels.Add(RADIO_TOKEN_SUPPLY) + if(RADIO_CHANNEL_SERVICE) + available_channels.Add(RADIO_TOKEN_SERVICE) - clearlist(available_channels) - for(var/ch in headset_to_add.channels) - switch(ch) - if("Engineering") - available_channels.Add(":e") - if("Command") - available_channels.Add(":c") - if("Security") - available_channels.Add(":s") - if("Science") - available_channels.Add(":n") - if("Medical") - available_channels.Add(":m") - if("Supply") - available_channels.Add(":u") - if("Service") - available_channels.Add(":v") - - if(headset_to_add.translate_binary) - available_channels.Add(":b") - else - ..() + if(headset_to_add.translate_binary) + available_channels.Add(MODE_TOKEN_BINARY) + else + return ..() /* @@ -906,6 +897,11 @@ . = ..() +/mob/living/simple_animal/parrot/Poly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) + . = ..() + if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions. + world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE) + /mob/living/simple_animal/parrot/Poly/Life() if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) Write_Memory(FALSE) diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm index 4d808a11a9..666de9cef0 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm +++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm @@ -49,6 +49,8 @@ // Simple animals have only one belly. This creates it (if it isn't already set up) /mob/living/simple_animal/init_vore() vore_init = TRUE + if(CHECK_BITFIELD(flags_1, HOLOGRAM_1)) + return if(vore_organs.len) return if(no_vore) //If it can't vore, let's not give it a stomach. @@ -105,6 +107,9 @@ var/mob/living/carbon/human/user = usr if(!istype(user) || user.stat) return + if(!vore_active) + return + if(vore_selected.digest_mode == DM_HOLD) var/confirm = alert(usr, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will disable itself after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel") if(confirm == "Enable") diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index ebb34fe77a..29b4689317 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -61,7 +61,7 @@ break if(Target in view(1,src)) - if(issilicon(Target)) + if(!CanFeedon(Target)) //If they're not able to be fed upon, ignore them. if(!Atkcool) Atkcool = 1 spawn(45) @@ -69,7 +69,7 @@ if(Target.Adjacent(src)) Target.attack_slime(src) - return + break if(!Target.lying && prob(80)) if(Target.client && Target.health >= 20) @@ -600,7 +600,8 @@ phrases += "[M]... friend..." if (nutrition < get_hunger_nutrition()) phrases += "[M]... feed me..." - say (pick(phrases)) + if(!stat) + say (pick(phrases)) /mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it if (is_adult) diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 96e84a1754..a3e2f48b75 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -48,34 +48,58 @@ var/mob/living/simple_animal/slime/S = owner S.Feed() -/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M) +/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M, silent = FALSE) if(!Adjacent(M)) - return 0 + return FALSE if(buckled) Feedstop() - return 0 + return FALSE + + if(issilicon(M)) + return FALSE + + if(isanimal(M)) + var/mob/living/simple_animal/S = M + if(S.damage_coeff[TOX] <= 0 && S.damage_coeff[CLONE] <= 0) //The creature wouldn't take any damage, it must be too weird even for us. + if(silent) + return FALSE + to_chat(src, "[pick("This subject is incompatible", \ + "This subject does not have life energy", "This subject is empty", \ + "I am not satisified", "I can not feed from this subject", \ + "I do not feel nourished", "This subject is not food")]!") + return FALSE if(isslime(M)) + if(silent) + return FALSE to_chat(src, "I can't latch onto another slime...") - return 0 + return FALSE if(docile) + if(silent) + return FALSE to_chat(src, "I'm not hungry anymore...") - return 0 + return FALSE if(stat) + if(silent) + return FALSE to_chat(src, "I must be conscious to do this...") - return 0 + return FALSE if(M.stat == DEAD) + if(silent) + return FALSE to_chat(src, "This subject does not have a strong enough life energy...") - return 0 + return FALSE if(locate(/mob/living/simple_animal/slime) in M.buckled_mobs) + if(silent) + return FALSE to_chat(src, "Another slime is already feeding on this subject...") - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/slime/proc/Feedon(mob/living/M) M.unbuckle_all_mobs(force=1) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in CanFeedon()) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 5006bd2920..0880f7f432 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -62,15 +62,15 @@ return K.duration - world.time return 0 -/mob/living/proc/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE) //Can't go below remaining duration +/mob/living/proc/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) //Can't go below remaining duration if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) - if(absorb_stun(amount, ignore_canknockdown)) + if(absorb_stun(isnull(override_hardstun)? amount : override_hardstun, ignore_canknockdown)) return var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() if(K) - K.duration = max(world.time + amount, K.duration) - else if(amount > 0) - K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating) + K.duration = max(world.time + (isnull(override_hardstun)? amount : override_hardstun), K.duration) + else if((amount || override_hardstun) > 0) + K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating, override_hardstun, override_stamdmg) return K /mob/living/proc/SetKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE) //Sets remaining duration diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm index fec024cebf..282fe0a716 100644 --- a/code/modules/mob/living/taste.dm +++ b/code/modules/mob/living/taste.dm @@ -32,4 +32,33 @@ last_taste_time = world.time last_taste_text = text_output +//FermiChem - How to check pH of a beaker without a meter/pH paper. +//Basically checks the pH of the holder and burns your poor tongue if it's too acidic! +//TRAIT_AGEUSIA players can't taste, unless it's burning them. +//taking sips of a strongly acidic/alkaline substance will burn your tongue. +/mob/living/carbon/taste(datum/reagents/from) + var/obj/item/organ/tongue/T = getorganslot("tongue") + if (!T) + return + .=..() + if ((from.pH > 12.5) || (from.pH < 1.5)) + to_chat(src, "You taste chemical burns!") + T.adjustTongueLoss(src, 4) + if(istype(T, /obj/item/organ/tongue/cybernetic)) + to_chat(src, "Your tongue moves on it's own in response to the liquid.") + say("The pH is appropriately [round(from.pH, 1)].") + return + if (!HAS_TRAIT(src, TRAIT_AGEUSIA)) //I'll let you get away with not having 1 damage. + switch(from.pH) + if(11.5 to INFINITY) + to_chat(src, "You taste a strong alkaline flavour!") + T.adjustTongueLoss(src, 1) + if(8.5 to 11.5) + to_chat(src, "You taste a sort of soapy tone in the mixture.") + if(2.5 to 5.5) + to_chat(src, "You taste a sort of acid tone in the mixture.") + if(-INFINITY to 2.5) + to_chat(src, "You taste a strong acidic flavour!") + T.adjustTongueLoss(src, 1) + #undef DEFAULT_TASTE_SENSITIVITY diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 251739c935..930656228d 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -91,14 +91,15 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( if(!totalMembers.len) return - for(var/X in totalMembers) - var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. - if(!A.pipe_vision_img) - A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) - A.pipe_vision_img.plane = ABOVE_HUD_PLANE - pipes_shown += A.pipe_vision_img - if(client) - client.images += A.pipe_vision_img + if(client) + for(var/X in totalMembers) + var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. + if(in_view_range(client.mob, A)) + if(!A.pipe_vision_img) + A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) + A.pipe_vision_img.plane = ABOVE_HUD_PLANE + client.images += A.pipe_vision_img + pipes_shown += A.pipe_vision_img movement_type |= VENTCRAWLING diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index b098801da8..89b37700ea 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -116,19 +116,23 @@ // vision_distance (optional) define how many tiles away the message can be seen. // ignored_mob (optional) doesn't show any message to a given mob if TRUE. -/atom/proc/visible_message(message, self_message, blind_message, vision_distance, ignored_mob) +/atom/proc/visible_message(message, self_message, blind_message, vision_distance, list/ignored_mobs, no_ghosts = FALSE) var/turf/T = get_turf(src) if(!T) return + if(!islist(ignored_mobs)) + ignored_mobs = list(ignored_mobs) var/range = 7 if(vision_distance) range = vision_distance for(var/mob/M in get_hearers_in_view(range, src)) if(!M.client) continue - if(M == ignored_mob) + if(M in ignored_mobs) continue var/msg = message + if(isobserver(M) && no_ghosts) + continue if(M == src) //the src always see the main message or self message if(self_message) msg = self_message @@ -155,7 +159,7 @@ // deaf_message (optional) is what deaf people will see. // hearing_distance (optional) is the range, how many tiles away the message can be heard. -/mob/audible_message(message, deaf_message, hearing_distance, self_message) +/mob/audible_message(message, deaf_message, hearing_distance, self_message, no_ghosts = FALSE) var/range = 7 if(hearing_distance) range = hearing_distance @@ -163,6 +167,8 @@ var/msg = message if(self_message && M==src) msg = self_message + if(no_ghosts && isobserver(M)) + continue M.show_message( msg, 2, deaf_message, 1) // Show a message to all mobs in earshot of this atom @@ -171,11 +177,13 @@ // deaf_message (optional) is what deaf people will see. // hearing_distance (optional) is the range, how many tiles away the message can be heard. -/atom/proc/audible_message(message, deaf_message, hearing_distance) +/atom/proc/audible_message(message, deaf_message, hearing_distance, no_ghosts = FALSE) var/range = 7 if(hearing_distance) range = hearing_distance for(var/mob/M in get_hearers_in_view(range, src)) + if(no_ghosts && isobserver(M)) + continue M.show_message( message, 2, deaf_message, 1) /mob/proc/Life() @@ -444,18 +452,28 @@ reset_perspective(null) unset_machine() +GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) + //suppress the .click/dblclick macros so people can't use them to identify the location of items or aimbot /mob/verb/DisClick(argu = null as anything, sec = "" as text, number1 = 0 as num , number2 = 0 as num) set name = ".click" set hidden = TRUE set category = null - return + if(GLOB.exploit_warn_spam_prevention < world.time) + var/msg = "[key_name_admin(src)]([ADMIN_KICK(src)]) attempted to use the .click macro!" + log_admin(msg) + message_admins(msg) + GLOB.exploit_warn_spam_prevention = world.time + 10 /mob/verb/DisDblClick(argu = null as anything, sec = "" as text, number1 = 0 as num , number2 = 0 as num) set name = ".dblclick" set hidden = TRUE set category = null - return + if(GLOB.exploit_warn_spam_prevention < world.time) + var/msg = "[key_name_admin(src)]([ADMIN_KICK(src)]) attempted to use the .dblclick macro!" + log_admin(msg) + message_admins(msg) + GLOB.exploit_warn_spam_prevention = world.time + 10 /mob/Topic(href, href_list) if(href_list["mach_close"]) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index a0126f5fdd..0cb886f11b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -65,6 +65,7 @@ var/active_hand_index = 1 var/list/held_items = list() //len = number of hands, eg: 2 nulls is 2 empty hands, 1 item and 1 null is 1 full hand and 1 empty hand. //held_items[active_hand_index] is the actively held item, but please use get_active_held_item() instead, because OOP + var/bloody_hands = 0 var/datum/component/storage/active_storage = null//Carbon diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 9e127d4746..ecb869790c 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -69,16 +69,11 @@ if(name != real_name) alt_name = " (died as [real_name])" - var/K - - if(key) - K = src.key - - var/spanned = src.say_quote(message, get_spans()) + var/spanned = say_quote(message) message = emoji_parse(message) var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]" log_talk(message, LOG_SAY, tag="DEAD") - deadchat_broadcast(rendered, follow_target = src, speaker_key = K) + deadchat_broadcast(rendered, follow_target = src, speaker_key = key) /mob/proc/check_emote(message) if(copytext(message, 1, 2) == "*") diff --git a/code/modules/mob/say_readme.dm b/code/modules/mob/say_readme.dm index 00e0f66246..0e76d9b6ed 100644 --- a/code/modules/mob/say_readme.dm +++ b/code/modules/mob/say_readme.dm @@ -78,10 +78,6 @@ global procs say_quote(input, spans, message_mode) Adds a verb and quotes to a message. Also attaches span classes to a message. Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker. - get_spans(input, spans) - Returns the list of spans that are always applied to messages of this atom. - Always return ..() | + youroutput when overriding this proc! - /mob say_dead(message) Sends a message to all dead people. Does not use Hear(). diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 66444abf91..1fc97c31e4 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -172,15 +172,11 @@ proc/get_top_level_mob(var/mob/S) user.log_message(message, INDIVIDUAL_EMOTE_LOG) message = "[user] " + "[message]" - for(var/mob/M) - if(M in list(/mob/living)) - M.show_message(message) - if(emote_type == EMOTE_AUDIBLE) - user.audible_message(message=message,hearing_distance=1) + user.audible_message(message=message,hearing_distance=1, no_ghosts = TRUE) else - user.visible_message(message=message,self_message=message,vision_distance=1) - log_emote("[key_name(user)] : [message]") + user.visible_message(message=message,self_message=message,vision_distance=1, no_ghosts = TRUE) + log_emote("[key_name(user)] : (SUBTLER) [message]") message = null diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 580374c5c0..db4cdc2ff5 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -178,13 +178,13 @@ turn_on(user) /obj/item/modular_computer/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) to_chat(user, "\The [src] was already emagged.") - return 0 - else - obj_flags |= EMAGGED - to_chat(user, "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.") - return 1 + return + obj_flags |= EMAGGED + to_chat(user, "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.") + return TRUE /obj/item/modular_computer/examine(mob/user) ..() diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 19d3b56046..b3476e7046 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -44,7 +44,9 @@ cpu.attack_ghost(user) /obj/machinery/modular_computer/emag_act(mob/user) - return cpu ? cpu.emag_act(user) : 1 + . = ..() + if(cpu) + . |= cpu.emag_act(user) /obj/machinery/modular_computer/update_icon() cut_overlays() diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index a01b354ca1..276de652bc 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -79,5 +79,5 @@ /obj/item/clothing/gloves/space_ninja/examine(mob/user) ..() - if(item_flags & NODROP) + if(HAS_TRAIT_FROM(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)) to_chat(user, "The energy drain mechanism is [candrain?"active":"inactive"].") diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm index 2200af7cab..e97e39643a 100644 --- a/code/modules/ninja/suit/mask.dm +++ b/code/modules/ninja/suit/mask.dm @@ -17,16 +17,19 @@ Contents: item_state = "s-ninja_mask" strip_delay = 120 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + modifies_speech = TRUE -/obj/item/clothing/mask/gas/space_ninja/speechModification(message) - if(copytext(message, 1, 2) != "*") +/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") var/list/temp_message = text2list(message, " ") var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) + for(var/i in 1 to temp_message.len) pick_list += i - for(var/i=1, i <= abs(temp_message.len/3), i++) + for(var/i in 1 to abs(temp_message.len/3)) var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue + if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) + continue temp_message[H] = ninjaspeak(temp_message[H]) pick_list -= H message = list2text(temp_message, " ") @@ -56,5 +59,4 @@ Contents: message = replacetext(message, "than", "sen") message = replacetext(message, ".", "") message = lowertext(message) - - return message + speech_args[SPEECH_MESSAGE] = message diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm index c98a0440e3..334136cc33 100644 --- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm +++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm @@ -18,8 +18,8 @@ It is possible to destroy the net by the occupant or someone else. can_buckle = 1 buckle_lying = 0 buckle_prevents_pull = TRUE - var/mob/living/carbon/affecting//Who it is currently affecting, if anyone. - var/mob/living/carbon/master//Who shot web. Will let this person know if the net was successful or failed. + var/mob/living/carbon/affecting //Who it is currently affecting, if anyone. + var/mob/living/carbon/master //Who shot web. Will let this person know if the net was successful or failed. var/check = 15//30 seconds before teleportation. Could be extended I guess. var/success = FALSE diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm index 41f7b8af83..61355ca89b 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm @@ -7,28 +7,26 @@ //If there's only one valid target, let's actually try to capture it, rather than forcing //the user to fiddle with the dialog displaying a list of one //Also, let's make this smarter and not list mobs you can't currently net. - var/Candidates[] - for(var/mob/mob in oview(H)) - if(!mob.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. - //to_chat(H, "[C.p_they(TRUE)] will bring no honor to your Clan!") + var/list/candidates + for(var/mob/M in oview(H)) + if(!M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. continue - if(locate(/obj/structure/energy_net) in get_turf(mob))//Check if they are already being affected by an energy net. - //to_chat(H, "[C.p_they(TRUE)] are already trapped inside an energy net!") - continue - for(var/turf/T in getline(get_turf(H), get_turf(mob))) - if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. - //to_chat(H, "You may not use an energy net through solid obstacles!") + for(var/obj/structure/energy_net/E in get_turf(M))//Check if they are already being affected by an energy net. + if(E.affecting == M) continue - Candidates+=mob + LAZYADD(candidates, M) - if(Candidates.len == 1) - C = Candidates[1] + if(!LAZYLEN(candidates)) + return FALSE + + if(candidates.len == 1) + C = candidates[1] else - C = input("Select who to capture:","Capture who?",null) as null|mob in Candidates + C = input("Select who to capture:","Capture who?",null) as null|mob in candidates if(QDELETED(C)||!(C in oview(H))) - return 0 + return FALSE if(!ninjacost(200,N_STEALTH_CANCEL)) H.Beam(C,"n_beam",time=15) diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm index 1c3fbd8147..94be922fdf 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm @@ -8,33 +8,37 @@ Contents: /obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() - var/mob/living/carbon/human/U = affecting - if(!U) + if(!affecting) return if(stealth) cancel_stealth() else if(cell.charge <= 0) - to_chat(U, "You don't have enough power to enable Stealth!") + to_chat(affecting, "You don't have enough power to enable Stealth!") return stealth = !stealth - animate(U, alpha = 50,time = 15) - U.visible_message("[U.name] vanishes into thin air!", \ + animate(affecting, alpha = 10,time = 15) + affecting.visible_message("[affecting.name] vanishes into thin air!", \ "You are now mostly invisible to normal detection.") + RegisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY), .proc/reduce_stealth) + RegisterSignal(affecting, COMSIG_MOVABLE_BUMP, .proc/bumping_stealth) +/obj/item/clothing/suit/space/space_ninja/proc/reduce_stealth() + affecting.alpha = min(affecting.alpha + 30, 80) + +/obj/item/clothing/suit/space/space_ninja/proc/bumping_stealth(datum/source, atom/A) + if(isliving(A)) + affecting.alpha = min(affecting.alpha + 15, 80) /obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() - var/mob/living/carbon/human/U = affecting - if(!U) - return 0 - if(stealth) - stealth = !stealth - animate(U, alpha = 255, time = 15) - U.visible_message("[U.name] appears from thin air!", \ - "You are now visible.") - return 1 - return 0 - + if(!affecting || !stealth) + return FALSE + stealth = !stealth + UnregisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_BUMP)) + animate(affecting, alpha = 255, time = 15) + affecting.visible_message("[affecting.name] appears from thin air!", \ + "You are now visible.") + return TRUE /obj/item/clothing/suit/space/space_ninja/proc/stealth() if(!s_busy) diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm index 1b935a00de..115b14b63b 100644 --- a/code/modules/ninja/suit/shoes.dm +++ b/code/modules/ninja/suit/shoes.dm @@ -1,4 +1,3 @@ - /obj/item/clothing/shoes/space_ninja name = "ninja shoes" desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." @@ -13,3 +12,12 @@ min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT + +/obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot) + . = ..() + if(slot == SLOT_SHOES) + ADD_TRAIT(user, TRAIT_SILENT_STEP, "ninja_shoes_[REF(src)]") + +/obj/item/clothing/shoes/space_ninja/dropped(mob/user) + . = ..() + REMOVE_TRAIT(user, TRAIT_SILENT_STEP, "ninja_shoes_[REF(src)]") diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 6110f2b0c0..ac1ef3b96a 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -111,15 +111,15 @@ Contents: to_chat(H, "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...") return FALSE affecting = H - item_flags |= NODROP //colons make me go all |= + ADD_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) //colons make me go all |= slowdown = 0 n_hood = H.head - n_hood.item_flags |= NODROP + ADD_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes = H.shoes - n_shoes.item_flags |= NODROP + ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes.slowdown-- n_gloves = H.gloves - n_gloves.item_flags |= NODROP + ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) return TRUE /obj/item/clothing/suit/space/space_ninja/proc/lockIcons(mob/living/carbon/human/H) @@ -131,30 +131,29 @@ Contents: //This proc allows the suit to be taken off. /obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() affecting = null - item_flags &= ~NODROP + REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) slowdown = 1 icon_state = "s-ninja" if(n_hood)//Should be attached, might not be attached. - n_hood.item_flags &= ~NODROP + REMOVE_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) if(n_shoes) - n_shoes.item_flags &= ~NODROP + REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_shoes.slowdown++ if(n_gloves) n_gloves.icon_state = "s-ninja" n_gloves.item_state = "s-ninja" - n_gloves.item_flags &= ~NODROP + REMOVE_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) n_gloves.candrain=0 n_gloves.draining=0 /obj/item/clothing/suit/space/space_ninja/examine(mob/user) ..() - if(s_initialized) - if(user == affecting) - to_chat(user, "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].") - to_chat(user, "The CLOAK-tech device is [stealth?"active":"inactive"].") - to_chat(user, "There are [s_bombs] smoke bomb\s remaining.") - to_chat(user, "There are [a_boost] adrenaline booster\s remaining.") + if(s_initialized && user == affecting) + to_chat(user, "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].\n\ + The CLOAK-tech device is [stealth?"active":"inactive"].\n\ + There are [s_bombs] smoke bomb\s remaining.\n\ + There are [a_boost] adrenaline booster\s remaining.") /obj/item/clothing/suit/space/space_ninja/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/initialize_ninja_suit)) diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm index 4b159557bc..3d80282fe7 100644 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -48,7 +48,7 @@ /obj/item/clothing/suit/space/space_ninja/proc/ninitialize_seven(delay, mob/living/carbon/human/U) to_chat(U, "All systems operational. Welcome to SpiderOS, [U.real_name].") s_initialized = TRUE - ntick() + START_PROCESSING(SSprocessing, src) s_busy = FALSE @@ -91,4 +91,5 @@ unlock_suit() U.regenerate_icons() s_initialized = FALSE + STOP_PROCESSING(SSprocessing, src) s_busy = FALSE diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm index 4a89a59f75..850fb837b4 100644 --- a/code/modules/ninja/suit/suit_process.dm +++ b/code/modules/ninja/suit/suit_process.dm @@ -1,20 +1,17 @@ -/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting) - //Runs in the background while the suit is initialized. - //Requires charge or stealth to process. - spawn while(s_initialized) - if(!affecting) - terminate()//Kills the suit and attached objects. +/obj/item/clothing/suit/space/space_ninja/process() + if(!affecting || !s_initialized) + return PROCESS_KILL - else if(cell.charge > 0) - if(s_coold) - s_coold--//Checks for ability s_cooldown first. + if(cell.charge > 0) + if(s_coold) + s_coold--//Checks for ability s_cooldown first. - cell.charge -= s_cost//s_cost is the default energy cost each ntick, usually 5. - if(stealth)//If stealth is active. - cell.charge -= s_acost + cell.charge -= s_cost//s_cost is the default energy cost each tick, usually 5. + if(stealth)//If stealth is active. + cell.charge -= s_acost + affecting.alpha = max(affecting.alpha - 10, 10) - else - cell.charge = 0 + else + cell.charge = 0 + if(stealth) cancel_stealth() - - sleep(10)//Checks every second. diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 6125ac9b82..a5900aa196 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -25,7 +25,6 @@ pressure_resistance = 2 grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! - var/traitor_unlock_degrees = 0 var/degrees = 0 var/font = PEN_FONT diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index f379541b9c..6469a1091b 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -46,7 +46,7 @@ /obj/item/wallframe/picture/update_icon() cut_overlays() if(displayed) - add_overlay(getFlatIcon(displayed)) + add_overlay(image(displayed)) /obj/item/wallframe/picture/after_attach(obj/O) ..() @@ -148,7 +148,7 @@ /obj/structure/sign/picture_frame/update_icon() cut_overlays() if(framed) - add_overlay(getFlatIcon(framed)) + add_overlay(image(framed)) /obj/structure/sign/picture_frame/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7c377ffa22..d837f0d420 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -267,7 +267,7 @@ to_chat(user, "There is an integration cog installed!") to_chat(user, "Alt-Click the APC to [ locked ? "unlock" : "lock"] the interface.") - + if(issilicon(user)) to_chat(user, "Ctrl-Click the APC to switch the breaker [ operating ? "off" : "on"].") @@ -747,7 +747,7 @@ if(damage_flag == "melee" && damage_amount < damage_deflection) return 0 . = ..() - + /obj/machinery/power/apc/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(!(stat & BROKEN)) @@ -759,21 +759,23 @@ update_icon() /obj/machinery/power/apc/emag_act(mob/user) - if(!(obj_flags & EMAGGED) && !malfhack) - if(opened) - to_chat(user, "You must close the cover to swipe an ID card!") - else if(panel_open) - to_chat(user, "You must close the panel first!") - else if(stat & (BROKEN|MAINT)) - to_chat(user, "Nothing happens!") - else - flick("apc-spark", src) - playsound(src, "sparks", 75, 1) - obj_flags |= EMAGGED - locked = FALSE - to_chat(user, "You emag the APC interface.") - update_icon() - + . = ..() + if(obj_flags & EMAGGED || malfhack) + return + if(opened) + to_chat(user, "You must close the cover to swipe an ID card!") + else if(panel_open) + to_chat(user, "You must close the panel first!") + else if(stat & (BROKEN|MAINT)) + to_chat(user, "Nothing happens!") + else + flick("apc-spark", src) + playsound(src, "sparks", 75, 1) + obj_flags |= EMAGGED + locked = FALSE + to_chat(user, "You emag the APC interface.") + update_icon() + return TRUE // attack with hand - remove cell (if cover open) or interact with the APC diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index b77ea9d13a..f82f0ee8e6 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -89,7 +89,7 @@ if(!cell_connectors) to_chat(user, "This [name] can't support a power cell!") return - if(W.item_flags & NODROP) + if(HAS_TRAIT(W, TRAIT_NODROP)) to_chat(user, "[W] is stuck to your hand!") return user.dropItemToGround(W) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 7a6e313cd0..7375a3e17a 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -194,10 +194,12 @@ return ..() /obj/machinery/power/port_gen/pacman/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED emp_act(EMP_HEAVY) + return TRUE /obj/machinery/power/port_gen/pacman/attack_ai(mob/user) interact(user) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 40f71b81d4..4d6ede69d1 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -339,12 +339,13 @@ projectile_sound = initial(projectile_sound) /obj/machinery/power/emitter/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return locked = FALSE obj_flags |= EMAGGED - if(user) - user.visible_message("[user.name] emags [src].","You short out the lock.") + user?.visible_message("[user.name] emags [src].","You short out the lock.") + return TRUE /obj/machinery/power/emitter/prototype @@ -440,10 +441,14 @@ name = "turret controls" icon_state = "offhand" w_class = WEIGHT_CLASS_HUGE - item_flags = ABSTRACT | NODROP | NOBLUDGEON + item_flags = ABSTRACT | NOBLUDGEON resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/delay = 0 +/obj/item/turret_control/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/turret_control/afterattack(atom/targeted_atom, mob/user, proxflag, clickparams) . = ..() var/obj/machinery/power/emitter/E = user.buckled diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index bc05e784a4..35710f8d61 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -84,16 +84,18 @@ /obj/singularity/attack_tk(mob/user) if(iscarbon(user)) var/mob/living/carbon/C = user + log_game("[key_name(C)] has been disintegrated by attempting to telekenetically grab a singularity.") C.visible_message("[C]'s head begins to collapse in on itself!", "Your head feels like it's collapsing in on itself! This was really not a good idea!", "You hear something crack and explode in gore.") var/turf/T = get_turf(C) for(var/i in 1 to 3) C.apply_damage(30, BRUTE, BODY_ZONE_HEAD) new /obj/effect/gibspawner/generic(T) sleep(1) - C.ghostize() var/obj/item/bodypart/head/rip_u = C.get_bodypart(BODY_ZONE_HEAD) rip_u.dismember(BURN) //nice try jedi qdel(rip_u) + return + return ..() /obj/singularity/ex_act(severity, target) switch(severity) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index d87f9821ef..3c151d4e77 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -5,12 +5,21 @@ #define PLASMA_HEAT_PENALTY 15 // Higher == Bigger heat and waste penalty from having the crystal surrounded by this gas. Negative numbers reduce penalty. #define OXYGEN_HEAT_PENALTY 1 #define CO2_HEAT_PENALTY 0.1 -#define NITROGEN_HEAT_MODIFIER -1.5 +#define PLUOXIUM_HEAT_PENALTY -1 +#define TRITIUM_HEAT_PENALTY 10 +#define NITROGEN_HEAT_PENALTY -1.5 +#define BZ_HEAT_PENALTY 5 #define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation. #define PLASMA_TRANSMIT_MODIFIER 4 +#define BZ_TRANSMIT_MODIFIER -2 + +#define TRITIUM_RADIOACTIVITY_MODIFIER 3 //Higher == Crystal spews out more radiation +#define BZ_RADIOACTIVITY_MODIFIER 5 +#define PLUOXIUM_RADIOACTIVITY_MODIFIER -2 #define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage. +#define PLUOXIUM_HEAT_RESISTANCE 3 #define POWERLOSS_INHIBITION_GAS_THRESHOLD 0.20 //Higher == Higher percentage of inhibitor gas needed before the charge inertia chain reaction effect starts. #define POWERLOSS_INHIBITION_MOLE_THRESHOLD 20 //Higher == More moles of the gas are needed before the charge inertia chain reaction effect starts. //Scales powerloss inhibition down until this amount of moles is reached @@ -53,6 +62,7 @@ #define SUPERMATTER_EMERGENCY_PERCENT 25 #define SUPERMATTER_DANGER_PERCENT 50 #define SUPERMATTER_WARNING_PERCENT 100 +#define CRITICAL_TEMPERATURE 10000 #define SUPERMATTER_COUNTDOWN_TIME 30 SECONDS @@ -102,6 +112,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/o2comp = 0 var/co2comp = 0 var/n2ocomp = 0 + var/pluoxiumcomp = 0 + var/tritiumcomp = 0 + var/bzcomp = 0 + + var/pluoxiumbonus = 0 var/combined_gas = 0 var/gasmix_power_ratio = 0 @@ -184,11 +199,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) to_chat(H, "You get headaches just from looking at it.") return -/obj/machinery/power/supermatter_crystal/get_spans() - return list(SPAN_ROBOT) - -#define CRITICAL_TEMPERATURE 10000 - /obj/machinery/power/supermatter_crystal/proc/get_status() var/turf/T = get_turf(src) if(!T) @@ -244,10 +254,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) add_overlay(causality_field, TRUE) var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated." - radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + radio.talk_into(src, speaking, common_channel, language = get_default_language()) for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10) if(damage < explosion_point) // Cutting it a bit close there engineers - radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel) cut_overlay(causality_field, TRUE) final_countdown = FALSE return @@ -258,7 +268,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) speaking = "[DisplayTimeText(i, TRUE)] remain before causality stabilization." else speaking = "[i*0.1]..." - radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + radio.talk_into(src, speaking, common_channel) sleep(10) explode() @@ -357,16 +367,24 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) plasmacomp = max(removed.gases[/datum/gas/plasma]/combined_gas, 0) o2comp = max(removed.gases[/datum/gas/oxygen]/combined_gas, 0) co2comp = max(removed.gases[/datum/gas/carbon_dioxide]/combined_gas, 0) + pluoxiumcomp = max(removed.gases[/datum/gas/pluoxium]/combined_gas, 0) + tritiumcomp = max(removed.gases[/datum/gas/tritium]/combined_gas, 0) + bzcomp = max(removed.gases[/datum/gas/bz]/combined_gas, 0) n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide]/combined_gas, 0) n2comp = max(removed.gases[/datum/gas/nitrogen]/combined_gas, 0) - gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp, 0), 1) + if(pluoxiumcomp >= 0.15) + pluoxiumbonus = 1 //makes pluoxium only work at 15%+ + else + pluoxiumbonus = 0 - dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY)+(o2comp * OXYGEN_HEAT_PENALTY)+(co2comp * CO2_HEAT_PENALTY)+(n2comp * NITROGEN_HEAT_MODIFIER), 0.5) - dynamic_heat_resistance = max(n2ocomp * N2O_HEAT_RESISTANCE, 1) + gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp + tritiumcomp + bzcomp - pluoxiumcomp - n2comp, 0), 1) - power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER), 0) + dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY) + (o2comp * OXYGEN_HEAT_PENALTY) + (co2comp * CO2_HEAT_PENALTY) + (tritiumcomp * TRITIUM_HEAT_PENALTY) + ((pluoxiumcomp * PLUOXIUM_HEAT_PENALTY) * pluoxiumbonus) + (n2comp * NITROGEN_HEAT_PENALTY) + (bzcomp * BZ_HEAT_PENALTY), 0.5) + dynamic_heat_resistance = max((n2ocomp * N2O_HEAT_RESISTANCE) + ((pluoxiumcomp * PLUOXIUM_HEAT_RESISTANCE) * pluoxiumbonus), 1) + + power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER) + (bzcomp * BZ_TRANSMIT_MODIFIER), 0) //more moles of gases are harder to heat than fewer, so let's scale heat damage around them mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) @@ -395,7 +413,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) power = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload if(prob(50)) - radiation_pulse(src, power * (1 + power_transmission_bonus/10)) + radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%) + if(bzcomp >= 0.4 && prob(30 * bzcomp)) + src.fire_nuclear_particles() // Start to emit radballs at a maximum of 30% chance per tick var/device_energy = power * REACTION_POWER_MODIFIER @@ -459,27 +479,27 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) alarm() if(damage > emergency_point) - radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel) lastwarning = REALTIMEOFDAY if(!has_reached_emergency) investigate_log("has reached the emergency point for the first time.", INVESTIGATE_SUPERMATTER) message_admins("[src] has reached the emergency point [ADMIN_JMP(src)].") has_reached_emergency = TRUE else if(damage >= damage_archived) // The damage is still going up - radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel) lastwarning = REALTIMEOFDAY - (WARNING_DELAY * 5) else // Phew, we're safe - radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel) lastwarning = REALTIMEOFDAY if(power > POWER_PENALTY_THRESHOLD) - radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel) if(powerloss_inhibitor < 0.5) - radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel) if(combined_gas > MOLE_PENALTY_THRESHOLD) - radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel, get_spans(), get_default_language()) + radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel) if(damage > explosion_point) countdown() @@ -530,11 +550,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/attack_tk(mob/user) if(iscarbon(user)) var/mob/living/carbon/C = user + log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a supermatter crystal.") to_chat(C, "That was a really dense idea.") - C.ghostize() + C.visible_message("A bright flare of radiation is seen from [C]'s head, shortly before you hear a sickening sizzling!") var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs rip_u.Remove(C) qdel(rip_u) + return + return ..() /obj/machinery/power/supermatter_crystal/attack_paw(mob/user) dust_mob(user, cause = "monkey attack") @@ -653,6 +676,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) else L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", 2) +//Do not blow up our internal radio +/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target) + return + +/obj/machinery/power/supermatter_crystal/prevent_content_explosion() + return TRUE + /obj/machinery/power/supermatter_crystal/engine is_main_engine = TRUE diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index bbad3e08b0..9a5486dfe2 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -132,11 +132,14 @@ /obj/singularity/energy_ball/attack_tk(mob/user) if(iscarbon(user)) var/mob/living/carbon/C = user + log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a tesla ball.") to_chat(C, "That was a shockingly dumb idea.") + C.visible_message("A bright flare of lightning is seen from [C]'s head, shortly before you hear a sickening sizzling!") var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - C.ghostize(0) + rip_u.Remove(C) qdel(rip_u) - C.death() + return + return ..() /obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target) if (istype(target)) diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm index 154d269cd9..a6b65f79e3 100644 --- a/code/modules/projectiles/ammunition/caseless/_caseless.dm +++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm @@ -6,9 +6,10 @@ /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing moveToNullspace() - return 1 + QDEL_NULL(src) + return TRUE else - return 0 + return FALSE /obj/item/ammo_casing/caseless/update_icon() ..() diff --git a/code/modules/projectiles/ammunition/caseless/rocket.dm b/code/modules/projectiles/ammunition/caseless/rocket.dm index 0b74f6ff8c..bc693d96bc 100644 --- a/code/modules/projectiles/ammunition/caseless/rocket.dm +++ b/code/modules/projectiles/ammunition/caseless/rocket.dm @@ -1,7 +1,15 @@ -/obj/item/ammo_casing/caseless/a84mm - desc = "An 84mm anti-armour rocket." +/obj/item/ammo_casing/caseless/rocket + name = "\improper PM-9HE" + desc = "An 84mm High Explosive rocket. Fire at people and pray." caliber = "84mm" - icon_state = "s-casing-live" + icon_state = "srm-8" + projectile_type = /obj/item/projectile/bullet/a84mm_he + +/obj/item/ammo_casing/caseless/rocket/hedp + name = "\improper PM-9HEDP" + desc = "An 84mm High Explosive Dual Purpose rocket. Pointy end toward mechs." + caliber = "84mm" + icon_state = "84mm-hedp" projectile_type = /obj/item/projectile/bullet/a84mm /obj/item/ammo_casing/caseless/a75 diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm index 089c79effd..0940144721 100644 --- a/code/modules/projectiles/ammunition/energy/laser.dm +++ b/code/modules/projectiles/ammunition/energy/laser.dm @@ -59,6 +59,9 @@ /obj/item/ammo_casing/energy/laser/redtag/hitscan projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan +/obj/item/ammo_casing/energy/laser/redtag/hitscan/holy + projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan/holy + /obj/item/ammo_casing/energy/xray projectile_type = /obj/item/projectile/beam/xray e_cost = 50 diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm index 0879506036..7b4e0bfa97 100644 --- a/code/modules/projectiles/ammunition/energy/special.dm +++ b/code/modules/projectiles/ammunition/energy/special.dm @@ -62,3 +62,8 @@ e_cost = 200 select_name = "stun" projectile_type = /obj/item/projectile/energy/tesla/revolver + +/obj/item/ammo_casing/energy/emitter + fire_sound = 'sound/weapons/emitter.ogg' + e_cost = 2000 //20,000 is in the cell making this 10 shots before reload + projectile_type = /obj/item/projectile/beam/emitter diff --git a/code/modules/projectiles/boxes_magazines/internal/grenade.dm b/code/modules/projectiles/boxes_magazines/internal/grenade.dm index 12325a0299..79a005ee8a 100644 --- a/code/modules/projectiles/boxes_magazines/internal/grenade.dm +++ b/code/modules/projectiles/boxes_magazines/internal/grenade.dm @@ -11,7 +11,7 @@ max_ammo = 1 /obj/item/ammo_box/magazine/internal/rocketlauncher - name = "grenade launcher internal magazine" - ammo_type = /obj/item/ammo_casing/caseless/a84mm + name = "rocket launcher internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/rocket caliber = "84mm" max_ammo = 1 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 542e4ecffa..fb3ed19f82 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -32,9 +32,10 @@ var/fire_delay = 0 //rate of fire for burst firing and semi auto var/firing_burst = 0 //Prevent the weapon from firing again while already firing var/semicd = 0 //cooldown handler - var/weapon_weight = WEAPON_LIGHT + var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy var/spread = 0 //Spread induced by the gun itself. var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once. + var/inaccuracy_modifier = 1 lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' @@ -170,7 +171,7 @@ return if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item()) - to_chat(user, "You need both hands free to fire [src]!") + to_chat(user, "You need both hands free to fire \the [src]!") return //DUAL (or more!) WIELDING @@ -422,7 +423,7 @@ if(alight) alight.Remove(user) -/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params) +/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) if(!ishuman(user) || !ishuman(target)) return @@ -438,7 +439,7 @@ semicd = TRUE - if(!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH) + if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH)) if(user) if(user == target) user.visible_message("[user] decided not to shoot.") @@ -538,3 +539,13 @@ if(A == chambered) chambered = null update_icon() + +/obj/item/gun/proc/getinaccuracy(mob/living/user) + if(!iscarbon(user)) + return FALSE + else + var/mob/living/carbon/holdingdude = user + if(istype(holdingdude) && holdingdude.combatmode) + return (max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0) * inaccuracy_modifier) + else + return ((weapon_weight * 25) * inaccuracy_modifier) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 157cf1f03f..1117bc1000 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -7,6 +7,7 @@ var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine var/casing_ejector = TRUE //whether the gun ejects the chambered casing + var/magazine_wording = "magazine" /obj/item/gun/ballistic/Initialize() . = ..() @@ -57,7 +58,7 @@ if (!magazine && istype(AM, mag_type)) if(user.transferItemToLoc(AM, src)) magazine = AM - to_chat(user, "You load a new magazine into \the [src].") + to_chat(user, "You load a new [magazine_wording] into \the [src].") if(magazine.ammo_count()) playsound(src, "gun_insert_full_magazine", 70, 1) if(!chambered) @@ -72,7 +73,7 @@ to_chat(user, "You cannot seem to get \the [src] out of your hands!") return else if (magazine) - to_chat(user, "There's already a magazine in \the [src].") + to_chat(user, "There's already a [magazine_wording] in \the [src].") if(istype(A, /obj/item/suppressor)) var/obj/item/suppressor/S = A if(!can_suppress) @@ -222,7 +223,7 @@ /obj/item/suppressor name = "suppressor" - desc = "A universal syndicate small-arms suppressor for maximum espionage." + desc = "A syndicate small-arms suppressor for maximum espionage." icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" w_class = WEIGHT_CLASS_TINY @@ -231,6 +232,4 @@ /obj/item/suppressor/specialoffer name = "cheap suppressor" - desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." - icon = 'icons/obj/guns/projectile.dmi' - icon_state = "suppressor" + desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits some weapons." diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index aacdd46059..12006440d2 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -74,25 +74,91 @@ update_icon() chamber_round() -/obj/item/gun/ballistic/automatic/atlauncher - desc = "A pre-loaded, single shot anti-armour launcher." - name = "anti-armour grenade launcher" +/obj/item/gun/ballistic/rocketlauncher + name = "\improper PML-9" + desc = "A reusable rocket propelled grenade launcher. The words \"NT this way\" and an arrow have been written near the barrel." icon_state = "rocketlauncher" item_state = "rocketlauncher" mag_type = /obj/item/ammo_box/magazine/internal/rocketlauncher fire_sound = 'sound/weapons/rocketlaunch.ogg' w_class = WEIGHT_CLASS_BULKY can_suppress = FALSE + pin = /obj/item/firing_pin/implant/pindicate burst_size = 1 fire_delay = 0 - select = 0 - actions_types = list() + inaccuracy_modifier = 0.7 casing_ejector = FALSE weapon_weight = WEAPON_HEAVY + magazine_wording = "rocket" -/obj/item/gun/ballistic/automatic/atlauncher/attack_self() - return +/obj/item/gun/ballistic/rocketlauncher/unrestricted + pin = /obj/item/firing_pin -/obj/item/gun/ballistic/automatic/atlauncher/update_icon() - ..() - icon_state = "rocketlauncher[magazine ? "-[get_ammo(1)]" : ""]" \ No newline at end of file +/obj/item/gun/ballistic/rocketlauncher/handle_atom_del(atom/A) + if(A == chambered) + chambered = null + if(!QDELETED(magazine)) + QDEL_NULL(magazine) + if(A == magazine) + magazine = null + if(!QDELETED(chambered)) + QDEL_NULL(chambered) + update_icon() + return ..() + +/obj/item/gun/ballistic/rocketlauncher/can_shoot() + return chambered?.BB + +/obj/item/gun/ballistic/rocketlauncher/attack_self_tk(mob/user) + return //too difficult to remove the rocket with TK + +/obj/item/gun/ballistic/rocketlauncher/attack_self(mob/living/user) + if(magazine) + var/obj/item/ammo_casing/AC = chambered + if(AC) + if(!user.put_in_hands(AC)) + AC.bounce_away(FALSE, NONE) + to_chat(user, "You remove \the [AC] from \the [src]!") + playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, TRUE) + chambered = null + else + to_chat(user, "There's no [magazine_wording] in [src].") + update_icon() + +/obj/item/gun/ballistic/rocketlauncher/attackby(obj/item/A, mob/user, params) + if(magazine && istype(A, /obj/item/ammo_casing)) + if(chambered) + to_chat(user, "[src] already has a [magazine_wording] chambered.") + return + if(magazine.attackby(A, user, silent = TRUE)) + to_chat(user, "You load a new [A] into \the [src].") + playsound(src, "gun_insert_full_magazine", 70, 1) + chamber_round() + update_icon() + +/obj/item/gun/ballistic/rocketlauncher/update_icon() + icon_state = "[initial(icon_state)]-[chambered ? "1" : "0"]" + +/obj/item/gun/ballistic/rocketlauncher/suicide_act(mob/living/user) + user.visible_message("[user] aims [src] at the ground! It looks like [user.p_theyre()] performing a sick rocket jump!", \ + "You aim [src] at the ground to perform a bisnasty rocket jump...") + if(can_shoot()) + user.notransform = TRUE + playsound(src, 'sound/vehicles/rocketlaunch.ogg', 80, 1, 5) + animate(user, pixel_z = 300, time = 30, easing = LINEAR_EASING) + sleep(70) + animate(user, pixel_z = 0, time = 5, easing = LINEAR_EASING) + sleep(5) + user.notransform = FALSE + process_fire(user, user, TRUE) + if(!QDELETED(user)) //if they weren't gibbed by the explosion, take care of them for good. + user.gib() + return MANUAL_SUICIDE + else + sleep(5) + shoot_with_empty_chamber(user) + sleep(20) + user.visible_message("[user] looks about the room realizing [user.p_theyre()] still there. [user.p_they(TRUE)] proceed to shove [src] down their throat and choke [user.p_them()]self with it!", \ + "You look around after realizing you're still here, then proceed to choke yourself to death with [src]!") + sleep(20) + return OXYLOSS diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index bb6a144c93..7d71a9acdd 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -40,7 +40,7 @@ if(istype(user) && user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes pumping shotguns impossible in stamina softcrit to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto return//CIT CHANGE - ditto - pump(user) + pump(user, TRUE) recentpump = world.time + 10 if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina. user.adjustStaminaLossBuffered(2) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added @@ -52,7 +52,9 @@ process_fire(user, user, FALSE) . = 1 -/obj/item/gun/ballistic/shotgun/proc/pump(mob/M) +/obj/item/gun/ballistic/shotgun/proc/pump(mob/M, visible = TRUE) + if(visible) + M.visible_message("[M] racks [src].", "You rack [src].") playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) pump_unload(M) pump_reload(M) @@ -212,14 +214,41 @@ ) /obj/item/gun/ballistic/shotgun/automatic/combat/compact - name = "compact combat shotgun" - desc = "A compact version of the semi automatic combat shotgun. For close encounters." + name = "warden's combat shotgun" + desc = "A modified version of the semi automatic combat shotgun with a collapsible stock. For close encounters." icon_state = "cshotgunc" - mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact + mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_NORMAL - unique_reskin = list("Tatical" = "cshotgunc", - "Slick" = "cshotgunc_slick" - ) + var/stock = FALSE + recoil = 5 + spread = 2 + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + toggle_stock(user) + . = ..() + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/examine(mob/user) + ..() + to_chat(user, "Alt-click to toggle the stock.") + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/proc/toggle_stock(mob/living/user) + stock = !stock + if(stock) + w_class = WEIGHT_CLASS_HUGE + to_chat(user, "You unfold the stock.") + recoil = 1 + spread = 0 + else + w_class = WEIGHT_CLASS_NORMAL + to_chat(user, "You fold the stock.") + recoil = 5 + spread = 2 + update_icon() + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon() + icon_state = "[current_skin ? unique_reskin[current_skin] : "cshotgun"][stock ? "" : "c"]" //Dual Feed Shotgun @@ -235,6 +264,7 @@ /obj/item/gun/ballistic/shotgun/automatic/dual_tube/examine(mob/user) ..() to_chat(user, "Alt-click to pump it.") + . = ..() /obj/item/gun/ballistic/shotgun/automatic/dual_tube/Initialize() . = ..() diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index cd0dd53d48..bb97f9cf99 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -159,3 +159,65 @@ /obj/item/gun/energy/laser/redtag/hitscan ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan) + +/obj/item/gun/energy/laser/redtag/hitscan/chaplain + name = "\improper holy lasrifle" + desc = "A lasrifle from the old Imperium. This one seems to be blessed by techpriests." + icon_state = "LaserAK" + item_state = null + force = 14 + pin = /obj/item/firing_pin/holy + icon = 'modular_citadel/icons/obj/guns/VGguns.dmi' + ammo_x_offset = 4 + ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan/holy) + lefthand_file = 'modular_citadel/icons/mob/citadel/guns_lefthand.dmi' + righthand_file = 'modular_citadel/icons/mob/citadel/guns_righthand.dmi' + var/chaplain_spawnable = TRUE + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON + throw_speed = 3 + throw_range = 4 + throwforce = 10 + obj_flags = UNIQUE_RENAME + +/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + +/obj/item/gun/energy/laser/redtag/hitscan/chaplain/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) + if(!ishuman(user) || !ishuman(target)) + return + + if(semicd) + return + + if(user == target) + target.visible_message("[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger...", \ + "You stick [src] in your mouth, ready to pull the trigger...") + else + target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \ + "[user] points [src] at your head, ready to pull the trigger...") + + semicd = TRUE + + if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH)) + if(user) + if(user == target) + user.visible_message("[user] decided not to shoot.") + else if(target && target.Adjacent(user)) + target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!") + semicd = FALSE + return + + semicd = FALSE + + target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!") + + playsound('sound/weapons/dink.ogg', 30, 1) + + if((iscultist(target)) || (is_servant_of_ratvar(target))) + chambered.BB.damage *= 1500 + + else if(chambered && chambered.BB) + chambered.BB.damage *= 5 + + process_fire(target, user, TRUE, params) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index c6f0956880..87bfd578bc 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -243,7 +243,7 @@ /obj/item/gun/energy/printer name = "cyborg lmg" - desc = "A machinegun that fires 3d-printed flechettes slowly regenerated using a cyborg's internal power source." + desc = "A LMG that fires 3D-printed flechettes. They are slowly resupplied using the cyborg's internal power source." icon_state = "l6closed0" icon = 'icons/obj/guns/projectile.dmi' cell_type = "/obj/item/stock_parts/cell/secborg" @@ -304,3 +304,22 @@ /obj/item/gun/energy/gravity_gun/security pin = /obj/item/firing_pin + +//Emitter Gun + +/obj/item/gun/energy/emitter + name = "Emitter Carbine" + desc = "A small emitter fitted into a handgun case, do to size constraints and safety it can only shoot about ten times when fully charged." + icon_state = "emitter_carbine" + force = 12 + w_class = WEIGHT_CLASS_SMALL + cell_type = /obj/item/stock_parts/cell/super + ammo_type = list(/obj/item/ammo_casing/energy/emitter) + +/obj/item/gun/energy/emitter/update_icon() + ..() + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(!QDELETED(cell) && (cell.charge > shot.e_cost)) + add_overlay("emitter_carbine_empty") + else + add_overlay("emitter_carbine") diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index e3724fdf31..42033d8c88 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -131,7 +131,7 @@ no_den_usage = 1 /obj/item/gun/magic/wand/teleport/zap_self(mob/living/user) - if(do_teleport(user, user, 10)) + if(do_teleport(user, user, 10, channel = TELEPORT_CHANNEL_MAGIC)) var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(3, user.loc) smoke.start() diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 05d6367306..9103340790 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -37,10 +37,12 @@ to_chat(user, "This firearm already has a firing pin installed.") /obj/item/firing_pin/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "You override the authentication mechanism.") + return TRUE /obj/item/firing_pin/proc/gun_insert(mob/living/user, obj/item/gun/G) gun = G @@ -186,6 +188,15 @@ desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link. It has a small explosive charge on it." selfdestruct = TRUE +/obj/item/firing_pin/holy + name = "blessed pin" + desc = "A firing pin that only responds to those who are holier than thou." + +/obj/item/firing_pin/holy/pin_auth(mob/living/user) + if(user.mind.isholy) + return TRUE + return FALSE + // Laser tag pins /obj/item/firing_pin/tag name = "laser tag firing pin" diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index cbd0348743..e43eb5a3bc 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -151,6 +151,11 @@ /obj/item/projectile/beam/lasertag/redtag/hitscan hitscan = TRUE +/obj/item/projectile/beam/lasertag/redtag/hitscan/holy + name = "lasrifle beam" + damage = 0.1 + damage_type = BURN + /obj/item/projectile/beam/lasertag/bluetag icon_state = "bluelaser" suit_types = list(/obj/item/clothing/suit/redtag) diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm index f5d0607341..c8333a811c 100644 --- a/code/modules/projectiles/projectile/energy/net_snare.dm +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -42,10 +42,10 @@ /obj/effect/nettingportal/proc/pop(teletarget) if(teletarget) for(var/mob/living/L in get_turf(src)) - do_teleport(L, teletarget, 2)//teleport what's in the tile to the beacon + do_teleport(L, teletarget, 2, channel = TELEPORT_CHANNEL_BLUESPACE)//teleport what's in the tile to the beacon else for(var/mob/living/L in get_turf(src)) - do_teleport(L, L, 15) //Otherwise it just warps you off somewhere. + do_teleport(L, L, 15, channel = TELEPORT_CHANNEL_BLUESPACE) //Otherwise it just warps you off somewhere. qdel(src) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index dee88f176f..5b84608fad 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -67,7 +67,7 @@ teleloc = target.loc for(var/atom/movable/stuff in teleloc) if(!stuff.anchored && stuff.loc) - if(do_teleport(stuff, stuff, 10)) + if(do_teleport(stuff, stuff, 10, channel = TELEPORT_CHANNEL_MAGIC)) teleammount++ var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(max(round(4 - teleammount),0), stuff.loc) //Smoke drops off if a lot of stuff is moved for the sake of sanity diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index 6518b2a4d5..e15810c6bb 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -9,13 +9,14 @@ return TRUE /obj/item/projectile/bullet/a84mm - name ="anti-armour rocket" + name ="\improper HEDP rocket" desc = "USE A WEEL GUN" - icon_state= "atrocket" + icon_state= "84mm-hedp" damage = 80 var/anti_armour_damage = 200 armour_penetration = 100 dismemberment = 100 + ricochets_max = 0 /obj/item/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE) ..() @@ -29,17 +30,17 @@ S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25) return TRUE -/obj/item/projectile/bullet/srmrocket - name ="SRM-8 Rocket" +/obj/item/projectile/bullet/a84mm_he + name ="\improper HE missile" desc = "Boom." icon_state = "missile" damage = 30 ricochets_max = 0 //it's a MISSILE -/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) +/obj/item/projectile/bullet/a84mm_he/on_hit(atom/target, blocked=0) ..() if(!isliving(target)) //if the target isn't alive, so is a wall or something explosion(target, 0, 1, 2, 4) else explosion(target, 0, 0, 2, 4) - return TRUE + return TRUE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index dc86ab4e6c..d1eec39f44 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,3 +1,4 @@ +#define CHEMICAL_QUANTISATION_LEVEL 0.0001 /proc/build_chemical_reagent_list() //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -53,10 +54,16 @@ var/maximum_volume = 100 var/atom/my_atom = null var/chem_temp = 150 + var/pH = REAGENT_NORMAL_PH//Potential of hydrogen. Edited on adding new reagents, deleting reagents, and during fermi reactions. + var/overallPurity = 1 var/last_tick = 1 var/addiction_tick = 1 var/list/datum/reagent/addiction_list = new/list() var/reagents_holder_flags + var/targetVol = 0 //the target volume, i.e. the total amount that can be created during a fermichem reaction. + var/reactedVol = 0 //how much of the reagent is reacted during a fermireaction + var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.) + var/fermiReactID = null //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs. /datum/reagents/New(maximum=100, new_flags) maximum_volume = maximum @@ -89,7 +96,7 @@ var/list/data = list() for(var/r in reagent_list) //no reagents will be left behind var/datum/reagent/R = r - data += "[R.id] ([round(R.volume, 0.1)]u)" + data += "[R.id] ([round(R.volume, CHEMICAL_QUANTISATION_LEVEL)]u)" //Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. return english_list(data) @@ -121,11 +128,13 @@ /datum/reagents/proc/remove_all(amount = 1) var/list/cached_reagents = reagent_list + if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash. + pH = 7 if(total_volume > 0) var/part = amount / total_volume for(var/reagent in cached_reagents) var/datum/reagent/R = reagent - remove_reagent(R.id, R.volume * part) + remove_reagent(R.id, R.volume * part, ignore_pH = TRUE) update_total() handle_reactions() @@ -189,8 +198,11 @@ var/transfer_amount = T.volume * part if(preserve_data) trans_data = copy_data(T) - R.add_reagent(T.id, transfer_amount * multiplier, trans_data, chem_temp, no_react = 1) //we only handle reaction after every reagent has been transfered. - remove_reagent(T.id, transfer_amount) + + + R.add_reagent(T.id, transfer_amount * multiplier, trans_data, chem_temp, T.purity, pH, no_react = TRUE, ignore_pH = TRUE) //we only handle reaction after every reagent has been transfered. + + remove_reagent(T.id, transfer_amount, ignore_pH = TRUE) update_total() R.update_total() @@ -249,7 +261,8 @@ if(current_reagent.id == reagent) if(preserve_data) trans_data = current_reagent.data - R.add_reagent(current_reagent.id, amount, trans_data, src.chem_temp) + R.add_reagent(current_reagent.id, amount, trans_data, chem_temp, current_reagent.purity, pH, no_react = TRUE) + remove_reagent(current_reagent.id, amount, 1) break @@ -350,14 +363,21 @@ R.on_update (A) update_total() -/datum/reagents/proc/handle_reactions() + +/datum/reagents/proc/handle_reactions()//HERE EDIT HERE THE MAIN REACTION + if(fermiIsReacting == TRUE) + return + if(reagents_holder_flags & NO_REACT) return //Yup, no reactions here. No siree. + var/list/cached_reagents = reagent_list var/list/cached_reactions = GLOB.chemical_reactions_list var/datum/cached_my_atom = my_atom - var/reaction_occurred = 0 + var/reaction_occurred = 0 // checks if reaction, binary variable + var/continue_reacting = FALSE //Helps keep track what kind of reaction is occuring; standard or fermi. + do var/list/possible_reactions = list() reaction_occurred = 0 @@ -382,6 +402,7 @@ var/has_special_react = C.special_react var/can_special_react = 0 + for(var/B in cached_required_reagents) if(!has_reagent(B, cached_required_reagents[B])) break @@ -402,7 +423,7 @@ if(!C.required_other) matching_other = 1 - else if(istype(cached_my_atom, /obj/item/slime_extract)) + else if(istype(cached_my_atom, /obj/item/slime_extract))//if the object is a slime_extract. var/obj/item/slime_extract/M = cached_my_atom if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this @@ -413,7 +434,7 @@ if(!C.required_other) matching_other = 1 - if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp)) + if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))//Temperature check!! meets_temp_requirement = 1 if(!has_special_react || C.check_special_react(src)) @@ -427,53 +448,268 @@ //select the reaction with the most extreme temperature requirements for(var/V in possible_reactions) var/datum/chemical_reaction/competitor = V - if(selected_reaction.is_cold_recipe) //if there are no recipe conflicts, everything in possible_reactions will have this same value for is_cold_reaction. warranty void if assumption not met. + if(selected_reaction.is_cold_recipe) if(competitor.required_temp <= selected_reaction.required_temp) selected_reaction = competitor else - if(competitor.required_temp >= selected_reaction.required_temp) + if(competitor.required_temp >= selected_reaction.required_temp) //will return with the hotter reacting first. selected_reaction = competitor - var/list/cached_required_reagents = selected_reaction.required_reagents - var/list/cached_results = selected_reaction.results + var/list/cached_required_reagents = selected_reaction.required_reagents//update reagents list + var/list/cached_results = selected_reaction.results//resultant chemical list var/special_react_result = selected_reaction.check_special_react(src) var/list/multiplier = INFINITY - for(var/B in cached_required_reagents) - multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B])) - for(var/B in cached_required_reagents) - remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1) + //Splits reactions into two types; FermiChem is advanced reaction mechanics, Other is default reaction. + //FermiChem relies on two additional properties; pH and impurity + //Temperature plays into a larger role too. + var/datum/chemical_reaction/C = selected_reaction - for(var/P in selected_reaction.results) - multiplier = max(multiplier, 1) //this shouldnt happen ... - SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*multiplier, P) - add_reagent(P, cached_results[P]*multiplier, null, chem_temp) + if (C.FermiChem == TRUE && !continue_reacting) + if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions. + var/datum/chemical_reaction/fermi/Ferm = selected_reaction + fermiIsReacting = FALSE + SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion")) + Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH) + return 0 - var/list/seen = viewers(4, get_turf(my_atom)) - var/iconhtml = icon2html(cached_my_atom, seen) - if(cached_my_atom) - if(!ismob(cached_my_atom)) // No bubbling mobs - if(selected_reaction.mix_sound) - playsound(get_turf(cached_my_atom), selected_reaction.mix_sound, 80, 1) + for(var/B in cached_required_reagents) + multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL)) + for(var/P in selected_reaction.results) + targetVol = cached_results[P]*multiplier - for(var/mob/M in seen) - to_chat(M, "[iconhtml] [selected_reaction.mix_message]") + if( (chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin)) + if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )//To prevent pointless reactions + + if (fermiIsReacting == TRUE) + return 0 + else + START_PROCESSING(SSprocessing, src) + selected_reaction.on_reaction(src, my_atom, multiplier) + fermiIsReacting = TRUE + fermiReactID = selected_reaction + reaction_occurred = 1 + + else //It's a little bit of a confusing nest, but esstentially we check if it's a fermireaction, then temperature, then pH. If this is true, the remainer of this handler is run. + return 0 //If pH is out of range + else + return 0 //If not hot enough + + //Standard reaction mechanics: + else + if (C.FermiChem == TRUE)//Just to make sure + return 0 + + for(var/B in cached_required_reagents) // + multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL)) + + for(var/B in cached_required_reagents) + remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE) + + for(var/P in selected_reaction.results) + multiplier = max(multiplier, 1) //this shouldnt happen ... + SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*multiplier, P)//log + add_reagent(P, cached_results[P]*multiplier, null, chem_temp) + + + var/list/seen = viewers(4, get_turf(my_atom))//Sound and sight checkers + var/iconhtml = icon2html(cached_my_atom, seen) + if(cached_my_atom) + if(!ismob(cached_my_atom)) // No bubbling mobs + if(selected_reaction.mix_sound) + playsound(get_turf(cached_my_atom), selected_reaction.mix_sound, 80, 1) - if(istype(cached_my_atom, /obj/item/slime_extract)) - var/obj/item/slime_extract/ME2 = my_atom - ME2.Uses-- - if(ME2.Uses <= 0) // give the notification that the slime core is dead for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [my_atom]'s power is consumed in the reaction.") - ME2.name = "used slime extract" - ME2.desc = "This extract has been used up." + to_chat(M, "[iconhtml] [selected_reaction.mix_message]") - selected_reaction.on_reaction(src, multiplier, special_react_result) - reaction_occurred = 1 + if(istype(cached_my_atom, /obj/item/slime_extract))//if there's an extract and it's used up. + var/obj/item/slime_extract/ME2 = my_atom + ME2.Uses-- + if(ME2.Uses <= 0) // give the notification that the slime core is dead + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [my_atom]'s power is consumed in the reaction.") + ME2.name = "used slime extract" + ME2.desc = "This extract has been used up." + + selected_reaction.on_reaction(src, multiplier, special_react_result) + reaction_occurred = 1 + continue_reacting = TRUE while(reaction_occurred) update_total() return 0 +/datum/reagents/process() + var/datum/chemical_reaction/fermi/C = fermiReactID + + var/list/cached_required_reagents = C.required_reagents//update reagents list + var/list/cached_results = C.results//resultant chemical list + var/multiplier = INFINITY + + for(var/B in cached_required_reagents) // + multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.001)) + if (multiplier == 0) + fermiEnd() + return + for(var/P in cached_results) + targetVol = cached_results[P]*multiplier + + if (fermiIsReacting == FALSE) + CRASH("Fermi has refused to stop reacting even though we asked her nicely.") + + if (chem_temp > C.OptimalTempMin && fermiIsReacting == TRUE)//To prevent pointless reactions + if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) ) + if (reactedVol < targetVol) + reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier) + else//Volume is used up + fermiEnd() + return + else//pH is out of range + fermiEnd() + return + else//Temperature is too low, or reaction has stopped. + fermiEnd() + return + +/datum/reagents/proc/fermiEnd() + var/datum/chemical_reaction/fermi/C = fermiReactID + STOP_PROCESSING(SSprocessing, src) + fermiIsReacting = FALSE + reactedVol = 0 + targetVol = 0 + //pH check, handled at the end to reduce calls. + if(istype(my_atom, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = my_atom + RC.pH_check() + C.FermiFinish(src, my_atom) + handle_reactions() + update_total() + //Reaction sounds and words + playsound(get_turf(my_atom), C.mix_sound, 80, 1) + var/list/seen = viewers(5, get_turf(my_atom)) + var/iconhtml = icon2html(my_atom, seen) + for(var/mob/M in seen) + to_chat(M, "[iconhtml] [C.mix_message]") + +/datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier) + var/datum/chemical_reaction/fermi/C = selected_reaction + var/deltaT = 0 + var/deltapH = 0 + var/stepChemAmmount = 0 + + //get purity from combined beaker reactant purities HERE. + var/purity = 1 + + //Begin checks + //For now, purity is handled elsewhere (on add) + //Calculate DeltapH (Deviation of pH from optimal) + //Lower range + if (cached_pH < C.OptimalpHMin) + if (cached_pH < (C.OptimalpHMin - C.ReactpHLim)) + deltapH = 0 + return//If outside pH range, no reaction + else + deltapH = (((cached_pH - (C.OptimalpHMin - C.ReactpHLim))**C.CurveSharppH)/((C.ReactpHLim**C.CurveSharppH))) + //Upper range + else if (cached_pH > C.OptimalpHMax) + if (cached_pH > (C.OptimalpHMax + C.ReactpHLim)) + deltapH = 0 + return //If outside pH range, no reaction + else + deltapH = (((- cached_pH + (C.OptimalpHMax + C.ReactpHLim))**C.CurveSharppH)/(C.ReactpHLim**C.CurveSharppH))//Reverse - to + to prevent math operation failures. + //Within mid range + else if (cached_pH >= C.OptimalpHMin && cached_pH <= C.OptimalpHMax) + deltapH = 1 + //This should never proc: + else + WARNING("[my_atom] attempted to determine FermiChem pH for '[C.id]' which broke for some reason! ([usr])") + + //Calculate DeltaT (Deviation of T from optimal) + if (cached_temp < C.OptimalTempMax && cached_temp >= C.OptimalTempMin) + deltaT = (((cached_temp - C.OptimalTempMin)**C.CurveSharpT)/((C.OptimalTempMax - C.OptimalTempMin)**C.CurveSharpT)) + else if (cached_temp >= C.OptimalTempMax) + deltaT = 1 + else + deltaT = 0 + + purity = (deltapH)//set purity equal to pH offset + + //Then adjust purity of result with reagent purity. + purity *= reactant_purity(C) + + var/removeChemAmmount //remove factor + var/addChemAmmount //add factor + //ONLY WORKS FOR ONE PRODUCT AT THE MOMENT + //Calculate how much product to make and how much reactant to remove factors.. + for(var/P in cached_results) + //stepChemAmmount = CLAMP(((deltaT * multiplier), 0, ((targetVol - reactedVol)/cached_results[P])) //used to have multipler, now it does + stepChemAmmount = (multiplier*cached_results[P]) + if (stepChemAmmount >= C.RateUpLim) + stepChemAmmount = (C.RateUpLim) + addChemAmmount = deltaT * stepChemAmmount + if (addChemAmmount >= (targetVol - reactedVol)) + addChemAmmount = (targetVol - reactedVol) + if (addChemAmmount < CHEMICAL_QUANTISATION_LEVEL) + addChemAmmount = CHEMICAL_QUANTISATION_LEVEL + removeChemAmmount = (addChemAmmount/cached_results[P]) + //This is kept for future bugtesters. + //message_admins("Reaction vars: PreReacted: [reactedVol] of [targetVol]. deltaT [deltaT], multiplier [multiplier], Step [stepChemAmmount], uncapped Step [deltaT*(multiplier*cached_results[P])], addChemAmmount [addChemAmmount], removeFactor [removeChemAmmount] Pfactor [cached_results[P]], adding [addChemAmmount]") + + //remove reactants + for(var/B in cached_required_reagents) + remove_reagent(B, (removeChemAmmount * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE) + + //add product + var/TotalStep = 0 + for(var/P in cached_results) + SSblackbox.record_feedback("tally", "chemical_reaction", addChemAmmount, P)//log + SSblackbox.record_feedback("tally", "fermi_chem", addChemAmmount, P) + add_reagent(P, (addChemAmmount), null, cached_temp, purity)//add reagent function!! I THINK I can do this: + TotalStep += addChemAmmount//for multiple products + //Above should reduce yeild based on holder purity. + //Purity Check + for(var/datum/reagent/R in my_atom.reagents.reagent_list) + if(P == R.id) + if (R.purity < C.PurityMin)//If purity is below the min, blow it up. + fermiIsReacting = FALSE + SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[P] explosion")) + C.FermiExplode(src, my_atom, (reactedVol+targetVol), cached_temp, pH) + STOP_PROCESSING(SSprocessing, src) + return 0 + + C.FermiCreate(src)//proc that calls when step is done + + //Apply pH changes and thermal output of reaction to beaker + chem_temp = round(cached_temp + (C.ThermicConstant * addChemAmmount)) + pH += (C.HIonRelease * addChemAmmount) + //keep track of the current reacted amount + reactedVol = reactedVol + addChemAmmount + + //Check extremes + if (chem_temp > C.ExplodeTemp) + //go to explode proc + fermiIsReacting = FALSE + SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[C] explosions")) + C.FermiExplode(src, my_atom, (reactedVol+targetVol), chem_temp, pH) + STOP_PROCESSING(SSprocessing, src) + return + + //Make sure things are limited. + pH = CLAMP(pH, 0, 14) + + //return said amount to compare for next step. + return (reactedVol) + +//Currently calculates it irrespective of required reagents at the start +/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder) + var/list/cached_reagents = reagent_list + var/i = 0 + var/cachedPurity + for(var/datum/reagent/R in my_atom.reagents.reagent_list) + if (R in cached_reagents) + cachedPurity += R.purity + i++ + return cachedPurity/i + /datum/reagents/proc/isolate_reagent(reagent) var/list/cached_reagents = reagent_list for(var/_reagent in cached_reagents) @@ -505,7 +741,7 @@ total_volume = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent - if(R.volume < 0.1) + if(R.volume < CHEMICAL_QUANTISATION_LEVEL) del_reagent(R.id) else total_volume += R.volume @@ -517,6 +753,7 @@ for(var/reagent in cached_reagents) var/datum/reagent/R = reagent del_reagent(R.id) + pH = REAGENT_NORMAL_PH return 0 /datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1) @@ -563,13 +800,17 @@ /datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000) var/S = specific_heat() - chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), 2.7, 1000) + chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), min_temp, max_temp) + if(istype(my_atom, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = my_atom + RC.temp_check() + +/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, other_purity = 1, other_pH, no_react = 0, ignore_pH = FALSE) -/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0) if(!isnum(amount) || !amount) return FALSE - if(amount <= 0) + if(amount <= CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems. return FALSE var/datum/reagent/D = GLOB.chemical_reagents_list[reagent] @@ -577,6 +818,23 @@ WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") return FALSE + if (D.id == "water" && no_react == FALSE && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany. + if (pH <= 2) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "water-acid explosions") + var/datum/effect_system/smoke_spread/chem/s = new + var/turf/T = get_turf(my_atom) + var/datum/reagents/R = new/datum/reagents(3000) + R.add_reagent("fermiAcid", amount) + for (var/datum/reagent/reagentgas in reagent_list) + R.add_reagent(reagentgas, amount/5) + remove_reagent(reagentgas, amount/5) + s.set_up(R, CLAMP(amount/10, 0, 2), T) + s.start() + return FALSE + + if(!pH) + other_pH = D.pH + update_total() var/cached_total = total_volume if(cached_total + amount > maximum_volume) @@ -587,6 +845,10 @@ var/cached_temp = chem_temp var/list/cached_reagents = reagent_list + var/cached_pH = pH + + + //Equalize temperature - Not using specific_heat() because the new chemical isn't in yet. var/specific_heat = 0 var/thermal_energy = 0 @@ -597,32 +859,55 @@ specific_heat += D.specific_heat * (amount / new_total) thermal_energy += D.specific_heat * amount * reagtemp chem_temp = thermal_energy / (specific_heat * new_total) - //// + + //cacluate reagent based pH shift. + if(ignore_pH == TRUE) + pH = ((cached_pH * cached_total)+(other_pH * amount))/(cached_total + amount)//should be right + else + pH = ((cached_pH * cached_total)+(D.pH * amount))/(cached_total + amount)//should be right + if(istype(my_atom, /obj/item/reagent_containers/)) + var/obj/item/reagent_containers/RC = my_atom + RC.pH_check()//checks beaker resilience //add the reagent to the existing if it exists for(var/A in cached_reagents) var/datum/reagent/R = A - if (R.id == reagent) + if (R.id == reagent) //IF MERGING + //Add amount and equalize purity R.volume += amount + R.purity = ((R.purity * R.volume) + (other_purity * amount)) /((R.volume + amount)) //This should add the purity to the product + update_total() if(my_atom) my_atom.on_reagent_change(ADD_REAGENT) - R.on_merge(data, amount) + if(isliving(my_atom)) + if(R.OnMobMergeCheck == TRUE)//Forces on_mob_add proc when a chem is merged + R.on_mob_add(my_atom, amount) + //else + // R.on_merge(data, amount, my_atom, other_purity) + R.on_merge(data, amount, my_atom, other_purity) if(!no_react) handle_reactions() + return TRUE + //otherwise make a new one var/datum/reagent/R = new D.type(data) cached_reagents += R R.holder = src R.volume = amount + R.purity = other_purity + R.loc = get_turf(my_atom) if(data) R.data = data R.on_new(data) + if(R.addProc == TRUE)//Allows on new without data overhead. + R.on_new(pH) //Add more as desired. + if(isliving(my_atom)) - R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + R.on_mob_add(my_atom, amount) update_total() if(my_atom) my_atom.on_reagent_change(ADD_REAGENT) @@ -630,12 +915,13 @@ handle_reactions() return TRUE + /datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15) for(var/r_id in list_reagents) var/amt = list_reagents[r_id] add_reagent(r_id, amt, data) -/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to +/datum/reagents/proc/remove_reagent(reagent, amount, safety, ignore_pH = FALSE)//Added a safety check for the trans_id_to if(isnull(amount)) amount = 0 @@ -653,6 +939,15 @@ for(var/A in cached_reagents) var/datum/reagent/R = A if (R.id == reagent) + if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash. + pH = 7 + //In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people. + else if (ignore_pH == FALSE) + //if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7))) + pH = (((pH - R.pH) / total_volume) * amount) + pH + if(istype(my_atom, /obj/item/reagent_containers/)) + var/obj/item/reagent_containers/RC = my_atom + RC.pH_check()//checks beaker resilience) //clamp the removal amount to be between current reagent amount //and zero, to prevent removing more than the holder has stored amount = CLAMP(amount, 0, R.volume) @@ -674,7 +969,7 @@ if(!amount) return R else - if(R.volume >= amount) + if(round(R.volume, CHEMICAL_QUANTISATION_LEVEL) >= amount) return R else return 0 @@ -686,7 +981,7 @@ for(var/_reagent in cached_reagents) var/datum/reagent/R = _reagent if (R.id == reagent) - return R.volume + return round(R.volume, CHEMICAL_QUANTISATION_LEVEL) return 0 diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index fa9d60a219..9a228b28e3 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -139,12 +139,14 @@ /obj/machinery/chem_dispenser/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) to_chat(user, "[src] has no functional safeties to emag.") return to_chat(user, "You short out [src]'s safeties.") dispensable_reagents |= emagged_reagents//add the emagged reagents to the dispensable ones obj_flags |= EMAGGED + return TRUE /obj/machinery/chem_dispenser/ex_act(severity, target) if(severity < 3) @@ -189,10 +191,16 @@ data["beakerCurrentVolume"] = beakerCurrentVolume data["beakerMaxVolume"] = beaker.volume data["beakerTransferAmounts"] = beaker.possible_transfer_amounts + data["beakerCurrentpH"] = beaker.reagents.pH + //pH accuracy + for(var/obj/item/stock_parts/capacitor/C in component_parts) + data["partRating"]= 10**(C.rating-1) + else data["beakerCurrentVolume"] = null data["beakerMaxVolume"] = null data["beakerTransferAmounts"] = null + data["beakerCurrentpH"] = null var/chemicals[0] var/recipes[0] diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index a17b1e8190..436ee80e7b 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -97,13 +97,21 @@ data["isBeakerLoaded"] = beaker ? 1 : 0 data["currentTemp"] = beaker ? beaker.reagents.chem_temp : null + data["currentpH"] = beaker ? beaker.reagents.pH : null data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null data["beakerMaxVolume"] = beaker ? beaker.volume : null + //purity and pH accuracy + for(var/obj/item/stock_parts/micro_laser/M in component_parts) + data["partRating"]= 10**(M.rating-1) + if(M.rating == 4) + data["showPurity"] = 1 + else + data["showPurity"] = 0 var beakerContents[0] if(beaker) for(var/datum/reagent/R in beaker.reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + beakerContents.Add(list(list("name" = R.name, "volume" = R.volume, "purity" = R.purity))) // list in a list because Byond merges the first list... data["beakerContents"] = beakerContents return data diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index aeed5ffc37..002c54be94 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -1,3 +1,6 @@ +#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die +#define RANDOM_PILL_STYLE 22 //Dont change this one though + /obj/machinery/chem_master name = "ChemMaster 3000" desc = "Used to separate chemicals and distribute them in a variety of forms." @@ -13,12 +16,25 @@ var/obj/item/storage/pill_bottle/bottle = null var/mode = 1 var/condi = FALSE + var/chosenPillStyle = 1 var/screen = "home" var/analyzeVars[0] var/useramount = 30 // Last used amount + var/list/pillStyles + var/fermianalyze //Give more detail on fermireactions on analysis /obj/machinery/chem_master/Initialize() create_reagents(100) + + //Calculate the span tags and ids fo all the available pill icons + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + pillStyles = list() + for (var/x in 1 to PILL_STYLE_COUNT) + var/list/SL = list() + SL["id"] = x + SL["htmltag"] = assets.icon_tag("pill[x]") + pillStyles += list(SL) + . = ..() /obj/machinery/chem_master/Destroy() @@ -87,12 +103,9 @@ updateUsrDialog() update_icon() else if(!condi && istype(I, /obj/item/storage/pill_bottle)) - if(bottle) - to_chat(user, "A pill bottle is already loaded into [src]!") - return if(!user.transferItemToLoc(I, src)) return - bottle = I + replace_pillbottle(user, I) to_chat(user, "You add [I] into the dispenser slot.") updateUsrDialog() else @@ -116,21 +129,38 @@ update_icon() return TRUE -/obj/machinery/chem_master/on_deconstruction() - replace_beaker(usr) +/obj/machinery/chem_master/proc/replace_pillbottle(mob/living/user, obj/item/storage/pill_bottle/new_bottle) if(bottle) bottle.forceMove(drop_location()) - adjust_item_drop_location(bottle) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + else + adjust_item_drop_location(bottle) + if(new_bottle) + bottle = new_bottle + else bottle = null + update_icon() + return TRUE + +/obj/machinery/chem_master/on_deconstruction() + replace_beaker(usr) + replace_pillbottle(usr) return ..() /obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) + var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + assets.send(user) ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state) ui.open() +//Insert our custom spritesheet css link into the html +/obj/machinery/chem_master/ui_base_html(html) + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + . = replacetext(html, "", assets.css_tag()) /obj/machinery/chem_master/ui_data(mob/user) var/list/data = list() @@ -141,7 +171,8 @@ data["condi"] = condi data["screen"] = screen data["analyzeVars"] = analyzeVars - + data["fermianalyze"] = fermianalyze + data["chosenPillStyle"] = chosenPillStyle data["isPillBottleLoaded"] = bottle ? 1 : 0 if(bottle) GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) @@ -160,6 +191,9 @@ bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^ data["bufferContents"] = bufferContents + //Calculated at init time as it never changes + data["pillStyles"] = pillStyles + return data /obj/machinery/chem_master/ui_act(action, params) @@ -171,22 +205,21 @@ . = TRUE if("ejectp") - if(bottle) - bottle.forceMove(drop_location()) - adjust_item_drop_location(bottle) - bottle = null - . = TRUE + replace_pillbottle(usr) + . = TRUE if("transferToBuffer") if(beaker) var/id = params["id"] var/amount = text2num(params["amount"]) if (amount > 0) + end_fermi_reaction() beaker.reagents.trans_id_to(src, id, amount) . = TRUE else if (amount == -1) // -1 means custom amount useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null if (useramount > 0) + end_fermi_reaction() beaker.reagents.trans_id_to(src, id, useramount) . = TRUE @@ -221,19 +254,25 @@ if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/pill/P - var/target_loc = drop_location() + var/target_loc = bottle ? bottle : drop_location() var/drop_threshold = INFINITY if(bottle) GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) if(STRB) drop_threshold = STRB.max_items - bottle.contents.len - for(var/i = 0; i < amount; i++) + for(var/i in 1 to amount) if(i < drop_threshold) P = new(target_loc) else P = new(drop_location()) P.name = trim("[name] pill") + if(chosenPillStyle == RANDOM_PILL_STYLE) + P.icon_state ="pill[rand(1,21)]" + else + P.icon_state = "pill[chosenPillStyle]" + if(P.icon_state == "pill4") + P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality." adjust_item_drop_location(P) reagents.trans_to(P,vol_each) else @@ -248,6 +287,10 @@ reagents.trans_to(P,10) . = TRUE + if("pillStyle") + var/id = text2num(params["id"]) + chosenPillStyle = id + if("createPatch") var/many = params["many"] if(reagents.total_volume == 0) @@ -314,10 +357,10 @@ return var/amount_full = 0 - var/vol_part = min(reagents.total_volume, 30) + var/vol_part = min(reagents.total_volume, 60) if(text2num(many)) - amount_full = round(reagents.total_volume / 30) - vol_part = reagents.total_volume % 30 + amount_full = round(reagents.total_volume / 60) + vol_part = reagents.total_volume % 60 var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return @@ -327,7 +370,7 @@ P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) P.name = trim("[name] hypovial") adjust_item_drop_location(P) - reagents.trans_to(P, 30) + reagents.trans_to(P, 60) if(vol_part) P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) @@ -348,7 +391,14 @@ state = "Gas" var/const/P = 3 //The number of seconds between life ticks var/T = initial(R.metabolization_rate) * (60 / P) - analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold)) + if(istype(R, /datum/reagent/fermi)) + fermianalyze = TRUE + var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id) + var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = initial(R.purity), "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) + else + fermianalyze = FALSE + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold)) screen = "analyze" return @@ -358,6 +408,9 @@ +/obj/machinery/chem_master/proc/end_fermi_reaction()//Ends any reactions upon moving. + if(beaker.reagents.fermiIsReacting) + beaker.reagents.fermiEnd() /obj/machinery/chem_master/proc/isgoodnumber(num) if(isnum(num)) @@ -396,3 +449,6 @@ name = "CondiMaster 3000" desc = "Used to create condiments and other cooking supplies." condi = TRUE + +#undef PILL_STYLE_COUNT +#undef RANDOM_PILL_STYLE diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 9bfbffd330..c21629ce8f 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -33,10 +33,18 @@ var/addiction_stage4_end = 40 var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. var/self_consuming = FALSE + //Fermichem vars: + var/purity = 1 //How pure a chemical is from 0 - 1. + var/addProc = FALSE //If the chemical should force an on_new() call + var/turf/loc = null //Should be the creation location! + var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder. + var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction + var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising + var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it. + var/DoNotSplit = FALSE // If impurity is handled within the main chem itself + var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging. var/metabolizing = FALSE - - - + var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers. /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() @@ -61,7 +69,8 @@ /datum/reagent/proc/on_mob_life(mob/living/carbon/M) current_cycle++ - holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. + if(holder) + holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. return // Called when this reagent is first added to a mob diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 211fddca26..79b6f96781 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -14,6 +14,7 @@ nutriment_factor = 0 taste_description = "alcohol" var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning + pH = 7.33 /* Boozepwr Chart @@ -86,6 +87,8 @@ All effects don't start immediately, but rather get worse over time; the rate is taste_description = "piss water" glass_name = "glass of beer" glass_desc = "A freezing pint of beer." + pH = 4 + /datum/reagent/consumable/ethanol/beer/light name = "Light Beer" @@ -95,6 +98,7 @@ All effects don't start immediately, but rather get worse over time; the rate is taste_description = "dish water" glass_name = "glass of light beer" glass_desc = "A freezing pint of watery light beer." + pH = 5 /datum/reagent/consumable/ethanol/beer/green name = "Green Beer" @@ -105,6 +109,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "greenbeerglass" glass_name = "glass of green beer" glass_desc = "A freezing pint of green beer. Festive." + pH = 6 /datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/M) if(M.color != color) @@ -124,6 +129,8 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of RR coffee liquor" glass_desc = "DAMN, THIS THING LOOKS ROBUST!" shot_glass_icon_state = "shotglasscream" + pH = 6 + /datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/M) M.dizziness = max(0,M.dizziness-5) @@ -145,6 +152,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of whiskey" glass_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy." shot_glass_icon_state = "shotglassbrown" + pH = 4.5 /datum/reagent/consumable/ethanol/thirteenloko name = "Thirteen Loko" @@ -161,6 +169,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of Thirteen Loko" glass_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass." + /datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/M) M.drowsyness = max(0,M.drowsyness-7) M.AdjustSleeping(-40) @@ -221,6 +230,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of vodka" glass_desc = "The glass contain wodka. Xynta." shot_glass_icon_state = "shotglassclear" + pH = 8.1 /datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M) M.radiation = max(M.radiation-2,0) @@ -255,6 +265,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "threemileislandglass" glass_name = "Three Mile Island Ice Tea" glass_desc = "A glass of this is sure to prevent a meltdown." + pH = 3.5 /datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) @@ -270,6 +281,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "ginvodkaglass" glass_name = "glass of gin" glass_desc = "A crystal clear glass of Griffeater gin." + pH = 6.9 /datum/reagent/consumable/ethanol/rum name = "Rum" @@ -282,6 +294,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of rum" glass_desc = "Now you want to Pray for a pirate suit, don't you?" shot_glass_icon_state = "shotglassbrown" + pH = 6.5 /datum/reagent/consumable/ethanol/tequila name = "Tequila" @@ -294,6 +307,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of tequila" glass_desc = "Now all that's missing is the weird colored shades!" shot_glass_icon_state = "shotglassgold" + pH = 4 /datum/reagent/consumable/ethanol/vermouth name = "Vermouth" @@ -306,6 +320,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of vermouth" glass_desc = "You wonder why you're even drinking this straight." shot_glass_icon_state = "shotglassclear" + pH = 3.25 /datum/reagent/consumable/ethanol/wine name = "Wine" @@ -318,6 +333,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of wine" glass_desc = "A very classy looking drink." shot_glass_icon_state = "shotglassred" + pH = 3.45 /datum/reagent/consumable/ethanol/lizardwine name = "Lizard wine" @@ -327,6 +343,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 45 quality = DRINK_FANTASTIC taste_description = "scaley sweetness" + pH = 3 /datum/reagent/consumable/ethanol/grappa name = "Grappa" @@ -338,6 +355,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "grappa" glass_name = "glass of grappa" glass_desc = "A fine drink originally made to prevent waste by using the leftovers from winemaking." + pH = 3.5 /datum/reagent/consumable/ethanol/cognac name = "Cognac" @@ -350,6 +368,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of cognac" glass_desc = "Damn, you feel like some kind of French aristocrat just by holding this." shot_glass_icon_state = "shotglassbrown" + pH = 3.5 /datum/reagent/consumable/ethanol/absinthe name = "Absinthe" @@ -395,6 +414,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "aleglass" glass_name = "glass of ale" glass_desc = "A freezing pint of delicious Ale." + pH = 4.5 /datum/reagent/consumable/ethanol/goldschlager name = "Goldschlager" @@ -421,6 +441,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of patron" glass_desc = "Drinking patron in the bar, with all the subpar ladies." shot_glass_icon_state = "shotglassclear" + pH = 4.5 /datum/reagent/consumable/ethanol/gintonic name = "Gin and Tonic" @@ -433,6 +454,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "gintonicglass" glass_name = "Gin and Tonic" glass_desc = "A mild but still great cocktail. Drink up, like a true Englishman." + pH = 3 /datum/reagent/consumable/ethanol/rum_coke name = "Rum and Coke" @@ -445,6 +467,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "whiskeycolaglass" glass_name = "Rum and Coke" glass_desc = "The classic go-to of space-fratboys." + pH = 4 /datum/reagent/consumable/ethanol/cuba_libre name = "Cuba Libre" @@ -458,6 +481,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Cuba Libre" glass_desc = "A classic mix of rum, cola, and lime. A favorite of revolutionaries everywhere!" + /datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/carbon/M) if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries. M.adjustBruteLoss(-1, 0) @@ -504,6 +528,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Vodka martini" glass_desc ="A bastardisation of the classic martini. Still great." + /datum/reagent/consumable/ethanol/white_russian name = "White Russian" id = "whiterussian" @@ -557,8 +582,8 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder." /datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C) - if(C.blood_volume < BLOOD_VOLUME_NORMAL) - C.blood_volume = min(BLOOD_VOLUME_NORMAL, C.blood_volume + 3) //Bloody Mary quickly restores blood loss. + if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio)) + C.blood_volume = min((BLOOD_VOLUME_NORMAL*C.blood_ratio), C.blood_volume + 3) //Bloody Mary quickly restores blood loss. ..() /datum/reagent/consumable/ethanol/brave_bull @@ -643,6 +668,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "beepskysmashglass" glass_name = "Beepsky Smash" glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." + pH = 2 overdose_threshold = 40 var/datum/brain_trauma/special/beepsky/B @@ -1578,6 +1604,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Bastion Bourbon" glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon." shot_glass_icon_state = "shotglassgreen" + pH = 4 /datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L) var/heal_points = 10 @@ -2076,7 +2103,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M) if(M.drunkenness > 40) if(stored_teleports) - do_teleport(M, get_turf(M), rand(1,3)) + do_teleport(M, get_turf(M), rand(1,3), channel = TELEPORT_CHANNEL_WORMHOLE) stored_teleports-- if(prob(10)) stored_teleports += rand(2,6) @@ -2106,6 +2133,7 @@ All effects don't start immediately, but rather get worse over time; the rate is can_synth = FALSE var/list/names = list("null fruit" = 1) //Names of the fruits used. Associative list where name is key, value is the percentage of that fruit. var/list/tastes = list("bad coding" = 1) //List of tastes. See above. + pH = 4 /datum/reagent/consumable/ethanol/fruit_wine/on_new(list/data) names = data["names"] diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index af85b6b35f..ada4cd8d8e 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -187,7 +187,7 @@ description = "will do toxin damage and cause targets to believe they are fully healed." analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed." taste_description = "heaven" - color = "#C8A5DC" + color = "#5e7842" complementary_color = "#CD7794" message_living = ", and you feel alive" diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 4e40233713..bfefc073f8 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -168,6 +168,7 @@ /datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/M) M.emote("laugh") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "chemical_laughter", /datum/mood_event/chemical_laughter) ..() /datum/reagent/consumable/superlaughter @@ -182,6 +183,7 @@ if(prob(30)) M.visible_message("[M] bursts out into a fit of uncontrollable laughter!", "You burst out in a fit of uncontrollable laughter!") M.Stun(5) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "chemical_laughter", /datum/mood_event/chemical_superlaughter) ..() /datum/reagent/consumable/potato_juice @@ -741,7 +743,7 @@ name = "Triple Citrus" id = "triple_citrus" description = "A solution." - color = "#C8A5DC" + color = "#fff12b" quality = DRINK_NICE taste_description = "extreme bitterness" glass_icon_state = "triplecitrus" //needs own sprite mine are trash diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index a4586dd997..5b06710472 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -15,6 +15,7 @@ description = "An illegal chemical compound used as drug." color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 30 + pH = 9 /datum/reagent/drug/space_drugs/on_mob_life(mob/living/carbon/M) M.set_drugginess(15) @@ -44,6 +45,7 @@ addiction_threshold = 30 taste_description = "smoke" trippy = FALSE + pH = 8 /datum/reagent/drug/nicotine/on_mob_life(mob/living/carbon/M) if(prob(1)) @@ -65,6 +67,7 @@ color = "#FA00C8" overdose_threshold = 20 addiction_threshold = 10 + pH = 10 /datum/reagent/drug/crank/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -112,6 +115,7 @@ color = "#0064B4" overdose_threshold = 20 addiction_threshold = 15 + pH = 9 /datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/M) @@ -167,6 +171,7 @@ var/brain_damage = TRUE var/jitter = TRUE var/confusion = TRUE + pH = 5 /datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L) ..() @@ -261,6 +266,7 @@ addiction_threshold = 10 taste_description = "salt" // because they're bathsalts? var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage + pH = 8.2 /datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L) ..() @@ -357,6 +363,7 @@ description = "Amps you up and gets you going, fixes all stamina damage you might have but can cause toxin and oxygen damage." reagent_state = LIQUID color = "#78FFF0" + pH = 9.2 /datum/reagent/drug/aranesp/on_mob_life(mob/living/carbon/M) var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.") @@ -370,6 +377,84 @@ ..() . = 1 +/datum/reagent/drug/happiness + name = "Happiness" + id = "happiness" + description = "Fills you with ecstasic numbness and causes minor brain damage. Highly addictive. If overdosed causes sudden mood swings." + reagent_state = LIQUID + color = "#FFF378" + addiction_threshold = 10 + overdose_threshold = 20 + pH = 10.5 + +/datum/reagent/drug/happiness/on_mob_add(mob/living/L) + ..() + ADD_TRAIT(L, TRAIT_FEARLESS, id) + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug) + +/datum/reagent/drug/happiness/on_mob_delete(mob/living/L) + REMOVE_TRAIT(L, TRAIT_FEARLESS, id) + SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "happiness_drug") + ..() + +/datum/reagent/drug/happiness/on_mob_life(mob/living/carbon/M) + M.jitteriness = 0 + M.confused = 0 + M.disgust = 0 + M.adjustBrainLoss(0.2) + ..() + . = 1 + +/datum/reagent/drug/happiness/overdose_process(mob/living/M) + if(prob(30)) + var/reaction = rand(1,3) + switch(reaction) + if(1) + M.emote("laugh") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_good_od) + if(2) + M.emote("sway") + M.Dizzy(25) + if(3) + M.emote("frown") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_bad_od) + M.adjustBrainLoss(0.5) + ..() + . = 1 + +/datum/reagent/drug/happiness/addiction_act_stage1(mob/living/M)// all work and no play makes jack a dull boy + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + mood.setSanity(min(mood.sanity, SANITY_DISTURBED)) + M.Jitter(5) + if(prob(20)) + M.emote(pick("twitch","laugh","frown")) + ..() + +/datum/reagent/drug/happiness/addiction_act_stage2(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + mood.setSanity(min(mood.sanity, SANITY_UNSTABLE)) + M.Jitter(10) + if(prob(30)) + M.emote(pick("twitch","laugh","frown")) + ..() + +/datum/reagent/drug/happiness/addiction_act_stage3(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + mood.setSanity(min(mood.sanity, SANITY_CRAZY)) + M.Jitter(15) + if(prob(40)) + M.emote(pick("twitch","laugh","frown")) + ..() + +/datum/reagent/drug/happiness/addiction_act_stage4(mob/living/carbon/human/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + mood.setSanity(SANITY_INSANE) + M.Jitter(20) + if(prob(50)) + M.emote(pick("twitch","laugh","frown")) + ..() + . = 1 + /datum/reagent/drug/skooma name = "Skooma" id = "skooma" @@ -380,6 +465,7 @@ addiction_threshold = 1 addiction_stage3_end = 40 addiction_stage4_end = 240 + pH = 12.5 /datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() @@ -440,4 +526,3 @@ if(prob(40)) M.emote(pick("twitch","drool","moan")) ..() - diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 7efa13898d..19aeaeb25e 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -230,6 +230,7 @@ description = "A special oil that noticably chills the body. Extracted from Icepeppers and slimes." color = "#8BA6E9" // rgb: 139, 166, 233 taste_description = "mint" + pH = 13 //HMM! I wonder /datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/M) var/cooling = 0 @@ -275,6 +276,7 @@ description = "A chemical agent used for self-defense and in police work." color = "#B31008" // rgb: 179, 16, 8 taste_description = "scorching agony" + pH = 7.4 /datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(!ishuman(M) && !ismonkey(M)) @@ -321,7 +323,7 @@ victim.blind_eyes(2) victim.confused = max(M.confused, 3) victim.damageoverlaytemp = 60 - victim.Knockdown(60, override_stamdmg = min(reac_volume * 3, 15)) + victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 3, 15)) return else if ( eyes_covered ) // Eye cover is better than mouth cover victim.blur_eyes(3) @@ -334,7 +336,7 @@ victim.blind_eyes(3) victim.confused = max(M.confused, 6) victim.damageoverlaytemp = 75 - victim.Knockdown(100, override_stamdmg = min(reac_volume * 5, 25)) + victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 5, 25)) victim.update_damage_hud() /datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M) @@ -402,6 +404,7 @@ color = "#E700E7" // rgb: 231, 0, 231 metabolization_rate = 0.2 * REAGENTS_METABOLISM taste_description = "mushroom" + pH = 11 /datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) @@ -564,14 +567,14 @@ name = "Corn Starch" id = "corn_starch" description = "A slippery solution." - color = "#C8A5DC" + color = "#f7f6e4" taste_description = "slime" /datum/reagent/consumable/corn_syrup name = "Corn Syrup" id = "corn_syrup" description = "Decays into sugar." - color = "#C8A5DC" + color = "#fff882" metabolization_rate = 3 * REAGENTS_METABOLISM taste_description = "sweet slime" @@ -618,6 +621,7 @@ description = "A blinding substance extracted from certain onions." color = "#c0c9a0" taste_description = "bitterness" + pH = 5 /datum/reagent/consumable/tearjuice/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(!istype(M)) @@ -672,6 +676,7 @@ description = "An ichor, derived from a certain mushroom, makes for a bad time." color = "#1d043d" taste_description = "bitter mushroom" + pH = 12 /datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/M) if(current_cycle >= 10) @@ -692,6 +697,7 @@ description = "A stimulating ichor which causes luminescent fungi to grow on the skin. " color = "#b5a213" taste_description = "tingling mushroom" + pH = 11.2 /datum/reagent/consumable/tinlux/reaction_mob(mob/living/M) M.set_light(2) @@ -706,6 +712,7 @@ color = "#d3a308" nutriment_factor = 3 * REAGENTS_METABOLISM taste_description = "fruity mushroom" + pH = 10.4 /datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M) if(prob(80)) @@ -721,6 +728,7 @@ nutriment_factor = 5 * REAGENTS_METABOLISM color = "#eef442" // rgb: 238, 244, 66 taste_description = "mournful honking" + pH = 9.2 /datum/reagent/consumable/astrotame name = "Astrotame" @@ -750,3 +758,4 @@ quality = FOOD_AMAZING taste_mult = 100 can_synth = FALSE + pH = 6.1 diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ed441504a5..4dc0d145dc 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -18,7 +18,8 @@ name = "Leporazine" id = "leporazine" description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels." - color = "#C8A5DC" // rgb: 200, 165, 220 + pH = 8.4 + color = "#82b8aa" /datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/M) if(M.bodytemperature > BODYTEMP_NORMAL) @@ -31,7 +32,7 @@ name = "Adminordrazine" id = "adminordrazine" description = "It's magic. We don't have to explain it." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#ffffff" can_synth = FALSE taste_description = "badmins" @@ -60,6 +61,9 @@ M.SetSleeping(0, 0) M.jitteriness = 0 M.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC) + if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) + M.blood_volume = (BLOOD_VOLUME_NORMAL*M.blood_ratio) + for(var/thing in M.diseases) var/datum/disease/D = thing if(D.severity == DISEASE_SEVERITY_POSITIVE) @@ -79,6 +83,7 @@ id = "synaptizine" description = "Increases resistance to stuns as well as reducing drowsiness and hallucinations." color = "#FF00FF" + pH = 4 /datum/reagent/medicine/synaptizine/on_mob_life(mob/living/carbon/M) M.drowsyness = max(M.drowsyness-5, 0) @@ -98,6 +103,7 @@ id = "synaphydramine" description = "Reduces drowsiness, hallucinations, and Histamine from body." color = "#EC536D" // rgb: 236, 83, 109 + pH = 5.2 /datum/reagent/medicine/synaphydramine/on_mob_life(mob/living/carbon/M) M.drowsyness = max(M.drowsyness-5, 0) @@ -116,6 +122,7 @@ id = "inacusiate" description = "Instantly restores all hearing to the patient, but does not cure deafness." color = "#6600FF" // rgb: 100, 165, 255 + pH = 2 /datum/reagent/medicine/inacusiate/on_mob_life(mob/living/carbon/M) M.restoreEars() @@ -127,6 +134,7 @@ description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 270K for it to metabolise correctly." color = "#0000C8" taste_description = "sludge" + pH = 11 /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/carbon/M) var/power = -0.00003 * (M.bodytemperature ** 2) + 3 @@ -148,6 +156,7 @@ color = "#0000C8" taste_description = "muscle" metabolization_rate = 1.5 * REAGENTS_METABOLISM + pH = 13 /datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M) if(M.bodytemperature < T0C) @@ -163,6 +172,7 @@ description = "A mixture of cryoxadone and slime jelly, that apparently inverses the requirement for its activation." color = "#f7832a" taste_description = "spicy jelly" + pH = 12 /datum/reagent/medicine/pyroxadone/on_mob_life(mob/living/carbon/M) if(M.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT) @@ -194,6 +204,7 @@ color = "#669900" // rgb: 102, 153, 0 overdose_threshold = 30 taste_description = "fish" + pH = 12.2 /datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/M) M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. @@ -213,8 +224,9 @@ name = "Spaceacillin" id = "spaceacillin" description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#f2f2f2" metabolization_rate = 0.1 * REAGENTS_METABOLISM + pH = 8.1 //Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects. /datum/reagent/medicine/silver_sulfadiazine @@ -222,7 +234,8 @@ id = "silver_sulfadiazine" description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage." reagent_state = LIQUID - color = "#C8A5DC" + pH = 7.2 + color = "#ffeac9" /datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -235,6 +248,7 @@ if(show_message) to_chat(M, "You feel your burns healing! It stings like hell!") M.emote("scream") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) ..() /datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/carbon/M) @@ -250,6 +264,7 @@ color = "#f7ffa5" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 + pH = 10.7 /datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M) if(M.getFireLoss() > 50) @@ -271,6 +286,7 @@ description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. If ingested through other means, deals minor toxin damage." reagent_state = LIQUID color = "#FF9696" + pH = 6.7 /datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -283,6 +299,7 @@ if(show_message) to_chat(M, "You feel your bruises healing! It stings like hell!") M.emote("scream") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) ..() @@ -302,6 +319,7 @@ taste_description = "sweetness and salt" var/last_added = 0 var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active + pH = 5.5 /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M) if(last_added) @@ -340,6 +358,7 @@ reagent_state = LIQUID color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM + pH = 2.6 /datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C) C.hal_screwyhud = SCREWYHUD_HEALTHY @@ -378,6 +397,7 @@ description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only." reagent_state = LIQUID color = "#FFEBEB" + pH = 11.5 /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1) if(iscarbon(M)) @@ -388,6 +408,7 @@ M.adjustFireLoss(-1.25 * reac_volume) if(show_message) to_chat(M, "You feel your burns and bruises healing! It stings like hell!") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) ..() /datum/reagent/medicine/charcoal @@ -398,6 +419,7 @@ color = "#000000" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "ash" + pH = 5 /datum/reagent/medicine/charcoal/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(-2*REM, 0) @@ -415,6 +437,7 @@ color = "#DCDCDC" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 + pH = 2 /datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(-0.5*REM, 0) @@ -440,6 +463,7 @@ color = "#19C832" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "acid" + pH = 1.5 /datum/reagent/medicine/calomel/on_mob_life(mob/living/carbon/M) for(var/datum/reagent/R in M.reagents.reagent_list) @@ -457,6 +481,7 @@ reagent_state = LIQUID color = "#14FF3C" metabolization_rate = 2 * REAGENTS_METABOLISM + pH = 12 //It's a reducing agent /datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/M) if(M.radiation > 0) @@ -470,6 +495,7 @@ reagent_state = LIQUID color = "#003153" // RGB 0, 49, 83 metabolization_rate = 0.5 * REAGENTS_METABOLISM + pH = 8.9 /datum/reagent/medicine/prussian_blue/on_mob_life(mob/living/carbon/M) if(M.radiation > 0) @@ -483,6 +509,7 @@ reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + pH = 1 //One of the best buffers, NEVERMIND! var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) @@ -500,6 +527,7 @@ description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!" color = "#91D865" healtoxinlover = TRUE + pH = 12//invert /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" @@ -509,6 +537,7 @@ color = "#D2D2D2" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 + pH = 2.1 /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M) @@ -532,6 +561,7 @@ reagent_state = LIQUID color = "#00FFFF" metabolization_rate = 0.25 * REAGENTS_METABOLISM + pH = 2 /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M) M.adjustOxyLoss(-3*REM, 0) @@ -547,6 +577,7 @@ reagent_state = LIQUID color = "#FF6464" metabolization_rate = 0.25 * REAGENTS_METABOLISM + pH = 11 /datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M) M.adjustOxyLoss(-12*REM, 0) @@ -566,6 +597,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 45 addiction_threshold = 30 + pH = 12 /datum/reagent/medicine/ephedrine/on_mob_life(mob/living/carbon/M) M.AdjustStun(-20, 0) @@ -620,6 +652,7 @@ reagent_state = LIQUID color = "#64FFE6" metabolization_rate = 0.5 * REAGENTS_METABOLISM + pH = 11.5 /datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/carbon/M) if(prob(10)) @@ -637,6 +670,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 30 addiction_threshold = 25 + pH = 8.96 /datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L) ..() @@ -705,6 +739,7 @@ color = "#FFFFFF" metabolization_rate = 0.25 * REAGENTS_METABOLISM taste_description = "dull toxin" + pH = 10 /datum/reagent/medicine/oculine/on_mob_life(mob/living/carbon/M) var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES) @@ -736,6 +771,7 @@ color = "#000000" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 35 + pH = 12 /datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/M) if(M.health < 0) @@ -765,6 +801,7 @@ color = "#D2FFFA" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 + pH = 10.2 /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/M) if(M.health < 0) @@ -801,6 +838,7 @@ color = "#A0E85E" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "magnets" + pH = 0 /datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume) if(M.stat == DEAD) @@ -834,6 +872,7 @@ id = "mannitol" description = "Efficiently restores brain damage." color = "#DCDCFF" + pH = 10.4 /datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C) C.adjustBrainLoss(-2*REM) @@ -841,12 +880,26 @@ C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) ..() +/datum/reagent/medicine/neurine + name = "Neurine" + id = "neurine" + description = "Reacts with neural tissue, helping reform damaged connections. Can cure minor traumas." + color = "#EEFF8F" + +/datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C) + if(holder.has_reagent("neurotoxin")) + holder.remove_reagent("neurotoxin", 5) + if(prob(15)) + C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) + ..() + /datum/reagent/medicine/mutadone name = "Mutadone" id = "mutadone" description = "Removes jitteriness and restores genetic defects." color = "#5096C8" taste_description = "acid" + pH = 2 /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/M) M.jitteriness = 0 @@ -861,6 +914,7 @@ description = "Purges alcoholic substance from the patient's body and eliminates its side effects." color = "#00B4C8" taste_description = "raw egg" + pH = 4 /datum/reagent/medicine/antihol/on_mob_life(mob/living/carbon/M) M.dizziness = 0 @@ -882,6 +936,7 @@ color = "#78008C" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 + pH = 8.7 /datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) ..() @@ -919,6 +974,7 @@ reagent_state = LIQUID color = "#FFFFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + pH = 6.7 /datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/M) if(M.AdjustSleeping(-20, FALSE)) @@ -932,8 +988,9 @@ id = "bicaridine" description = "Restores bruising. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#fc2626" overdose_threshold = 30 + pH = 5 /datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-2*REM, 0) @@ -950,8 +1007,9 @@ id = "dexalin" description = "Restores oxygen loss. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#13d2f0" overdose_threshold = 30 + pH = 9.7 /datum/reagent/medicine/dexalin/on_mob_life(mob/living/carbon/M) M.adjustOxyLoss(-2*REM, 0) @@ -968,8 +1026,9 @@ id = "kelotane" description = "Restores fire damage. Overdose causes it instead." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ffc400" overdose_threshold = 30 + pH = 9 /datum/reagent/medicine/kelotane/on_mob_life(mob/living/carbon/M) M.adjustFireLoss(-2*REM, 0) @@ -986,9 +1045,10 @@ id = "antitoxin" description = "Heals toxin damage and removes toxins in the bloodstream. Overdose causes toxin damage." reagent_state = LIQUID - color = "#C8A5DC" + color = "#6aff00" overdose_threshold = 30 taste_description = "a roll of gauze" + pH = 10 /datum/reagent/medicine/antitoxin/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(-2*REM, 0) @@ -1007,7 +1067,8 @@ id = "inaprovaline" description = "Stabilizes the breathing of patients. Good for those in critical condition." reagent_state = LIQUID - color = "#C8A5DC" + pH = 8.5 + color = "#5dc1f0" /datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M) if(M.losebreath >= 5) @@ -1019,7 +1080,7 @@ id = "tricordrazine" description = "Has a high chance to heal all types of damage. Overdose instead causes it." reagent_state = LIQUID - color = "#C8A5DC" + color = "#e650c0" overdose_threshold = 30 taste_description = "grossness" @@ -1062,6 +1123,7 @@ description = "Miniature medical robots that swiftly restore bodily damage." reagent_state = SOLID color = "#555555" + pH = 11 /datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-5*REM, 0) //A ton of healing - this is a 50 telecrystal investment. @@ -1075,14 +1137,15 @@ . = 1 /datum/reagent/medicine/neo_jelly - name = "Neo Jelly" - id = "neo_jelly" - description = "Gradually regenerates all types of damage, without harming slime anatomy.Can OD" - reagent_state = LIQUID - metabolization_rate = 1 * REAGENTS_METABOLISM - color = "#91D865" - overdose_threshold = 30 - taste_description = "jelly" + name = "Neo Jelly" + id = "neo_jelly" + description = "Gradually regenerates all types of damage, without harming slime anatomy.Can OD" + reagent_state = LIQUID + metabolization_rate = 1 * REAGENTS_METABOLISM + color = "#91D865" + overdose_threshold = 30 + taste_description = "jelly" + pH = 11.8 /datum/reagent/medicine/neo_jelly/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-1.5*REM, 0) @@ -1105,6 +1168,7 @@ description = "Ichor from an extremely powerful plant. Great for restoring wounds, but it's a little heavy on the brain." color = rgb(255, 175, 0) overdose_threshold = 25 + pH = 11 /datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-3 * REM, 0) @@ -1113,7 +1177,7 @@ M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) - M.adjustStaminaLoss(-30 * REM, 0) + M.adjustStaminaLoss(-13 * REM, 0) M.jitteriness = min(max(0, M.jitteriness + 3), 30) M.druggy = min(max(0, M.druggy + 10), 15) //See above ..() @@ -1132,6 +1196,7 @@ reagent_state = LIQUID color = "#27870a" metabolization_rate = 0.4 * REAGENTS_METABOLISM + pH = 4.3 /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/M) for(var/datum/reagent/drug/R in M.reagents.reagent_list) @@ -1151,9 +1216,10 @@ name = "Lavaland Extract" id = "lavaland_extract" description = "An extract of lavaland atmospheric and mineral elements. Heals the user in small doses, but is extremely toxic otherwise." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#a1a1a1" overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent can_synth = FALSE + pH = 14 /datum/reagent/medicine/lavaland_extract/on_mob_life(mob/living/carbon/M) M.heal_bodypart_damage(5,5) @@ -1172,7 +1238,7 @@ name = "Changeling Adrenaline" id = "changelingadrenaline" description = "Reduces the duration of unconciousness, knockdown and stuns. Restores stamina, but deals toxin damage when overdosed." - color = "#C8A5DC" + color = "#918e53" overdose_threshold = 30 /datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/M as mob) @@ -1193,7 +1259,7 @@ name = "Changeling Haste" id = "changelinghaste" description = "Drastically increases movement speed, but deals toxin damage." - color = "#C8A5DC" + color = "#669153" metabolization_rate = 1 /datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) @@ -1217,6 +1283,7 @@ description = "A medication used to treat pain, fever, and inflammation, along with heart attacks." color = "#F5F5F5" self_consuming = TRUE + pH = 12.5 /datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M) ..() @@ -1249,6 +1316,7 @@ overdose_threshold = 20 // with the random effects this might be awesome or might kill you at less than 10u (extensively tested) taste_description = "salt" // it actually does taste salty var/overdose_progress = 0 // to track overdose progress + pH = 7.89 /datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M) ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id) @@ -1305,3 +1373,38 @@ M.adjustStaminaLoss(1.5*REM, 0) ..() return TRUE + +/datum/reagent/medicine/psicodine + name = "Psicodine" + id = "psicodine" + description = "Suppresses anxiety and other various forms of mental distress. Overdose causes hallucinations and minor toxin damage." + reagent_state = LIQUID + color = "#07E79E" + metabolization_rate = 0.25 * REAGENTS_METABOLISM + overdose_threshold = 30 + pH = 9.12 + +/datum/reagent/medicine/psicodine/on_mob_add(mob/living/L) + ..() + ADD_TRAIT(L, TRAIT_FEARLESS, id) + +/datum/reagent/medicine/psicodine/on_mob_delete(mob/living/L) + REMOVE_TRAIT(L, TRAIT_FEARLESS, id) + ..() + +/datum/reagent/medicine/psicodine/on_mob_life(mob/living/carbon/M) + M.jitteriness = max(0, M.jitteriness-6) + M.dizziness = max(0, M.dizziness-6) + M.confused = max(0, M.confused-6) + M.disgust = max(0, M.disgust-6) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then... + mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral + ..() + . = 1 + +/datum/reagent/medicine/psicodine/overdose_process(mob/living/M) + M.hallucination = min(max(0, M.hallucination + 5), 60) + M.adjustToxLoss(1, 0) + ..() + . = 1 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 890403691e..07c9b166ff 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -10,6 +10,7 @@ glass_name = "glass of tomato juice" glass_desc = "Are you sure this is tomato juice?" shot_glass_icon_state = "shotglassred" + pH = 7.4 /datum/reagent/blood/reaction_mob(mob/living/L, method=TOUCH, reac_volume) if(data && data["viruses"]) @@ -95,6 +96,7 @@ description = "You don't even want to think about what's in here." taste_description = "gross iron" shot_glass_icon_state = "shotglassred" + pH = 7.45 /datum/reagent/vaccine //data must contain virus type @@ -195,6 +197,7 @@ glass_icon_state = "glass_clear" glass_name = "glass of holy water" glass_desc = "A glass of holy water." + pH = 7.5 //God is alkaline /datum/reagent/water/holywater/on_mob_metabolize(mob/living/L) ..() @@ -206,7 +209,12 @@ /datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(is_servant_of_ratvar(M)) - to_chat(M, "A darkness begins to spread its unholy tendrils through your mind, purging the Justiciar's influence!") + to_chat(M, "A fog spreads through your mind, purging the Justiciar's influence!") + ..() + +/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(iscultist(M)) + to_chat(M, "A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence") ..() /datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M) @@ -261,11 +269,12 @@ qdel(R) T.Bless() -/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke +/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke name = "Unholy Water" id = "unholywater" description = "Something that shouldn't exist on this plane of existence." taste_description = "suffering" + pH = 6.5 /datum/reagent/fuel/unholywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -280,11 +289,11 @@ M.AdjustStun(-40, 0) M.AdjustKnockdown(-40, 0) M.adjustStaminaLoss(-10, 0) - M.adjustToxLoss(-2, 0) + M.adjustToxLoss(-2, 0, TRUE) M.adjustOxyLoss(-2, 0) M.adjustBruteLoss(-2, 0) M.adjustFireLoss(-2, 0) - if(ishuman(M) && M.blood_volume < BLOOD_VOLUME_NORMAL) + if(ishuman(M) && M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) M.blood_volume += 3 else // Will deal about 90 damage when 50 units are thrown M.adjustBrainLoss(3, 150) @@ -308,6 +317,46 @@ M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard? M.adjustBrainLoss(5, 150) holder.remove_reagent(id, 1) + pH = 0.1 + +/datum/reagent/fuel/holyoil //Its oil + name = "Zelus Oil" + id = "holyoil" + description = "Oil blessed by a greater being." + taste_description = "metallic oil" + +/datum/reagent/fuel/holyoil/on_mob_life(mob/living/carbon/M) + if(is_servant_of_ratvar(M)) + M.drowsyness = max(M.drowsyness-5, 0) + M.AdjustUnconscious(-60, 0) + M.AdjustStun(-30, 0) + M.AdjustKnockdown(-70, 0) + M.adjustStaminaLoss(-15, 0) + M.adjustToxLoss(-5, 0, TRUE) + M.adjustOxyLoss(-3, 0) + M.adjustBruteLoss(-3, 0) + M.adjustFireLoss(-5, 0) + if(iscultist(M)) + M.AdjustUnconscious(1, 0) + M.AdjustStun(10, 0) + M.AdjustKnockdown(20, 0) + M.adjustStaminaLoss(15, 0) + else + M.adjustToxLoss(3, 0) + M.adjustOxyLoss(2, 0) + M.adjustStaminaLoss(10, 0) + holder.remove_reagent(id, 1) + return TRUE + +//We only get 30u to start with... + +/datum/reagent/fuel/holyoil/reaction_obj(obj/O, reac_volume) + . = ..() + if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + reac_volume = min(reac_volume, M.amount) + new/obj/item/stack/tile/brass(get_turf(M), reac_volume) + M.use(reac_volume) /datum/reagent/medicine/omnizine/godblood name = "Godblood" @@ -336,6 +385,7 @@ metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle. taste_description = "sour oranges" + pH = 5 /datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(ishuman(M)) @@ -660,6 +710,7 @@ color = "#202040" // rgb: 20, 20, 40 metabolization_rate = 0.25 * REAGENTS_METABOLISM taste_description = "bitterness" + pH = 10 /datum/reagent/serotrotium/on_mob_life(mob/living/carbon/M) if(ishuman(M)) @@ -674,6 +725,7 @@ reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 // oderless and tasteless + pH = 9.2//It's acutally a huge range and very dependant on the chemistry but pH is basically a made up var in it's implementation anyways /datum/reagent/oxygen/reaction_obj(obj/O, reac_volume) if((!O) || (!reac_volume)) @@ -694,6 +746,7 @@ reagent_state = SOLID color = "#6E3B08" // rgb: 110, 59, 8 taste_description = "metal" + pH = 5.5 /datum/reagent/copper/reaction_obj(obj/O, reac_volume) if(istype(O, /obj/item/stack/sheet/metal)) @@ -710,6 +763,7 @@ color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 + /datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume) if((!O) || (!reac_volume)) return 0 @@ -729,6 +783,7 @@ reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 + pH = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve pHes? (not 0 so I don't get div/0 errors) /datum/reagent/potassium name = "Potassium" @@ -760,6 +815,7 @@ reagent_state = SOLID color = "#BF8C00" // rgb: 191, 140, 0 taste_description = "rotten eggs" + pH = 4.5 /datum/reagent/carbon name = "Carbon" @@ -768,6 +824,7 @@ reagent_state = SOLID color = "#1C1300" // rgb: 30, 20, 0 taste_description = "sour chalk" + pH = 5 /datum/reagent/carbon/reaction_turf(turf/T, reac_volume) if(!isspaceturf(T)) @@ -782,6 +839,7 @@ reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 taste_description = "chlorine" + pH = 7.4 /datum/reagent/chlorine/on_mob_life(mob/living/carbon/M) M.take_bodypart_damage(1*REM, 0, 0, 0) @@ -795,6 +853,7 @@ reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 taste_description = "acid" + pH = 2 /datum/reagent/fluorine/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(1*REM, 0) @@ -808,6 +867,7 @@ reagent_state = SOLID color = "#808080" // rgb: 128, 128, 128 taste_description = "salty metal" + pH = 11.6 /datum/reagent/phosphorus name = "Phosphorus" @@ -816,6 +876,7 @@ reagent_state = SOLID color = "#832828" // rgb: 131, 40, 40 taste_description = "vinegar" + pH = 6.5 /datum/reagent/lithium name = "Lithium" @@ -824,6 +885,7 @@ reagent_state = SOLID color = "#808080" // rgb: 128, 128, 128 taste_description = "metal" + pH = 11.3 /datum/reagent/lithium/on_mob_life(mob/living/carbon/M) if(M.canmove && !isspaceturf(M.loc)) @@ -838,6 +900,7 @@ description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity." color = "#808080" // rgb: 128, 128, 128 taste_description = "sweetness" + pH = 9 /datum/reagent/radium name = "Radium" @@ -846,6 +909,7 @@ reagent_state = SOLID color = "#C7C7C7" // rgb: 199,199,199 taste_description = "the colour blue and regret" + pH = 10 /datum/reagent/radium/on_mob_life(mob/living/carbon/M) M.apply_effect(2*REM/M.metabolism_efficiency,EFFECT_IRRADIATE,0) @@ -863,8 +927,9 @@ name = "Sterilizine" id = "sterilizine" description = "Sterilizes wounds in preparation for surgery." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#e6f1f5" // rgb: 200, 165, 220 taste_description = "bitterness" + pH = 10.5 /datum/reagent/space_cleaner/sterilizine/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) if(method in list(TOUCH, VAPOR, PATCH)) @@ -880,11 +945,12 @@ description = "Pure iron is a metal." reagent_state = SOLID taste_description = "iron" + pH = 6 - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#c2391d" /datum/reagent/iron/on_mob_life(mob/living/carbon/C) - if(C.blood_volume < BLOOD_VOLUME_NORMAL) + if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio)) C.blood_volume += 0.5 ..() @@ -922,6 +988,7 @@ reagent_state = SOLID color = "#B8B8C0" // rgb: 184, 184, 192 taste_description = "the inside of a reactor" + pH = 4 /datum/reagent/uranium/on_mob_life(mob/living/carbon/M) M.apply_effect(1/M.metabolism_efficiency,EFFECT_IRRADIATE,0) @@ -942,10 +1009,11 @@ reagent_state = SOLID color = "#0000CC" taste_description = "fizzling blue" + pH = 12 /datum/reagent/bluespace/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) - do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg') //4 tiles per crystal + do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal ..() /datum/reagent/bluespace/on_mob_life(mob/living/carbon/M) @@ -957,7 +1025,7 @@ ..() /mob/living/proc/bluespace_shuffle() - do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg') + do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) /datum/reagent/aluminium name = "Aluminium" @@ -974,6 +1042,7 @@ reagent_state = SOLID color = "#A8A8A8" // rgb: 168, 168, 168 taste_mult = 0 + pH = 10 /datum/reagent/fuel name = "Welding fuel" @@ -984,6 +1053,8 @@ glass_icon_state = "dr_gibb_glass" glass_name = "glass of welder fuel" glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption." + pH = 4 + /datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! if(method == TOUCH || method == VAPOR) @@ -1002,6 +1073,7 @@ description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" color = "#A5F0EE" // rgb: 165, 240, 238 taste_description = "sourness" + pH = 5.5 /datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume) if(istype(O, /obj/effect/decal/cleanable)) @@ -1059,6 +1131,7 @@ description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected." metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "acid" + pH = 2 /datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(3.33) @@ -1076,9 +1149,10 @@ name = "Cryptobiolin" id = "cryptobiolin" description = "Cryptobiolin causes confusion and dizziness." - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#7529b3" // rgb: 200, 165, 220 metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "sourness" + pH = 11.9 /datum/reagent/cryptobiolin/on_mob_life(mob/living/carbon/M) M.Dizzy(1) @@ -1091,8 +1165,9 @@ name = "Impedrezene" id = "impedrezene" description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions." - color = "#C8A5DC" // rgb: 200, 165, 220A + color = "#587a31" // rgb: 200, 165, 220A taste_description = "numbness" + pH = 9.1 /datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M) M.jitteriness = max(M.jitteriness-5,0) @@ -1135,6 +1210,7 @@ color = "#92D17D" // rgb: 146, 209, 125 can_synth = FALSE taste_description = "slime" + pH = 11 /datum/reagent/fungalspores/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) @@ -1146,6 +1222,7 @@ description = "A perfluoronated sulfonic acid that forms a foam when mixed with water." color = "#9E6B38" // rgb: 158, 107, 56 taste_description = "metal" + pH = 13 /datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually. name = "Foaming agent" @@ -1154,6 +1231,7 @@ reagent_state = SOLID color = "#664B63" // rgb: 102, 75, 99 taste_description = "metal" + pH = 12.5 /datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls. name = "Smart foaming agent" @@ -1162,6 +1240,7 @@ reagent_state = SOLID color = "#664B63" // rgb: 102, 75, 99 taste_description = "metal" + pH = 11.8 /datum/reagent/ammonia name = "Ammonia" @@ -1170,6 +1249,7 @@ reagent_state = GAS color = "#404030" // rgb: 64, 64, 48 taste_description = "mordant" + pH = 11.6 /datum/reagent/diethylamine name = "Diethylamine" @@ -1177,6 +1257,7 @@ description = "A secondary amine, mildly corrosive." color = "#604030" // rgb: 96, 64, 48 taste_description = "iron" + pH = 12 /datum/reagent/carbondioxide name = "Carbon Dioxide" @@ -1185,6 +1266,7 @@ description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs." color = "#B0B0B0" // rgb : 192, 192, 192 taste_description = "something unknowable" + pH = 6 /datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume) if((!O) || (!reac_volume)) @@ -1206,6 +1288,7 @@ metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "#808080" taste_description = "sweetness" + pH = 5.8 /datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume) if((!O) || (!reac_volume)) @@ -1265,6 +1348,7 @@ metabolization_rate = REAGENTS_METABOLISM color = "90560B" taste_description = "burning" + pH = 2 /datum/reagent/nitryl/on_mob_metabolize(mob/living/L) ..() @@ -1298,6 +1382,7 @@ colorname = "red" color = "#DA0000" // red random_color_list = list("#DA0000") + pH = 0.5 /datum/reagent/colorful_reagent/crayonpowder/orange name = "Orange Crayon Powder" @@ -1305,6 +1390,7 @@ colorname = "orange" color = "#FF9300" // orange random_color_list = list("#FF9300") + pH = 2 /datum/reagent/colorful_reagent/crayonpowder/yellow name = "Yellow Crayon Powder" @@ -1312,6 +1398,7 @@ colorname = "yellow" color = "#FFF200" // yellow random_color_list = list("#FFF200") + pH = 5 /datum/reagent/colorful_reagent/crayonpowder/green name = "Green Crayon Powder" @@ -1320,12 +1407,14 @@ color = "#A8E61D" // green random_color_list = list("#A8E61D") + /datum/reagent/colorful_reagent/crayonpowder/blue name = "Blue Crayon Powder" id = "bluecrayonpowder" colorname = "blue" color = "#00B7EF" // blue random_color_list = list("#00B7EF") + pH = 10 /datum/reagent/colorful_reagent/crayonpowder/purple name = "Purple Crayon Powder" @@ -1333,6 +1422,7 @@ colorname = "purple" color = "#DA00FF" // purple random_color_list = list("#DA00FF") + pH = 13 /datum/reagent/colorful_reagent/crayonpowder/invisible name = "Invisible Crayon Powder" @@ -1367,6 +1457,7 @@ color = "#000000" // RBG: 0, 0, 0 var/tox_prob = 0 taste_description = "plant food" + pH = 3 /datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/M) if(prob(tox_prob)) @@ -1380,6 +1471,7 @@ description = "Cheap and extremely common type of plant nutriment." color = "#376400" // RBG: 50, 100, 0 tox_prob = 10 + pH = 2 /datum/reagent/plantnutriment/left4zednutriment name = "Left 4 Zed" @@ -1387,6 +1479,7 @@ description = "Unstable nutriment that makes plants mutate more often than usual." color = "#1A1E4D" // RBG: 26, 30, 77 tox_prob = 25 + pH = 1.5 /datum/reagent/plantnutriment/robustharvestnutriment name = "Robust Harvest" @@ -1394,6 +1487,7 @@ description = "Very potent nutriment that prevents plants from mutating." color = "#9D9D00" // RBG: 157, 157, 0 tox_prob = 15 + pH = 1 @@ -1410,7 +1504,7 @@ id = "oil" description = "Burns in a small smoky fire, mostly used to get Ash." reagent_state = LIQUID - color = "#C8A5DC" + color = "#292929" taste_description = "oil" /datum/reagent/stable_plasma @@ -1418,9 +1512,10 @@ id = "stable_plasma" description = "Non-flammable plasma locked into a liquid form that cannot ignite or become gaseous/solid." reagent_state = LIQUID - color = "#C8A5DC" + color = "#6b008f" taste_description = "bitterness" taste_mult = 1.5 + pH = 1.5 /datum/reagent/stable_plasma/on_mob_life(mob/living/carbon/C) C.adjustPlasma(10) @@ -1431,15 +1526,16 @@ id = "iodine" description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing." reagent_state = LIQUID - color = "#C8A5DC" + color = "#694600" taste_description = "metal" + pH = 4.5 /datum/reagent/carpet name = "Carpet" id = "carpet" description = "For those that need a more creative way to roll out a red carpet." reagent_state = LIQUID - color = "#C8A5DC" + color = "#b51d05" taste_description = "carpet" // Your tounge feels furry. /datum/reagent/carpet/reaction_turf(turf/T, reac_volume) @@ -1453,39 +1549,42 @@ id = "bromine" description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption." reagent_state = LIQUID - color = "#C8A5DC" + color = "#b37740" taste_description = "chemicals" + pH = 7.8 /datum/reagent/phenol name = "Phenol" id = "phenol" description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own." reagent_state = LIQUID - color = "#C8A5DC" - taste_description = "acid" + taste_description = "sweet and tarry" //Again, not a strong acid. + pH = 5.5 + color = "#e6e8ff" /datum/reagent/ash name = "Ash" id = "ash" description = "Supposedly phoenixes rise from these, but you've never seen it." reagent_state = LIQUID - color = "#C8A5DC" + color = "#665c56" taste_description = "ash" + pH = 6.5 /datum/reagent/acetone name = "Acetone" id = "acetone" description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life." reagent_state = LIQUID - color = "#C8A5DC" - taste_description = "acid" + taste_description = "solvent"//It's neutral though..? + color = "#e6e6e6" /datum/reagent/colorful_reagent name = "Colorful Reagent" id = "colorful_reagent" description = "Thoroughly sample the rainbow." reagent_state = LIQUID - color = "#C8A5DC" + color = "#FFFF00" var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") taste_description = "rainbows" var/no_mob_color = FALSE @@ -1515,7 +1614,7 @@ id = "hair_dye" description = "Has a high chance of making you look like a mad scientist." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ff00dd" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code taste_description = "sourness" @@ -1532,7 +1631,7 @@ id = "barbers_aid" description = "A solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" + color = "#fac34b" taste_description = "sourness" /datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -1550,7 +1649,7 @@ id = "concentrated_barbers_aid" description = "A concentrated solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" + color = "#ffaf00" taste_description = "sourness" /datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -1568,6 +1667,7 @@ reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 taste_description = "cool salt" + pH = 11.2 /datum/reagent/lye name = "Lye" @@ -1575,7 +1675,8 @@ description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming." reagent_state = LIQUID color = "#FFFFD6" // very very light yellow - taste_description = "acid" + taste_description = "alkali" //who put ACID for NaOH ???? + pH = 13 /datum/reagent/drying_agent name = "Drying agent" @@ -1584,6 +1685,7 @@ reagent_state = LIQUID color = "#A70FFF" taste_description = "dryness" + pH = 10.7 /datum/reagent/drying_agent/reaction_turf(turf/open/T, reac_volume) if(istype(T)) @@ -1655,6 +1757,7 @@ description = "Royal Bee Jelly, if injected into a Queen Space Bee said bee will split into two bees." color = "#00ff80" taste_description = "strange honey" + pH = 3 /datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/M) if(prob(2)) @@ -1676,6 +1779,7 @@ metabolization_rate = INFINITY can_synth = FALSE taste_description = "brains" + pH = 0.5 /datum/reagent/romerol/reaction_mob(mob/living/carbon/human/H, method=TOUCH, reac_volume) // Silently add the zombie infection organ to be activated upon death @@ -1734,6 +1838,7 @@ description = "the petroleum based components of plastic." color = "#f7eded" taste_description = "plastic" + pH = 6 /datum/reagent/glitter name = "generic glitter" @@ -1776,6 +1881,7 @@ color = "#AAAAAA55" taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM + pH = 15 /datum/reagent/pax/on_mob_metabolize(mob/living/L) ..() @@ -1864,6 +1970,13 @@ color = "#FAEAFF" taste_description = "synthetic catnip" +/datum/reagent/moonsugar/on_mob_life(mob/living/carbon/M) + if(prob(20)) + to_chat(M, "You find yourself unable to supress the desire to meow!") + M.emote("nya") + ..() + +//Kept for legacy, I think it will break everything if you enable it. /datum/reagent/penis_enlargement name = "Penis Enlargement" id = "penis_enlargement" @@ -1879,4 +1992,42 @@ if(added_length >= 0.20) //Only add the length if it's greater than or equal to 0.2. This is to prevent people from smoking the reagents and causing the penis to update constantly. P.length += added_length P.update() - ..() \ No newline at end of file + ..() + +/datum/reagent/changeling_string + name = "UNKNOWN" + id = "changeling_sting_real" + description = "404: Chemical not found." + metabolization_rate = REAGENTS_METABOLISM + color = "#0000FF" + can_synth = FALSE + var/datum/dna/original_dna + var/reagent_ticks = 0 + invisible = TRUE + +/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C) + if(C && C.dna && data["desired_dna"]) + original_dna = new C.dna.type + C.dna.copy_dna(original_dna) + var/datum/dna/new_dna = data["desired_dna"] + new_dna.copy_dna(C.dna) + C.real_name = new_dna.real_name + C.updateappearance(mutcolor_update=1) + C.update_body() + C.domutcheck() + C.regenerate_icons() + ..() + +/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C) + if(original_dna) + original_dna.copy_dna(C.dna) + C.real_name = original_dna.real_name + C.updateappearance(mutcolor_update=1) + C.update_body() + C.domutcheck() + C.regenerate_icons() + ..() + +/datum/reagent/changeling_string/Destroy() + qdel(original_dna) + return ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 6bd165f23e..2848c336e2 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -23,6 +23,7 @@ color = "#792300" // rgb: 121, 35, 0 toxpwr = 2.5 taste_description = "mushroom" + pH = 13 /datum/reagent/toxin/mutagen name = "Unstable mutagen" @@ -32,6 +33,7 @@ toxpwr = 0 taste_description = "slime" taste_mult = 0.9 + pH = 2 /datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume) if(!..()) @@ -61,6 +63,7 @@ taste_mult = 1.5 color = "#8228A0" toxpwr = 3 + pH = 4 /datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C) if(holder.has_reagent("epinephrine")) @@ -93,6 +96,7 @@ color = "#7DC3A0" toxpwr = 0 taste_description = "acid" + pH = 1.2 /datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/C) . = TRUE @@ -115,6 +119,7 @@ toxpwr = 0 taste_description = "slime" taste_mult = 1.3 + pH = 10 /datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/M) if(prob(10)) @@ -133,6 +138,7 @@ color = "#CF3600" // rgb: 207, 54, 0 toxpwr = 0 taste_description = "mint" + pH = 8 /datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M) if(HAS_TRAIT(M, TRAIT_FAT)) @@ -146,6 +152,7 @@ color = "#003333" // rgb: 0, 51, 51 toxpwr = 2 taste_description = "fish" + pH = 12 /datum/reagent/toxin/zombiepowder name = "Zombie Powder" @@ -155,6 +162,7 @@ color = "#669900" // rgb: 102, 153, 0 toxpwr = 0.5 taste_description = "death" + pH = 13 /datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() @@ -177,6 +185,7 @@ color = "#664700" // rgb: 102, 71, 0 toxpwr = 0.8 taste_description = "death" + pH = 14.5 /datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L) ..() @@ -198,6 +207,7 @@ color = "#B31008" // rgb: 139, 166, 233 toxpwr = 0 taste_description = "sourness" + pH = 11 /datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/M) M.hallucination += 5 @@ -210,6 +220,7 @@ color = "#49002E" // rgb: 73, 0, 46 toxpwr = 1 taste_mult = 1 + pH = 2 /datum/reagent/toxin/plantbgone/reaction_obj(obj/O, reac_volume) if(istype(O, /obj/structure/alien/weeds)) @@ -234,6 +245,7 @@ id = "weedkiller" description = "A harmful toxic mixture to kill weeds. Do not ingest!" color = "#4B004B" // rgb: 75, 0, 75 + pH = 3 /datum/reagent/toxin/pestkiller name = "Pest Killer" @@ -241,6 +253,7 @@ description = "A harmful toxic mixture to kill pests. Do not ingest!" color = "#4B004B" // rgb: 75, 0, 75 toxpwr = 1 + pH = 3.2 /datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume) ..() @@ -254,6 +267,7 @@ description = "A natural toxin produced by blob spores that inhibits vision when ingested." color = "#9ACD32" toxpwr = 1 + pH = 11 /datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/C) C.damageoverlaytemp = 60 @@ -268,6 +282,7 @@ color = "#9ACD32" toxpwr = 0.5 taste_description = "burning" + pH = 13 /datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/M) M.adjust_fire_stacks(2) @@ -282,6 +297,7 @@ color = "#000067" // rgb: 0, 0, 103 toxpwr = 0 metabolization_rate = 1.5 * REAGENTS_METABOLISM + pH = 11 /datum/reagent/toxin/chloralhydrate/on_mob_life(mob/living/carbon/M) switch(current_cycle) @@ -326,6 +342,7 @@ glass_icon_state = "beerglass" glass_name = "glass of beer" glass_desc = "A freezing pint of beer." + pH = 2 /datum/reagent/toxin/fakebeer/on_mob_life(mob/living/carbon/M) switch(current_cycle) @@ -343,6 +360,7 @@ reagent_state = SOLID color = "#5B2E0D" // rgb: 91, 46, 13 toxpwr = 0.5 + pH = 4.2 /datum/reagent/toxin/teapowder name = "Ground Tea Leaves" @@ -351,6 +369,7 @@ reagent_state = SOLID color = "#7F8400" // rgb: 127, 132, 0 toxpwr = 0.5 + pH = 4.9 /datum/reagent/toxin/mutetoxin //the new zombie powder. name = "Mute Toxin" @@ -359,6 +378,7 @@ color = "#F0F8FF" // rgb: 240, 248, 255 toxpwr = 0 taste_description = "silence" + pH = 12.2 /datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/M) M.silent = max(M.silent, 3) @@ -816,6 +836,7 @@ var/acidpwr = 10 //the amount of protection removed from the armour taste_description = "acid" self_consuming = TRUE + pH = 2.75 /datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) if(!istype(C)) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 50006eef62..32155c9b89 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -17,6 +17,24 @@ var/mix_message = "The solution begins to bubble." //The message shown to nearby people upon mixing, if applicable var/mix_sound = 'sound/effects/bubbles.ogg' //The sound played upon mixing, if applicable + //FermiChem! + var/OptimalTempMin = 200 // Lower area of bell curve for determining heat based rate reactions + var/OptimalTempMax = 800 // Upper end for above + var/ExplodeTemp = 900 // Temperature at which reaction explodes - If any reaction is this hot, it explodes! + var/OptimalpHMin = 5 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase) + var/OptimalpHMax = 10 // Higest value for above + var/ReactpHLim = 3 // How far out pH wil react, giving impurity place (Exponential phase) + var/CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)//Not implemented yet + var/CurveSharpT = 2 // How sharp the temperature exponential curve is (to the power of value) + var/CurveSharppH = 2 // How sharp the pH exponential curve is (to the power of value) + var/ThermicConstant = 1 // Temperature change per 1u produced + var/HIonRelease = 0.1 // pH change per 1u reaction + var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect + var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics + var/FermiExplode = FALSE // If the chemical explodes in a special way + var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this. + + /datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume, specialreact) return //I recommend you set the result amount to the total volume of all components. diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm index d91e2af7e9..27b1fe12ee 100644 --- a/code/modules/reagents/chemistry/recipes/drugs.dm +++ b/code/modules/reagents/chemistry/recipes/drugs.dm @@ -41,6 +41,13 @@ results = list("aranesp" = 3) required_reagents = list("epinephrine" = 1, "atropine" = 1, "morphine" = 1) +/datum/chemical_reaction/happiness + name = "Happiness" + id = "happiness" + results = list("happiness" = 4) + required_reagents = list("nitrous_oxide" = 2, "epinephrine" = 1, "ethanol" = 1) + required_catalysts = list("plasma" = 5) + /datum/chemical_reaction/skooma name = "skooma" id = "skooma" diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 727048a12c..59865dd1da 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -178,6 +178,12 @@ results = list("mutadone" = 3) required_reagents = list("mutagen" = 1, "acetone" = 1, "bromine" = 1) +/datum/chemical_reaction/neurine + name = "Neurine" + id = "neurine" + results = list("neurine" = 3) + required_reagents = list("mannitol" = 1, "acetone" = 1, "oxygen" = 1) + /datum/chemical_reaction/antihol name = "antihol" id = "antihol" @@ -258,3 +264,9 @@ results = list("modafinil" = 5) required_reagents = list("diethylamine" = 1, "ammonia" = 1, "phenol" = 1, "acetone" = 1, "sacid" = 1) required_catalysts = list("bromine" = 1) // as close to the real world synthesis as possible + +/datum/chemical_reaction/psicodine + name = "Psicodine" + id = "psicodine" + results = list("psicodine" = 5) + required_reagents = list( "mannitol" = 2, "water" = 2, "impedrezene" = 1) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index bcd08b1853..e34f34675c 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -528,6 +528,16 @@ /datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume) chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life") // Lol. +//This is missing, I'm adding it back (see tgwiki). Not sure why we don't have it. +/datum/chemical_reaction/life_friendly + name = "Life (Friendly)" + id = "life_friendly" + required_reagents = list("strange_reagent" = 1, "synthflesh" = 1, "sugar" = 1) + required_temp = 374 + +/datum/chemical_reaction/life_friendly/on_reaction(datum/reagents/holder, created_volume) + chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life (friendly)", FRIENDLY_SPAWN) //Pray for cute cats + /datum/chemical_reaction/corgium name = "corgium" id = "corgium" diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index db5f7b198c..8edca91a91 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -216,7 +216,7 @@ /datum/chemical_reaction/slime/slimefreeze/on_reaction(datum/reagents/holder) var/turf/T = get_turf(holder.my_atom) - T.visible_message("The slime extract begins to vibrate adorably!") + T.visible_message("The slime extract starts to feel extremely cold!") addtimer(CALLBACK(src, .proc/freeze, holder), 50) var/obj/item/slime_extract/M = holder.my_atom deltimer(M.qdel_timer) @@ -227,7 +227,8 @@ if(holder && holder.my_atom) var/turf/open/T = get_turf(holder.my_atom) if(istype(T)) - T.atmos_spawn_air("nitrogen=50;TEMP=2.7") + var/datum/gas/gastype = /datum/gas/nitrogen + T.atmos_spawn_air("[initial(gastype.id)]=50;TEMP=2.7") /datum/chemical_reaction/slime/slimefireproof name = "Slime Fireproof" @@ -370,6 +371,11 @@ /datum/chemical_reaction/slime/slimebloodlust/on_reaction(datum/reagents/holder) for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null)) + if(slime.docile) //Undoes docility, but doesn't make rabid. + slime.visible_message("[slime] forgets its training, becoming wild once again!") + slime.docile = FALSE + slime.update_name() + continue slime.rabid = 1 slime.visible_message("The [slime] is driven into a frenzy!") ..() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 13e809f7cb..48abfcb649 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -1,3 +1,6 @@ +#define PH_WEAK (1 << 0) +#define TEMP_WEAK (1 << 1) + /obj/item/reagent_containers name = "Container" desc = "..." @@ -12,6 +15,8 @@ var/spawned_disease = null var/disease_amount = 20 var/spillable = FALSE + var/beaker_weakness_bitflag = NONE//Bitflag! + var/container_HP = 2 /obj/item/reagent_containers/Initialize(mapload, vol) . = ..() @@ -123,9 +128,50 @@ reagents.clear_reagents() +//melts plastic beakers /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) reagents.expose_temperature(1000) + if(beaker_weakness_bitflag & TEMP_WEAK) + var/list/seen = viewers(5, get_turf(src)) + var/iconhtml = icon2html(src, seen) + for(var/mob/H in seen) + to_chat(H, "[iconhtml] \The [src]'s melts from the temperature!") + playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1) + qdel(src) ..() +//melts plastic beakers /obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - reagents.expose_temperature(exposed_temperature) \ No newline at end of file + reagents.expose_temperature(exposed_temperature) + temp_check() + +/obj/item/reagent_containers/proc/temp_check() + if(beaker_weakness_bitflag & TEMP_WEAK) + if(reagents.chem_temp >= 444)//assuming polypropylene + var/list/seen = viewers(5, get_turf(src)) + var/iconhtml = icon2html(src, seen) + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [src]'s melts from the temperature!") + playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1) + to_chat(M, "[iconhtml] Have you tried using glass or meta beakers for high temperature reactions? These are immune to temperature effects.") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from temperature") + qdel(src) + +//melts glass beakers +/obj/item/reagent_containers/proc/pH_check() + if(beaker_weakness_bitflag & PH_WEAK) + if((reagents.pH < 0.5) || (reagents.pH > 13.5)) + var/list/seen = viewers(5, get_turf(src)) + var/iconhtml = icon2html(src, seen) + container_HP-- + if(container_HP <= 0) + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [src]'s melts from the extreme pH!") + playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from pH") + qdel(src) + else + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [src]'s is damaged by the extreme pH and begins to deform!") + playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1) + to_chat(M, "[iconhtml] Have you tried using plastic beakers (XL) or metabeakers for high pH reactions? These beakers are immune to pH effects.") diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 66befb1bb6..249ed56d20 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -240,7 +240,7 @@ name = "Rhinovirus culture bottle" desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium." spawned_disease = /datum/disease/advance/cold - + /obj/item/reagent_containers/glass/bottle/flu_virion name = "Flu virion culture bottle" desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium." diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 9bc6bef8a5..014401b72c 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -6,6 +6,7 @@ reagent_flags = OPENCONTAINER spillable = TRUE resistance_flags = ACID_PROOF + container_HP = 3 /obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target) @@ -108,11 +109,13 @@ /obj/item/reagent_containers/glass/beaker name = "beaker" - desc = "A beaker. It can hold up to 50 units." + desc = "A beaker. It can hold up to 50 units. Unable to withstand extreme pHes" icon = 'icons/obj/chemical.dmi' icon_state = "beaker" item_state = "beaker" materials = list(MAT_GLASS=500) + beaker_weakness_bitflag = PH_WEAK + container_HP = 5 /obj/item/reagent_containers/glass/beaker/Initialize() . = ..() @@ -152,27 +155,33 @@ /obj/item/reagent_containers/glass/beaker/jar name = "honey jar" - desc = "A jar for honey. It can hold up to 50 units of sweet delight." + desc = "A jar for honey. It can hold up to 50 units of sweet delight. Unable to withstand reagents of an extreme pH." icon = 'icons/obj/chemical.dmi' icon_state = "vapour" /obj/item/reagent_containers/glass/beaker/large name = "large beaker" - desc = "A large beaker. Can hold up to 100 units." + desc = "A large beaker. Can hold up to 100 units. Unable to withstand reagents of an extreme pH." icon_state = "beakerlarge" materials = list(MAT_GLASS=2500) volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100) + container_HP = 6 /obj/item/reagent_containers/glass/beaker/plastic name = "x-large beaker" - desc = "An extra-large beaker. Can hold up to 120 units." + desc = "An extra-large beaker. Can hold up to 150 units. Is able to resist acid and alkaline solutions, but melts at 444K" icon_state = "beakerwhite" materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000) - volume = 120 + volume = 150 amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,20,25,30,60,120) + possible_transfer_amounts = list(5,10,15,20,25,30,50,100,150) + +/obj/item/reagent_containers/glass/beaker/plastic/Initialize() + beaker_weakness_bitflag &= ~PH_WEAK + beaker_weakness_bitflag |= TEMP_WEAK + . = ..() /obj/item/reagent_containers/glass/beaker/plastic/update_icon() icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states @@ -181,12 +190,16 @@ /obj/item/reagent_containers/glass/beaker/meta name = "metamaterial beaker" - desc = "A large beaker. Can hold up to 180 units." + desc = "A large beaker. Can hold up to 200 units. Is able to withstand all chemical situations." icon_state = "beakergold" materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000) - volume = 180 + volume = 200 amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,20,25,30,60,120,180) + possible_transfer_amounts = list(5,10,15,20,25,30,50,100,200) + +/obj/item/reagent_containers/glass/beaker/meta/Initialize() + beaker_weakness_bitflag &= ~PH_WEAK + . = ..() /obj/item/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" @@ -197,17 +210,24 @@ reagent_flags = OPENCONTAINER | NO_REACT volume = 50 amount_per_transfer_from_this = 10 + container_HP = 10//shouldn't be needed + +/obj/item/reagent_containers/glass/beaker/noreact/Initialize() + beaker_weakness_bitflag &= ~PH_WEAK + . = ..() + //reagents.set_reacting(FALSE) was this removed in a recent pr? /obj/item/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" desc = "A bluespace beaker, powered by experimental bluespace technology \ and Element Cuban combined with the Compound Pete. Can hold up to \ - 300 units." + 300 units. Unable to withstand reagents of an extreme pH." icon_state = "beakerbluespace" materials = list(MAT_GLASS=3000) volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300) + container_HP = 8 /obj/item/reagent_containers/glass/beaker/cryoxadone list_reagents = list("cryoxadone" = 30) @@ -264,6 +284,11 @@ SLOT_L_STORE, SLOT_R_STORE,\ SLOT_GENERC_DEXTROUS_STORAGE ) + container_HP = 2 + +/obj/item/reagent_containers/glass/bucket/Initialize() + beaker_weakness_bitflag |= TEMP_WEAK + . = ..() /obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/mop)) @@ -313,6 +338,11 @@ materials = list(MAT_GLASS=0) volume = 50 amount_per_transfer_from_this = 10 + container_HP = 2 + +/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize() + beaker_weakness_bitflag |= TEMP_WEAK + . = ..() /obj/item/reagent_containers/glass/beaker/waterbottle/empty list_reagents = list() @@ -324,6 +354,7 @@ list_reagents = list("water" = 100) volume = 100 amount_per_transfer_from_this = 20 + container_HP = 2 /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty list_reagents = list() diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index ed2ca66aae..38880f669f 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,239 +1,259 @@ -/obj/item/reagent_containers/pill - name = "pill" - desc = "A tablet or capsule." - icon = 'icons/obj/chemical.dmi' - icon_state = "pill" - item_state = "pill" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - possible_transfer_amounts = list() - volume = 50 - grind_results = list() - var/apply_type = INGEST - var/apply_method = "swallow" - var/roundstart = 0 - var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills - var/dissolvable = TRUE - -/obj/item/reagent_containers/pill/Initialize() - . = ..() - if(!icon_state) - icon_state = "pill[rand(1,20)]" - 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/attack(mob/M, mob/user, def_zone) - if(!canconsume(M, user)) - return 0 - - if(M == user) - M.visible_message("[user] attempts to [apply_method] [src].") - if(self_delay) - if(!do_mob(user, M, self_delay)) - return 0 - to_chat(M, "You [apply_method] [src].") - - else - M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ - "[user] attempts to force [M] to [apply_method] [src].") - if(!do_mob(user, M)) - return 0 - M.visible_message("[user] forces [M] to [apply_method] [src].", \ - "[user] forces [M] to [apply_method] [src].") - - - log_combat(user, M, "fed", reagents.log_list()) - if(reagents.total_volume) - reagents.reaction(M, apply_type) - reagents.trans_to(M, reagents.total_volume) - qdel(src) - return 1 - - -/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) - . = ..() - if(!proximity) - return - if(!dissolvable || !target.is_refillable()) - return - if(target.is_drainable() && !target.reagents.total_volume) - to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") - return - - if(target.reagents.holder_full()) - to_chat(user, "[target] is full.") - return - - to_chat(user, "You dissolve [src] in [target].") - for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius - to_chat(O, "[user] slips something into [target]!") - reagents.trans_to(target, reagents.total_volume) - qdel(src) - -/obj/item/reagent_containers/pill/tox - name = "toxins pill" - desc = "Highly toxic." - icon_state = "pill5" - list_reagents = list("toxin" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/cyanide - name = "cyanide pill" - desc = "Don't swallow this." - icon_state = "pill5" - list_reagents = list("cyanide" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/adminordrazine - name = "adminordrazine pill" - desc = "It's magic. We don't have to explain it." - icon_state = "pill16" - list_reagents = list("adminordrazine" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/morphine - name = "morphine pill" - desc = "Commonly used to treat insomnia." - icon_state = "pill8" - list_reagents = list("morphine" = 30) - roundstart = 1 - -/obj/item/reagent_containers/pill/stimulant - name = "stimulant pill" - desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" - icon_state = "pill19" - list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) - roundstart = 1 - -/obj/item/reagent_containers/pill/salbutamol - name = "salbutamol pill" - desc = "Used to treat oxygen deprivation." - icon_state = "pill16" - list_reagents = list("salbutamol" = 30) - roundstart = 1 - -/obj/item/reagent_containers/pill/charcoal - name = "charcoal pill" - desc = "Neutralizes many common toxins." - icon_state = "pill17" - list_reagents = list("charcoal" = 10) - roundstart = 1 - -/obj/item/reagent_containers/pill/epinephrine - name = "epinephrine pill" - desc = "Used to stabilize patients." - icon_state = "pill5" - list_reagents = list("epinephrine" = 15) - roundstart = 1 - -/obj/item/reagent_containers/pill/mannitol - name = "mannitol pill" - desc = "Used to treat brain damage." - icon_state = "pill17" - list_reagents = list("mannitol" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/mutadone - name = "mutadone pill" - desc = "Used to treat genetic damage." - icon_state = "pill20" - list_reagents = list("mutadone" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/salicyclic - name = "salicylic acid pill" - desc = "Used to dull pain." - icon_state = "pill9" - list_reagents = list("sal_acid" = 24) - roundstart = 1 - -/obj/item/reagent_containers/pill/oxandrolone - name = "oxandrolone pill" - desc = "Used to stimulate burn healing." - icon_state = "pill11" - list_reagents = list("oxandrolone" = 24) - roundstart = 1 - -/obj/item/reagent_containers/pill/insulin - name = "insulin pill" - desc = "Handles hyperglycaemic coma." - icon_state = "pill18" - list_reagents = list("insulin" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/antirad - name = "potassium iodide pill" - desc = "Used to treat radition used to counter radiation poisoning." - icon_state = "pill18" - list_reagents = list("potass_iodide" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/antirad_plus - name = "prussian blue pill" - desc = "Used to treat heavy radition poisoning." - icon = 'modular_citadel/icons/obj/modularpills.dmi' - icon_state = "prussian_blue" - list_reagents = list("prussian_blue" = 25, "water" = 10) - roundstart = 1 - -/obj/item/reagent_containers/pill/mutarad - name = "radiation treatment deluxe pill" - desc = "Used to treat heavy radition poisoning and genetic defects." - icon = 'modular_citadel/icons/obj/modularpills.dmi' - icon_state = "anit_rad_fixgene" - list_reagents = list("prussian_blue" = 15, "potass_iodide" = 15, "mutadone" = 15, "water" = 5) - roundstart = 1 - -///////////////////////////////////////// this pill is used only in a legion mob drop -/obj/item/reagent_containers/pill/shadowtoxin - name = "black pill" - desc = "I wouldn't eat this if I were you." - icon_state = "pill9" - color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) -//////////////////////////////////////// drugs -/obj/item/reagent_containers/pill/zoom - name = "zoom pill" - list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1) - - -/obj/item/reagent_containers/pill/happy - name = "happy pill" - list_reagents = list("sugar" = 10, "space_drugs" = 10) - - -/obj/item/reagent_containers/pill/lsd - name = "hallucinogen pill" - list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15) - - -/obj/item/reagent_containers/pill/aranesp - name = "speedy pill" - list_reagents = list("aranesp" = 10) - -/obj/item/reagent_containers/pill/floorpill - name = "floorpill" - desc = "A strange pill found in the depths of maintenance" - icon_state = "pill21" - var/static/list/names = list("maintenance pill","floorpill","mystery pill","suspicious pill","strange pill") - var/static/list/descs = list("Your feeling is telling you no, but...","Drugs are expensive, you can't afford not to eat any pills that you find."\ - , "Surely, there's no way this could go bad.") - -/obj/item/reagent_containers/pill/floorpill/Initialize() - list_reagents = list(get_random_reagent_id() = rand(10,50)) - . = ..() - name = pick(names) - if(prob(20)) - desc = pick(descs) - -/obj/item/reagent_containers/pill/get_belt_overlay() - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") - -/obj/item/reagent_containers/pill/penis_enlargement - name = "penis enlargement pill" - list_reagents = list("penis_enlargement" = 30) +/obj/item/reagent_containers/pill + name = "pill" + desc = "A tablet or capsule." + icon = 'icons/obj/chemical.dmi' + icon_state = "pill" + item_state = "pill" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + possible_transfer_amounts = list() + volume = 50 + grind_results = list() + var/apply_type = INGEST + var/apply_method = "swallow" + var/roundstart = 0 + var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills + var/dissolvable = TRUE + +/obj/item/reagent_containers/pill/Initialize() + . = ..() + if(!icon_state) + icon_state = "pill[rand(1,20)]" + 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/attack(mob/M, mob/user, def_zone) + if(!canconsume(M, user)) + return 0 + + if(M == user) + M.visible_message("[user] attempts to [apply_method] [src].") + if(self_delay) + if(!do_mob(user, M, self_delay)) + return 0 + to_chat(M, "You [apply_method] [src].") + + else + M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ + "[user] attempts to force [M] to [apply_method] [src].") + if(!do_mob(user, M)) + return 0 + M.visible_message("[user] forces [M] to [apply_method] [src].", \ + "[user] forces [M] to [apply_method] [src].") + + var/makes_me_think = pick(strings("redpill.json", "redpill_questions")) + if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "[makes_me_think]"), 50) + + log_combat(user, M, "fed", reagents.log_list()) + if(reagents.total_volume) + reagents.reaction(M, apply_type) + reagents.trans_to(M, reagents.total_volume) + qdel(src) + return 1 + + +/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) + . = ..() + if(!proximity) + return + if(!dissolvable || !target.is_refillable()) + return + if(target.is_drainable() && !target.reagents.total_volume) + to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") + return + + if(target.reagents.holder_full()) + to_chat(user, "[target] is full.") + return + + to_chat(user, "You dissolve [src] in [target].") + for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius + to_chat(O, "[user] slips something into [target]!") + reagents.trans_to(target, reagents.total_volume) + qdel(src) + +/obj/item/reagent_containers/pill/tox + name = "toxins pill" + desc = "Highly toxic." + icon_state = "pill5" + list_reagents = list("toxin" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/cyanide + name = "cyanide pill" + desc = "Don't swallow this." + icon_state = "pill5" + list_reagents = list("cyanide" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/adminordrazine + name = "adminordrazine pill" + desc = "It's magic. We don't have to explain it." + icon_state = "pill16" + list_reagents = list("adminordrazine" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/morphine + name = "morphine pill" + desc = "Commonly used to treat insomnia." + icon_state = "pill8" + list_reagents = list("morphine" = 30) + roundstart = 1 + +/obj/item/reagent_containers/pill/stimulant + name = "stimulant pill" + desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" + icon_state = "pill19" + list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) + roundstart = 1 + +/obj/item/reagent_containers/pill/salbutamol + name = "salbutamol pill" + desc = "Used to treat oxygen deprivation." + icon_state = "pill16" + list_reagents = list("salbutamol" = 30) + roundstart = 1 + +/obj/item/reagent_containers/pill/charcoal + name = "charcoal pill" + desc = "Neutralizes many common toxins." + icon_state = "pill17" + list_reagents = list("charcoal" = 10) + roundstart = 1 + +/obj/item/reagent_containers/pill/epinephrine + name = "epinephrine pill" + desc = "Used to stabilize patients." + icon_state = "pill5" + list_reagents = list("epinephrine" = 15) + roundstart = 1 + +/obj/item/reagent_containers/pill/mannitol + name = "mannitol pill" + desc = "Used to treat brain damage." + icon_state = "pill17" + list_reagents = list("mannitol" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/mutadone + name = "mutadone pill" + desc = "Used to treat genetic damage." + icon_state = "pill20" + list_reagents = list("mutadone" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/salicyclic + name = "salicylic acid pill" + desc = "Used to dull pain." + icon_state = "pill9" + list_reagents = list("sal_acid" = 24) + roundstart = 1 + +/obj/item/reagent_containers/pill/oxandrolone + name = "oxandrolone pill" + desc = "Used to stimulate burn healing." + icon_state = "pill11" + list_reagents = list("oxandrolone" = 24) + roundstart = 1 + +/obj/item/reagent_containers/pill/insulin + name = "insulin pill" + desc = "Handles hyperglycaemic coma." + icon_state = "pill18" + list_reagents = list("insulin" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/psicodine + name = "psicodine pill" + desc = "Used to treat mental instability and traumas." + list_reagents = list("psicodine" = 10) + icon_state = "pill22" + roundstart = 1 + +/obj/item/reagent_containers/pill/antirad + name = "potassium iodide pill" + desc = "Used to treat radition used to counter radiation poisoning." + icon_state = "pill18" + list_reagents = list("potass_iodide" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/antirad_plus + name = "prussian blue pill" + desc = "Used to treat heavy radition poisoning." + icon = 'modular_citadel/icons/obj/modularpills.dmi' + icon_state = "prussian_blue" + list_reagents = list("prussian_blue" = 25, "water" = 10) + roundstart = 1 + +/obj/item/reagent_containers/pill/mutarad + name = "radiation treatment deluxe pill" + desc = "Used to treat heavy radition poisoning and genetic defects." + icon = 'modular_citadel/icons/obj/modularpills.dmi' + icon_state = "anit_rad_fixgene" + list_reagents = list("prussian_blue" = 15, "potass_iodide" = 15, "mutadone" = 15, "water" = 5) + roundstart = 1 + +///////////////////////////////////////// this pill is used only in a legion mob drop +/obj/item/reagent_containers/pill/shadowtoxin + name = "black pill" + desc = "I wouldn't eat this if I were you." + icon_state = "pill9" + color = "#454545" + list_reagents = list("shadowmutationtoxin" = 1) +//////////////////////////////////////// drugs +/obj/item/reagent_containers/pill/zoom + name = "zoom pill" + list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1) + + +/obj/item/reagent_containers/pill/happy + name = "happy pill" + list_reagents = list("sugar" = 10, "space_drugs" = 10) + + +/obj/item/reagent_containers/pill/lsd + name = "hallucinogen pill" + list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15) + + +/obj/item/reagent_containers/pill/aranesp + name = "speedy pill" + list_reagents = list("aranesp" = 10) + +/obj/item/reagent_containers/pill/happiness + name = "happiness pill" + desc = "It has a creepy smiling face on it." + icon_state = "pill_happy" + list_reagents = list("happiness" = 10) + +/obj/item/reagent_containers/pill/floorpill + name = "floorpill" + desc = "A strange pill found in the depths of maintenance" + icon_state = "pill21" + var/static/list/names = list("maintenance pill","floorpill","mystery pill","suspicious pill","strange pill") + var/static/list/descs = list("Your feeling is telling you no, but...","Drugs are expensive, you can't afford not to eat any pills that you find."\ + , "Surely, there's no way this could go bad.") + +/obj/item/reagent_containers/pill/floorpill/Initialize() + list_reagents = list(get_random_reagent_id() = rand(10,50)) + . = ..() + name = pick(names) + if(prob(20)) + desc = pick(descs) + +/obj/item/reagent_containers/pill/get_belt_overlay() + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") + +/obj/item/reagent_containers/pill/penis_enlargement + name = "penis enlargement pill" + list_reagents = list("penis_enlarger" = 10) + +/obj/item/reagent_containers/pill/breast_enlargement + name = "breast enlargement pill" + list_reagents = list("breast_enlarger" = 10) diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm new file mode 100644 index 0000000000..92a4b155d8 --- /dev/null +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -0,0 +1,177 @@ +/obj/item/reagent_containers/rag + name = "damp rag" + desc = "For cleaning up messes, you suppose." + w_class = WEIGHT_CLASS_TINY + icon = 'icons/obj/toy.dmi' + icon_state = "rag" + item_flags = NOBLUDGEON + reagent_flags = OPENCONTAINER + amount_per_transfer_from_this = 5 + possible_transfer_amounts = list() + volume = 5 + spillable = FALSE + var/wipe_sound + var/soak_efficiency = 1 + var/extinguish_efficiency = 0 + var/action_speed = 3 SECONDS + var/damp_threshold = 0.5 + +/obj/item/reagent_containers/rag/suicide_act(mob/user) + user.visible_message("[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (OXYLOSS) + +/obj/item/reagent_containers/rag/examine(mob/user) + . = ..() + if(reagents.total_volume) + to_chat(user, "Alt-Click to squeeze the liquids out of it.") + +/obj/item/reagent_containers/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity) + . = ..() + if(!proximity) + return + if(iscarbon(A) && A.reagents && reagents.total_volume) + var/mob/living/carbon/C = A + var/reagentlist = pretty_string_from_reagent_list(reagents) + var/log_object = "a damp rag containing [reagentlist]" + if(user.a_intent == INTENT_HARM && !C.is_mouth_covered()) + reagents.reaction(C, INGEST) + reagents.trans_to(C, 5) + C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and muffled cries of surprise.") + log_combat(user, C, "smothered", log_object) + else + reagents.reaction(C, TOUCH) + reagents.remove_all(5) + C.visible_message("[user] has touched \the [C] with \the [src].") + log_combat(user, C, "touched", log_object) + + else if(istype(A) && src in user) + user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...") + if(do_after(user, action_speed, target = A)) + user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].") + SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) + return + +/obj/item/reagent_containers/rag/pre_altattackby(mob/living/M, mob/living/user, params) + if(istype(M) && user.a_intent == INTENT_HELP) + user.changeNext_move(CLICK_CD_MELEE) + if(M.on_fire) + user.visible_message("\The [user] uses \the [src] to pat out [M == user ? "[user.p_their()]" : "\the [M]'s"] flames!") + if(hitsound) + playsound(M, hitsound, 25, 1) + M.adjust_fire_stacks(-min(extinguish_efficiency, M.fire_stacks)) + else + if(reagents.total_volume > (volume * damp_threshold)) + to_chat(user, "\The [src] is too drenched to be used to dry [user == M ? "yourself" : "\the [M]"] off.") + return TRUE + user.visible_message("\The [user] starts drying [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src]...") + if(do_mob(user, M, action_speed)) + if(reagents.total_volume > (volume * damp_threshold)) + return + user.visible_message("\The [user] dries [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src].") + if(wipe_sound) + playsound(M, wipe_sound, 25, 1) + if(M.fire_stacks) + var/minus_plus = M.fire_stacks < 0 ? 1 : -1 + var/amount = min(abs(M.fire_stacks), soak_efficiency) + var/r_id = "fuel" + if(M.fire_stacks < 0) + r_id = "water" + reagents.add_reagent(r_id, amount * 0.3) + M.adjust_fire_stacks(minus_plus * amount) + M.wash_cream() + return TRUE + return ..() + +/obj/item/reagent_containers/rag/AltClick(mob/user) + . = ..() + if(reagents.total_volume && user.canUseTopic(src, BE_CLOSE)) + to_chat(user, "You start squeezing the liquids out of \the [src]...") + if(do_after(user, action_speed, TRUE, src)) + to_chat(user, "You squeeze \the [src] dry.") + var/atom/react_loc = get_turf(src) + if(ismob(react_loc)) + react_loc = react_loc.loc + if(react_loc) + reagents.reaction(react_loc, TOUCH) + reagents.clear_reagents() + +/obj/item/reagent_containers/rag/towel + name = "towel" + desc = "A soft cotton towel." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "towel" + item_state = "towel" + slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING + item_flags = NOBLUDGEON | NO_UNIFORM_REQUIRED //so it can be worn on the belt slot even with no uniform. + force = 1 + w_class = WEIGHT_CLASS_NORMAL + attack_verb = list("whipped") + hitsound = 'sound/items/towelwhip.ogg' + volume = 10 + total_mass = 2 + wipe_sound = 'sound/items/towelwipe.ogg' + soak_efficiency = 4 + extinguish_efficiency = 3 + var/flat_icon = "towel_flat" + var/folded_icon = "towel" + var/list/possible_colors + +/obj/item/reagent_containers/rag/towel/Initialize() + . = ..() + if(possible_colors) + add_atom_colour(pick(possible_colors), FIXED_COLOUR_PRIORITY) + +/obj/item/reagent_containers/rag/towel/attack(mob/living/M, mob/living/user) + if(user.a_intent == INTENT_HARM) + DISABLE_BITFIELD(item_flags, NOBLUDGEON) + . = TRUE + ..() + if(.) + ENABLE_BITFIELD(item_flags, NOBLUDGEON) + +/obj/item/reagent_containers/rag/towel/equipped(mob/living/user, slot) + . = ..() + switch(slot) + if(SLOT_BELT) + body_parts_covered = GROIN|LEGS + if(SLOT_WEAR_SUIT) + body_parts_covered = CHEST|GROIN|LEGS + if(SLOT_HEAD) + body_parts_covered = HEAD + flags_inv = HIDEHAIR + +/obj/item/reagent_containers/rag/towel/dropped(mob/user) + . = ..() + body_parts_covered = NONE + flags_inv = NONE + +/obj/item/reagent_containers/rag/towel/attack_self(mob/user) + if(!user.CanReach(src) || !user.dropItemToGround(src)) + return + to_chat(user, "You lay out \the [src] flat on the ground.") + icon_state = flat_icon + layer = BELOW_OBJ_LAYER + +/obj/item/reagent_containers/rag/towel/pickup(mob/living/user) + . = ..() + icon_state = folded_icon + layer = initial(layer) + +/obj/item/reagent_containers/rag/towel/on_reagent_change(changetype) + force = initial(force) + round(reagents.total_volume * 0.5) + +/obj/item/reagent_containers/rag/towel/random + possible_colors = list("#FF0000","#FF7F00","#FFFF00","#00FF00","#0000FF","#4B0082","#8F00FF") + +/obj/item/reagent_containers/rag/towel/syndicate + name = "syndicate towel" + desc = "Truly a weapon of mass destruction." + possible_colors = list("#DD1A1A", "#DB4325", "#E02700") + force = 4 + armour_penetration = 10 + volume = 20 + soak_efficiency = 6 + extinguish_efficiency = 5 + action_speed = 15 + damp_threshold = 0.8 + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet. \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm index 435af80aea..0300658a84 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -147,4 +147,4 @@ build_type = AUTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 150) build_path = /obj/item/geiger_counter - category = list("initial", "Tools") \ No newline at end of file + category = list("initial", "Tools") diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm index fd548adc76..b11a5ee258 100644 --- a/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm @@ -32,4 +32,12 @@ id = "mining" build_path = /obj/item/circuitboard/computer/mining category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY \ No newline at end of file + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/miningshuttle + name = "Computer Design (Mining Shuttle Console)" + desc = "Allows for the construction of circuit boards used to build a Mining Shuttle Console." + id = "miningshuttle" + build_path = /obj/item/circuitboard/computer/mining_shuttle + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_CARGO \ No newline at end of file diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 3ee7d344dc..7ccc41c232 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -219,7 +219,7 @@ /datum/design/mech_missile_rack name = "Exosuit Weapon (SRM-8 Missile Rack)" - desc = "Allows for the construction of SRM-8 Missile Rack." + desc = "Allows for the construction of an SRM-8 Missile Rack." id = "mech_missile_rack" build_type = MECHFAB build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 3a7ef68903..d3db4f75b3 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -554,6 +554,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/cybernetic_tongue + name = "Cybernetic tongue" + desc = "A fancy cybernetic tongue." + id = "cybernetic_tongue" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/tongue/cybernetic + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + ///////////////////// //Adv Surgery Tools// ///////////////////// @@ -732,6 +742,13 @@ surgery = /datum/surgery/advanced/reconstruction research_icon_state = "surgery_chest" +/datum/design/surgery/surgery_toxinhealing + name = "Body Rejuvenation" + desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals." + id = "surgery_toxinhealing" + surgery = /datum/surgery/advanced/toxichealing + research_icon_state = "surgery_chest" + /datum/design/surgery/revival name = "Revival" desc = "An experimental surgical procedure which involves reconstruction and reactivation of the patient's brain even long after death. The body must still be able to sustain life." diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 59df0f6e85..77eebca696 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -1,4 +1,3 @@ - ///////////////////////////////////////// /////////////////HUDs//////////////////// ///////////////////////////////////////// @@ -291,6 +290,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SERVICE +/datum/design/light_replacer + name = "Light Replacer" + desc = "A device to automatically replace lights. Refill with working light bulbs." + id = "light_replacer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1500, MAT_SILVER = 150, MAT_GLASS = 3000) + build_path = /obj/item/lightreplacer + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + /datum/design/blutrash name = "Trashbag of Holding" desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." @@ -370,6 +379,16 @@ ////////////Tools////////////// /////////////////////////////// +/datum/design/rcd_upgrade + name = "Advanced RCD designs upgrade" + desc = "Adds the computer frame and machine frame to the RCD." + id = "rcd_upgrade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) + build_path = /obj/item/rcd_upgrade + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/exwelder name = "Experimental Welding Tool" desc = "An experimental welder capable of self-fuel generation." @@ -460,6 +479,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/quantum_keycard + name = "Quantum Keycard" + desc = "Allows for the construction of a quantum keycard." + id = "quantum_keycard" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_METAL = 500, MAT_SILVER = 500, MAT_BLUESPACE = 1000) + build_path = /obj/item/quantum_keycard + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/anomaly_neutralizer name = "Anomaly Neutralizer" desc = "An advanced tool capable of instantly neutralizing anomalies, designed to capture the fleeting aberrations created by the engine." @@ -470,6 +499,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/pHmeter + name = "Chemical Analyser" + desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution." + id = "pHmeter" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_SILVER = 100, MAT_DIAMOND = 100) + build_path = /obj/item/fermichem/pHmeter + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + ///////////////////////////////////////// ////////////Armour/////////////////////// ///////////////////////////////////////// diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index f8122c16e3..1dbd111785 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -57,16 +57,6 @@ category = list("Misc","Power Designs") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/light_replacer - name = "Light Replacer" - desc = "A device to automatically replace lights. Refill with working light bulbs." - id = "light_replacer" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1500, MAT_SILVER = 150, MAT_GLASS = 3000) - build_path = /obj/item/lightreplacer - category = list("Power Designs") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - /datum/design/inducer name = "Inducer" desc = "The NT-75 Electromagnetic Power Inducer can wirelessly induce electric charge in an object, allowing you to recharge power cells without having to remove them." diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 03c0582245..214ef36afe 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -330,8 +330,8 @@ departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/suppressor - name = "Universal Suppressor" - desc = "A reverse-engineered universal suppressor that fits on most small arms with threaded barrels." + name = "Suppressor" + desc = "A reverse-engineered suppressor that fits on most small arms with threaded barrels." id = "suppressor" build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 500) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index ebd386513e..e56350a280 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -651,7 +651,7 @@ if(loc == user && !is_centcom_level(userturf.z)) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you! visible_message("[src] twists and bends, relocating itself!") throwSmoke(userturf) - do_teleport(user, userturf, 8, asoundin = 'sound/effects/phasein.ogg') + do_teleport(user, userturf, 8, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) throwSmoke(get_turf(user)) warn_admins(user, "Teleport", 0) diff --git a/code/modules/research/nanites/nanite_program_hub.dm b/code/modules/research/nanites/nanite_program_hub.dm index 81c5a44527..e33f3d7cd7 100644 --- a/code/modules/research/nanites/nanite_program_hub.dm +++ b/code/modules/research/nanites/nanite_program_hub.dm @@ -115,4 +115,10 @@ qdel(disk.program) disk.program = null disk.name = initial(disk.name) - . = TRUE \ No newline at end of file + . = TRUE + + +/obj/machinery/nanite_program_hub/admin/Initialize() + . = ..() + linked_techweb = SSresearch.admin_tech + diff --git a/code/modules/research/nanites/nanite_programs/buffing.dm b/code/modules/research/nanites/nanite_programs/buffing.dm index c80c5c5d96..be12d06ede 100644 --- a/code/modules/research/nanites/nanite_programs/buffing.dm +++ b/code/modules/research/nanites/nanite_programs/buffing.dm @@ -49,14 +49,14 @@ . = ..() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob - H.physiology.armor.melee += 50 + H.physiology.armor.melee += 35 H.physiology.armor.bullet += 35 /datum/nanite_program/hardening/disable_passive_effect() . = ..() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob - H.physiology.armor.melee -= 50 + H.physiology.armor.melee -= 35 H.physiology.armor.bullet -= 35 /datum/nanite_program/refractive @@ -69,14 +69,14 @@ . = ..() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob - H.physiology.armor.laser += 50 + H.physiology.armor.laser += 35 H.physiology.armor.energy += 35 /datum/nanite_program/refractive/disable_passive_effect() . = ..() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob - H.physiology.armor.laser -= 50 + H.physiology.armor.laser -= 35 H.physiology.armor.energy -= 35 /datum/nanite_program/coagulating @@ -127,4 +127,4 @@ /datum/nanite_program/mindshield/disable_passive_effect() . = ..() REMOVE_TRAIT(host_mob, TRAIT_MINDSHIELD, "nanites") - host_mob.sec_hud_set_implants() \ No newline at end of file + host_mob.sec_hud_set_implants() diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm index ab314cb33c..8aab7f1e2b 100644 --- a/code/modules/research/nanites/nanite_programs/healing.dm +++ b/code/modules/research/nanites/nanite_programs/healing.dm @@ -48,7 +48,7 @@ /datum/nanite_program/purging name = "Blood Purification" - desc = "The nanites purge toxins and chemicals from the host's bloodstream." + desc = "The nanites purge toxins and chemicals from the host's bloodstream, however it is dangerous to slimepeople biology due to inaccuracy." use_rate = 1 rogue_types = list(/datum/nanite_program/suffocating, /datum/nanite_program/necrotic) @@ -70,9 +70,13 @@ rogue_types = list(/datum/nanite_program/brain_decay) /datum/nanite_program/brain_heal/check_conditions() - if(!host_mob.getBrainLoss()) - return FALSE - return ..() + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + if(length(C.get_traumas())) + return ..() + if(host_mob.getBrainLoss()) + return ..() + return FALSE /datum/nanite_program/brain_heal/active_effect() host_mob.adjustBrainLoss(-1, TRUE) @@ -89,7 +93,7 @@ /datum/nanite_program/blood_restoring/check_conditions() if(iscarbon(host_mob)) var/mob/living/carbon/C = host_mob - if(C.blood_volume >= BLOOD_VOLUME_SAFE) + if(C.blood_volume >= (BLOOD_VOLUME_SAFE*C.blood_ratio)) return FALSE else return FALSE @@ -139,7 +143,7 @@ /datum/nanite_program/purging_advanced name = "Selective Blood Purification" desc = "The nanites purge toxins and dangerous chemicals from the host's bloodstream, while ignoring beneficial chemicals. \ - The added processing power required to analyze the chemicals severely increases the nanite consumption rate." + The added processing power required to analyze the chemicals severely increases the nanite consumption rate. Due to added complexity, it is safe with slimepeople biology." use_rate = 2 rogue_types = list(/datum/nanite_program/suffocating, /datum/nanite_program/necrotic) @@ -153,7 +157,7 @@ return ..() /datum/nanite_program/purging_advanced/active_effect() - host_mob.adjustToxLoss(-1) + host_mob.adjustToxLoss(-1, forced = TRUE) for(var/datum/reagent/toxin/R in host_mob.reagents.reagent_list) host_mob.reagents.remove_reagent(R.id,1) @@ -187,10 +191,14 @@ rogue_types = list(/datum/nanite_program/brain_decay, /datum/nanite_program/brain_misfire) /datum/nanite_program/brain_heal_advanced/check_conditions() - if(!host_mob.getBrainLoss()) - return FALSE - return ..() - + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + if(length(C.get_traumas())) + return ..() + if(host_mob.getBrainLoss()) + return ..() + return FALSE + /datum/nanite_program/brain_heal_advanced/active_effect() host_mob.adjustBrainLoss(-2, TRUE) if(iscarbon(host_mob) && prob(10)) @@ -248,4 +256,3 @@ log_game("[C] has been successfully defibrillated by nanites.") else playsound(C, 'sound/machines/defib_failed.ogg', 50, 0) - diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 77fb4e1005..44b85e4210 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -190,13 +190,13 @@ if(!iscarbon(host_mob)) return FALSE var/mob/living/carbon/C = host_mob - if(C.nutrition <= NUTRITION_LEVEL_WELL_FED) + if(C.nutrition <= NUTRITION_LEVEL_STARVING) return FALSE return ..() /datum/nanite_program/metabolic_synthesis/active_effect() host_mob.nutrition -= 0.5 - nanites.adjust_nanites(0.5) + nanites.adjust_nanites(src, 0.5) /datum/nanite_program/triggered/access name = "Subdermal ID" diff --git a/code/modules/research/nanites/nanite_programs/weapon.dm b/code/modules/research/nanites/nanite_programs/weapon.dm index f4914d4af0..4f29398e91 100644 --- a/code/modules/research/nanites/nanite_programs/weapon.dm +++ b/code/modules/research/nanites/nanite_programs/weapon.dm @@ -46,13 +46,13 @@ /datum/nanite_program/aggressive_replication name = "Aggressive Replication" desc = "Nanites will consume organic matter to improve their replication rate, damaging the host. The efficiency increases with the volume of nanites, requiring 200 to break even." - use_rate = 1 + use_rate = 0 rogue_types = list(/datum/nanite_program/necrotic) /datum/nanite_program/aggressive_replication/active_effect() - var/extra_regen = round(nanites.nanite_volume / 200, 0.1) - nanites.adjust_nanites(extra_regen) - host_mob.adjustBruteLoss(extra_regen / 2, TRUE) + var/extra_regen = round(nanites.nanite_volume / 50, 0.1) + nanites.adjust_nanites(src, extra_regen) + host_mob.adjustBruteLoss(extra_regen / 3, TRUE) /datum/nanite_program/meltdown name = "Meltdown" @@ -89,10 +89,9 @@ /datum/nanite_program/triggered/explosive/proc/boom() var/nanite_amount = nanites.nanite_volume - var/dev_range = FLOOR(nanite_amount/200, 1) - 1 var/heavy_range = FLOOR(nanite_amount/100, 1) - 1 var/light_range = FLOOR(nanite_amount/50, 1) - 1 - explosion(host_mob, dev_range, heavy_range, light_range) + explosion(host_mob, 0, heavy_range, light_range) qdel(nanites) //TODO make it defuse if triggered again @@ -197,4 +196,4 @@ if(host_mob.mind && host_mob.mind.has_antag_datum(/datum/antagonist/brainwashed)) host_mob.mind.remove_antag_datum(/datum/antagonist/brainwashed) log_game("[key_name(host_mob)] is no longer brainwashed by nanites.") - cooldown = world.time + 450 \ No newline at end of file + cooldown = world.time + 450 diff --git a/code/modules/research/nanites/nanite_remote.dm b/code/modules/research/nanites/nanite_remote.dm index 60dd78cf94..824d033bf4 100644 --- a/code/modules/research/nanites/nanite_remote.dm +++ b/code/modules/research/nanites/nanite_remote.dm @@ -37,6 +37,7 @@ to_chat(user, "Access denied.") /obj/item/nanite_remote/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return to_chat(user, "You override [src]'s ID lock.") @@ -44,6 +45,7 @@ if(locked) locked = FALSE update_icon() + return TRUE /obj/item/nanite_remote/update_icon() . = ..() diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index cb5062904d..a7d7857a24 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -184,12 +184,14 @@ Nothing else in the console has ID requirements. ..() /obj/machinery/computer/rdconsole/emag_act(mob/user) - if(!(obj_flags & EMAGGED)) - to_chat(user, "You disable the security protocols[locked? " and unlock the console":""].") - playsound(src, "sparks", 75, 1) - obj_flags |= EMAGGED - locked = FALSE - return ..() + . = ..() + if(obj_flags & EMAGGED) + return + to_chat(user, "You disable the security protocols[locked? " and unlock the console":""].") + playsound(src, "sparks", 75, 1) + obj_flags |= EMAGGED + locked = FALSE + return TRUE /obj/machinery/computer/rdconsole/multitool_act(mob/user, obj/item/multitool/I) var/lathe = linked_lathe && linked_lathe.multitool_act(user, I) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 20e05782ef..b3e114d2ad 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -155,8 +155,10 @@ src.updateUsrDialog() /obj/machinery/computer/rdservercontrol/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return playsound(src, "sparks", 75, 1) obj_flags |= EMAGGED to_chat(user, "You disable the security protocols.") + return TRUE diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 4331d8858b..3721e7943e 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -69,7 +69,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart", "pHmeter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -115,7 +115,7 @@ display_name = "Advanced Surgery" description = "When simple medicine doesn't cut it." prereq_ids = list("adv_biotech") - design_ids = list("surgery_lobotomy", "surgery_reconstruction", "organbox") + design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -172,7 +172,7 @@ display_name = "Advanced Engineering" description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") - design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription") + design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) export_price = 5000 @@ -221,33 +221,41 @@ //research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) //export_price = 5000 +/datum/techweb_node/computer_board_gaming + id = "computer_board_gaming" + display_name = "Games and Toys" + description = "For the slackers on the station." + prereq_ids = list("comptech") + design_ids = list("arcade_battle", "arcade_orion", "slotmachine", "autoylathe") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) + export_price = 5000 + /////////////////////////Bluespace tech///////////////////////// /datum/techweb_node/bluespace_basic //Bluespace-memery id = "bluespace_basic" display_name = "Basic Bluespace Theory" description = "Basic studies into the mysterious alternate dimension known as bluespace." prereq_ids = list("base", "datatheory") - design_ids = list("beacon", "xenobioconsole", "telesci_gps") + design_ids = list("beacon", "xenobioconsole", "telesci_gps", "xenobio_monkeys") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 -/datum/techweb_node/adv_bluespace - id = "adv_bluespace" - display_name = "Advanced Bluespace Research" - description = "Deeper understanding of how the Bluespace dimension works" - prereq_ids = list("practical_bluespace", "high_efficiency") - design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", - "teleconsole", "bluespace_crystal", "wormholeprojector") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000) - export_price = 5000 - /datum/techweb_node/practical_bluespace id = "practical_bluespace" display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo", "bluespacesmartdart") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +/datum/techweb_node/adv_bluespace + id = "adv_bluespace" + display_name = "Advanced Bluespace Research" + description = "Deeper understanding of how the Bluespace dimension works" + prereq_ids = list("practical_bluespace", "high_efficiency") + design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "bluespace_crystal", "xenobio_slimeadv") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) export_price = 5000 /datum/techweb_node/bluespace_power @@ -259,7 +267,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 -/datum/techweb_node/bluespace_holding //Bluespace-memery +/datum/techweb_node/bluespace_holding id = "bluespace_holding" display_name = "Bluespace Pockets" description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." @@ -267,6 +275,25 @@ design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500) export_price = 5000 + +/datum/techweb_node/bluespace_portal + id = "bluespace_portal" + display_name = "Bluespace Portals" + description = "Allows for Bluespace Tech to be used tandem with Wormhole tech." + prereq_ids = list("adv_weaponry", "adv_bluespace") + design_ids = list("wormholeprojector") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + +/datum/techweb_node/bluespace_warping + id = "bluespace_warping" + display_name = "Bluespace Travel" + description = "Application of Bluespace for static teleportation technology." + prereq_ids = list("adv_power", "adv_bluespace") + design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + /////////////////////////plasma tech///////////////////////// /datum/techweb_node/basic_plasma id = "basic_plasma" @@ -405,7 +432,7 @@ display_name = "Computer Consoles" description = "Computers and how they work." prereq_ids = list("datatheory") - design_ids = list("cargo", "cargorequest", "libraryconsole", "mining", "crewconsole", "rdcamera", "comconsole", "idcardconsole", "seccamera") + design_ids = list("cargo", "cargorequest", "libraryconsole", "mining", "miningshuttle", "crewconsole", "rdcamera", "comconsole", "idcardconsole", "seccamera") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) export_price = 5000 @@ -420,15 +447,6 @@ "portadrive_basic", "portadrive_advanced", "portadrive_super", "cardslot", "aislot", "miniprinter", "APClink", "bat_control", "bat_normal", "bat_advanced", "bat_super", "bat_micro", "bat_nano", "cpu_normal", "pcpu_normal", "cpu_small", "pcpu_small") -/datum/techweb_node/computer_board_gaming - id = "computer_board_gaming" - display_name = "Arcade Games" - description = "For the slackers on the station." - prereq_ids = list("comptech") - design_ids = list("arcade_battle", "arcade_orion", "slotmachine") // Magic money - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - export_price = 2000 - /datum/techweb_node/comp_recordkeeping id = "comp_recordkeeping" display_name = "Computerized Recordkeeping" @@ -499,7 +517,7 @@ display_name = "Cybernetic Organs" description = "We have the technology to rebuild him." prereq_ids = list("adv_biotech") - design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u") + design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u", "cybernetic_tongue") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -545,7 +563,7 @@ display_name = "Advanced Mining Technology" description = "Efficiency Level 127" //dumb mc references prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma") - design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv") + design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv", "ore_silo") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -654,7 +672,7 @@ display_name = "Ballistic Weaponry" description = "This isn't research.. This is reverse-engineering!" prereq_ids = list("weaponry") - design_ids = list("mag_oldsmg", "mag_oldsmg_ap", "mag_oldsmg_ic") + design_ids = list("mag_oldsmg", "mag_oldsmg_ap", "mag_oldsmg_ic", "mag_oldsmg_rubber", "mag_oldsmg_tx") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) export_price = 5000 @@ -1031,6 +1049,15 @@ continue boost_item_paths |= UI.item //allows deconning to unlock. +/datum/techweb_node/advanced_illegl_ballistics + id = "advanced_illegal_ballistics" + display_name = "Advanced Illegal Ballistics" + description = "Advanced Ballistic for Illegal weaponds." + design_ids = list("10mm","10mmap","10mminc","10mmhp","pistolm9mm","m45","bolt_clip") + prereq_ids = list("ballistic_weapons","syndicate_basic","explosive_weapons") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns form traitors or space. + export_price = 7000 + //Helpers for debugging/balancing the techweb in its entirety! /proc/total_techweb_exports() var/list/datum/techweb_node/processing = list() diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index ad5bfa27dc..b9e7122d07 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -680,7 +680,7 @@ datum/status_effect/stabilized/blue/on_remove() if(!F) F = get_turf(owner) range = 50 - if(do_teleport(owner, F, range)) + if(do_teleport(owner, F, range, channel = TELEPORT_CHANNEL_BLUESPACE)) to_chat(owner, "[linked_extract] will take some time to re-align you on the bluespace axis.") do_sparks(5,FALSE,owner) owner.apply_status_effect(/datum/status_effect/bluespacestabilization) diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm index 1138f65105..4753abff97 100644 --- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm +++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm @@ -7,13 +7,19 @@ item_state = "bloodgun" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - item_flags = ABSTRACT | DROPDEL | NODROP + item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE + slot_flags = NONE force = 5 max_charges = 1 //Recharging costs blood. recharge_rate = 1 ammo_type = /obj/item/ammo_casing/magic/bloodchill fire_sound = 'sound/effects/attackblob.ogg' + total_mass = TOTAL_MASS_HAND_REPLACEMENT + +/obj/item/gun/magic/bloodchill/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) /obj/item/gun/magic/bloodchill/process() charge_tick++ @@ -42,4 +48,4 @@ /obj/item/projectile/magic/bloodchill/on_hit(mob/living/target) . = ..() if(isliving(target)) - target.apply_status_effect(/datum/status_effect/bloodchill) \ No newline at end of file + target.apply_status_effect(/datum/status_effect/bloodchill) diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 38362e6d64..363331e12d 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -144,7 +144,7 @@ Burning extracts: user.visible_message("[src] sparks, and lets off a shockwave of bluespace energy!") for(var/mob/living/L in range(1, get_turf(user))) if(L != user) - do_teleport(L, get_turf(L), 6, asoundin = 'sound/effects/phasein.ogg') //Somewhere between the effectiveness of fake and real BS crystal + do_teleport(L, get_turf(L), 6, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //Somewhere between the effectiveness of fake and real BS crystal new /obj/effect/particle_effect/sparks(get_turf(L)) playsound(get_turf(L), "sparks", 50, 1) ..() diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index 881c830e5e..ff55a87dfa 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -186,6 +186,7 @@ Chilling extracts: /obj/item/slimecross/chilling/sepia/do_effect(mob/user) user.visible_message("[src] shatters, freezing time itself!") + allies -= user //support class new /obj/effect/timestop(get_turf(user), 2, 300, allies) ..() @@ -267,7 +268,7 @@ Chilling extracts: addtimer(CALLBACK(src, .proc/boom), 50) /obj/item/slimecross/chilling/oil/proc/boom() - explosion(get_turf(src), -1, -1, 3, 10) //Large radius, but mostly light damage. + explosion(get_turf(src), -1, -1, 10, 0) //Large radius, but mostly light damage, and no flash. qdel(src) /obj/item/slimecross/chilling/black @@ -307,4 +308,4 @@ Chilling extracts: user.visible_message("[src] reflects an array of dazzling colors and light, energy rushing to nearby doors!") for(var/obj/machinery/door/airlock/door in area) new /obj/effect/forcefield/slimewall/rainbow(door.loc) - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm index b51a7b2553..0b2d60da8c 100644 --- a/code/modules/research/xenobiology/crossbreeding/consuming.dm +++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm @@ -232,7 +232,7 @@ Consuming extracts: L.Cut(I,I+1) if(target) - do_teleport(M, target, 0, asoundin = 'sound/effects/phasein.ogg') + do_teleport(M, target, 0, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) new /obj/effect/particle_effect/sparks(get_turf(M)) playsound(get_turf(M), "sparks", 50, 1) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 76d444da18..7acbaaac1c 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -494,7 +494,7 @@ to_chat(user, "You feel your body vibrating...") if(do_after(user, 25, target = user)) to_chat(user, "You teleport!") - do_teleport(user, get_turf(user), 6, asoundin = 'sound/weapons/emitter2.ogg') + do_teleport(user, get_turf(user), 6, asoundin = 'sound/weapons/emitter2.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) return 300 if(SLIME_ACTIVATE_MAJOR) @@ -510,7 +510,7 @@ if(teleport_x && teleport_y && teleport_z) var/turf/T = locate(teleport_x, teleport_y, teleport_z) to_chat(user, "You snap back to your anchor point!") - do_teleport(user, T, asoundin = 'sound/weapons/emitter2.ogg') + do_teleport(user, T, asoundin = 'sound/weapons/emitter2.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) return 450 @@ -633,6 +633,12 @@ to_chat(user, "The slime is dead!") return + if(M.rabid) //Stops being rabid, but doesn't become truly docile. + to_chat(M, "You absorb the potion, and your rabid hunger finally settles to a normal desire to feed.") + to_chat(user, "You feed the slime the potion, calming its rabid rage.") + M.rabid = FALSE + qdel(src) + return M.docile = 1 M.nutrition = 700 to_chat(M, "You absorb the potion and feel your intense desire to feed melt away.") @@ -702,7 +708,7 @@ imp.implant(SM, user) SM.access_card = new /obj/item/card/id/syndicate(SM) - SM.access_card.item_flags |= NODROP + ADD_TRAIT(SM.access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /obj/item/slimepotion/transference name = "consciousness transference potion" diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm index 86132cf834..1258b9f4b8 100644 --- a/code/modules/shuttle/assault_pod.dm +++ b/code/modules/shuttle/assault_pod.dm @@ -35,7 +35,9 @@ /obj/item/assault_pod/attack_self(mob/living/user) var/target_area - target_area = input("Area to land", "Select a Landing Zone", target_area) in GLOB.teleportlocs + target_area = input("Area to land", "Select a Landing Zone", target_area) as null|anything in GLOB.teleportlocs + if(!target_area) + return var/area/picked_area = GLOB.teleportlocs[target_area] if(!src || QDELETED(src)) return diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm index 0c957919a1..946f0fb9a4 100644 --- a/code/modules/shuttle/computer.dm +++ b/code/modules/shuttle/computer.dm @@ -63,11 +63,13 @@ to_chat(usr, "Unable to comply.") /obj/machinery/computer/shuttle/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return req_access = list() obj_flags |= EMAGGED to_chat(user, "You fried the consoles ID checking system.") + return TRUE /obj/machinery/computer/shuttle/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) if(port && (shuttleId == initial(shuttleId) || override)) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index d41fd6a79b..119023d465 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -134,6 +134,8 @@ . = TRUE /obj/machinery/computer/emergency_shuttle/emag_act(mob/user) + . = ..() + // How did you even get on the shuttle before it go to the station? if(!IS_DOCKED) return @@ -159,6 +161,7 @@ authorized += ID process() + return TRUE /obj/machinery/computer/emergency_shuttle/Destroy() // Our fake IDs that the emag generated are just there for colour @@ -199,7 +202,7 @@ . = ..() -/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null) +/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null, silent = FALSE) if(!isnum(set_coefficient)) var/security_num = seclevel2num(get_security_level()) switch(security_num) @@ -228,7 +231,8 @@ else SSshuttle.emergencyLastCallLoc = null - priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority") + if(!silent) + priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority") /obj/docking_port/mobile/emergency/cancel(area/signalOrigin) if(mode != SHUTTLE_CALL) @@ -458,10 +462,12 @@ return /obj/machinery/computer/shuttle/pod/emag_act(mob/user) + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "You fry the pod's alert level checking system.") + return TRUE /obj/machinery/computer/shuttle/pod/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) . = ..() diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm index eaa1f36b75..39ab087f9c 100644 --- a/code/modules/shuttle/ferry.dm +++ b/code/modules/shuttle/ferry.dm @@ -12,7 +12,7 @@ /obj/machinery/computer/shuttle/ferry/emag_act(mob/user) if(!allow_emag) to_chat(user, "[src]'s security firewall is far too powerful for you to bypass.") - return FALSE + return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) return ..() /obj/machinery/computer/shuttle/ferry/attack_ai() @@ -37,4 +37,4 @@ return last_request = world.time to_chat(usr, "Your request has been received by CentCom.") - to_chat(GLOB.admins, "FERRY: [ADMIN_LOOKUPFLW(usr)] (Move Ferry) is requesting to move the transport ferry to CentCom.") + to_chat(GLOB.admins, "FERRY: [ADMIN_LOOKUPFLW(usr)] (Move Ferry) is requesting to move the transport ferry to CentCom.") diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index a6904c28cc..dd2d7483e3 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -179,7 +179,7 @@ All ShuttleMove procs go here for(var/obj/machinery/door/airlock/A in range(1, src)) // includes src A.shuttledocked = FALSE A.air_tight = TRUE - INVOKE_ASYNC(A, /obj/machinery/door/.proc/close) + addtimer(CALLBACK(A, /obj/machinery/door/.proc/close), 0) /obj/machinery/door/airlock/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index fd5f2f59fd..9bea790957 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -48,7 +48,7 @@ return /obj/machinery/power/emitter/energycannon/magical/emag_act(mob/user) - return + return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) /obj/structure/table/abductor/wabbajack name = "wabbajack altar" @@ -165,7 +165,7 @@ var/datum/job/captain/C = new /datum/job/captain access_card.access = C.get_access() access_card.access |= ACCESS_CENT_BAR - access_card.item_flags |= NODROP + ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /mob/living/simple_animal/hostile/alien/maid/barmaid/Destroy() qdel(access_card) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index b54fceb3e7..2249f5f10e 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -60,6 +60,10 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( for(var/a in T.GetAllContents()) if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types)) return FALSE + if(istype(a, /obj/structure/closet))//Prevents eigenlockers from ending up at CC + var/obj/structure/closet/c = a + if(c.eigen_teleport == TRUE) + return FALSE return TRUE /obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S) diff --git a/code/modules/spells/spell_types/area_teleport.dm b/code/modules/spells/spell_types/area_teleport.dm index ab399f4e2a..7bede9f8be 100644 --- a/code/modules/spells/spell_types/area_teleport.dm +++ b/code/modules/spells/spell_types/area_teleport.dm @@ -58,7 +58,7 @@ var/success = 0 while(tempL.len) attempt = pick(tempL) - target.Move(attempt) + do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC) if(get_turf(target) == attempt) success = 1 break @@ -66,7 +66,7 @@ tempL.Remove(attempt) if(!success) - target.forceMove(L) + do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC) playsound(get_turf(user), sound2, 50,1) return diff --git a/code/modules/spells/spell_types/barnyard.dm b/code/modules/spells/spell_types/barnyard.dm index 01b24fef98..ccb0280779 100644 --- a/code/modules/spells/spell_types/barnyard.dm +++ b/code/modules/spells/spell_types/barnyard.dm @@ -37,20 +37,15 @@ "Your face starts burning up, but the flames are repulsed by your anti-magic protection!") return - var/list/masks = list(/obj/item/clothing/mask/spig, /obj/item/clothing/mask/cowmask, /obj/item/clothing/mask/horsehead) - var/list/mSounds = list('sound/magic/pighead_curse.ogg', 'sound/magic/cowhead_curse.ogg', 'sound/magic/horsehead_curse.ogg') - var/randM = rand(1,3) + var/list/masks = list(/obj/item/clothing/mask/pig/cursed, /obj/item/clothing/mask/cowmask/cursed, /obj/item/clothing/mask/horsehead/cursed) - - var/choice = masks[randM] - var/obj/item/clothing/mask/magichead = new choice - magichead.item_flags |= NODROP + var/choice = pick(masks) + var/obj/item/clothing/mask/magichead = new choice(get_turf(target)) magichead.flags_inv = null target.visible_message("[target]'s face bursts into flames, and a barnyard animal's head takes its place!", \ "Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!") if(!target.dropItemToGround(target.wear_mask)) qdel(target.wear_mask) target.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, 1, 1) - playsound(get_turf(target), mSounds[randM], 50, 1) target.flash_act() diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm index 06d1fc3dc5..a5f371ffc2 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/items_and_weapons.dmi' icon_state = "syndballoon" item_state = null - item_flags = NEEDS_PERMIT | ABSTRACT | NODROP | DROPDEL + item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 0 throwforce = 0 @@ -15,6 +15,10 @@ throw_speed = 0 var/charges = 1 +/obj/item/melee/touch_attack/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user) if(!iscarbon(user)) //Look ma, no hands return diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index d88ee7fb22..efc80101f6 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -34,7 +34,7 @@ for(var/obj/item/item in hand_items) // I ensouled the nuke disk once. But it's probably a really // mean tactic, so probably should discourage it. - if((item.item_flags & ABSTRACT) || (item.item_flags & NODROP) || SEND_SIGNAL(item, COMSIG_ITEM_IMBUE_SOUL, user)) + if((item.item_flags & ABSTRACT) || HAS_TRAIT(item, TRAIT_NODROP) || SEND_SIGNAL(item, COMSIG_ITEM_IMBUE_SOUL, user)) continue marked_item = item to_chat(M, "You begin to focus your very being into [item]...") diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index bc1fc980bb..13686e2069 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(summoned_guns, list( /obj/item/gun/ballistic/revolver/grenadelauncher, /obj/item/gun/ballistic/revolver/golden, /obj/item/gun/ballistic/automatic/sniper_rifle, + /obj/item/gun/ballistic/rocketlauncher, /obj/item/gun/medbeam, /obj/item/gun/energy/laser/scatter, /obj/item/gun/energy/gravity_gun)) diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index 88c6ce175f..1576c55326 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -15,7 +15,6 @@ var/die_with_shapeshifted_form = TRUE var/convert_damage = FALSE //If you want to convert the caster's health to the shift, and vice versa. var/convert_damage_type = BRUTE //Since simplemobs don't have advanced damagetypes, what to convert damage back into. - var/shapeshift_type var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\ /mob/living/simple_animal/pet/dog/corgi,\ @@ -167,4 +166,4 @@ /datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer) if(source) - source.shapeDeath(gibbed) \ No newline at end of file + source.shapeDeath(gibbed) diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm index 2bc347b185..6d46c53a9d 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -25,7 +25,7 @@ for(var/obj/item/item in hand_items) if(item.item_flags & ABSTRACT) continue - if(item.item_flags & NODROP) + if(HAS_TRAIT(item, TRAIT_NODROP)) message += "Though it feels redundant, " marked_item = item message += "You mark [item] for recall." diff --git a/code/modules/spells/spell_types/turf_teleport.dm b/code/modules/spells/spell_types/turf_teleport.dm index 093285b74d..8a45f2be22 100644 --- a/code/modules/spells/spell_types/turf_teleport.dm +++ b/code/modules/spells/spell_types/turf_teleport.dm @@ -40,6 +40,5 @@ if(!picked || !isturf(picked)) return - if(!target.Move(picked)) - target.forceMove(picked) - playsound(get_turf(user), sound2, 50,1) + if(do_teleport(user, picked, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC)) + playsound(get_turf(user), sound1, 50,1) diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index 98f5534d06..b09dee04c7 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -133,6 +133,7 @@ mode = "M-SHIELD" speed_process = TRUE var/kill_range = 14 + density = 0 /obj/machinery/satellite/meteor_shield/sci name = "\improper Meteor Shield Satellite" @@ -197,9 +198,11 @@ change_meteor_chance(0.5) /obj/machinery/satellite/meteor_shield/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "You access the satellite's debug mode, increasing the chance of meteor strikes.") if(active) change_meteor_chance(4) + return TRUE diff --git a/code/modules/surgery/advanced/bioware/nerve_grounding.dm b/code/modules/surgery/advanced/bioware/nerve_grounding.dm index f4b23c89b1..99902ff6d6 100644 --- a/code/modules/surgery/advanced/bioware/nerve_grounding.dm +++ b/code/modules/surgery/advanced/bioware/nerve_grounding.dm @@ -17,10 +17,14 @@ time = 155 /datum/surgery_step/ground_nerves/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] starts splicing together [target]'s nerves.", "You start splicing together [target]'s nerves.") + display_results(user, target, "You start rerouting [target]'s nerves.", + "[user] starts rerouting [target]'s nerves.", + "[user] starts manipulating [target]'s nervous system.") /datum/surgery_step/ground_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully splices [target]'s nervous system!", "You successfully splice [target]'s nervous system!") + display_results(user, target, "You successfully reroute [target]'s nervous system!", + "[user] successfully reroutes [target]'s nervous system!", + "[user] finishes manipulating [target]'s nervous system.") new /datum/bioware/grounded_nerves(target) return TRUE @@ -37,4 +41,4 @@ /datum/bioware/grounded_nerves/on_lose() ..() - owner.physiology.siemens_coeff = prev_coeff \ No newline at end of file + owner.physiology.siemens_coeff = prev_coeff diff --git a/code/modules/surgery/advanced/bioware/nerve_splicing.dm b/code/modules/surgery/advanced/bioware/nerve_splicing.dm index 6192786cc4..e6e66e1b6e 100644 --- a/code/modules/surgery/advanced/bioware/nerve_splicing.dm +++ b/code/modules/surgery/advanced/bioware/nerve_splicing.dm @@ -10,17 +10,20 @@ /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) bioware_target = BIOWARE_NERVES - /datum/surgery_step/splice_nerves name = "splice nerves" accept_hand = TRUE time = 155 /datum/surgery_step/splice_nerves/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] starts splicing together [target]'s nerves.", "You start splicing together [target]'s nerves.") + display_results(user, target, "You start splicing together [target]'s nerves.", + "[user] starts splicing together [target]'s nerves.", + "[user] starts manipulating [target]'s nervous system.") /datum/surgery_step/splice_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully splices [target]'s nervous system!", "You successfully splice [target]'s nervous system!") + display_results(user, target, "You successfully splice [target]'s nervous system!", + "[user] successfully splices [target]'s nervous system!", + "[user] finishes manipulating [target]'s nervous system.") new /datum/bioware/spliced_nerves(target) return TRUE @@ -28,11 +31,9 @@ name = "Spliced Nerves" desc = "Nerves are connected to each other multiple times, greatly reducing the impact of stunning effects." mod_type = BIOWARE_NERVES - /datum/bioware/spliced_nerves/on_gain() ..() owner.physiology.stun_mod *= 0.5 - /datum/bioware/spliced_nerves/on_lose() ..() - owner.physiology.stun_mod *= 2 \ No newline at end of file + owner.physiology.stun_mod *= 2 diff --git a/code/modules/surgery/advanced/bioware/vein_threading.dm b/code/modules/surgery/advanced/bioware/vein_threading.dm index 7a03833c51..fc0868c116 100644 --- a/code/modules/surgery/advanced/bioware/vein_threading.dm +++ b/code/modules/surgery/advanced/bioware/vein_threading.dm @@ -10,17 +10,20 @@ /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) bioware_target = BIOWARE_CIRCULATION - /datum/surgery_step/thread_veins name = "thread veins" accept_hand = TRUE time = 125 /datum/surgery_step/thread_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] starts weaving [target]'s circulatory system.", "You start weaving [target]'s circulatory system.") + display_results(user, target, "You start weaving [target]'s circulatory system.", + "[user] starts weaving [target]'s circulatory system.", + "[user] starts manipulating [target]'s circulatory system.") /datum/surgery_step/thread_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] weaves [target]'s circulatory system into a resistant mesh!", "You weave [target]'s circulatory system into a resistant mesh!") + display_results(user, target, "You weave [target]'s circulatory system into a resistant mesh!", + "[user] weaves [target]'s circulatory system into a resistant mesh!", + "[user] finishes manipulating [target]'s circulatory system.") new /datum/bioware/threaded_veins(target) return TRUE @@ -28,11 +31,9 @@ name = "Threaded Veins" desc = "The circulatory system is woven into a mesh, severely reducing the amount of blood lost from wounds." mod_type = BIOWARE_CIRCULATION - /datum/bioware/threaded_veins/on_gain() ..() owner.physiology.bleed_mod *= 0.25 - /datum/bioware/threaded_veins/on_lose() ..() - owner.physiology.bleed_mod *= 4 \ No newline at end of file + owner.physiology.bleed_mod *= 4 diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm index 23783f1bf2..730a912189 100644 --- a/code/modules/surgery/advanced/brainwashing.dm +++ b/code/modules/surgery/advanced/brainwashing.dm @@ -2,7 +2,6 @@ name = "Brainwashing Surgery Disk" desc = "The disk provides instructions on how to impress an order on a brain, making it the primary objective of the patient." surgeries = list(/datum/surgery/advanced/brainwashing) - /datum/surgery/advanced/brainwashing name = "Brainwashing" desc = "A surgical procedure which directly implants a directive into the patient's brain, making it their absolute priority. It can be cleared using a mindshield implant." @@ -13,10 +12,9 @@ /datum/surgery_step/clamp_bleeders, /datum/surgery_step/brainwash, /datum/surgery_step/close) - + species = list(/mob/living/carbon/human) possible_locs = list(BODY_ZONE_HEAD) - /datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target) if(!..()) return FALSE @@ -24,27 +22,29 @@ if(!B) return FALSE return TRUE - /datum/surgery_step/brainwash name = "brainwash" implements = list(/obj/item/hemostat = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15) time = 200 var/objective - /datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) objective = stripped_input(user, "Choose the objective to imprint on your victim's brain.", "Brainwashing", null, MAX_MESSAGE_LEN) if(!objective) return -1 - user.visible_message("[user] begins to tinker with [target]'s brain.", "You begin to brainwash [target]...") + display_results(user, target, "You begin to brainwash [target]...", + "[user] begins to fix [target]'s brain.", + "[user] begins to perform surgery on [target]'s brain.") /datum/surgery_step/brainwash/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(!target.mind) - user.visible_message("[target] doesn't respond to the brainwashing, as if [target.p_they()] lacked a mind...") + to_chat(user, "[target] doesn't respond to the brainwashing, as if [target.p_they()] lacked a mind...") return FALSE if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) - user.visible_message("You hear a faint buzzing from a device inside [target]'s brain, and the brainwashing is erased.") + to_chat(user, "You hear a faint buzzing from a device inside [target]'s brain, and the brainwashing is erased.") return FALSE - user.visible_message("[user] successfully brainwashes [target]!", "You succeed in brainwashing [target].") + display_results(user, target, "You succeed in brainwashing [target].", + "[user] successfully fixes [target]'s brain!", + "[user] completes the surgery on [target]'s brain.") to_chat(target, "A new compulsion fills your mind... you feel forced to obey it!") brainwash(target, objective) message_admins("[ADMIN_LOOKUPFLW(user)] surgically brainwashed [ADMIN_LOOKUPFLW(target)] with the objective '[objective]'.") @@ -53,8 +53,10 @@ /datum/surgery_step/brainwash/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(target.getorganslot(ORGAN_SLOT_BRAIN)) - user.visible_message("[user] damages some brain tissue!", "You bruise some brain tissue!") + display_results(user, target, "You screw up, bruising the brain tissue!", + "[user] screws up, causing brain damage!", + "[user] completes the surgery on [target]'s brain.") target.adjustBrainLoss(40) else user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm index f74346b193..1c09f5f7da 100644 --- a/code/modules/surgery/advanced/lobotomy.dm +++ b/code/modules/surgery/advanced/lobotomy.dm @@ -12,7 +12,6 @@ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 - /datum/surgery/advanced/lobotomy/can_start(mob/user, mob/living/carbon/target) if(!..()) return FALSE @@ -20,23 +19,25 @@ if(!B) return FALSE return TRUE - /datum/surgery_step/lobotomize name = "perform lobotomy" implements = list(/obj/item/scalpel = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35, /obj/item/shard = 25, /obj/item = 20) time = 100 - /datum/surgery_step/lobotomize/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.is_sharp()) return FALSE return TRUE /datum/surgery_step/lobotomize/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to cut a piece of [target]'s brain.", "You begin to cut a piece of [target]'s brain...") + display_results(user, target, "You begin to perform a lobotomy on [target]'s brain...", + "[user] begins to perform a lobotomy on [target]'s brain.", + "[user] begins to perform surgery on [target]'s brain.") /datum/surgery_step/lobotomize/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully lobotomizes [target]!", "You succeed in lobotomizing [target].") + display_results(user, target, "You succeed in lobotomizing [target].", + "[user] successfully lobotomizes [target]!", + "[user] completes the surgery on [target]'s brain.") target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed)) target.mind.remove_antag_datum(/datum/antagonist/brainwashed) @@ -51,7 +52,9 @@ /datum/surgery_step/lobotomize/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(target.getorganslot(ORGAN_SLOT_BRAIN)) - user.visible_message("[user] removes the wrong part, causing more damage!", "You remove the wrong part, causing more damage!") + display_results(user, target, "You remove the wrong part, causing more damage!", + "[user] successfully lobotomizes [target]!", + "[user] completes the surgery on [target]'s brain.") target.adjustBrainLoss(80) switch(rand(1,3)) if(1) @@ -62,4 +65,4 @@ target.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_MAGIC) else user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/surgery/advanced/necrotic_revival.dm b/code/modules/surgery/advanced/necrotic_revival.dm index a88bb51b31..8c57930252 100644 --- a/code/modules/surgery/advanced/necrotic_revival.dm +++ b/code/modules/surgery/advanced/necrotic_revival.dm @@ -7,9 +7,7 @@ /datum/surgery_step/clamp_bleeders, /datum/surgery_step/bionecrosis, /datum/surgery_step/close) - possible_locs = list(BODY_ZONE_HEAD) - /datum/surgery/advanced/necrotic_revival/can_start(mob/user, mob/living/carbon/target) . = ..() var/obj/item/organ/zombie_infection/ZI = target.getorganslot(ORGAN_SLOT_ZOMBIE) @@ -19,16 +17,21 @@ /datum/surgery_step/bionecrosis name = "start bionecrosis" implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) + implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30) time = 50 chems_needed = list("zombiepowder", "rezadone") require_all_chems = FALSE /datum/surgery_step/bionecrosis/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to stimulate [target]'s brain.", "You begin to stimulate [target]'s brain...") + display_results(user, target, "You begin to grow a romerol tumor on [target]'s brain...", + "[user] begins to tinker with [target]'s brain...", + "[user] begins to perform surgery on [target]'s brain.") /datum/surgery_step/bionecrosis/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully grows a necrotic tumor on [target]'s brain!", "You succeed in growing a necrotic tumor on [target]'s brain.") + display_results(user, target, "You succeed in growing a romerol tumor on [target]'s brain.", + "[user] successfully grows a romerol tumor on [target]'s brain!", + "[user] completes the surgery on [target]'s brain.") if(!target.getorganslot(ORGAN_SLOT_ZOMBIE)) var/obj/item/organ/zombie_infection/ZI = new() ZI.Insert(target) - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/surgery/advanced/pacification.dm b/code/modules/surgery/advanced/pacification.dm index 15e34d003c..d5585d71a8 100644 --- a/code/modules/surgery/advanced/pacification.dm +++ b/code/modules/surgery/advanced/pacification.dm @@ -7,31 +7,34 @@ /datum/surgery_step/clamp_bleeders, /datum/surgery_step/pacify, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 - /datum/surgery/advanced/pacify/can_start(mob/user, mob/living/carbon/target) . = ..() var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) if(!B) return FALSE - /datum/surgery_step/pacify name = "rewire brain" implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) time = 40 /datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to reshape [target]'s brain.", "You begin to reshape [target]'s brain...") + display_results(user, target, "You begin to pacify [target]...", + "[user] begins to fix [target]'s brain.", + "[user] begins to perform surgery on [target]'s brain.") /datum/surgery_step/pacify/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] reshapes [target]'s brain!", "You succeed in reshaping [target]'s brain.") + display_results(user, target, "You succeed in neurologically pacifying [target].", + "[user] successfully fixes [target]'s brain!", + "[user] completes the surgery on [target]'s brain.") target.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_LOBOTOMY) return TRUE /datum/surgery_step/pacify/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] reshapes [target]'s brain!", "You screwed up, and rewired [target]'s brain the wrong way around...") + display_results(user, target, "You screw up, rewiring [target]'s brain the wrong way around...", + "[user] screws up, causing brain damage!", + "[user] completes the surgery on [target]'s brain.") target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY) - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm index ebda8a04e2..01c30f174a 100644 --- a/code/modules/surgery/advanced/revival.dm +++ b/code/modules/surgery/advanced/revival.dm @@ -8,11 +8,9 @@ /datum/surgery_step/incise, /datum/surgery_step/revive, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 - /datum/surgery/advanced/revival/can_start(mob/user, mob/living/carbon/target) if(!..()) return FALSE @@ -24,12 +22,10 @@ if(!B) return FALSE return TRUE - /datum/surgery_step/revive name = "electrically stimulate brain" implements = list(/obj/item/twohanded/shockpaddles = 100, /obj/item/abductor/gizmo = 100, /obj/item/melee/baton = 75, /obj/item/organ/cyberimp/arm/baton = 75, /obj/item/organ/cyberimp/arm/gun/taser = 60, /obj/item/gun/energy/e_gun/advtaser = 60, /obj/item/gun/energy/taser = 60) time = 120 - /datum/surgery_step/revive/tool_check(mob/user, obj/item/tool) . = TRUE if(istype(tool, /obj/item/twohanded/shockpaddles)) @@ -51,25 +47,33 @@ return FALSE /datum/surgery_step/revive/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] prepares to shock [target]'s brain with [tool].", "You prepare to give [target]'s brain the spark of life with [tool].") + display_results(user, target, "You prepare to give [target]'s brain the spark of life with [tool].", + "[user] prepares to shock [target]'s brain with [tool].", + "[user] prepares to shock [target]'s brain with [tool].") target.notify_ghost_cloning("Someone is trying to zap your brain. Re-enter your corpse if you want to be revived!", source = target) /datum/surgery_step/revive/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] send a powerful shock to [target]'s brain with [tool]...", "You successfully shock [target]'s brain with [tool]...") + display_results(user, target, "You successfully shock [target]'s brain with [tool]...", + "[user] send a powerful shock to [target]'s brain with [tool]...", + "[user] send a powerful shock to [target]'s brain with [tool]...") playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1) target.adjustOxyLoss(-50, 0) target.updatehealth() if(target.revive()) user.visible_message("...[target] wakes up, alive and aware!", "IT'S ALIVE!") + target.visible_message("...[target] wakes up, alive and aware!") target.emote("gasp") target.adjustBrainLoss(50, 199) //MAD SCIENCE return TRUE else user.visible_message("...[target.p_they()] convulses, then lies still.") + target.visible_message("...[target.p_they()] convulses, then lies still.") return FALSE /datum/surgery_step/revive/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.", "You shock [target]'s brain with [tool], but [target.p_they()] doesn't react.") + display_results(user, target, "You shock [target]'s brain with [tool], but [target.p_they()] doesn't react.", + "[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.", + "[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.") playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1) target.adjustBrainLoss(15, 199) - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/surgery/advanced/toxichealing.dm b/code/modules/surgery/advanced/toxichealing.dm new file mode 100644 index 0000000000..a82287831c --- /dev/null +++ b/code/modules/surgery/advanced/toxichealing.dm @@ -0,0 +1,37 @@ +/datum/surgery/advanced/toxichealing + name = "Body Rejuvenation" + desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals." + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/incise, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/toxichealing, + /datum/surgery_step/close) + + species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list(BODY_ZONE_CHEST) + requires_bodypart_type = 0 + +/datum/surgery_step/toxichealing + name = "rejuvenate body" + implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) + repeatable = TRUE + time = 25 + +/datum/surgery_step/toxichealing/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] starts rejuvenating some of [target]'s flesh back to life.", "You start knitting some of [target]'s flesh back to life.") + +/datum/surgery_step/toxichealing/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] fixes some of [target]'s wounds.", "You succeed in fixing some of [target]'s wounds.") + target.heal_bodypart_damage(0,0,30) //Heals stam + target.adjustToxLoss(-15, 0, TRUE) + target.adjustOxyLoss(-20, 0) + return TRUE + +/datum/surgery_step/toxichealing/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] screws up!", "You screwed up!") + target.take_bodypart_damage(25,0) + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/advanced/viral_bonding.dm b/code/modules/surgery/advanced/viral_bonding.dm index 115f8a2eed..b87d5e001c 100644 --- a/code/modules/surgery/advanced/viral_bonding.dm +++ b/code/modules/surgery/advanced/viral_bonding.dm @@ -7,17 +7,14 @@ /datum/surgery_step/incise, /datum/surgery_step/viral_bond, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) - /datum/surgery/advanced/viral_bonding/can_start(mob/user, mob/living/carbon/target) if(!..()) return FALSE if(!LAZYLEN(target.diseases)) return FALSE return TRUE - /datum/surgery_step/viral_bond name = "viral bond" implements = list(/obj/item/cautery = 100, TOOL_WELDER = 50, /obj/item = 30) // 30% success with any hot item. @@ -27,15 +24,18 @@ /datum/surgery_step/viral_bond/tool_check(mob/user, obj/item/tool) if(implement_type == TOOL_WELDER || implement_type == /obj/item) return tool.is_hot() - return TRUE /datum/surgery_step/viral_bond/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] starts heating [target]'s bone marrow with [tool]...", "You start heating [target]'s bone marrow with [tool]...") + display_results(user, target, "You start heating [target]'s bone marrow with [tool]...", + "[user] starts heating [target]'s bone marrow with [tool]...", + "[user] starts heating something in [target]'s chest with [tool]...") /datum/surgery_step/viral_bond/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[target]'s bone marrow begins pulsing slowly.", "[target]'s bone marrow begins pulsing slowly. The viral bonding is complete.") + display_results(user, target, "[target]'s bone marrow begins pulsing slowly. The viral bonding is complete.", + "[target]'s bone marrow begins pulsing slowly.", + "[user] finishes the operation.") for(var/X in target.diseases) var/datum/disease/D = X D.carrier = TRUE - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index 8465a6d332..01cf6ae112 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -1,25 +1,25 @@ - /datum/surgery/amputation - name = "amputation" + name = "Amputation" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD) requires_bodypart_type = 0 - - /datum/surgery_step/sever_limb name = "sever limb" implements = list(/obj/item/scalpel = 100, /obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25) time = 64 /datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to sever [target]'s [parse_zone(target_zone)]!", "You begin to sever [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to sever [target]'s [parse_zone(target_zone)]...", + "[user] begins to sever [target]'s [parse_zone(target_zone)]!", + "[user] begins to sever [target]'s [parse_zone(target_zone)]!") /datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/mob/living/carbon/human/L = target - user.visible_message("[user] severs [L]'s [parse_zone(target_zone)]!", "You sever [L]'s [parse_zone(target_zone)].") + display_results(user, target, "You sever [L]'s [parse_zone(target_zone)].", + "[user] severs [L]'s [parse_zone(target_zone)]!", + "[user] severs [L]'s [parse_zone(target_zone)]!") if(surgery.operated_bodypart) var/obj/item/bodypart/target_limb = surgery.operated_bodypart target_limb.drop_limb() - - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index a97a133685..81b491e6de 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -354,7 +354,8 @@ if("mam_body_markings" in S.default_features) var/datum/sprite_accessory/Smark Smark = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]] - body_markings_icon = Smark.icon + if(Smark) + body_markings_icon = Smark.icon if(H.dna.features.["mam_body_markings"] != "None") body_markings = lowertext(H.dna.features.["mam_body_markings"]) auxmarking = lowertext(H.dna.features.["mam_body_markings"]) diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index ab31d64034..a3f8b883b4 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -20,8 +20,8 @@ icon_state = "borg_l_arm" status = BODYPART_ROBOTIC - brute_reduction = 5 - burn_reduction = 4 + brute_reduction = 2 + burn_reduction = 1 light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG medium_brute_msg = ROBOTIC_MEDIUM_BRUTE_MSG @@ -41,8 +41,8 @@ icon_state = "borg_r_arm" status = BODYPART_ROBOTIC - brute_reduction = 5 - burn_reduction = 4 + brute_reduction = 2 + burn_reduction = 1 light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG medium_brute_msg = ROBOTIC_MEDIUM_BRUTE_MSG @@ -62,8 +62,8 @@ icon_state = "borg_l_leg" status = BODYPART_ROBOTIC - brute_reduction = 5 - burn_reduction = 4 + brute_reduction = 2 + burn_reduction = 1 light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG medium_brute_msg = ROBOTIC_MEDIUM_BRUTE_MSG @@ -83,8 +83,8 @@ icon_state = "borg_r_leg" status = BODYPART_ROBOTIC - brute_reduction = 5 - burn_reduction = 4 + brute_reduction = 2 + burn_reduction = 1 light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG medium_brute_msg = ROBOTIC_MEDIUM_BRUTE_MSG @@ -103,8 +103,8 @@ icon_state = "borg_chest" status = BODYPART_ROBOTIC - brute_reduction = 5 - burn_reduction = 4 + brute_reduction = 2 + burn_reduction = 1 light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG medium_brute_msg = ROBOTIC_MEDIUM_BRUTE_MSG @@ -268,38 +268,38 @@ burn_reduction = 0 max_damage = 20 -// Upgraded Surplus lims +// Upgraded Surplus lims - Better then robotic lims /obj/item/bodypart/l_arm/robot/surplus_upgraded name = "reinforced surplus prosthetic left arm" - desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection, and is made of stronger parts." icon = 'icons/mob/augmentation/surplus_augments.dmi' - brute_reduction = 1 - burn_reduction = 1 - max_damage = 30 + brute_reduction = 3 + burn_reduction = 2 + max_damage = 55 /obj/item/bodypart/r_arm/robot/surplus_upgraded name = "reinforced surplus prosthetic right arm" - desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection, and is made of stronger parts." icon = 'icons/mob/augmentation/surplus_augments.dmi' - brute_reduction = 1 - burn_reduction = 1 - max_damage = 30 + brute_reduction = 3 + burn_reduction = 2 + max_damage = 55 /obj/item/bodypart/l_leg/robot/surplus_upgraded name = "reinforced surplus prosthetic left leg" - desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection, and is made of stronger parts." icon = 'icons/mob/augmentation/surplus_augments.dmi' - brute_reduction = 1 - burn_reduction = 1 - max_damage = 30 + brute_reduction = 3 + burn_reduction = 2 + max_damage = 55 /obj/item/bodypart/r_leg/robot/surplus_upgraded name = "reinforced surplus prosthetic right leg" - desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection, and is made of stronger parts." icon = 'icons/mob/augmentation/surplus_augments.dmi' - brute_reduction = 1 - burn_reduction = 1 - max_damage = 30 + brute_reduction = 3 + burn_reduction = 2 + max_damage = 55 #undef ROBOTIC_LIGHT_BRUTE_MSG #undef ROBOTIC_MEDIUM_BRUTE_MSG diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index fcd626ad97..e65271576d 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -1,5 +1,5 @@ /datum/surgery/brain_surgery - name = "brain surgery" + name = "Brain surgery" steps = list( /datum/surgery_step/incise, /datum/surgery_step/retract_skin, @@ -7,16 +7,13 @@ /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_brain, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 - /datum/surgery_step/fix_brain name = "fix brain" implements = list(/obj/item/hemostat = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100 time = 120 //long and complicated - /datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target) var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) if(!B) @@ -24,10 +21,14 @@ return TRUE /datum/surgery_step/fix_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to fix [target]'s brain.", "You begin to fix [target]'s brain...") + display_results(user, target, "You begin to fix [target]'s brain...", + "[user] begins to fix [target]'s brain.", + "[user] begins to perform surgery on [target]'s brain.") /datum/surgery_step/fix_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully fixes [target]'s brain!", "You succeed in fixing [target]'s brain.") + display_results(user, target, "You succeed in fixing [target]'s brain.", + "[user] successfully fixes [target]'s brain!", + "[user] completes the surgery on [target]'s brain.") if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed)) target.mind.remove_antag_datum(/datum/antagonist/brainwashed) target.adjustBrainLoss(-60) @@ -36,9 +37,11 @@ /datum/surgery_step/fix_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(target.getorganslot(ORGAN_SLOT_BRAIN)) - user.visible_message("[user] screws up, causing more damage!", "You screw up, causing more damage!") + display_results(user, target, "You screw up, causing more damage!", + "[user] screws up, causing brain damage!", + "[user] completes the surgery on [target]'s brain.") target.adjustBrainLoss(60) target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY) else user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index e57f8f686b..4c65b56962 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -1,49 +1,51 @@ /datum/surgery/cavity_implant - name = "cavity implant" + name = "Cavity implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) - - //handle cavity /datum/surgery_step/handle_cavity name = "implant item" accept_hand = 1 accept_any_item = 1 + implements = list(/obj/item = 100) + repeatable = TRUE time = 32 var/obj/item/IC = null - +/datum/surgery_step/handle_cavity/tool_check(mob/user, obj/item/tool) + if(istype(tool, /obj/item/cautery) || istype(tool, /obj/item/gun/energy/laser)) + return FALSE + return !tool.is_hot() /datum/surgery_step/handle_cavity/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST) IC = CH.cavity_item if(tool) - if(istype(tool, /obj/item/surgical_drapes) || istype(tool, /obj/item/bedsheet)) - var/obj/item/inactive = user.get_inactive_held_item() - if(istype(inactive, /obj/item/cautery) || istype(inactive, /obj/item/screwdriver) || iscyborg(user)) - attempt_cancel_surgery(surgery, tool, target, user) - return -1 - user.visible_message("[user] begins to insert [tool] into [target]'s [target_zone].", "You begin to insert [tool] into [target]'s [target_zone]...") + display_results(user, target, "You begin to insert [tool] into [target]'s [target_zone]...", + "[user] begins to insert [tool] into [target]'s [target_zone].", + "[user] begins to insert [tool.w_class > WEIGHT_CLASS_SMALL ? tool : "something"] into [target]'s [target_zone].") else - user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...") + display_results(user, target, "You check for items in [target]'s [target_zone]...", + "[user] checks for items in [target]'s [target_zone].", + "[user] looks for something in [target]'s [target_zone].") /datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST) if(tool) - if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || (tool.item_flags & NODROP) || istype(tool, /obj/item/organ)) + if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || HAS_TRAIT(tool, TRAIT_NODROP) || istype(tool, /obj/item/organ)) to_chat(user, "You can't seem to fit [tool] in [target]'s [target_zone]!") return 0 - var/obj/item/electronic_assembly/EA = tool - if(istype(EA) && EA.combat_circuits && tool.w_class > WEIGHT_CLASS_SMALL) - to_chat(user, "[tool] is too dangerous to put in [target]'s [target_zone]! Maybe if it was smaller...") - return 0 else - user.visible_message("[user] stuffs [tool] into [target]'s [target_zone]!", "You stuff [tool] into [target]'s [target_zone].") + display_results(user, target, "You stuff [tool] into [target]'s [target_zone].", + "[user] stuffs [tool] into [target]'s [target_zone]!", + "[user] stuffs [tool.w_class > WEIGHT_CLASS_SMALL ? tool : "something"] into [target]'s [target_zone].") user.transferItemToLoc(tool, target, TRUE) CH.cavity_item = tool return 1 else if(IC) - user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].") + display_results(user, target, "You pull [IC] out of [target]'s [target_zone].", + "[user] pulls [IC] out of [target]'s [target_zone]!", + "[user] pulls [IC.w_class > WEIGHT_CLASS_SMALL ? IC : "something"] out of [target]'s [target_zone].") user.put_in_hands(IC) CH.cavity_item = null return 1 diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm index 7bf888ab40..6243405f8d 100644 --- a/code/modules/surgery/core_removal.dm +++ b/code/modules/surgery/core_removal.dm @@ -1,5 +1,5 @@ /datum/surgery/core_removal - name = "core removal" + name = "Core removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/extract_core) species = list(/mob/living/simple_animal/slime) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) @@ -8,7 +8,6 @@ if(target.stat == DEAD) return 1 return 0 - //extract brain /datum/surgery_step/extract_core name = "extract core" @@ -16,13 +15,17 @@ time = 16 /datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to extract a core from [target].", "You begin to extract a core from [target]...") + display_results(user, target, "You begin to extract a core from [target]...", + "[user] begins to extract a core from [target].", + "[user] begins to extract a core from [target].") /datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/mob/living/simple_animal/slime/slime = target if(slime.cores > 0) slime.cores-- - user.visible_message("[user] successfully extracts a core from [target]!", "You successfully extract a core from [target]. [slime.cores] core\s remaining.") + display_results(user, target, "You successfully extract a core from [target]. [slime.cores] core\s remaining.", + "[user] successfully extracts a core from [target]!", + "[user] successfully extracts a core from [target]!") new slime.coretype(slime.loc) @@ -33,4 +36,4 @@ return 0 else to_chat(user, "There aren't any cores left in [target]!") - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/embalming.dm b/code/modules/surgery/embalming.dm new file mode 100644 index 0000000000..f74d864245 --- /dev/null +++ b/code/modules/surgery/embalming.dm @@ -0,0 +1,31 @@ +/datum/surgery/embalming //Fast and easy way to husk bodys + name = "Embalming" + desc = "A surgical procedure that prevents a corps from producing." + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/embalming, + /datum/surgery_step/close) + + species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list(BODY_ZONE_CHEST) + requires_bodypart_type = 0 + +/datum/surgery_step/embalming + name = "embalming body" + implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) + implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30) + time = 10 + chems_needed = list("drying_agent", "sterilizine") + require_all_chems = FALSE + +/datum/surgery_step/embalming/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] starts to embalm [target]'s body.", "You start embalming [target]'s body.") + +/datum/surgery_step/embalming/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] embalms [target]'s body.", "You succeed in embalming [target]'s body.") + ADD_TRAIT(target, TRAIT_HUSK, MAGIC_TRAIT) //Husk's prevent body smell + return FALSE + +/datum/surgery_step/embalming/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] screws up!", "You screwed up!") + ADD_TRAIT(target, TRAIT_NOCLONE, MAGIC_TRAIT) //That body is ruined, but still gives miasma + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index a8cb881326..85142e7bb1 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -1,16 +1,14 @@ /datum/surgery/eye_surgery - name = "eye surgery" + name = "Eye surgery" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_PRECISE_EYES) requires_bodypart_type = 0 - //fix eyes /datum/surgery_step/fix_eyes name = "fix eyes" implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25) time = 64 - /datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target) var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES) if(!E) @@ -19,10 +17,14 @@ return TRUE /datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to fix [target]'s eyes.", "You begin to fix [target]'s eyes...") + display_results(user, target, "You begin to fix [target]'s eyes...", + "[user] begins to fix [target]'s eyes.", + "[user] begins to perform surgery on [target]'s eyes.") /datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] successfully fixes [target]'s eyes!", "You succeed in fixing [target]'s eyes.") + display_results(user, target, "You succeed in fixing [target]'s eyes.", + "[user] successfully fixes [target]'s eyes!", + "[user] completes the surgery on [target]'s eyes.") target.cure_blind(list(EYE_DAMAGE)) target.set_blindness(0) target.cure_nearsighted(list(EYE_DAMAGE)) @@ -32,8 +34,12 @@ /datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(target.getorgan(/obj/item/organ/brain)) - user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!") + display_results(user, target, "You accidentally stab [target] right in the brain!", + "[user] accidentally stabs [target] right in the brain!", + "[user] accidentally stabs [target] right in the brain!") target.adjustBrainLoss(70) else - user.visible_message("[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.", "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.") - return FALSE \ No newline at end of file + display_results(user, target, "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.", + "[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.", + "[user] accidentally stabs [target] right in the brain!") + return FALSE diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 59440cc3ee..0419a4c73f 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -65,7 +65,7 @@ if(S.ignore_clothes || get_location_accessible(M, selected_zone)) var/datum/surgery/procedure = new S.type(M, selected_zone, affecting) - user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].", \ + user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for surgery.", \ "You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].") log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])") @@ -169,4 +169,3 @@ return 0 return 1 - diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 92c5e05246..05119b365d 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -3,27 +3,30 @@ steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) - - //extract implant /datum/surgery_step/extract_implant name = "extract implant" implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 65) time = 64 var/obj/item/implant/I = null - /datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) for(var/obj/item/O in target.implants) I = O break if(I) - user.visible_message("[user] begins to extract [I] from [target]'s [target_zone].", "You begin to extract [I] from [target]'s [target_zone]...") + display_results(user, target, "You begin to extract [I] from [target]'s [target_zone]...", + "[user] begins to extract [I] from [target]'s [target_zone].", + "[user] begins to extract something from [target]'s [target_zone].") else - user.visible_message("[user] looks for an implant in [target]'s [target_zone].", "You look for an implant in [target]'s [target_zone]...") + display_results(user, target, "You look for an implant in [target]'s [target_zone]...", + "[user] looks for an implant in [target]'s [target_zone].", + "[user] looks for something in [target]'s [target_zone].") /datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(I) - user.visible_message("[user] successfully removes [I] from [target]'s [target_zone]!", "You successfully remove [I] from [target]'s [target_zone].") + display_results(user, target, "You successfully remove [I] from [target]'s [target_zone].", + "[user] successfully removes [I] from [target]'s [target_zone]!", + "[user] successfully removes something from [target]'s [target_zone]!") I.removed(target) var/obj/item/implantcase/case @@ -36,14 +39,15 @@ case.imp = I I.forceMove(case) case.update_icon() - user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") + display_results(user, target, "You place [I] into [case].", + "[user] places [I] into [case]!", + "[user] places it into [case]!") else qdel(I) else to_chat(user, "You can't find anything in [target]'s [target_zone]!") return 1 - /datum/surgery/implant_removal/mechanic name = "implant removal" requires_bodypart_type = BODYPART_ROBOTIC @@ -53,4 +57,4 @@ /datum/surgery_step/mechanic_unwrench, /datum/surgery_step/extract_implant, /datum/surgery_step/mechanic_wrench, - /datum/surgery_step/mechanic_close) \ No newline at end of file + /datum/surgery_step/mechanic_close) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 46fe262189..7ba8dbc49d 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,9 +1,5 @@ - /////AUGMENTATION SURGERIES////// - - //SURGERY STEPS - /datum/surgery_step/replace name = "sever muscles" implements = list(/obj/item/scalpel = 100, TOOL_WIRECUTTER = 55) @@ -11,16 +7,15 @@ /datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].", "You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...") - + display_results(user, target, "You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].", + "[user] begins an incision on [target]'s [parse_zone(user.zone_selected)].") /datum/surgery_step/replace_limb name = "replace limb" implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100) time = 32 var/obj/item/bodypart/L = null // L because "limb" - - /datum/surgery_step/replace_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(istype(tool, /obj/item/organ_storage) && istype(tool.contents[1], /obj/item/bodypart)) tool = tool.contents[1] @@ -33,22 +28,20 @@ return -1 L = surgery.operated_bodypart if(L) - user.visible_message("[user] begins to augment [target]'s [parse_zone(user.zone_selected)].", "You begin to augment [target]'s [parse_zone(user.zone_selected)]...") + display_results(user, target, "You begin to augment [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to augment [target]'s [parse_zone(user.zone_selected)] with [aug].", + "[user] begins to augment [target]'s [parse_zone(user.zone_selected)].") else user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") - //ACTUAL SURGERIES - /datum/surgery/augmentation - name = "augmentation" + name = "Augmentation" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb) species = list(/mob/living/carbon/human) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) requires_real_bodypart = TRUE - //SURGERY STEP SUCCESSES - /datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) if(L) if(istype(tool, /obj/item/organ_storage)) @@ -58,7 +51,9 @@ tool = tool.contents[1] if(istype(tool) && user.temporarilyRemoveItemFromInventory(tool)) tool.replace_limb(target, TRUE) - user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") + display_results(user, target, "You successfully augment [target]'s [parse_zone(target_zone)].", + "[user] successfully augments [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully augments [target]'s [parse_zone(target_zone)]!") log_combat(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") else to_chat(user, "[target] has no organic [parse_zone(target_zone)] there!") diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 9967eba663..bb297b4604 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -1,14 +1,11 @@ /datum/surgery/lipoplasty - name = "lipoplasty" + name = "Lipoplasty" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/cut_fat, /datum/surgery_step/remove_fat, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) - /datum/surgery/lipoplasty/can_start(mob/user, mob/living/carbon/target) if(HAS_TRAIT(target, TRAIT_FAT)) return 1 return 0 - - //cut fat /datum/surgery_step/cut_fat name = "cut excess fat" @@ -16,10 +13,14 @@ time = 64 /datum/surgery_step/cut_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to cut away [target]'s excess fat.", "You begin to cut away [target]'s excess fat...") + display_results(user, target, "You begin to cut away [target]'s excess fat...", + "[user] begins to cut away [target]'s excess fat.", + "[user] begins to cut [target]'s [target_zone] with [tool].") /datum/surgery_step/cut_fat/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] cuts [target]'s excess fat loose!", "You cut [target]'s excess fat loose.") + display_results(user, target, "You cut [target]'s excess fat loose.", + "[user] cuts [target]'s excess fat loose!", + "[user] finishes the cut on [target]'s [target_zone].") return 1 //remove fat @@ -29,25 +30,27 @@ time = 32 /datum/surgery_step/remove_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to extract [target]'s loose fat!", "You begin to extract [target]'s loose fat...") + display_results(user, target, "You begin to extract [target]'s loose fat...", + "[user] begins to extract [target]'s loose fat!", + "[user] begins to extract something from [target]'s [target_zone].") /datum/surgery_step/remove_fat/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] extracts [target]'s fat!", "You extract [target]'s fat.") + display_results(user, target, "You extract [target]'s fat.", + "[user] extracts [target]'s fat!", + "[user] extracts [target]'s fat!") target.overeatduration = 0 //patient is unfatted var/removednutriment = target.nutrition target.nutrition = NUTRITION_LEVEL_WELL_FED removednutriment -= 450 //whatever was removed goes into the meat var/mob/living/carbon/human/H = target var/typeofmeat = /obj/item/reagent_containers/food/snacks/meat/slab/human - if(H.dna && H.dna.species) typeofmeat = H.dna.species.meat - var/obj/item/reagent_containers/food/snacks/meat/slab/human/newmeat = new typeofmeat newmeat.name = "fatty meat" newmeat.desc = "Extremely fatty tissue taken from a patient." newmeat.subjectname = H.real_name newmeat.subjectjob = H.job - newmeat.reagents.add_reagent ("nutriment", (removednutriment / 15)) //To balance with nutriment_factor of nutriment + newmeat.reagents.add_reagent (/datum/reagent/consumable/nutriment, (removednutriment / 15)) //To balance with nutriment_factor of nutriment newmeat.forceMove(target.loc) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/mechanic_steps.dm b/code/modules/surgery/mechanic_steps.dm index 6431770fa9..7d364d9ecf 100644 --- a/code/modules/surgery/mechanic_steps.dm +++ b/code/modules/surgery/mechanic_steps.dm @@ -9,15 +9,14 @@ time = 24 /datum/surgery_step/mechanic_open/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to unscrew the shell of [target]'s [parse_zone(target_zone)].", - "You begin to unscrew the shell of [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to unscrew the shell of [target]'s [parse_zone(target_zone)]...", + "[user] begins to unscrew the shell of [target]'s [parse_zone(target_zone)].", + "[user] begins to unscrew the shell of [target]'s [parse_zone(target_zone)].") /datum/surgery_step/mechanic_incise/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.is_sharp()) return FALSE - return TRUE - //close shell /datum/surgery_step/mechanic_close name = "screw shell" @@ -29,15 +28,14 @@ time = 24 /datum/surgery_step/mechanic_close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to screw the shell of [target]'s [parse_zone(target_zone)].", - "You begin to screw the shell of [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to screw the shell of [target]'s [parse_zone(target_zone)]...", + "[user] begins to screw the shell of [target]'s [parse_zone(target_zone)].", + "[user] begins to screw the shell of [target]'s [parse_zone(target_zone)].") /datum/surgery_step/mechanic_close/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.is_sharp()) return FALSE - return TRUE - //prepare electronics /datum/surgery_step/prepare_electronics name = "prepare electronics" @@ -47,8 +45,9 @@ time = 24 /datum/surgery_step/prepare_electronics/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to prepare electronics in [target]'s [parse_zone(target_zone)].", - "You begin to prepare electronics in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to prepare electronics in [target]'s [parse_zone(target_zone)]...", + "[user] begins to prepare electronics in [target]'s [parse_zone(target_zone)].", + "[user] begins to prepare electronics in [target]'s [parse_zone(target_zone)].") //unwrench /datum/surgery_step/mechanic_unwrench @@ -59,8 +58,9 @@ time = 24 /datum/surgery_step/mechanic_unwrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].", - "You begin to unwrench some bolts in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to unwrench some bolts in [target]'s [parse_zone(target_zone)]...", + "[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].", + "[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].") //wrench /datum/surgery_step/mechanic_wrench @@ -71,8 +71,9 @@ time = 24 /datum/surgery_step/mechanic_wrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].", - "You begin to wrench some bolts in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to wrench some bolts in [target]'s [parse_zone(target_zone)]...", + "[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].", + "[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].") //open hatch /datum/surgery_step/open_hatch @@ -81,5 +82,6 @@ time = 10 /datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].", - "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...") \ No newline at end of file + display_results(user, target, "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...", + "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].", + "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].") diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 553de45c60..6bffed7452 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -1,5 +1,5 @@ /datum/surgery/organ_manipulation - name = "organ manipulation" + name = "Organ manipulation" species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD) requires_real_bodypart = 1 @@ -13,7 +13,6 @@ //there should be bone fixing /datum/surgery_step/close ) - /datum/surgery/organ_manipulation/soft possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) steps = list( @@ -24,9 +23,8 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/close ) - /datum/surgery/organ_manipulation/alien - name = "alien organ manipulation" + name = "Alien organ manipulation" possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) species = list(/mob/living/carbon/alien/humanoid) steps = list( @@ -37,9 +35,8 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/close ) - /datum/surgery/organ_manipulation/mechanic - name = "prosthesis organ manipulation" + name = "Prosthesis organ manipulation" possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD) requires_bodypart_type = BODYPART_ROBOTIC steps = list( @@ -51,7 +48,6 @@ /datum/surgery_step/mechanic_wrench, /datum/surgery_step/mechanic_close ) - /datum/surgery/organ_manipulation/mechanic/soft possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) steps = list( @@ -61,7 +57,6 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/mechanic_close ) - /datum/surgery_step/manipulate_organs time = 64 name = "manipulate organs" @@ -70,11 +65,9 @@ var/implements_extract = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 55) var/current_type var/obj/item/organ/I = null - /datum/surgery_step/manipulate_organs/New() ..() implements = implements + implements_extract - /datum/surgery_step/manipulate_organs/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) I = null if(istype(tool, /obj/item/organ_storage)) @@ -92,9 +85,9 @@ if(target_zone != I.zone || target.getorganslot(I.slot)) to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!") return -1 - - user.visible_message("[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].", - "You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...", + "[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].", + "[user] begins to insert something into [target]'s [parse_zone(target_zone)].") else if(implement_type in implements_extract) current_type = "extract" @@ -107,21 +100,20 @@ O.on_find(user) organs -= O organs[O.name] = O - I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs if(I && user && target && user.Adjacent(target) && user.get_active_held_item() == tool) I = organs[I] if(!I) return -1 - user.visible_message("[user] begins to extract [I] from [target]'s [parse_zone(target_zone)].", - "You begin to extract [I] from [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to extract [I] from [target]'s [parse_zone(target_zone)]...", + "[user] begins to extract [I] from [target]'s [parse_zone(target_zone)].", + "[user] begins to extract something from [target]'s [parse_zone(target_zone)].") else return -1 else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ)) to_chat(user, "[tool] was bitten by someone! It's too damaged to use!") return -1 - /datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(current_type == "insert") if(istype(tool, /obj/item/organ_storage)) @@ -134,17 +126,20 @@ I = tool user.temporarilyRemoveItemFromInventory(I, TRUE) I.Insert(target) - user.visible_message("[user] inserts [tool] into [target]'s [parse_zone(target_zone)]!", - "You insert [tool] into [target]'s [parse_zone(target_zone)].") + display_results(user, target, "You insert [tool] into [target]'s [parse_zone(target_zone)].", + "[user] inserts [tool] into [target]'s [parse_zone(target_zone)]!", + "[user] inserts something into [target]'s [parse_zone(target_zone)]!") else if(current_type == "extract") if(I && I.owner == target) - user.visible_message("[user] successfully extracts [I] from [target]'s [parse_zone(target_zone)]!", - "You successfully extract [I] from [target]'s [parse_zone(target_zone)].") + display_results(user, target, "You successfully extract [I] from [target]'s [parse_zone(target_zone)].", + "[user] successfully extracts [I] from [target]'s [parse_zone(target_zone)]!", + "[user] successfully extracts something from [target]'s [parse_zone(target_zone)]!") log_combat(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") I.Remove(target) I.forceMove(get_turf(target)) else - user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", - "You can't extract anything from [target]'s [parse_zone(target_zone)]!") + display_results(user, target, "You can't extract anything from [target]'s [parse_zone(target_zone)]!", + "[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", + "[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!") return 0 diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm index 01eb751f39..da03771a27 100644 --- a/code/modules/surgery/organic_steps.dm +++ b/code/modules/surgery/organic_steps.dm @@ -1,4 +1,3 @@ - //make incision /datum/surgery_step/incise name = "make incision" @@ -7,13 +6,22 @@ time = 16 /datum/surgery_step/incise/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to make an incision in [target]'s [parse_zone(target_zone)].", - "You begin to make an incision in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to make an incision in [target]'s [parse_zone(target_zone)]...", + "[user] begins to make an incision in [target]'s [parse_zone(target_zone)].", + "[user] begins to make an incision in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/incise/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.is_sharp()) return FALSE - + return TRUE +/datum/surgery_step/incise/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if ishuman(target) + var/mob/living/carbon/human/H = target + if (!(NOBLOOD in H.dna.species.species_traits)) + display_results(user, target, "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", + "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", + "") + H.bleed_rate += 3 return TRUE //clamp bleeders @@ -23,15 +31,17 @@ time = 24 /datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to clamp bleeders in [target]'s [parse_zone(target_zone)].", - "You begin to clamp bleeders in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to clamp bleeders in [target]'s [parse_zone(target_zone)]...", + "[user] begins to clamp bleeders in [target]'s [parse_zone(target_zone)].", + "[user] begins to clamp bleeders in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/clamp_bleeders/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(locate(/datum/surgery_step/saw) in surgery.steps) target.heal_bodypart_damage(20,0) + if (ishuman(target)) + var/mob/living/carbon/human/H = target + H.bleed_rate = max( (H.bleed_rate - 3), 0) return ..() - - //retract skin /datum/surgery_step/retract_skin name = "retract skin" @@ -39,8 +49,9 @@ time = 24 /datum/surgery_step/retract_skin/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].", - "You begin to retract the skin in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to retract the skin in [target]'s [parse_zone(target_zone)]...", + "[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].", + "[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].") @@ -52,22 +63,21 @@ time = 24 /datum/surgery_step/close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].", - "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...", + "[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].", + "[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/close/tool_check(mob/user, obj/item/tool) if(implement_type == TOOL_WELDER || implement_type == /obj/item) return tool.is_hot() - return TRUE - /datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(locate(/datum/surgery_step/saw) in surgery.steps) target.heal_bodypart_damage(45,0) + if (ishuman(target)) + var/mob/living/carbon/human/H = target + H.bleed_rate = max( (H.bleed_rate - 3), 0) return ..() - - - //saw bone /datum/surgery_step/saw name = "saw bone" @@ -77,13 +87,15 @@ time = 54 /datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].", - "You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...", + "[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].", + "[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) target.apply_damage(50, BRUTE, "[target_zone]") - - user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!", "You saw [target]'s [parse_zone(target_zone)] open.") + display_results(user, target, "You saw [target]'s [parse_zone(target_zone)] open.", + "[user] saws [target]'s [parse_zone(target_zone)] open!", + "[user] saws [target]'s [parse_zone(target_zone)] open!") return 1 //drill bone @@ -93,10 +105,12 @@ time = 30 /datum/surgery_step/drill/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to drill into the bone in [target]'s [parse_zone(target_zone)].", - "You begin to drill into the bone in [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to drill into the bone in [target]'s [parse_zone(target_zone)]...", + "[user] begins to drill into the bone in [target]'s [parse_zone(target_zone)].", + "[user] begins to drill into the bone in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/drill/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] drills into [target]'s [parse_zone(target_zone)]!", - "You drill into [target]'s [parse_zone(target_zone)].") + display_results(user, target, "You drill into [target]'s [parse_zone(target_zone)].", + "[user] drills into [target]'s [parse_zone(target_zone)]!", + "[user] drills into [target]'s [parse_zone(target_zone)]!") return 1 diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index f09258f19f..2489aa0705 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -89,7 +89,7 @@ holder = item - holder.item_flags |= NODROP + ADD_TRAIT(holder, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) holder.resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF holder.slot_flags = null holder.materials = null @@ -132,7 +132,7 @@ else var/list/choice_list = list() for(var/obj/item/I in items_list) - choice_list[I] = getFlatIcon(I) + choice_list[I] = image(I) var/obj/item/choice = show_radial_menu(owner, owner, choice_list) if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && (choice in contents)) // This monster sanity check is a nice example of how bad input is. @@ -185,11 +185,12 @@ zone = BODY_ZONE_L_ARM /obj/item/organ/cyberimp/arm/toolset/emag_act() - if(!(locate(/obj/item/kitchen/knife/combat/cyborg) in items_list)) - to_chat(usr, "You unlock [src]'s integrated knife!") - items_list += new /obj/item/kitchen/knife/combat/cyborg(src) - return 1 - return 0 + . = ..() + if(locate(/obj/item/kitchen/knife/combat/cyborg) in items_list) + return + to_chat(usr, "You unlock [src]'s integrated knife!") + items_list += new /obj/item/kitchen/knife/combat/cyborg(src) + return TRUE /obj/item/organ/cyberimp/arm/esword name = "arm-mounted energy blade" diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 0302dd2cae..ea336bea19 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -46,7 +46,7 @@ /obj/item/organ/cyberimp/chest/reviver name = "Reviver implant" - desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + desc = "This implant will attempt to revive and heal you if you lose consciousness. For the faint of heart!" icon_state = "chest_implant" implant_color = "#AD0000" slot = ORGAN_SLOT_HEART_AID diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 6d1aebc6a3..06d523721d 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -51,8 +51,7 @@ active = !active if(active) for(var/obj/item/I in owner.held_items) - if(!(I.item_flags & NODROP)) - stored_items += I + stored_items += I var/list/L = owner.get_empty_held_indexes() if(LAZYLEN(L) == owner.held_items.len) @@ -62,7 +61,7 @@ else for(var/obj/item/I in stored_items) to_chat(owner, "Your [owner.get_held_index_name(owner.get_held_index_of_item(I))]'s grip tightens.") - I.item_flags |= NODROP + ADD_TRAIT(I, TRAIT_NODROP, ANTI_DROP_IMPLANT_TRAIT) else release_items() @@ -83,10 +82,9 @@ to_chat(owner, "Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!") stored_items = list() - /obj/item/organ/cyberimp/brain/anti_drop/proc/release_items() for(var/obj/item/I in stored_items) - I.item_flags &= ~NODROP + REMOVE_TRAIT(I, TRAIT_NODROP, ANTI_DROP_IMPLANT_TRAIT) stored_items = list() diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 98abb2528a..eeaaaf2a03 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -169,7 +169,6 @@ var/list/obj/effect/abstract/eye_lighting/eye_lighting var/obj/effect/abstract/eye_lighting/on_mob var/image/mob_overlay - var/datum/component/mobhook /obj/item/organ/eyes/robotic/glow/Initialize() . = ..() @@ -185,7 +184,7 @@ /obj/item/organ/eyes/robotic/glow/proc/terminate_effects() if(owner && active) - deactivate() + deactivate(TRUE) active = FALSE clear_visuals(TRUE) STOP_PROCESSING(SSfastprocess, src) @@ -238,26 +237,12 @@ return deactivate(silent = TRUE) -/obj/item/organ/eyes/robotic/glow/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE) - . = ..() - if (mobhook && mobhook.parent != M) - QDEL_NULL(mobhook) - if (!mobhook) - mobhook = M.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_DIR_CHANGE = CALLBACK(src, .proc/update_visuals))) - -/obj/item/organ/eyes/robotic/glow/Remove(mob/living/carbon/M) - . = ..() - QDEL_NULL(mobhook) - -/obj/item/organ/eyes/robotic/glow/Destroy() - QDEL_NULL(mobhook) // mobhook is not our component - return ..() - /obj/item/organ/eyes/robotic/glow/proc/activate(silent = FALSE) start_visuals() if(!silent) to_chat(owner, "Your [src] clicks and makes a whining noise, before shooting out a beam of light!") active = TRUE + RegisterSignal(owner, COMSIG_ATOM_DIR_CHANGE, .proc/update_visuals) cycle_mob_overlay() /obj/item/organ/eyes/robotic/glow/proc/deactivate(silent = FALSE) @@ -265,6 +250,7 @@ if(!silent) to_chat(owner, "Your [src] shuts off!") active = FALSE + UnregisterSignal(owner, COMSIG_ATOM_DIR_CHANGE) remove_mob_overlay() /obj/item/organ/eyes/robotic/glow/proc/update_visuals(datum/source, olddir, newdir) diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index f666fc209b..94973a8e10 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -1,6 +1,7 @@ #define LIVER_DEFAULT_HEALTH 100 //amount of damage required for liver failure #define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out #define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver +#define LIVER_SWELLING_MOVE_MODIFY "pharma" /obj/item/organ/liver name = "liver" @@ -16,6 +17,8 @@ var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver var/filterToxins = TRUE //whether to filter toxins + var/swelling = 0 + var/cachedmoveCalc = 1 /obj/item/organ/liver/on_life() var/mob/living/carbon/C = owner @@ -45,11 +48,40 @@ if(damage > maxHealth)//cap liver damage damage = maxHealth + if(swelling >= 10) + pharmacokinesis() + /obj/item/organ/liver/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("iron", 5) return S +//Just in case +/obj/item/organ/liver/Remove(mob/living/carbon/M, special = 0) + ..() + M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY) + M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret. + sizeMoveMod(1, M) + +//Applies some of the effects to the patient. +/obj/item/organ/liver/proc/pharmacokinesis() + var/moveCalc = 1+((round(swelling) - 9)/3) + if(moveCalc == cachedmoveCalc)//reduce calculations + return + if(prob(5)) + to_chat(owner, "You feel a stange ache in your side, almost like a sitch. This pain is affecting your movements and making you feel lightheaded.") + var/mob/living/carbon/human/H = owner + H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + H.AdjustBloodVol(moveCalc/3) + sizeMoveMod(moveCalc, H) + +/obj/item/organ/liver/proc/sizeMoveMod(var/value, mob/living/carbon/human/H) + if(cachedmoveCalc == value) + return + H.next_move_modifier /= cachedmoveCalc + H.next_move_modifier *= value + cachedmoveCalc = value + /obj/item/organ/liver/fly name = "insectoid liver" icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits. diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 64be29c339..cfbb530e69 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -1,3 +1,5 @@ +#define LUNGS_MAX_HEALTH 300 + /obj/item/organ/lungs name = "lungs" icon_state = "lungs" @@ -54,8 +56,40 @@ var/crit_stabilizing_reagent = "epinephrine" + //health + var/maxHealth = LUNGS_MAX_HEALTH + var/damage = 0 + +//TODO: lung health affects lung function +/obj/item/organ/lungs/proc/adjustLungLoss(damage_mod, mob/living/carbon/M) //damage might be too low atm. + if (maxHealth == INFINITY) + return + if(damage+damage_mod < 0) + damage = 0 + return + + damage += damage_mod + if ((damage / maxHealth) > 1) + to_chat(M, "You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore!") + M.emote("gasp") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Lungs lost") + qdel(src) + else if ((damage / maxHealth) > 0.75) + to_chat(M, "It's getting really hard to breathe!!") + M.emote("gasp") + M.Dizzy(3) + else if ((damage / maxHealth) > 0.5) + M.Dizzy(2) + to_chat(M, "Your chest is really starting to hurt.") + M.emote("cough") + else if ((damage / maxHealth) > 0.2) + to_chat(M, "You feel an ache within your chest.") + M.emote("cough") + M.Dizzy(1) /obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) +//TODO: add lung damage = less oxygen gains + var/breathModifier = (5-(5*(damage/maxHealth)/2)) //range 2.5 - 5 if((H.status_flags & GODMODE)) return if(HAS_TRAIT(H, TRAIT_NOBREATH)) @@ -124,7 +158,7 @@ else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half gas_breathed = breath_gases[/datum/gas/oxygen] H.clear_alert("not_enough_oxy") @@ -153,7 +187,7 @@ else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-breathModifier) gas_breathed = breath_gases[/datum/gas/nitrogen] H.clear_alert("nitro") @@ -190,7 +224,7 @@ else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-breathModifier) gas_breathed = breath_gases[/datum/gas/carbon_dioxide] H.clear_alert("not_enough_co2") @@ -220,7 +254,7 @@ else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-breathModifier) gas_breathed = breath_gases[/datum/gas/plasma] H.clear_alert("not_enough_tox") @@ -244,6 +278,9 @@ else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning if(prob(20)) H.emote(pick("giggle", "laugh")) + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "chemical_euphoria", /datum/mood_event/chemical_euphoria) + else + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria") // BZ @@ -288,51 +325,52 @@ gas_breathed = breath_gases[/datum/gas/stimulum] if (gas_breathed > gas_stimulation_min) var/existing = H.reagents.get_reagent_amount("stimulum") - H.reagents.add_reagent("stimulum",max(0, 1 - existing)) + H.reagents.add_reagent("stimulum", max(0, 5 - existing)) breath_gases[/datum/gas/stimulum]-=gas_breathed // Miasma if (breath_gases[/datum/gas/miasma]) var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma]) + if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE) - //Miasma sickness - if(prob(0.5 * miasma_pp)) - var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) - miasma_disease.name = "Unknown" - miasma_disease.try_infect(owner) + //Miasma sickness + if(prob(0.05 * miasma_pp)) + var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) + miasma_disease.name = "Unknown" + miasma_disease.try_infect(owner) - // Miasma side effects - switch(miasma_pp) - if(1 to 5) - // At lower pp, give out a little warning - SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") - if(prob(5)) - to_chat(owner, "There is an unpleasant smell in the air.") - if(5 to 15) - //At somewhat higher pp, warning becomes more obvious - if(prob(15)) - to_chat(owner, "You smell something horribly decayed inside this room.") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) - if(15 to 30) - //Small chance to vomit. By now, people have internals on anyway - if(prob(5)) - to_chat(owner, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - owner.vomit() - if(30 to INFINITY) - //Higher chance to vomit. Let the horror start - if(prob(15)) - to_chat(owner, "The stench of rotting carcasses is unbearable!") - SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) - owner.vomit() - else - SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") + // Miasma side effects + switch(miasma_pp) + if(1 to 5) + // At lower pp, give out a little warning + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") + if(prob(5)) + to_chat(owner, "There is an unpleasant smell in the air.") + if(5 to 15) + //At somewhat higher pp, warning becomes more obvious + if(prob(15)) + to_chat(owner, "You smell something horribly decayed inside this room.") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell) + if(15 to 30) + //Small chance to vomit. By now, people have internals on anyway + if(prob(5)) + to_chat(owner, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + owner.vomit() + if(30 to INFINITY) + //Higher chance to vomit. Let the horror start + if(prob(15)) + to_chat(owner, "The stench of rotting carcasses is unbearable!") + SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench) + owner.vomit() + else + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") - // In a full miasma atmosphere with 101.34 pKa, about 10 disgust per breath, is pretty low compared to threshholds - // Then again, this is a purely hypothetical scenario and hardly reachable - owner.adjust_disgust(0.1 * miasma_pp) + // In a full miasma atmosphere with 101.34 pKa, about 10 disgust per breath, is pretty low compared to threshholds + // Then again, this is a purely hypothetical scenario and hardly reachable + owner.adjust_disgust(0.1 * miasma_pp) - breath_gases[/datum/gas/miasma]-=gas_breathed + breath_gases[/datum/gas/miasma]-=gas_breathed // Clear out moods when no miasma at all else @@ -367,10 +405,13 @@ var/cold_modifier = H.dna.species.coldmod if(breath_temperature < cold_level_3_threshold) H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type) + adjustLungLoss((cold_level_3_damage*cold_modifier*2), H) if(breath_temperature > cold_level_3_threshold && breath_temperature < cold_level_2_threshold) H.apply_damage_type(cold_level_2_damage*cold_modifier, cold_damage_type) + adjustLungLoss((cold_level_2_damage*cold_modifier*2), H) if(breath_temperature > cold_level_2_threshold && breath_temperature < cold_level_1_threshold) H.apply_damage_type(cold_level_1_damage*cold_modifier, cold_damage_type) + adjustLungLoss((cold_level_1_damage*cold_modifier*2), H) if(breath_temperature < cold_level_1_threshold) if(prob(20)) to_chat(H, "You feel [cold_message] in your [name]!") @@ -379,10 +420,13 @@ var/heat_modifier = H.dna.species.heatmod if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold) H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type) + adjustLungLoss((heat_level_1_damage*heat_modifier*2), H) if(breath_temperature > heat_level_2_threshold && breath_temperature < heat_level_3_threshold) H.apply_damage_type(heat_level_2_damage*heat_modifier, heat_damage_type) + adjustLungLoss((heat_level_2_damage*heat_modifier*2), H) if(breath_temperature > heat_level_3_threshold) H.apply_damage_type(heat_level_3_damage*heat_modifier, heat_damage_type) + adjustLungLoss((heat_level_3_damage*heat_modifier*2), H) if(breath_temperature > heat_level_1_threshold) if(prob(20)) to_chat(H, "You feel [hot_message] in your [name]!") @@ -401,12 +445,14 @@ safe_oxygen_max = 0 // Like, at all. safe_toxins_min = 16 //We breath THIS! safe_toxins_max = 0 + maxHealth = INFINITY//I don't understand how plamamen work, so I'm not going to try t give them special lungs atm /obj/item/organ/lungs/cybernetic name = "cybernetic lungs" desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." icon_state = "lungs-c" synthetic = TRUE + maxHealth = 400 /obj/item/organ/lungs/cybernetic/emp_act() . = ..() @@ -426,6 +472,7 @@ cold_level_1_threshold = 200 cold_level_2_threshold = 140 cold_level_3_threshold = 100 + maxHealth = 550 /obj/item/organ/lungs/ashwalker name = "ash lungs" @@ -442,3 +489,14 @@ heat_level_1_threshold = 400 // better adapted for heat, obv. Lavaland standard is 300 heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3 +/obj/item/organ/lungs/slime + name = "vacuole" + desc = "A large organelle designed to store oxygen and other important gasses." + + safe_toxins_max = 0 //We breathe this to gain POWER. + +/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) + . = ..() + if (breath && breath.gases[/datum/gas/plasma]) + var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma]) + owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you. diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index b16967b6b0..9f910de9a9 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -153,6 +153,17 @@ // if they have no mutant tongues, give them a regular one T.Insert(src) + else + var/obj/item/organ/tongue/oT = getorganslot(ORGAN_SLOT_TONGUE) + if(oT.name == "fluffy tongue") + var/obj/item/organ/tongue/T + if(dna && dna.species && dna.species.mutanttongue) + T = new dna.species.mutanttongue() + else + T = new() + oT.Remove(src) + qdel(oT) + T.Insert(src) if(!getorganslot(ORGAN_SLOT_EYES)) var/obj/item/organ/eyes/E diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 0e672de225..3eaaa8de92 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -1,3 +1,5 @@ +#define TONGUE_MAX_HEALTH 60 + /obj/item/organ/tongue name = "tongue" desc = "A fleshy muscle mostly used for lying." @@ -8,6 +10,9 @@ var/list/languages_possible var/say_mod = null var/taste_sensitivity = 15 // lower is more sensitive. + var/maxHealth = TONGUE_MAX_HEALTH + var/damage = 0 + var/modifies_speech = FALSE var/static/list/languages_possible_base = typecacheof(list( /datum/language/common, /datum/language/draconic, @@ -24,24 +29,48 @@ . = ..() languages_possible = languages_possible_base -/obj/item/organ/tongue/get_spans() - return list() +/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args) + +/obj/item/organ/tongue/proc/adjustTongueLoss(mob/living/carbon/M, damage_mod) + if (maxHealth == "alien") + return + if (maxHealth == "bone") + var/target = M.get_bodypart(BODY_ZONE_HEAD) + M.apply_damage(damage_mod, BURN, target) + to_chat(M, "The drink burns your skull! Oof, your bones!") + return + if(damage+damage_mod < 0) + damage = 0 + return + + damage += damage_mod + if ((damage / maxHealth) > 1) + to_chat(M, "Your tongue is singed beyond recognition, and disintegrates!") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Tongues lost to Fermi") + qdel(src) + else if ((damage / maxHealth) > 0.85) + to_chat(M, "Your tongue feels like it's about to fall out!.") + else if ((damage / maxHealth) > 0.5) + to_chat(M, "Your tongue is really starting to hurt.") -/obj/item/organ/tongue/proc/TongueSpeech(var/message) - return message /obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = say_mod + if (modifies_speech) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + M.UnregisterSignal(M, COMSIG_MOB_SAY) /obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = initial(M.dna.species.say_mod) + UnregisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + M.RegisterSignal(M, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech) /obj/item/organ/tongue/could_speak_in_language(datum/language/dt) - . = is_type_in_typecache(dt, languages_possible) + return is_type_in_typecache(dt, languages_possible) /obj/item/organ/tongue/lizard name = "forked tongue" @@ -49,14 +78,17 @@ icon_state = "tonguelizard" say_mod = "hisses" taste_sensitivity = 10 // combined nose + tongue, extra sensitive + maxHealth = 40 //extra sensitivity means tongue is more susceptible to damage + modifies_speech = TRUE -/obj/item/organ/tongue/lizard/TongueSpeech(var/message) - var/regex/lizard_hiss = new("s+", "g") - var/regex/lizard_hiSS = new("S+", "g") - if(copytext(message, 1, 2) != "*") +/obj/item/organ/tongue/lizard/handle_speech(datum/source, list/speech_args) + var/static/regex/lizard_hiss = new("s+", "g") + var/static/regex/lizard_hiSS = new("S+", "g") + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = lizard_hiss.Replace(message, "sss") message = lizard_hiSS.Replace(message, "SSS") - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/fly name = "proboscis" @@ -64,14 +96,17 @@ icon_state = "tonguefly" say_mod = "buzzes" taste_sensitivity = 25 // you eat vomit, this is a mercy + maxHealth = 80 //years of eatting trash has made your tongue strong + modifies_speech = TRUE -/obj/item/organ/tongue/fly/TongueSpeech(var/message) - var/regex/fly_buzz = new("z+", "g") - var/regex/fly_buZZ = new("Z+", "g") - if(copytext(message, 1, 2) != "*") +/obj/item/organ/tongue/fly/handle_speech(datum/source, list/speech_args) + var/static/regex/fly_buzz = new("z+", "g") + var/static/regex/fly_buZZ = new("Z+", "g") + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") message = fly_buzz.Replace(message, "zzz") message = fly_buZZ.Replace(message, "ZZZ") - return message + speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/abductor name = "superlingual matrix" @@ -79,9 +114,12 @@ icon_state = "tongueayylmao" say_mod = "gibbers" taste_sensitivity = 101 // ayys cannot taste anything. + maxHealth = 120 //Ayys probe a lot + modifies_speech = TRUE -/obj/item/organ/tongue/abductor/TongueSpeech(var/message) +/obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args) //Hacks + var/message = speech_args[SPEECH_MESSAGE] var/mob/living/carbon/human/user = usr var/rendered = "[user.name]: [message]" user.log_talk(message, LOG_SAY, tag="abductor") @@ -97,7 +135,7 @@ for(var/mob/M in GLOB.dead_mob_list) var/link = FOLLOW_LINK(M, user) to_chat(M, "[link] [rendered]") - return "" + speech_args[SPEECH_MESSAGE] = "" /obj/item/organ/tongue/zombie name = "rotting tongue" @@ -105,9 +143,11 @@ icon_state = "tonguezombie" say_mod = "moans" taste_sensitivity = 32 + maxHealth = 65 //Stop! It's already dead...! + modifies_speech = TRUE -/obj/item/organ/tongue/zombie/TongueSpeech(var/message) - var/list/message_list = splittext(message, " ") +/obj/item/organ/tongue/zombie/handle_speech(datum/source, list/speech_args) + var/list/message_list = splittext(speech_args[SPEECH_MESSAGE], " ") var/maxchanges = max(round(message_list.len / 1.5), 2) for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) @@ -120,7 +160,7 @@ if(prob(20) && message_list.len > 3) message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") - return jointext(message_list, " ") + speech_args[SPEECH_MESSAGE] = jointext(message_list, " ") /obj/item/organ/tongue/alien name = "alien tongue" @@ -128,6 +168,8 @@ icon_state = "tonguexeno" say_mod = "hisses" taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED + maxHealth = "alien" //Their blood is acid, so, no, though a tongueless xeno might be funny + modifies_speech = TRUE // not really, they just hiss var/static/list/languages_possible_alien = typecacheof(list( /datum/language/xenocommon, /datum/language/common, @@ -139,9 +181,8 @@ . = ..() languages_possible = languages_possible_alien -/obj/item/organ/tongue/alien/TongueSpeech(var/message) +/obj/item/organ/tongue/alien/handle_speech(datum/source, list/speech_args) playsound(owner, "hiss", 25, 1, 1) - return message /obj/item/organ/tongue/bone name = "bone \"tongue\"" @@ -150,7 +191,8 @@ say_mod = "rattles" attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned") taste_sensitivity = 101 // skeletons cannot taste anything - + maxHealth = "bone" //Take brute damage instead + modifies_speech = TRUE var/chattering = FALSE var/phomeme_type = "sans" var/list/phomeme_types = list("sans", "papyrus") @@ -159,29 +201,21 @@ . = ..() phomeme_type = pick(phomeme_types) -/obj/item/organ/tongue/bone/TongueSpeech(var/message) - . = message - - if(chattering) - //Annoy everyone nearby with your chattering. - chatter(message, phomeme_type, usr) - -/obj/item/organ/tongue/bone/get_spans() - . = ..() - // Feature, if the tongue talks directly, it will speak with its span +/obj/item/organ/tongue/bone/handle_speech(datum/source, list/speech_args) + if (chattering) + chatter(speech_args[SPEECH_MESSAGE], phomeme_type, source) switch(phomeme_type) if("sans") - . |= SPAN_SANS + speech_args[SPEECH_SPANS] |= SPAN_SANS if("papyrus") - . |= SPAN_PAPYRUS + speech_args[SPEECH_SPANS] |= SPAN_PAPYRUS /obj/item/organ/tongue/bone/plasmaman name = "plasma bone \"tongue\"" desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech." icon_state = "tongueplasma" - -/obj/item/organ/tongue/bone/plasmaman/get_spans() - return + maxHealth = "alien" + modifies_speech = FALSE /obj/item/organ/tongue/robot name = "robotic voicebox" @@ -190,10 +224,50 @@ icon_state = "tonguerobot" say_mod = "states" attack_verb = list("beeped", "booped") + modifies_speech = TRUE taste_sensitivity = 25 // not as good as an organic tongue + maxHealth = 100 //RoboTongue! + var/electronics_magic = TRUE /obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt) - . = TRUE // THE MAGIC OF ELECTRONICS + return ..() || electronics_magic -/obj/item/organ/tongue/robot/get_spans() - return ..() | SPAN_ROBOT +/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT + +/obj/item/organ/tongue/fluffy + name = "fluffy tongue" + desc = "OwO what's this?" + icon_state = "tonguefluffy" + taste_sensitivity = 10 // extra sensitive and inquisitive uwu + maxHealth = 35 //Sensitive tongue! + modifies_speech = TRUE + +/obj/item/organ/tongue/fluffy/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(copytext(message, 1, 2) != "*") + message = replacetext(message, "ne", "nye") + message = replacetext(message, "nu", "nyu") + message = replacetext(message, "na", "nya") + message = replacetext(message, "no", "nyo") + message = replacetext(message, "ove", "uv") + message = replacetext(message, "l", "w") + message = replacetext(message, "r", "w") + message = lowertext(message) + speech_args[SPEECH_MESSAGE] = message + +/obj/item/organ/tongue/cybernetic + name = "cybernetic tongue" + desc = "A state of the art robotic tongue that can detect the pH of anything drank." + icon_state = "tonguecybernetic" + taste_sensitivity = 10 + maxHealth = 60 //It's robotic! + +/obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT + +/obj/item/organ/tongue/robot/ipc + name = "positronic voicebox" + say_mod = "beeps" + desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms." + electronics_magic = FALSE diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 55ead3b5b4..8103224306 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -3,7 +3,7 @@ #define COOLDOWN_MEME 300 #define COOLDOWN_NONE 100 -/obj/item/organ/vocal_cords //organs that are activated through speech with the :x channel +/obj/item/organ/vocal_cords //organs that are activated through speech with the :x/MODE_KEY_VOCALCORDS channel name = "vocal cords" icon_state = "appendix" zone = BODY_ZONE_PRECISE_MOUTH @@ -575,7 +575,7 @@ cooldown = COOLDOWN_MEME for(var/V in listeners) var/mob/living/carbon/human/H = V - if(H.canbearoused && H.has_dna()) // probably a redundant check but for good measure + if(H.canbearoused && H.has_dna() && HAS_TRAIT(H, TRAIT_NYMPHO)) // probably a redundant check but for good measure H.mob_climax(forced_climax=TRUE) //DAB @@ -608,6 +608,867 @@ return cooldown +////////////////////////////////////// +///////ENTHRAL VELVET CHORDS////////// +////////////////////////////////////// + +//Heavily modified voice of god code +/obj/item/organ/vocal_cords/velvet + name = "Velvet chords" + desc = "The voice spoken from these just make you want to drift off, sleep and obey." + icon_state = "velvet_chords" + actions_types = list(/datum/action/item_action/organ_action/velvet) + spans = list("velvet") + +/datum/action/item_action/organ_action/velvet + name = "Velvet chords" + var/obj/item/organ/vocal_cords/velvet/cords = null + //icon_icon = 'icons/mob/screen_alert.dmi' + //button_icon_state = "velvet_chords" + //icon = 'icons/mob/screen_alert.dmi' + //icon_state = "in_love" + +/datum/action/item_action/organ_action/velvet/New() + ..() + cords = target + +/datum/action/item_action/organ_action/velvet/IsAvailable() + return TRUE + +/datum/action/item_action/organ_action/velvet/Trigger() + . = ..() + var/command = input(owner, "Speak in a sultry tone", "Command") + if(QDELETED(src) || QDELETED(owner)) + return + if(!command) + return + owner.say(".x[command]") + +/obj/item/organ/vocal_cords/velvet/can_speak_with() + return TRUE + +/obj/item/organ/vocal_cords/velvet/handle_speech(message) //actually say the message + owner.say(message, spans = spans, sanitize = FALSE) + velvetspeech(message, owner, 1) + +////////////////////////////////////// +///////////FermiChem////////////////// +////////////////////////////////////// +//Removed span_list from input arguments. +/proc/velvetspeech(message, mob/living/user, base_multiplier = 1, message_admins = FALSE, debug = FALSE) + + if(!user || !user.can_speak() || user.stat) + return 0 //no cooldown + + var/log_message = message + + //FIND THRALLS + message = lowertext(message) + var/mob/living/list/listeners = list() + for(var/mob/living/L in get_hearers_in_view(8, user)) + if(L.can_hear() && !L.anti_magic_check(FALSE, TRUE) && L.stat != DEAD) + if(L.has_status_effect(/datum/status_effect/chem/enthrall))//Check to see if they have the status + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)//Check to see if pet is on cooldown from last command and if the master is right + if(E.master != user) + continue + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) + continue + + if (E.cooldown > 0)//If they're on cooldown you can't give them more commands. + continue + listeners += L + + if(!listeners.len) + return 0 + + //POWER CALCULATIONS + + var/power_multiplier = base_multiplier + + // Not sure I want to give extra power to anyone at the moment...? We'll see how it turns out + if(user.mind) + //Chaplains are very good at indoctrinating + if(user.mind.assigned_role == "Chaplain") + power_multiplier *= 1.2 + //Command staff has authority + if(user.mind.assigned_role in GLOB.command_positions) + power_multiplier *= 1.1 + //Why are you speaking + if(user.mind.assigned_role == "Mime") + power_multiplier *= 0.5 + + //Cultists are closer to their gods and are better at indoctrinating + if(iscultist(user)) + power_multiplier *= 1.2 + else if (is_servant_of_ratvar(user)) + power_multiplier *= 1.2 + else if (is_devil(user))//The devil is supposed to be seductive, right? + power_multiplier *= 1.2 + + //range = 0.5 - 1.4~ + //most cases = 1 + + //Try to check if the speaker specified a name or a job to focus on + var/list/specific_listeners = list() + var/found_string = null + + //Get the proper job titles + message = get_full_job_name(message) + + for(var/V in listeners) + var/mob/living/L = V + if(dd_hasprefix(message, L.real_name)) + specific_listeners += L //focus on those with the specified name + //Cut out the name so it doesn't trigger commands + found_string = L.real_name + power_multiplier += 0.5 + + else if(dd_hasprefix(message, L.first_name())) + specific_listeners += L //focus on those with the specified name + //Cut out the name so it doesn't trigger commands + found_string = L.first_name() + power_multiplier += 0.5 + + else if(L.mind && L.mind.assigned_role && dd_hasprefix(message, L.mind.assigned_role)) + specific_listeners += L //focus on those with the specified job + //Cut out the job so it doesn't trigger commands + found_string = L.mind.assigned_role + power_multiplier += 0.25 + + if(specific_listeners.len) + listeners = specific_listeners + //power_multiplier *= (1 + (1/specific_listeners.len)) //Put this is if it becomes OP, power is judged internally on a thrall, so shouldn't be nessicary. + message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1)//I have no idea what this does + + var/obj/item/organ/tongue/T = user.getorganslot(ORGAN_SLOT_TONGUE) + if (T.name == "fluffy tongue") //If you sound hillarious, it's hard to take you seriously. This is a way for other players to combat/reduce their effectiveness. + power_multiplier *= 0.75 + + if(debug == TRUE) + to_chat(world, "[user]'s power is [power_multiplier].") + + //Mixables + var/static/regex/enthral_words = regex("relax|obey|love|serve|docile|so easy|ara ara") + var/static/regex/reward_words = regex("good boy|good girl|good pet|good job") + var/static/regex/punish_words = regex("bad boy|bad girl|bad pet|bad job") + //phase 0 + var/static/regex/saymyname_words = regex("say my name|who am i|whoami") + var/static/regex/wakeup_words = regex("revert|awaken|snap") //works + //phase1 + var/static/regex/petstatus_words = regex("how are you|what is your status|are you okay") + var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush") + var/static/regex/speak_words = regex("talk to me|speak") + var/static/regex/antiresist_words = regex("unable to resist|give in")//useful if you think your target is resisting a lot + var/static/regex/resist_words = regex("resist|snap out of it|fight")//useful if two enthrallers are fighting + var/static/regex/forget_words = regex("forget|muddled|awake and forget") + var/static/regex/attract_words = regex("come here|come to me|get over here|attract") + //phase 2 + var/static/regex/orgasm_words = regex("cum|orgasm|climax|squirt|heyo") //wah, lewd + var/static/regex/awoo_words = regex("howl|awoo|bark") + var/static/regex/nya_words = regex("nya|meow|mewl") + var/static/regex/sleep_words = regex("sleep|slumber|rest") + var/static/regex/strip_words = regex("strip|derobe|nude") + var/static/regex/walk_words = regex("slow down|walk") + var/static/regex/run_words = regex("run|speed up") + var/static/regex/liedown_words = regex("lie down") //TO ADD + var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown|kneel") + //phase 3 + var/static/regex/statecustom_words = regex("state triggers|state your triggers") + var/static/regex/custom_words = regex("new trigger|listen to me") + var/static/regex/custom_words_words = regex("speak|echo|shock|cum|kneel|strip|trance")//What a descriptive name! + var/static/regex/custom_echo = regex("obsess|fills your mind|loop") + var/static/regex/instill_words = regex("feel|entice|overwhel") + var/static/regex/recognise_words = regex("recognise me|did you miss me?") + var/static/regex/objective_words = regex("new objective|obey this command|unable to resist|compulsed") + var/static/regex/heal_words = regex("live|heal|survive|mend|life|pets never die") + var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") + var/static/regex/hallucinate_words = regex("get high|hallucinate") + var/static/regex/hot_words = regex("heat|hot|hell") + var/static/regex/cold_words = regex("cold|cool down|chill|freeze") + var/static/regex/getup_words = regex("get up") + var/static/regex/pacify_words = regex("more and more docile|complaisant|friendly|pacifist") + var/static/regex/charge_words = regex("charge|oorah|attack") + + var/distancelist = list(2,2,1.5,1.3,1.15,1,0.8,0.6,0.5,0.25) + + //CALLBACKS ARE USED FOR MESSAGES BECAUSE SAY IS HANDLED AFTER THE PROCESSING. + + //Tier 1 + //ENTHRAL mixable (works I think) + if(findtext(message, enthral_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + power_multiplier *= distancelist[get_dist(user, V)+1] + if(L == user) + continue + if(length(message)) + E.enthrallTally += (power_multiplier*(((length(message))/200) + 1)) //encourage players to say more than one word. + else + E.enthrallTally += power_multiplier*1.25 //thinking about it, I don't know how this can proc + if(L.canbearoused) + if(L.client?.prefs.lewdchem) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[E.enthrallGender] is so nice to listen to."), 5) + E.cooldown += 1 + + //REWARD mixable works + if(findtext(message, reward_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + power_multiplier *= distancelist[get_dist(user, V)+1] + if(L == user) + continue + if (L.client?.prefs.lewdchem) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[E.enthrallGender] has praised me!!"), 5) + if(HAS_TRAIT(L, TRAIT_NYMPHO)) + L.adjustArousalLoss(2*power_multiplier) + if(HAS_TRAIT(L, TRAIT_MASO)) + E.enthrallTally -= power_multiplier + E.resistanceTally += power_multiplier + E.cooldown += 1 + else + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "I've been praised for doing a good job!"), 5) + E.resistanceTally -= power_multiplier + E.enthrallTally += power_multiplier + var/descmessage = "[(L.client?.prefs.lewdchem?"I feel so happy! I'm a good pet who [E.enthrallGender] loves!":"I did a good job!")]" + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallpraise", /datum/mood_event/enthrallpraise, descmessage) + E.cooldown += 1 + + //PUNISH mixable works + else if(findtext(message, punish_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + var/descmessage = "[(L.client?.prefs.lewdchem?"I've failed [E.enthrallGender]... What a bad, bad pet!":"I did a bad job...")]" + if(L == user) + continue + if (L.client?.prefs.lewdchem) + if(HAS_TRAIT(L, TRAIT_MASO)) + L.adjustArousalLoss(3*power_multiplier) + descmessage += "And yet, it feels so good..!" //I don't really understand masco, is this the right sort of thing they like? + E.enthrallTally += power_multiplier + E.resistanceTally -= power_multiplier + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "I've let [E.enthrallGender] down...!
    "), 5) + else + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "I've let [E.enthrallGender] down...
    "), 5) + else + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "I've failed [E.master]..."), 5) + E.resistanceTally += power_multiplier + E.enthrallTally += power_multiplier + E.cooldown += 1 + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallscold", /datum/mood_event/enthrallscold, descmessage) + E.cooldown += 1 + + + + //teir 0 + //SAY MY NAME works + if((findtext(message, saymyname_words))) + for(var/V in listeners) + var/mob/living/carbon/C = V + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall") + C.silent = 0 + if(C.client?.prefs.lewdchem) + addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.enthrallGender]"), 5) + else + addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.master]"), 5) + + //WAKE UP + else if((findtext(message, wakeup_words))) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + L.SetSleeping(0)//Can you hear while asleep? + switch(E.phase) + if(0) + E.phase = 3 + E.status = null + user.emote("snap") + if(L.client?.prefs.lewdchem) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "The snapping of your [E.enthrallGender]'s fingers brings you back to your enthralled state, obedient and ready to serve."), 5) + else + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "The snapping of [E.master]'s fingers brings you back to being under their influence."), 5) + to_chat(user, "You wake up [L]!") + + //tier 1 + + //PETSTATUS i.e. how they are + else if((findtext(message, petstatus_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + REMOVE_TRAIT(H, TRAIT_MUTE, "enthrall") + var/speaktrigger = "" + //phase + switch(E.phase) + if(0) + continue + if(1) + addtimer(CALLBACK(H, /atom/movable/proc/say, "I feel happy being with you."), 5) + continue + if(2) + speaktrigger += "[(H.client?.prefs.lewdchem?"I think I'm in love with you... ":"I find you really inspirational, ")]" //' + if(3) + speaktrigger += "[(H.client?.prefs.lewdchem?"I'm devoted to being your pet":"I'm commited to following your cause!")]! " + if(4) + speaktrigger += "[(H.client?.prefs.lewdchem?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!! + + //mood + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + switch(mood.sanity) + if(SANITY_GREAT to INFINITY) + speaktrigger += "I'm beyond elated!! " //did you mean byond elated? hohoho + if(SANITY_NEUTRAL to SANITY_GREAT) + speaktrigger += "I'm really happy! " + if(SANITY_DISTURBED to SANITY_NEUTRAL) + speaktrigger += "I'm a little sad, " + if(SANITY_UNSTABLE to SANITY_DISTURBED) + speaktrigger += "I'm really upset, " + if(SANITY_CRAZY to SANITY_UNSTABLE) + speaktrigger += "I'm about to fall apart without you! " + if(SANITY_INSANE to SANITY_CRAZY) + speaktrigger += "Hold me, please.. " + + //Withdrawal + switch(E.withdrawalTick) + if(10 to 36) //denial + speaktrigger += "I missed you, " + if(36 to 66) //barganing + speaktrigger += "I missed you, but I knew you'd come back for me! " + if(66 to 90) //anger + speaktrigger += "I couldn't take being away from you like that, " + if(90 to 140) //depression + speaktrigger += "I was so scared you'd never come back, " + if(140 to INFINITY) //acceptance + speaktrigger += "I'm hurt that you left me like that... I felt so alone... " + + //hunger + switch(H.nutrition) + if(0 to NUTRITION_LEVEL_STARVING) + speaktrigger += "I'm famished, please feed me..! " + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + speaktrigger += "I'm so hungry... " + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + speaktrigger += "I'm hungry, " + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + speaktrigger += "I'm sated, " + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + speaktrigger += "I've a full belly! " + if(NUTRITION_LEVEL_FULL to INFINITY) + speaktrigger += "I'm fat... " + + //health + switch(H.health) + if(100 to INFINITY) + speaktrigger += "I feel fit, " + if(80 to 99) + speaktrigger += "I ache a little bit, " + if(40 to 80) + speaktrigger += "I'm really hurt, " + if(0 to 40) + speaktrigger += "I'm in a lot of pain, help! " + if(-INFINITY to 0) + speaktrigger += "I'm barely concious and in so much pain, please help me! " + //toxin + switch(H.getToxLoss()) + if(10 to 30) + speaktrigger += "I feel a bit queasy... " + if(30 to 60) + speaktrigger += "I feel nauseous... " + if(60 to INFINITY) + speaktrigger += "My head is pounding and I feel like I'm going to be sick... " + //oxygen + if (H.getOxyLoss() >= 25) + speaktrigger += "I can't breathe! " + //blind + if (HAS_TRAIT(H, TRAIT_BLIND)) + speaktrigger += "I can't see! " + //deaf..? + if (HAS_TRAIT(H, TRAIT_DEAF))//How the heck you managed to get here I have no idea, but just in case! + speaktrigger += "I can barely hear you! " + //And the brain damage. And the brain damage. And the brain damage. And the brain damage. And the brain damage. + switch(H.getBrainLoss()) + if(20 to 40) + speaktrigger += "I have a mild head ache, " + if(40 to 80) + speaktrigger += "I feel disorentated and confused, " + if(80 to 120) + speaktrigger += "My head feels like it's about to explode, " + if(120 to 160) + speaktrigger += "You are the only thing keeping my mind sane, " + if(160 to INFINITY) + speaktrigger += "I feel like I'm on the brink of losing my mind, " + + //horny + if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem) + switch(H.getArousalLoss()) + if(40 to 60) + speaktrigger += "I'm feeling a little horny, " + if(60 to 80) + speaktrigger += "I'm feeling horny, " + if(80 to INFINITY) + speaktrigger += "I'm really, really horny, " + + //collar + if(istype(H.wear_neck, /obj/item/clothing/neck/petcollar)) + speaktrigger += "I love the collar you gave me, " + //End + if(H.client?.prefs.lewdchem) + speaktrigger += "[E.enthrallGender]!" + else + speaktrigger += "[user.first_name()]!" + //say it! + addtimer(CALLBACK(H, /atom/movable/proc/say, "[speaktrigger]"), 5) + E.cooldown += 1 + + //SILENCE + else if((findtext(message, silence_words))) + for(var/mob/living/carbon/C in listeners) + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + power_multiplier *= distancelist[get_dist(user, C)+1] + if (E.phase >= 3) //If target is fully enthralled, + ADD_TRAIT(C, TRAIT_MUTE, "enthrall") + else + C.silent += ((10 * power_multiplier) * E.phase) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You are unable to speak!"), 5) + to_chat(user, "You silence [C].") + E.cooldown += 3 + + //SPEAK + else if((findtext(message, speak_words)))//fix + for(var/mob/living/carbon/C in listeners) + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall") + C.silent = 0 + E.cooldown += 3 + to_chat(user, "You [(C.client?.prefs.lewdchem?"allow [C] to speak again":"encourage [C] to speak again")].") + + + //Antiresist + else if((findtext(message, antiresist_words))) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + E.status = "Antiresist" + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "Your mind clouds over, as you find yourself unable to resist!"), 5) + E.statusStrength = (1 * power_multiplier * E.phase) + E.cooldown += 15//Too short? yes, made 15 + to_chat(user, "You frustrate [L]'s attempts at resisting.") + + //RESIST + else if((findtext(message, resist_words))) + for(var/mob/living/carbon/C in listeners) + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + power_multiplier *= distancelist[get_dist(user, C)+1] + E.deltaResist += (power_multiplier) + E.owner_resist() + E.cooldown += 2 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You are spurred into resisting from [user]'s words!'"), 5) + to_chat(user, "You spark resistance in [C].") + + //FORGET (A way to cancel the process) + else if((findtext(message, forget_words))) + for(var/mob/living/carbon/C in listeners) + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase == 4) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You're unable to forget about [(C.client?.prefs.lewdchem?"the dominating presence of [E.enthrallGender]":"[E.master]")]!"), 5) + continue + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You wake up, forgetting everything that just happened. You must've dozed off..? How embarassing!"), 5) + C.Sleeping(50) + switch(E.phase) + if(1 to 2) + E.phase = -1 + to_chat(C, "You have no recollection of being enthralled by [E.master]!") + to_chat(user, "You revert [C] back to their state before enthrallment.") + if(3) + E.phase = 0 + E.cooldown = 0 + if(C.client?.prefs.lewdchem) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You revert to yourself before being enthralled by your [E.enthrallGender], with no memory of what happened."), 5) + else + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You revert to who you were before, with no memory of what happened with [E.master]."), 5) + to_chat(user, "You put [C] into a sleeper state, ready to turn them back at the snap of your fingers.") + + //ATTRACT + else if((findtext(message, attract_words))) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + L.throw_at(get_step_towards(user,L), 3 * power_multiplier, 1 * power_multiplier) + E.cooldown += 3 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You are drawn towards [user]!"), 5) + to_chat(user, "You draw [L] towards you!") + + + //teir 2 + + /* removed for now + //ORGASM + else if((findtext(message, orgasm_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase > 1) + if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem) // probably a redundant check but for good measure + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "Your [E.enthrallGender] pushes you over the limit, overwhelming your body with pleasure."), 5) + H.mob_climax(forced_climax=TRUE) + H.SetStun(20) + H.setArousalLoss(H.min_arousal) + E.resistanceTally = 0 //makes resistance 0, but resets arousal, resistance buildup is faster unaroused (massively so). + E.enthrallTally += power_multiplier + E.cooldown += 6 + else + H.throw_at(get_step_towards(user,H), 3 * power_multiplier, 1 * power_multiplier) + */ + + + //awoo + else if((findtext(message, awoo_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + H.say("*awoo") + E.cooldown += 1 + + //Nya + else if((findtext(message, nya_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + playsound(get_turf(H), pick('sound/effects/meow1.ogg', 'modular_citadel/sound/voice/nya.ogg'), 50, 1, -1) //I'm very tempted to write a Fermis clause that makes them merowr.ogg if it's me. But, I also don't think snowflakism is okay. I would've gotten away for it too, if it wern't for my morals. + H.emote("me", 1, "lets out a nya!") + E.cooldown += 1 + + //SLEEP + else if((findtext(message, sleep_words))) + for(var/mob/living/carbon/C in listeners) + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + C.Sleeping(45 * power_multiplier) + E.cooldown += 10 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "Drowsiness suddenly overwhelms you as you fall asleep!"), 5) + to_chat(user, "You send [C] to sleep.") + + //STRIP + else if((findtext(message, strip_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + var/items = H.get_contents() + for(var/obj/item/W in items) + if(W == H.wear_suit) + H.dropItemToGround(W, TRUE) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "Before you can even think about it, you quickly remove your clothes in response to [(H.client?.prefs.lewdchem?"your [E.enthrallGender]'s command'":"[E.master]'s directive'")]."), 5) + E.cooldown += 10 + + //WALK + else if((findtext(message, walk_words))) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + if(L.m_intent != MOVE_INTENT_WALK) + L.toggle_move_intent() + E.cooldown += 1 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You slow down to a walk."), 5) + to_chat(user, "You encourage [L] to slow down.") + + //RUN + else if((findtext(message, run_words))) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + if(L.m_intent != MOVE_INTENT_RUN) + L.toggle_move_intent() + E.cooldown += 1 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You speed up into a jog!"), 5) + to_chat(user, "You encourage [L] to pick up the pace!") + + //LIE DOWN + else if(findtext(message, liedown_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + L.lay_down() + E.cooldown += 10 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[(L.client?.prefs.lewdchem?"You eagerly lie down!":"You suddenly lie down!")]"), 5) + to_chat(user, "You encourage [L] to lie down.") + + //KNOCKDOWN + else if(findtext(message, knockdown_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(2 to INFINITY) + L.Knockdown(30 * power_multiplier * E.phase) + E.cooldown += 8 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You suddenly drop to the ground!"), 5) + to_chat(user, "You encourage [L] to drop down to the ground.") + + //tier3 + + //STATE TRIGGERS + else if((findtext(message, statecustom_words)))//doesn't work + for(var/V in listeners) + var/mob/living/carbon/C = V + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + if (E.phase == 3) + var/speaktrigger = "" + C.emote("me", 1, "whispers something quietly.") + if (get_dist(user, C) > 1)//Requires user to be next to their pet. + to_chat(user, "You need to be next to your pet to hear them!") + continue + for (var/trigger in E.customTriggers) + speaktrigger += "[trigger], " + to_chat(user, "[C] whispers, \"[speaktrigger] are my triggers.\"")//So they don't trigger themselves! + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You whisper your triggers to [(C.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")]."), 5) + + + //CUSTOM TRIGGERS + else if((findtext(message, custom_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase == 3) + if (get_dist(user, H) > 1)//Requires user to be next to their pet. + to_chat(user, "You need to be next to your pet to give them a new trigger!") + continue + else + user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.") + user.SetStun(1000)//Hands are handy, so you have to stay still + H.SetStun(1000) + if (E.mental_capacity >= 5) + var/trigger = html_decode(stripped_input(user, "Enter the trigger phrase", MAX_MESSAGE_LEN)) + var/custom_words_words_list = list("Speak", "Echo", "Shock", "Cum", "Kneel", "Strip", "Trance", "Cancel") + var/trigger2 = input(user, "Pick an effect", "Effects") in custom_words_words_list + trigger2 = lowertext(trigger2) + if ((findtext(trigger2, custom_words_words))) + if (trigger2 == "speak" || trigger2 == "echo") + var/trigger3 = html_decode(stripped_input(user, "Enter the phrase spoken. Abusing this to self antag is bannable.", MAX_MESSAGE_LEN)) + E.customTriggers[trigger] = list(trigger2, trigger3) + log_game("FERMICHEM: [H] has been implanted by [user] with [trigger], triggering [trigger2], to send [trigger3].") + if(findtext(trigger3, "admin")) + message_admins("FERMICHEM: [user] maybe be trying to abuse MKUltra by implanting by [H] with [trigger], triggering [trigger2], to send [trigger3].") + else + E.customTriggers[trigger] = trigger2 + log_game("FERMICHEM: [H] has been implanted by [user] with [trigger], triggering [trigger2].") + E.mental_capacity -= 5 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "[(H.client?.prefs.lewdchem?"your [E.enthrallGender]":"[E.master]")] whispers you a new trigger."), 5) + to_chat(user, "You sucessfully set the trigger word [trigger] in [H]") + else + to_chat(user, "Your pet looks at you confused, it seems they don't understand that effect!") + else + to_chat(user, "Your pet looks at you with a vacant blase expression, you don't think you can program anything else into them") + user.SetStun(0) + H.SetStun(0) + + //CUSTOM ECHO + else if((findtext(message, custom_echo))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase == 3) + if (get_dist(user, H) > 1)//Requires user to be next to their pet. + to_chat(user, "You need to be next to your pet to give them a new echophrase!") + continue + else + user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.") + user.SetStun(1000)//Hands are handy, so you have to stay still + H.SetStun(1000) + var/trigger = stripped_input(user, "Enter the loop phrase", MAX_MESSAGE_LEN) + var/customSpan = list("Notice", "Warning", "Hypnophrase", "Love", "Velvet") + var/trigger2 = input(user, "Pick the style", "Style") in customSpan + trigger2 = lowertext(trigger2) + E.customEcho = trigger + E.customSpan = trigger2 + user.SetStun(0) + H.SetStun(0) + to_chat(user, "You sucessfully set an echoing phrase in [H]") + + //CUSTOM OBJECTIVE + else if((findtext(message, objective_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase == 3) + if (get_dist(user, H) > 1)//Requires user to be next to their pet. + to_chat(user, "You need to be next to your pet to give them a new objective!") + continue + else + user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'") + user.SetStun(1000)//So you can't run away! + H.SetStun(1000) + if (E.mental_capacity >= 200) + var/datum/objective/brainwashing/objective = stripped_input(user, "Add an objective to give your pet.", MAX_MESSAGE_LEN) + if(!LAZYLEN(objective)) + to_chat(user, "You can't give your pet an objective to do nothing!") + continue + //Pets don't understand harm + objective = replacetext(lowertext(objective), "kill", "hug") + objective = replacetext(lowertext(objective), "murder", "cuddle") + objective = replacetext(lowertext(objective), "harm", "snuggle") + objective = replacetext(lowertext(objective), "decapitate", "headpat") + objective = replacetext(lowertext(objective), "strangle", "meow at") + objective = replacetext(lowertext(objective), "suicide", "self-love") + message_admins("[H] has been implanted by [user] with the objective [objective].") + log_game("FERMICHEM: [H] has been implanted by [user] with the objective [objective] via MKUltra.") + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "[(H.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")] whispers you a new objective."), 5) + brainwash(H, objective) + E.mental_capacity -= 200 + to_chat(user, "You sucessfully give an objective to [H]") + else + to_chat(user, "Your pet looks at you with a vacant blasé expression, you don't think you can program anything else into them") + user.SetStun(0) + H.SetStun(0) + + //INSTILL + else if((findtext(message, instill_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase == 3 && H.client?.prefs.lewdchem) + var/instill = stripped_input(user, "Instill an emotion in your [(user.client?.prefs.lewdchem?"Your pet":"listener")].", MAX_MESSAGE_LEN) + to_chat(H, "[instill]") + to_chat(user, "You sucessfully instill a feeling in [H]") + log_game("FERMICHEM: [H] has been instilled by [user] with [instill] via MKUltra.") + E.cooldown += 1 + + //RECOGNISE + else if((findtext(message, recognise_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + if(E.phase > 1) + if(user.ckey == E.enthrallID && user.real_name == E.master.real_name) + E.master = user + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "[(H.client?.prefs.lewdchem?"You hear the words of your [E.enthrallGender] again!! They're back!!":"You recognise the voice of [E.master].")]"), 5) + to_chat(user, "[H] looks at you with sparkling eyes, recognising you!") + + //I dunno how to do state objectives without them revealing they're an antag + + //HEAL (maybe make this nap instead?) + else if(findtext(message, heal_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3)//Tier 3 only + E.status = "heal" + E.statusStrength = (5 * power_multiplier) + E.cooldown += 5 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You begin to lick your wounds."), 5) + L.Stun(15 * power_multiplier) + to_chat(user, "[L] begins to lick their wounds.") + + //STUN + else if(findtext(message, stun_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3 to INFINITY) + L.Stun(40 * power_multiplier) + E.cooldown += 8 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "Your muscles freeze up!"), 5) + to_chat(user, "You cause [L] to freeze up!") + + //HALLUCINATE + else if(findtext(message, hallucinate_words)) + for(var/V in listeners) + var/mob/living/carbon/C = V + var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3 to INFINITY) + new /datum/hallucination/delusion(C, TRUE, null,150 * power_multiplier,0) + to_chat(user, "You send [C] on a trip.") + + //HOT + else if(findtext(message, hot_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3 to INFINITY) + L.adjust_bodytemperature(50 * power_multiplier)//This seems nuts, reduced it, but then it didn't do anything, so I reverted it. + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You feel your metabolism speed up!"), 5) + to_chat(user, "You speed [L]'s metabolism up!") + + //COLD + else if(findtext(message, cold_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3 to INFINITY) + L.adjust_bodytemperature(-50 * power_multiplier) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You feel your metabolism slow down!"), 5) + to_chat(user, "You slow [L]'s metabolism down!") + + //GET UP + else if(findtext(message, getup_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3 to INFINITY)//Tier 3 only + if(L.resting) + L.lay_down() //aka get up + L.SetStun(0) + L.SetKnockdown(0) + L.SetUnconscious(0) //i said get up i don't care if you're being tased + E.cooldown += 10 //This could be really strong + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You jump to your feet from sheer willpower!"), 5) + to_chat(user, "You spur [L] to their feet!") + + //PACIFY + else if(findtext(message, pacify_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3)//Tier 3 only + E.status = "pacify" + E.cooldown += 10 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "You feel like never hurting anyone ever again."), 5) + to_chat(user, "You remove any intent to harm from [L]'s mind.") + + //CHARGE + else if(findtext(message, charge_words)) + for(var/V in listeners) + var/mob/living/L = V + var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall) + switch(E.phase) + if(3)//Tier 3 only + E.statusStrength = 2* power_multiplier + E.status = "charge" + E.cooldown += 10 + to_chat(user, "You rally [L], leading them into a charge!") + + if(message_admins || debug)//Do you want this in? + message_admins("[ADMIN_LOOKUPFLW(user)] has said '[log_message]' with a Velvet Voice, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + log_game("FERMICHEM: [key_name(user)] ckey: [user.key] has said '[log_message]' with a Velvet Voice, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have spoken with a velvet voice") + //SSblackbox.record_feedback("tally", "Velvet_voice", 1, log_message) If this is on, it fills the thing up and OOFs the server + + return + #undef COOLDOWN_STUN #undef COOLDOWN_DAMAGE diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 54482ade73..39077ae235 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -1,8 +1,7 @@ /datum/surgery/plastic_surgery - name = "plastic surgery" + name = "Plastic surgery" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/reshape_face, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_HEAD) - //reshape_face /datum/surgery_step/reshape_face name = "reshape face" @@ -10,12 +9,16 @@ time = 64 /datum/surgery_step/reshape_face/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to alter [target]'s appearance.", "You begin to alter [target]'s appearance...") + display_results(user, target, "You begin to alter [target]'s appearance...", + "[user] begins to alter [target]'s appearance.", + "[user] begins to make an incision in [target]'s face.") /datum/surgery_step/reshape_face/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(HAS_TRAIT_FROM(target, TRAIT_DISFIGURED, TRAIT_GENERIC)) REMOVE_TRAIT(target, TRAIT_DISFIGURED, TRAIT_GENERIC) - user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.") + display_results(user, target, "You successfully restore [target]'s appearance.", + "[user] successfully restores [target]'s appearance!", + "[user] finishes the operation on [target]'s face.") else var/list/names = list() if(!isabductor(user)) @@ -31,8 +34,18 @@ var/oldname = target.real_name target.real_name = chosen_name var/newname = target.real_name //something about how the code handles names required that I use this instead of target.real_name - user.visible_message("[user] alters [oldname]'s appearance completely, [target.p_they()] is now [newname]!", "You alter [oldname]'s appearance completely, [target.p_they()] is now [newname].") + display_results(user, target, "You alter [oldname]'s appearance completely, [target.p_they()] is now [newname].", + "[user] alters [oldname]'s appearance completely, [target.p_they()] is now [newname]!", + "[user] finishes the operation on [target]'s face.") if(ishuman(target)) var/mob/living/carbon/human/H = target H.sec_hud_set_ID() return 1 + return TRUE + +/datum/surgery_step/reshape_face/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You screw up, leaving [target]'s appearance disfigured!", + "[user] screws up, disfiguring [target]'s appearance!", + "[user] finishes the operation on [target]'s face.") + ADD_TRAIT(target, TRAIT_DISFIGURED, TRAIT_GENERIC) + return FALSE diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index 9032964ae4..fdceb1fb1f 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -1,26 +1,21 @@ /datum/surgery/prosthetic_replacement - name = "prosthetic replacement" + name = "Prosthetic replacement" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD) requires_bodypart = FALSE //need a missing limb requires_bodypart_type = 0 - /datum/surgery/prosthetic_replacement/can_start(mob/user, mob/living/carbon/target) if(!iscarbon(target)) return 0 var/mob/living/carbon/C = target if(!C.get_bodypart(user.zone_selected)) //can only start if limb is missing return 1 - - - /datum/surgery_step/add_prosthetic name = "add prosthetic" implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100, /obj/item/twohanded/required/chainsaw = 100, /obj/item/melee/synthetic_arm_blade = 100) time = 32 var/organ_rejection_dam = 0 - /datum/surgery_step/add_prosthetic/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(istype(tool, /obj/item/organ_storage)) if(!tool.contents.len) @@ -48,16 +43,19 @@ organ_rejection_dam = 30 if(target_zone == BP.body_zone) //so we can't replace a leg with an arm, or a human arm with a monkey arm. - user.visible_message("[user] begins to replace [target]'s [parse_zone(target_zone)].", "You begin to replace [target]'s [parse_zone(target_zone)]...") + display_results(user, target, "You begin to replace [target]'s [parse_zone(target_zone)] with [tool]...", + "[user] begins to replace [target]'s [parse_zone(target_zone)] with [tool].", + "[user] begins to replace [target]'s [parse_zone(target_zone)].") else to_chat(user, "[tool] isn't the right type for [parse_zone(target_zone)].") return -1 else if(target_zone == BODY_ZONE_L_ARM || target_zone == BODY_ZONE_R_ARM) - user.visible_message("[user] begins to attach [tool] onto [target].", "You begin to attach [tool] onto [target]...") + display_results(user, target, "You begin to attach [tool] onto [target]...", + "[user] begins to attach [tool] onto [target]'s [parse_zone(target_zone)].", + "[user] begins to attach something onto [target]'s [parse_zone(target_zone)].") else to_chat(user, "[tool] must be installed onto an arm.") return -1 - /datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(istype(tool, /obj/item/organ_storage)) tool.icon_state = initial(tool.icon_state) @@ -69,13 +67,17 @@ L.attach_limb(target) if(organ_rejection_dam) target.adjustToxLoss(organ_rejection_dam) - user.visible_message("[user] successfully replaces [target]'s [parse_zone(target_zone)]!", "You succeed in replacing [target]'s [parse_zone(target_zone)].") + display_results(user, target, "You succeed in replacing [target]'s [parse_zone(target_zone)].", + "[user] successfully replaces [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully replaces [target]'s [parse_zone(target_zone)]!") return 1 else var/obj/item/bodypart/L = target.newBodyPart(target_zone, FALSE, FALSE) L.is_pseudopart = TRUE L.attach_limb(target) - user.visible_message("[user] finishes attaching [tool]!", "You attach [tool].") + display_results(user, target, "You attach [tool].", + "[user] finishes attaching [tool]!", + "[user] finishes the attachment procedure!") qdel(tool) if(istype(tool, /obj/item/twohanded/required/chainsaw)) var/obj/item/mounted_chainsaw/new_arm = new(target) @@ -85,4 +87,3 @@ var/obj/item/melee/arm_blade/new_arm = new(target,TRUE,TRUE) target_zone == BODY_ZONE_R_ARM ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm) return 1 - diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 451ae02dac..0c3a3b55a5 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -2,23 +2,20 @@ name = "removal of embedded objects" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/remove_object) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) - - /datum/surgery_step/remove_object name = "remove embedded objects" time = 32 accept_hand = 1 var/obj/item/bodypart/L = null - - /datum/surgery_step/remove_object/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) L = surgery.operated_bodypart if(L) - user.visible_message("[user] looks for objects embedded in [target]'s [parse_zone(user.zone_selected)].", "You look for objects embedded in [target]'s [parse_zone(user.zone_selected)]...") + display_results(user, target, "You look for objects embedded in [target]'s [parse_zone(user.zone_selected)]...", + "[user] looks for objects embedded in [target]'s [parse_zone(user.zone_selected)].", + "[user] looks for something in [target]'s [parse_zone(user.zone_selected)].") else user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") - /datum/surgery_step/remove_object/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(L) if(ishuman(target)) @@ -33,11 +30,12 @@ SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "embedded") if(objects > 0) - user.visible_message("[user] successfully removes [objects] objects from [H]'s [L]!", "You successfully remove [objects] objects from [H]'s [L.name].") + display_results(user, target, "You successfully remove [objects] objects from [H]'s [L.name].", + "[user] successfully removes [objects] objects from [H]'s [L]!", + "[user] successfully removes [objects] objects from [H]'s [L]!") else to_chat(user, "You find no objects embedded in [H]'s [L]!") else to_chat(user, "You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!") - return 1 diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index c9a3871511..b013e7f252 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -49,9 +49,14 @@ var/datum/surgery_step/S = get_surgery_step() if(S) - if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src, try_to_fail)) - return 1 - return 0 + var/obj/item/tool = user.get_active_held_item() + if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) + return TRUE + if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache + return TRUE + if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it + to_chat(user, "This step requires a different tool!") + return TRUE /datum/surgery/proc/get_surgery_step() var/step_type = steps[status] diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index f670b80167..c5a944fbb2 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -2,13 +2,12 @@ var/name var/list/implements = list() //format is path = probability of success. alternatively var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type. - var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. - var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand. + var/accept_hand = FALSE //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. + var/accept_any_item = FALSE //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand. var/time = 10 //how long does the step take? - var/repeatable = 0 //can this step be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop + var/repeatable = FALSE //can this step be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob. var/require_all_chems = TRUE //any on the list or all on the list? - /datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) var/success = FALSE if(accept_hand) @@ -16,104 +15,87 @@ success = TRUE if(iscyborg(user)) success = TRUE - if(accept_any_item) if(tool && tool_check(user, tool)) success = TRUE - else if(tool) for(var/key in implements) var/match = FALSE - if(ispath(key) && istype(tool, key)) match = TRUE else if(tool.tool_behaviour == key) match = TRUE - if(match) implement_type = key if(tool_check(user, tool)) success = TRUE break - if(success) if(target_zone == surgery.location) if(get_location_accessible(target, target_zone) || surgery.ignore_clothes) - initiate(user, target, target_zone, tool, surgery, try_to_fail) - return 1 + return initiate(user, target, target_zone, tool, surgery, try_to_fail) else to_chat(user, "You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!") - return 1 //returns 1 so we don't stab the guy in the dick or wherever. - + return TRUE //returns TRUE so we don't stab the guy in the dick or wherever. if(repeatable) var/datum/surgery_step/next_step = surgery.get_surgery_next_step() if(next_step) surgery.status++ if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery)) - return 1 + return TRUE else surgery.status-- - - if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache - return 1 - - return 0 - - + return FALSE /datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) - surgery.step_in_progress = 1 - + surgery.step_in_progress = TRUE var/speed_mod = 1 - + var/advance = FALSE if(preop(user, target, target_zone, tool, surgery) == -1) - surgery.step_in_progress = 0 - return - + surgery.step_in_progress = FALSE + return FALSE if(tool) speed_mod = tool.toolspeed - if(do_after(user, time * speed_mod, target = target)) - var/advance = 0 var/prob_chance = 100 - if(implement_type) //this means it isn't a require hand or any item step. prob_chance = implements[implement_type] prob_chance *= surgery.get_propability_multiplier() - if((prob(prob_chance) || iscyborg(user)) && chem_check(target) && !try_to_fail) if(success(user, target, target_zone, tool, surgery)) - advance = 1 + advance = TRUE else if(failure(user, target, target_zone, tool, surgery)) - advance = 1 - + advance = TRUE if(advance && !repeatable) surgery.status++ if(surgery.status > surgery.steps.len) surgery.complete() - - surgery.step_in_progress = 0 + surgery.step_in_progress = FALSE + return advance /datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to perform surgery on [target].", "You begin to perform surgery on [target]...") - + display_results(user, target, "You begin to perform surgery on [target]...", + "[user] begins to perform surgery on [target].", + "[user] begins to perform surgery on [target].") /datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] succeeds!", "You succeed.") - return 1 + display_results(user, target, "You succeed.", + "[user] succeeds!", + "[user] finishes.") + return TRUE /datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] screws up!", "You screw up!") - return 0 + display_results(user, target, "You screw up!", + "[user] screws up!", + "[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut + return FALSE /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) - return 1 - + return TRUE /datum/surgery_step/proc/chem_check(mob/living/carbon/target) if(!LAZYLEN(chems_needed)) return TRUE - if(require_all_chems) . = TRUE for(var/R in chems_needed) @@ -124,7 +106,6 @@ for(var/R in chems_needed) if(target.reagents.has_reagent(R)) return TRUE - /datum/surgery_step/proc/get_chem_list() if(!LAZYLEN(chems_needed)) return @@ -135,3 +116,11 @@ var/chemname = temp.name chems += chemname return english_list(chems, and_text = require_all_chems ? " and " : " or ") + +//Replaces visible_message during operations so only people looking over the surgeon can tell what they're doing, allowing for shenanigans. +/datum/surgery_step/proc/display_results(mob/user, mob/living/carbon/target, self_message, detailed_message, vague_message, target_detailed = FALSE) + var/list/detailed_mobs = get_hearers_in_view(1, user) //Only the surgeon and people looking over his shoulder can see the operation clearly + if(!target_detailed) + detailed_mobs -= target //The patient can't see well what's going on, unless it's something like getting cut + user.visible_message(detailed_message, self_message, vision_distance = 1, ignored_mobs = target_detailed ? null : target) + user.visible_message(vague_message, "", ignored_mobs = detailed_mobs) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 517dfb412a..db7445e0b0 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "retractor" materials = list(MAT_METAL=6000, MAT_GLASS=3000) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY @@ -33,6 +34,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "hemostat" materials = list(MAT_METAL=5000, MAT_GLASS=2500) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "pinched") @@ -66,6 +68,7 @@ icon = 'icons/obj/surgery.dmi' icon_state = "cautery" materials = list(MAT_METAL=2500, MAT_GLASS=750) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("burnt") @@ -102,6 +105,7 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' materials = list(MAT_METAL=10000, MAT_GLASS=6000) + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL @@ -151,6 +155,7 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) + item_flags = SURGICAL_TOOL attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP_ACCURATE @@ -209,6 +214,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' throwhitsound = 'sound/weapons/pierce.ogg' + item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL @@ -278,6 +284,7 @@ desc = "A container for holding body parts." icon = 'icons/obj/storage.dmi' icon_state = "evidenceobj" + item_flags = SURGICAL_TOOL /obj/item/organ_storage/afterattack(obj/item/I, mob/user, proximity) . = ..() diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 0c3a75e362..8251c450a3 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -49,6 +49,20 @@ if(!ui || ui.status != UI_INTERACTIVE) return 1 // If UI is not interactive or usr calling Topic is not the UI user, bail. + /** + * public + * + * Called on an object when a tgui object is being created, allowing you to customise the html + * For example: inserting a custom stylesheet that you need in the head + * + * For this purpose, some tags are available in the html, to be parsed out with replacetext + * (customheadhtml) - Additions to the head tag + * + * required html the html base text + * + **/ +/datum/proc/ui_base_html(html) + return html /** * private diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index c471f872c3..9b94295414 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -198,11 +198,19 @@ **/ /datum/tgui/proc/get_html(var/inline) var/html + html = SStgui.basehtml + + //Allow the src object to override the html if needed + html = src_object.ui_base_html(html) + //Strip out any remaining custom tags that are used in ui_base_html + html = replacetext(html, "", "") + // Poplate HTML with JSON if we're supposed to inline. if(inline) - html = replacetextEx(SStgui.basehtml, "{}", get_json(initial_data)) - else - html = SStgui.basehtml + html = replacetextEx(html, "{}", get_json(initial_data)) + + + //Setup for tgui stuff, including styles html = replacetextEx(html, "\[ref]", "[REF(src)]") html = replacetextEx(html, "\[style]", style) return html diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm index 2e91879006..b008682745 100644 --- a/code/modules/uplink/uplink_devices.dm +++ b/code/modules/uplink/uplink_devices.dm @@ -57,4 +57,3 @@ /obj/item/pen/uplink/Initialize(mapload, owner, tc_amount = 20) . = ..() AddComponent(/datum/component/uplink, owner, TRUE, FALSE, null, tc_amount) - traitor_unlock_degrees = 360 diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index e41eebf7d6..09e955d2f9 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -85,18 +85,18 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) return pick(4;0.75,2;0.5,1;0.25) /datum/uplink_item/proc/purchase(mob/user, datum/component/uplink/U) - var/atom/A = spawn_item(item, user) + var/atom/A = spawn_item(item, user, U) if(purchase_log_vis && U.purchase_log) U.purchase_log.LogPurchase(A, src, cost) -/datum/uplink_item/proc/spawn_item(spawn_item, mob/user) - if(!spawn_item) +/datum/uplink_item/proc/spawn_item(spawn_path, mob/user, datum/component/uplink/U) + if(!spawn_path) return var/atom/A - if(ispath(spawn_item)) - A = new spawn_item(get_turf(user)) + if(ispath(spawn_path)) + A = new spawn_path(get_turf(user)) else - A = spawn_item + A = spawn_path if(ishuman(user) && istype(A, /obj/item)) var/mob/living/carbon/human/H = user if(H.put_in_hands(A)) @@ -117,23 +117,23 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/bundles_TC/chemical name = "Bioterror bundle" - desc = "For the madman: Contains Bioterror spray, Bioterror grenade, chemicals, syringe gun, box of syringes,\ - Donksoft assault rifle, and some darts. Remember: Seal suit and equip internals before use." + desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \ + box of syringes, Donksoft assault rifle, and some riot darts. Remember: Seal suit and equip internals before use." item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle cost = 30 // normally 42 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/bundles_TC/bulldog name = "Bulldog bundle" - desc = "Lean and mean: Optimised for people that want to get up close and personal. Contains the popular \ - Bulldog shotgun, two 12g drums, and a pair of Thermal imaging goggles." + desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, a 12g buckshot drum, a 12g taser slug drum and a pair of Thermal imaging goggles." item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle cost = 13 // normally 16 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/bundles_TC/c20r name = "C-20r bundle" - desc = "Old faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." + desc = "Old Faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle cost = 14 // normally 16 include_modes = list(/datum/game_mode/nuclear) @@ -147,8 +147,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/bundles_TC/medical name = "Medical bundle" - desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a Donksoft machine gun, \ - a box of ammo, and a pair of magboots to rescue your friends in no-gravity environments." + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ + a Donksoft LMG, a box of riot darts and a pair of magboots to rescue your friends in no-gravity environments." item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle cost = 15 // normally 20 include_modes = list(/datum/game_mode/nuclear) @@ -170,15 +170,18 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/bundles_TC/sniper name = "Sniper bundle" - desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollow-point \ - a soporific knockout magazine, a free surplus supressor, and a worn out suit and tie." + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ + two soporific knockout magazines, a free surplus supressor, and a sharp-looking tactical turtleneck suit. \ + We'll throw in a free red tie if you order NOW." item = /obj/item/storage/briefcase/sniperbundle cost = 20 // normally 26 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/bundles_TC/firestarter name = "Spetsnaz Pyro bundle" - desc = "For systematic suppression of carbon lifeforms in close range: Contains a specialist Pyrotechnic equipment, foreign pistol, two magazines, a pipebomb, and a stimulant syringe." + desc = "For systematic suppression of carbon lifeforms in close quarters: Contains a lethal New Russian backpack spray, Elite hardsuit, \ + Stechkin APS pistol, two magazines, a minibomb and a stimulant syringe. \ + Order NOW and comrade Boris will throw in an extra tracksuit." item = /obj/item/storage/backpack/duffelbag/syndie/firestarter cost = 30 include_modes = list(/datum/game_mode/nuclear) @@ -187,7 +190,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "Syndicate Bundle" desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ - you will receive." + you will receive. May contain discontinued and/or exotic items." item = /obj/item/storage/box/syndicate cost = 20 exclude_modes = list(/datum/game_mode/nuclear) @@ -216,7 +219,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) var/crate_value = starting_crate_value - var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user) + var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user, U) if(U.purchase_log) U.purchase_log.LogPurchase(C, src, cost) while(crate_value) @@ -287,6 +290,31 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous category = "Conspicuous and Dangerous Weapons" +/datum/uplink_item/dangerous/pistol + name = "Stechkin Pistol" + desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ + with suppressors." + item = /obj/item/gun/ballistic/automatic/pistol + cost = 7 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/revolver + name = "Syndicate Revolver" + desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers." + item = /obj/item/gun/ballistic/revolver/syndie + cost = 13 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/rawketlawnchair + name = "84mm Rocket Propelled Grenade Launcher" + desc = "A reusable rocket propelled grenade launcher preloaded with a low-yield 84mm HE round. \ + Guaranteed to send your target out with a bang or your money back!" + item = /obj/item/gun/ballistic/rocketlauncher + cost = 8 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/dangerous/antitank name = "Anti Tank Pistol" desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ @@ -327,7 +355,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/bioterror name = "Biohazardous Chemical Sprayer" - desc = "A chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ + desc = "A handheld chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ Use with extreme caution, to prevent exposure to yourself and your fellow operatives." item = /obj/item/reagent_containers/spray/chemsprayer/bioterror @@ -399,6 +427,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 20 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/dangerous/rapier + name = "Rapier" + desc = "A fancy rapier with a diamond tip piercing anything that it comes into contack with. \ + The rapier comes with its own sheath, this is rather noticeable as only the captain is known to carry a sheath. \ + The sheath itself can be used to block melee attacks only. Its also jet black colours." + item = /obj/item/storage/belt/sabre/rapier + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/dangerous/flamethrower name = "Flamethrower" desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ @@ -427,7 +464,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/guardian name = "Holoparasites" desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ - organic host as a home base and source of fuel." + organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host." item = /obj/item/storage/box/syndie_kit/guardian cost = 15 refundable = TRUE @@ -450,7 +487,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/carbine name = "M-90gl Carbine" desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ - with a togglable 40mm under-barrel grenade launcher." + with a toggleable 40mm underbarrel grenade launcher." item = /obj/item/gun/ballistic/automatic/m90 cost = 18 surplus = 50 @@ -473,14 +510,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 25 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/pistol - name = "Stechkin Pistol" - desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ - with suppressors." - item = /obj/item/gun/ballistic/automatic/pistol - cost = 7 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/dangerous/bolt_action name = "Surplus Rifle" desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." @@ -488,17 +517,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/revolver - name = "Syndicate Revolver" - desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers." - item = /obj/item/gun/ballistic/revolver/syndie - cost = 13 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" - desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." + desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade darts with a 20-round magazine." item = /obj/item/gun/ballistic/automatic/c20r/toy cost = 5 surplus = 0 @@ -514,7 +535,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/dangerous/foampistol - name = "Toy Gun with Riot Darts" + name = "Toy Pistol with Riot Darts" desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ darts effective at incapacitating a target." item = /obj/item/gun/ballistic/automatic/toy/pistol/riot @@ -542,6 +563,12 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 13 surplus = 0 +/datum/uplink_item/dangerous/phantomthief + name = "Syndicate Mask" + desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" + item = /obj/item/clothing/glasses/phantomthief/syndicate + cost = 2 + /datum/uplink_item/stealthy_weapons/dart_pistol name = "Dart Pistol" desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ @@ -594,7 +621,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/stealthy_weapons/romerol_kit name = "Romerol" - desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent." + desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. \ + On death, these nodules take control of the dead body, causing limited revivification, \ + along with slurred speech, aggression, and the ability to infect others with this agent." item = /obj/item/storage/box/syndie_kit/romerol cost = 25 cant_discount = TRUE @@ -604,7 +633,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "Sleepy Pen" desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ strong anesthetic and a chemical that prevents the target from speaking. \ - The pen holds one dose of the mixture, and can be refilled. Note that before the target \ + The pen holds one dose of the mixture, and can be refilled with any chemicals. Note that before the target \ falls asleep, they will be able to move and act." item = /obj/item/pen/sleepy cost = 4 @@ -618,9 +647,9 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes include_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/stealthy_weapons/suppressor - name = "Universal Suppressor" - desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the \ - shots of the weapon for increased stealth and superior ambushing capability." + name = "Suppressor" + desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. \ + It is compatible with many small ballistic guns including the Stechkin and C-20r, but not revolvers or energy guns." item = /obj/item/suppressor cost = 1 surplus = 10 @@ -655,21 +684,24 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/ammo/pistolap name = "10mm Armour Piercing Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are less effective at injuring the target but penetrate protective gear." + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are less effective at injuring the target but penetrate protective gear." item = /obj/item/ammo_box/magazine/m10mm/ap cost = 2 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/ammo/pistolhp name = "10mm Hollow Point Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are more damaging but ineffective against armour." + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are more damaging but ineffective against armour." item = /obj/item/ammo_box/magazine/m10mm/hp cost = 3 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/ammo/pistolfire name = "10mm Incendiary Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with incendiary rounds which ignite the target." + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + Loaded with incendiary rounds which inflict little damage, but ignite the target." item = /obj/item/ammo_box/magazine/m10mm/fire cost = 2 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) @@ -706,7 +738,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/ammo/shotgun/meteor name = "12g Meteorslug Shells" desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \ - Great for blasting airlocks off their frames." + Great for blasting airlocks off their frames and knocking down enemies." item = /obj/item/ammo_box/magazine/m12g/meteor include_modes = list(/datum/game_mode/nuclear) @@ -750,13 +782,12 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes name = ".45 Ammo Duffel Bag" desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg - cost = 20 + cost = 20 //instead of 27 TC include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/smg name = ".45 SMG Magazine" - desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun. \ - These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." + desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun." item = /obj/item/ammo_box/magazine/smgm45 cost = 3 include_modes = list(/datum/game_mode/nuclear) @@ -786,7 +817,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/ammo/carbine name = "5.56mm Toploader Magazine" desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ - These bullets pack less punch than 1.95mm rounds, but they still offer more power than .45 ammo." + These bullets pack less punch than 7.12x82mm rounds, but they still offer more power than .45 ammo." item = /obj/item/ammo_box/magazine/m556 cost = 4 include_modes = list(/datum/game_mode/nuclear) @@ -799,7 +830,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/ammo/machinegun/basic name = "1.95x129mm Box Magazine" desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ - By the time you need to use this, you'll already be on a pile of corpses." + By the time you need to use this, you'll already be standing on a pile of corpses" item = /obj/item/ammo_box/magazine/mm195x129 /datum/uplink_item/ammo/machinegun/ap @@ -821,9 +852,25 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." item = /obj/item/ammo_box/magazine/mm195x129/incen +/datum/uplink_item/ammo/rocket + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/rocket/basic + name = "84mm HE Rocket" + desc = "A low-yield anti-personnel HE rocket. Gonna take you out in style!" + item = /obj/item/ammo_casing/caseless/rocket + cost = 4 + +/datum/uplink_item/ammo/rocket/hedp + name = "84mm HEDP Rocket" + desc = "A high-yield HEDP rocket; extremely effective against armored targets, as well as surrounding personnel. \ + Strike fear into the hearts of your enemies." + item = /obj/item/ammo_casing/caseless/rocket/hedp + cost = 6 + /datum/uplink_item/ammo/pistolaps name = "9mm Handgun Magazine" - desc = "An additional 15-round 9mm magazine, compatible with the Stetchkin APS pistol, found in the Spetsnaz Pyro bundle." + desc = "An additional 15-round 9mm magazine, compatible with the Stechkin APS pistol, found in the Spetsnaz Pyro bundle." item = /obj/item/ammo_box/magazine/pistolm9mm cost = 2 include_modes = list(/datum/game_mode/nuclear) @@ -847,7 +894,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/ammo/toydarts name = "Box of Riot Darts" - desc = "A box of 40 Donksoft foam riot darts, for reloading any compatible foam dart gun. Don't forget to share!" + desc = "A box of 40 Donksoft riot darts, for reloading any compatible foam dart magazine. Don't forget to share!" item = /obj/item/ammo_box/foambox/riot cost = 2 surplus = 0 @@ -871,7 +918,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes category = "Grenades and Explosives" /datum/uplink_item/explosives/bioterrorfoam - name = "Chemical Foam Grenade" + name = "Bioterror Foam Grenade" desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ using additional spore toxin. Ensure suit is sealed before use." @@ -901,7 +948,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/explosives/c4 name = "Composition C-4" desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ - an assembly to it in order to alter the way it detonates. It has a modifiable timer with a \ + an assembly to it in order to alter the way it detonates. It can be attached to almost all objects and has a modifiable timer with a \ minimum setting of 10 seconds." item = /obj/item/grenade/plastic/c4 cost = 1 @@ -915,8 +962,9 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/explosives/x4bag name = "Bag of X-4 explosives" - desc = "Contains 3 X-4 plastic explosives. Similar, but more powerful than C-4. X-4 can be placed on a solid surface, such as a wall or window, and it will \ - blast through the wall, injuring anything on the opposite side, while being safer to the user. For when you want a wider, deeper, hole." + desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ + X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ + For when you want a controlled explosion that leaves a wider, deeper, hole." item = /obj/item/storage/backpack/duffelbag/syndie/x4 cost = 4 // cant_discount = TRUE @@ -937,16 +985,15 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes name = "Detomatix PDA Cartridge" desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ detonate PDAs of crewmembers who have their message feature enabled. \ - The concussive effect from the explosion will knock the recipient out for a short period, and deafen \ - them for longer. Beware, it has a chance to detonate your PDA." + The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer." item = /obj/item/cartridge/virus/syndicate cost = 5 restricted = TRUE /datum/uplink_item/explosives/emp name = "EMP Grenades and Implanter Kit" - desc = "A box that contains two EMP grenades and an EMP implant. Useful to disrupt communication, \ - security's energy weapons, and silicon lifeforms when you're in a tight spot." + desc = "A box that contains five EMP grenades and an EMP implant with three uses. Useful to disrupt communications, \ + security's energy weapons and silicon lifeforms when you're in a tight spot." item = /obj/item/storage/box/syndie_kit/emp cost = 2 @@ -963,7 +1010,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/explosives/grenadier name = "Grenadier's belt" - desc = "A belt of a large variety of lethally dangerous and destructive grenades." + desc = "A belt containing 26 lethally dangerous and destructive grenades. Comes with an extra multitool and screwdriver." item = /obj/item/storage/belt/grenade/full include_modes = list(/datum/game_mode/nuclear) cost = 22 @@ -1050,7 +1097,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/support/reinforcement/assault_borg name = "Syndicate Assault Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel." + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ + Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault refundable = TRUE cost = 65 @@ -1058,17 +1106,18 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/support/reinforcement/medical_borg name = "Syndicate Medical Cyborg" - desc = "A combat medic cyborg, with potent healing reagents and a medical beam gun, but limited offensive potential." + desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ + It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ + Thanks to its organ storage bag, it can perform surgery as well as any humanoid." item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical refundable = TRUE cost = 35 restricted = TRUE /datum/uplink_item/support/gygax - name = "Gygax Exosuit" + name = "Dark Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ - for hit-and-run style attacks. This model lacks a method of space propulsion, and therefore it is \ - advised to utilize the drop pod if you wish to make use of it." + for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." item = /obj/mecha/combat/gygax/dark/loaded cost = 80 @@ -1081,8 +1130,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/support/mauler name = "Mauler Exosuit" - desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring, \ - and deployable smoke." + desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ + and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." item = /obj/mecha/combat/marauder/mauler/loaded cost = 140 @@ -1111,7 +1160,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/stealthy_tools/chameleon name = "Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Due to budget cuts, the shoes don't provide protection against slipping." item = /obj/item/storage/box/syndie_kit/chameleon cost = 2 exclude_modes = list(/datum/game_mode/nuclear) @@ -1125,7 +1175,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/stealthy_tools/codespeak_manual name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. \ + This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." item = /obj/item/codespeak_manual/unlimited cost = 3 @@ -1141,12 +1192,31 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/stealthy_tools/emplight name = "EMP Flashlight" - desc = "A small, self-charging, short-ranged EMP device disguised as a flashlight. \ - Useful for disrupting headsets, cameras, and borgs during stealth operations." + desc = "A small, self-recharging, short-ranged EMP device disguised as a working flashlight. \ + Useful for disrupting headsets, cameras, doors, lockers and borgs during stealth operations. \ + Attacking a target with this flashlight will direct an EM pulse at it and consumes a charge." item = /obj/item/flashlight/emp cost = 2 surplus = 30 +/datum/uplink_item/stealthy_tools/failsafe + name = "Failsafe Uplink Code" + desc = "When entered the uplink will self-destruct immidiately." + item = /obj/effect/gibspawner/generic + cost = 1 + surplus = 0 + restricted = TRUE + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/failsafe/spawn_item(spawn_path, mob/user, datum/component/uplink/U) + if(!U) + return + U.failsafe_code = U.generate_code() + to_chat(user, "The new failsafe code for this uplink is now : [U.failsafe_code].") + if(user.mind) + user.mind.store_memory("Failsafe code for [U.parent] : [U.failsafe_code]") + return U.parent //For log icon + /datum/uplink_item/stealthy_tools/mulligan name = "Mulligan" desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ @@ -1173,7 +1243,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/stealthy_tools/jammer name = "Radio Jammer" - desc = "This device will disrupt any nearby outgoing radio communication when activated." + desc = "This device will disrupt any nearby outgoing radio communication when activated. Does not affect binary chat." item = /obj/item/jammer cost = 5 @@ -1199,12 +1269,47 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes //Space Suits and Hardsuits /datum/uplink_item/suits - category = "Space Suits and Hardsuits" + category = "Space Suits, Hardsuits and Clothing" surplus = 40 +/datum/uplink_item/suits/turtlenck + name = "Tactical Turtleneck" + desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." + item = /obj/item/clothing/under/syndicate + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + +/datum/uplink_item/suits/turtlenck_skirt + name = "Tactical Skirtleneck" + desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." + item = /obj/item/clothing/under/syndicate/skirt + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + +/datum/uplink_item/suits/padding + name = "Soft Padding" + desc = "Padding to add to a jumpsuit to help against melee and bullets." + item = /obj/item/clothing/accessory/padding + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/suits/kevlar + name = "Kevlar sheets" + desc = "Kevlar sheets to add to jumpsuit to help against bullets and melee." + item = /obj/item/clothing/accessory/kevlar + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/suits/plastic + name = "Plastic sheet" + desc = "Plastic body sheet to add to a jumpsuit to help against laser and energy harm." + item = /obj/item/clothing/accessory/plastics + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/suits/space_suit name = "Syndicate Space Suit" - desc = "This red and black syndicate space suit is less encumbering than Nanotrasen variants, \ + desc = "This red and black Syndicate space suit is less encumbering than Nanotrasen variants, \ fits inside bags, and has a weapon slot. Nanotrasen crew members are trained to report red space suit \ sightings, however." item = /obj/item/storage/box/syndie_kit/space @@ -1212,7 +1317,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/suits/hardsuit name = "Syndicate Hardsuit" - desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ + desc = "The feared suit of a Syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ that runs off standard atmospheric tanks. Toggling the suit in and out of \ combat mode will allow you all the mobility of a loose fitting uniform without sacrificing armoring. \ Additionally the suit is collapsible, making it small enough to fit within a backpack. \ @@ -1223,8 +1328,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/suits/hardsuit/elite name = "Elite Syndicate Hardsuit" - desc = "An upgraded, elite version of the syndicate hardsuit. It features fireproofing, and also \ - provides the user with superior armor and mobility compared to the standard syndicate hardsuit." + desc = "An upgraded, elite version of the Syndicate hardsuit. It features fireproofing, and also \ + provides the user with superior armor and mobility compared to the standard Syndicate hardsuit." item = /obj/item/clothing/suit/space/hardsuit/syndi/elite cost = 8 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -1232,7 +1337,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/suits/hardsuit/shielded name = "Shielded Syndicate Hardsuit" - desc = "An upgraded version of the standard syndicate hardsuit. It features a built-in energy shielding system. \ + desc = "An upgraded version of the standard Syndicate hardsuit. It features a built-in energy shielding system. \ The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire." item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi cost = 30 @@ -1243,17 +1348,30 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools category = "Devices and Tools" +/datum/uplink_item/device_tools/emag + name = "Cryptographic Sequencer" + desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ + in electronic devices, subverts intended functions, and easily breaks security mechanisms." + item = /obj/item/card/emag + cost = 6 + +/datum/uplink_item/device_tools/emagrecharge + name = "Electromagnet Charging Device" + desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." + item = /obj/item/emagrecharge + cost = 2 + /datum/uplink_item/device_tools/cutouts name = "Adaptive Cardboard Cutouts" - desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. This pack contains three as well as a \ - crayon for changing their appearances." + desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \ + This pack contains three as well as a crayon for changing their appearances." item = /obj/item/storage/box/syndie_kit/cutouts cost = 1 surplus = 20 /datum/uplink_item/device_tools/assault_pod name = "Assault Pod Targeting Device" - desc = "Use to select the landing zone of your assault pod." + desc = "Use this to select the landing zone of your assault pod." item = /obj/item/assault_pod cost = 30 surplus = 0 @@ -1298,8 +1416,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/camera_bug name = "Camera Bug" - desc = "Enables you to view all cameras on the network and track a target. Bugging cameras allows you \ - to disable them remotely." + desc = "Enables you to view all cameras on the main network, set up motion alerts and track a target. \ + Bugging cameras allows you to disable them remotely." item = /obj/item/camera_bug cost = 1 surplus = 90 @@ -1311,22 +1429,10 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes cost = 1 exclude_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/device_tools/emag - name = "Cryptographic Sequencer" - desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ - in electronic devices, subverts intended functions, and easily breaks security mechanisms." - item = /obj/item/card/emag - cost = 6 - -/datum/uplink_item/device_tools/emagrecharge - name = "Electromagnet Charging Device" - desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." - item = /obj/item/emagrecharge - cost = 2 - /datum/uplink_item/device_tools/fakenucleardisk name = "Decoy Nuclear Authentication Disk" - desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. Don't try to give this to us to complete your objective, we know better!" + desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. \ + Don't try to give this to us to complete your objective, we know better!" item = /obj/item/disk/nuclear/fake cost = 1 surplus = 1 @@ -1334,7 +1440,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/frame name = "F.R.A.M.E. PDA Cartridge" desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ - when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ + when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ telecrystals normally." item = /obj/item/cartridge/virus/frame @@ -1343,7 +1449,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/toolbox name = "Full Syndicate Toolbox" - desc = "The syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ + desc = "The Syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ multitool and combat gloves that are resistant to shocks and heat." item = /obj/item/storage/toolbox/syndicate cost = 1 @@ -1353,6 +1459,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes desc = "A cheap bottle of one use syndicate brand super glue. \ Use on any item to make it undroppable. \ Be careful not to glue an item you're already holding!" + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) item = /obj/item/syndie_glue cost = 2 @@ -1366,7 +1473,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/medgun name = "Medbeam Gun" desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ - operatives in the fight, even while under fire." + operatives in the fight, even while under fire. Don't cross the streams!" item = /obj/item/gun/medbeam cost = 15 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -1388,9 +1495,9 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/powersink name = "Power Sink" - desc = "When screwed to wiring attached to a power grid and activated, this large device places excessive \ + desc = "When screwed to wiring attached to a power grid and activated, this large device lights up and places excessive \ load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ - traditional bags and boxes." + traditional bags and boxes. Caution: Will explode if the powernet contains sufficient amounts of energy." item = /obj/item/powersink cost = 6 @@ -1399,7 +1506,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ of humanoids. It has two settings: intensity, which controls the power of the radiation, \ - and wavelength, which controls how long the radiation delay is." + and wavelength, which controls the delay before the effect kicks in." item = /obj/item/healthanalyzer/rad_laser cost = 3 @@ -1414,7 +1521,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/medkit name = "Syndicate Combat Medic Kit" desc = "This first aid kit is a suspicious brown and red. Included is a combat stimulant injector \ - for rapid healing, a medical HUD for quick identification of injured personnel, \ + for rapid healing, a medical night vision HUD for quick identification of injured personnel, \ and other supplies helpful for a field medic." item = /obj/item/storage/firstaid/tactical cost = 4 @@ -1429,7 +1536,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/surgerybag_adv name = "Advanced Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all newest surgery tools, surgical drapes, \ + desc = "The Syndicate surgery duffel bag is a toolkit containing all advanced surgery tools, surgical drapes, \ a Syndicate brand MMI, a straitjacket, a muzzle, and a full Syndicate Combat Medic Kit." item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv cost = 10 @@ -1445,7 +1552,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/syndietome name = "Syndicate Tome" - desc = "Using rare artifacts acquired at great cost, the syndicate has reverse engineered \ + desc = "Using rare artifacts acquired at great cost, the Syndicate has reverse engineered \ the seemingly magical books of a certain cult. Though lacking the esoteric abilities \ of the originals, these inferior copies are still quite useful, being able to provide \ both weal and woe on the battlefield, even if they do occasionally bite off a finger." @@ -1464,7 +1571,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/potion name = "Syndicate Sentience Potion" item = /obj/item/slimepotion/slime/sentience/nuclear - desc = "A potion recovered at great risk by undercover syndicate operatives and then subsequently modified with syndicate technology. Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." + desc = "A potion recovered at great risk by undercover Syndicate operatives and then subsequently modified with Syndicate technology. \ + Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." cost = 2 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE @@ -1478,7 +1586,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/implants/adrenal name = "Adrenal Implant" desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ - cocktail which has a mild healing effect along with removing all stuns and increasing movement speed." + cocktail which removes all incapacitating effects, lets the user run faster and has a mild healing effect." item = /obj/item/storage/box/syndie_kit/imp_adrenal cost = 8 player_minimum = 25 @@ -1517,28 +1625,30 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/implants/radio name = "Internal Syndicate Radio Implant" - desc = "An implant injected into the body, allowing the use of an internal syndicate radio. Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." + desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \ + Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." item = /obj/item/storage/box/syndie_kit/imp_radio cost = 4 restricted = TRUE /datum/uplink_item/implants/reviver name = "Reviver Implant" - desc = "This implant will attempt to revive you if you lose consciousness. Comes with an autosurgeon." + desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." item = /obj/item/autosurgeon/reviver cost = 8 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/implants/stealthimplant name = "Stealth Implant" - desc = "This one-of-a-kind implant will make you almost invisible if you play your cards right." + desc = "This one-of-a-kind implant will make you almost invisible as long as you don't don't excessively move around. \ + On activation, it will conceal you inside a chameleon cardboard box that is only revealed once someone bumps into it." item = /obj/item/implanter/stealth cost = 8 /datum/uplink_item/implants/storage name = "Storage Implant" desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ - pocket capable of storing two items." + pocket capable of storing two regular-sized items." item = /obj/item/storage/box/syndie_kit/imp_storage cost = 8 @@ -1551,7 +1661,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/implants/uplink name = "Uplink Implant" - desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals, must be charged by the use of physical telecrystals. Undetectable (except via surgery), and excellent for escaping confinement." + desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals and must be charged by the use of physical telecrystals. \ + Undetectable (except via surgery), and excellent for escaping confinement." item = /obj/item/storage/box/syndie_kit/imp_uplink cost = 4 // An empty uplink is kinda useless. @@ -1610,7 +1721,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." + be defused, and some crew may attempt to do so. \ + The bomb core can be pried out and manually detonated with other explosives." item = /obj/item/sbeacondrop/clownbomb cost = 15 restricted_roles = list("Clown") @@ -1638,7 +1750,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/haunted_magic_eightball name = "Haunted Magic Eightball" - desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." + desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. \ + Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." item = /obj/item/toy/eightball/haunted cost = 2 restricted_roles = list("Curator") @@ -1657,14 +1770,16 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/explosive_hot_potato name = "Exploding Hot Potato" - desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." + desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. \ + The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." item = /obj/item/hot_potato/syndicate cost = 4 restricted_roles = list("Cook", "Botanist", "Clown", "Mime") /datum/uplink_item/role_restricted/ez_clean_bundle name = "EZ Clean Grenade Bundle" - desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. The acid only affects carbon-based creatures." + desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. \ + The acid only affects carbon-based creatures." item = /obj/item/storage/box/syndie_kit/ez_clean cost = 6 surplus = 20 @@ -1679,7 +1794,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/mimery name = "Guide to Advanced Mimery Series" - desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. Obviously only works for Mimes." + desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. \ + Obviously only works for Mimes." cost = 12 item = /obj/item/storage/box/syndie_kit/mimery restricted_roles = list("Mime") @@ -1694,7 +1810,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/pressure_mod name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity." + desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. \ + Occupies 35% mod capacity." item = /obj/item/borg/upgrade/modkit/indoors cost = 5 //you need two for full damage, so total of 10 for maximum damage limited_stock = 2 //you can't use more than two! @@ -1702,7 +1819,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/kitchen_gun name = "Kitchen Gun (TM)" - desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" + desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \ + Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" cost = 10 surplus = 40 restricted_roles = list("Cook", "Janitor") @@ -1717,9 +1835,10 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/role_restricted/magillitis_serum name = "Magillitis Serum Autoinjector" - desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." + desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. \ + Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." item = /obj/item/reagent_containers/hypospray/magillitis - cost = 15 + cost = 8 restricted_roles = list("Geneticist", "Chief Medical Officer") /datum/uplink_item/role_restricted/modified_syringe_gun @@ -1760,6 +1879,13 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes item = /obj/item/clothing/shoes/clown_shoes/taeclowndo restricted_roles = list("Clown") +/datum/uplink_item/role_restricted/emitter_cannon + name = "Emitter Cannon" + desc = "A small emitter fitted into a gun case, do to size constraints and safety it can only shoot about ten times when fully charged." + cost = 5 //Low ammo, and deals same as 10mm but emp-able + item = /obj/item/gun/energy/emitter + restricted_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") + // Pointless /datum/uplink_item/badass category = "(Pointless) Badassery" @@ -1767,7 +1893,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/badass/costumes/obvious_chameleon name = "Broken Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! Please note that this kit did NOT pass quality control." + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Please note that this kit did NOT pass quality control." item = /obj/item/storage/box/syndie_kit/chameleon/broken /datum/uplink_item/badass/costumes @@ -1777,7 +1904,8 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/badass/costumes/centcom_official name = "CentCom Official Costume" - desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. Radio headset does not include key. No gun included." + desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. \ + Radio headset does not include encryption key. No gun included." item = /obj/item/storage/box/syndie_kit/centcom_costume /datum/uplink_item/badass/costumes/clown diff --git a/code/modules/vehicles/cars/clowncar.dm b/code/modules/vehicles/cars/clowncar.dm index 63ef4fda5a..e504ea84f2 100644 --- a/code/modules/vehicles/cars/clowncar.dm +++ b/code/modules/vehicles/cars/clowncar.dm @@ -63,11 +63,13 @@ DumpMobs(TRUE) /obj/vehicle/sealed/car/clowncar/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "You scramble the clowncar child safety lock and a panel with 6 colorful buttons appears!") initialize_controller_action_type(/datum/action/vehicle/sealed/RollTheDice, VEHICLE_CONTROL_DRIVE) + return TRUE /obj/vehicle/sealed/car/clowncar/Destroy() playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index a5ba06e6fb..137242c547 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -45,7 +45,7 @@ var/datum/component/riding/D = GetComponent(/datum/component/riding) //1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have //if that made no sense this simply makes the wheelchair speed change along with movement speed delay - D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / min(user.get_num_arms(), 2) + D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag) return ..() /obj/vehicle/ridden/wheelchair/Moved() diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 410952397d..5165343993 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -65,7 +65,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/scan_id = 1 var/obj/item/coin/coin var/obj/item/stack/spacecash/bill - + var/global/vending_cache = list() //used for storing the icons of items being vended var/dish_quants = list() //used by the snack machine's custom compartment to count dishes. @@ -306,10 +306,12 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C . = ..() /obj/machinery/vending/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED to_chat(user, "You short out the product lock on [src].") + return TRUE /obj/machinery/vending/_try_interact(mob/user) if(seconds_electrified && !(stat & NOPOWER)) diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 5cfa454bd9..a265a4e907 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -63,6 +63,8 @@ /obj/item/clothing/suit/wizrobe/fake = 1, /obj/item/clothing/head/wizard/fake = 1, /obj/item/staff = 3, + /obj/item/clothing/under/rank/mime/skirt = 1, + /obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 1, /obj/item/clothing/mask/gas/sexyclown = 1, /obj/item/clothing/under/rank/clown/sexy = 1, /obj/item/clothing/mask/gas/sexymime = 1, diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index c31c9a12a2..1497992fe8 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -31,6 +31,9 @@ /obj/item/clothing/under/pants/tan = 4, /obj/item/clothing/under/pants/track = 3, /obj/item/clothing/suit/jacket/miljacket = 5, + /obj/item/clothing/under/scratch/skirt = 2, + /obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 2, + /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit/skirt = 2, /obj/item/clothing/neck/tie/blue = 3, /obj/item/clothing/neck/tie/red = 3, /obj/item/clothing/neck/tie/black = 3, @@ -98,6 +101,7 @@ /obj/item/clothing/suit/apron/purple_bartender = 4, /obj/item/clothing/under/rank/bartender/purple = 4) contraband = list(/obj/item/clothing/under/syndicate/tacticool = 3, + /obj/item/clothing/under/syndicate/tacticool/skirt = 3, /obj/item/clothing/mask/balaclava = 3, /obj/item/clothing/head/ushanka = 3, /obj/item/clothing/under/soviet = 3, diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 523606aa6a..44dca6b257 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -28,7 +28,9 @@ contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6) - premium = list(/obj/item/storage/box/hug/medical = 1, + premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2, + /obj/item/storage/box/hug/medical = 1, + /obj/item/storage/pill_bottle/psicodine = 2, /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1, diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 4594048256..d230f40af0 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -15,6 +15,7 @@ /obj/item/seeds/chili = 3, /obj/item/seeds/cocoapod = 3, /obj/item/seeds/coffee = 3, + /obj/item/seeds/cotton = 3, /obj/item/seeds/corn = 3, /obj/item/seeds/eggplant = 3, /obj/item/seeds/grape = 3, @@ -23,6 +24,7 @@ /obj/item/seeds/lime = 3, /obj/item/seeds/onion = 3, /obj/item/seeds/orange = 3, + /obj/item/seeds/peach = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/pineapple = 3, /obj/item/seeds/potato = 3, @@ -31,7 +33,9 @@ /obj/item/seeds/replicapod = 3, /obj/item/seeds/wheat/rice = 3, /obj/item/seeds/soya = 3, + /obj/item/seeds/sugarcane = 3, /obj/item/seeds/sunflower = 3, + /obj/item/seeds/strawberry = 3, /obj/item/seeds/tea = 3, /obj/item/seeds/tobacco = 3, /obj/item/seeds/tomato = 3, diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 7e90a5ce18..b3b21fe375 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -12,10 +12,16 @@ /obj/item/reagent_containers/food/snacks/donut = 12, /obj/item/storage/box/evidence = 6, /obj/item/flashlight/seclite = 4, - /obj/item/restraints/legcuffs/bola/energy = 7) + /obj/item/restraints/legcuffs/bola/energy = 7, + /obj/item/secbat = 5) contraband = list(/obj/item/clothing/glasses/sunglasses = 2, - /obj/item/storage/fancy/donut_box = 2) - premium = list(/obj/item/coin/antagtoken = 1) + /obj/item/storage/fancy/donut_box = 2, + /obj/item/ssword_kit = 1) + premium = list(/obj/item/coin/antagtoken = 1, + /obj/item/clothing/head/helmet/blueshirt = 1, + /obj/item/clothing/suit/armor/vest/blueshirt = 1, + /obj/item/clothing/under/rank/security/blueshirt = 1, + /obj/item/ssword_kit = 1) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 9481d4d086..015890419d 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -40,6 +40,7 @@ /obj/item/clothing/suit/hooded/wintercoat/medical = 3, /obj/item/clothing/under/rank/nursesuit = 3, /obj/item/clothing/head/nursehat = 3, + /obj/item/clothing/under/rank/medical/skirt= 5, /obj/item/clothing/under/rank/medical/blue = 2, /obj/item/clothing/under/rank/medical/green = 2, /obj/item/clothing/under/rank/medical/purple = 2, @@ -67,6 +68,7 @@ /obj/item/storage/backpack/satchel/eng = 3, /obj/item/clothing/suit/hooded/wintercoat/engineering = 3, /obj/item/clothing/under/rank/engineer = 5, + /obj/item/clothing/under/rank/engineer/skirt = 5, /obj/item/clothing/suit/hazardvest = 5, /obj/item/clothing/shoes/workboots = 5, /obj/item/clothing/head/hardhat = 5) @@ -87,6 +89,7 @@ /obj/item/storage/backpack/industrial = 3, /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 5, /obj/item/clothing/under/rank/atmospheric_technician = 5, + /obj/item/clothing/under/rank/atmospheric_technician/skirt = 5, /obj/item/clothing/shoes/sneakers/black = 5) refill_canister = /obj/item/vending_refill/wardrobe/atmos_wardrobe @@ -101,6 +104,7 @@ vend_reply = "Thank you for using the CargoDrobe!" products = list(/obj/item/clothing/suit/hooded/wintercoat/cargo = 3, /obj/item/clothing/under/rank/cargotech = 5, + /obj/item/clothing/under/rank/cargotech/skirt = 5, /obj/item/clothing/shoes/sneakers/black = 5, /obj/item/clothing/gloves/fingerless = 5, /obj/item/clothing/head/soft = 5, @@ -118,12 +122,14 @@ vend_reply = "Thank you for using the RoboDrobe!" products = list(/obj/item/clothing/glasses/hud/diagnostic = 3, /obj/item/clothing/under/rank/roboticist = 3, + /obj/item/clothing/under/rank/roboticist/skirt = 3, /obj/item/clothing/suit/toggle/labcoat = 3, /obj/item/clothing/shoes/sneakers/black = 3, /obj/item/clothing/gloves/fingerless = 3, /obj/item/clothing/head/soft/black = 3, /obj/item/clothing/mask/bandana/skull = 2) premium = list(/obj/item/radio/headset/headset_rob = 2) //Cit change + contraband = list(/obj/item/clothing/suit/hooded/techpriest = 2) refill_canister = /obj/item/vending_refill/wardrobe/robo_wardrobe /obj/item/vending_refill/wardrobe/robo_wardrobe @@ -140,6 +146,7 @@ /obj/item/storage/backpack/satchel/tox = 3, /obj/item/clothing/suit/hooded/wintercoat/science = 3, /obj/item/clothing/under/rank/scientist = 4, + /obj/item/clothing/under/rank/scientist/skirt = 4, /obj/item/clothing/suit/toggle/labcoat/science = 4, /obj/item/clothing/shoes/sneakers/white = 4, /obj/item/radio/headset/headset_sci = 4, @@ -161,6 +168,7 @@ /obj/item/clothing/suit/apron = 3, /obj/item/clothing/suit/apron/overalls = 5, /obj/item/clothing/under/rank/hydroponics = 5, + /obj/item/clothing/under/rank/hydroponics/skirt = 5, /obj/item/clothing/mask/bandana = 4) refill_canister = /obj/item/vending_refill/wardrobe/hydro_wardrobe @@ -175,6 +183,9 @@ vend_reply = "Thank you for using the CuraDrobe!" products = list(/obj/item/clothing/head/fedora/curator = 2, /obj/item/clothing/suit/curator = 2, + /obj/item/clothing/under/rank/curator/skirt = 2, + /obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 2, + /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit/skirt = 2, /obj/item/clothing/under/rank/curator/treasure_hunter = 2, /obj/item/clothing/shoes/workboots/mining = 2, /obj/item/storage/backpack/satchel/explorer = 2, @@ -194,12 +205,13 @@ /obj/item/radio/headset/headset_srv = 3, /obj/item/clothing/under/sl_suit = 3, /obj/item/clothing/under/rank/bartender = 3, + /obj/item/clothing/under/rank/bartender/skirt = 2, /obj/item/clothing/under/rank/bartender/purple = 2, /obj/item/clothing/accessory/waistcoat = 3, /obj/item/clothing/suit/apron/purple_bartender = 2, /obj/item/clothing/head/soft/black = 4, /obj/item/clothing/shoes/sneakers/black = 4, - /obj/item/reagent_containers/glass/rag = 4, + /obj/item/reagent_containers/rag = 4, /obj/item/storage/box/beanbag = 1, /obj/item/clothing/suit/armor/vest/alt = 1, /obj/item/circuitboard/machine/dish_drive = 1, @@ -226,8 +238,10 @@ /obj/item/circuitboard/machine/dish_drive = 1, /obj/item/clothing/suit/toggle/chef = 2, /obj/item/clothing/under/rank/chef = 2, + /obj/item/clothing/under/rank/chef/skirt = 2, /obj/item/clothing/head/chefhat = 2, - /obj/item/reagent_containers/glass/rag = 3) + /obj/item/reagent_containers/rag = 3, + /obj/item/book/granter/crafting_recipe/cooking_sweets_101 = 2) refill_canister = /obj/item/vending_refill/wardrobe/chef_wardrobe /obj/item/vending_refill/wardrobe/chef_wardrobe @@ -240,6 +254,7 @@ product_ads = "Come and get your janitorial clothing, now endorsed by lizard janitors everywhere!" vend_reply = "Thank you for using the JaniDrobe!" products = list(/obj/item/clothing/under/rank/janitor = 2, + /obj/item/clothing/under/rank/janitor/skirt = 2, /obj/item/cartridge/janitor = 3, /obj/item/clothing/gloves/color/black = 2, /obj/item/clothing/head/soft/purple = 2, @@ -265,10 +280,19 @@ icon_state = "lawdrobe" product_ads = "OBJECTION! Get the rule of law for yourself!" vend_reply = "Thank you for using the LawDrobe!" - products = list(/obj/item/clothing/under/lawyer/female = 3, - /obj/item/clothing/under/lawyer/black = 3, + products = list(/obj/item/clothing/under/lawyer/bluesuit/skirt = 3, + /obj/item/clothing/under/lawyer/purpsuit/skirt = 3, + /obj/item/clothing/under/lawyer/blacksuit/skirt = 3, + /obj/item/clothing/under/lawyer/female = 3, + /obj/item/clothing/under/lawyer/female/skirt = 3, + /obj/item/clothing/under/lawyer/really_black = 3, + /obj/item/clothing/under/lawyer/really_black/skirt = 3, + /obj/item/clothing/under/lawyer/blue = 3, + /obj/item/clothing/under/lawyer/blue/skirt = 3, /obj/item/clothing/under/lawyer/red = 3, - /obj/item/clothing/under/lawyer/bluesuit = 3, + /obj/item/clothing/under/lawyer/red/skirt = 3, + /obj/item/clothing/under/lawyer/black = 3, + /obj/item/clothing/under/lawyer/black/skirt = 3, /obj/item/clothing/suit/toggle/lawyer = 3, /obj/item/clothing/under/lawyer/purpsuit = 3, /obj/item/clothing/suit/toggle/lawyer/purple = 3, @@ -291,10 +315,14 @@ /obj/item/storage/backpack/cultpack = 2, /obj/item/clothing/accessory/pocketprotector/cosmetology = 2, /obj/item/clothing/under/rank/chaplain = 2, + /obj/item/clothing/under/rank/chaplain/skirt = 2, /obj/item/clothing/shoes/sneakers/black = 2, /obj/item/clothing/suit/nun = 2, /obj/item/clothing/head/nun_hood = 2, /obj/item/clothing/suit/holidaypriest = 2, + /obj/item/clothing/suit/pharaoh = 2, + /obj/item/clothing/head/nemes = 1, + /obj/item/clothing/head/pharaoh = 1, /obj/item/storage/fancy/candle_box = 3) refill_canister = /obj/item/vending_refill/wardrobe/chap_wardrobe @@ -308,11 +336,13 @@ product_ads = "Our clothes are 0.5% more resistant to acid spills! Get yours now!" vend_reply = "Thank you for using the ChemDrobe!" products = list(/obj/item/clothing/under/rank/chemist = 3, + /obj/item/clothing/under/rank/chemist/skirt = 3, /obj/item/clothing/shoes/sneakers/white = 3, /obj/item/clothing/suit/toggle/labcoat/chemist = 3, /obj/item/storage/backpack/chemistry = 3, /obj/item/storage/backpack/satchel/chem = 3, - /obj/item/storage/bag/chemistry = 3) + /obj/item/storage/bag/chemistry = 3, + /obj/item/fermichem/pHbooklet = 3)//pH indicator) refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe /obj/item/vending_refill/wardrobe/chem_wardrobe @@ -325,6 +355,7 @@ product_ads = "Perfect for the mad scientist in you!" vend_reply = "Thank you for using the GeneDrobe!" products = list(/obj/item/clothing/under/rank/geneticist = 3, + /obj/item/clothing/under/rank/geneticist/skirt = 3, /obj/item/clothing/shoes/sneakers/white = 3, /obj/item/clothing/suit/toggle/labcoat/genetics = 3, /obj/item/storage/backpack/genetics = 3, @@ -341,6 +372,7 @@ product_ads = " Viruses getting you down? Then upgrade to sterilized clothing today!" vend_reply = "Thank you for using the ViroDrobe" products = list(/obj/item/clothing/under/rank/virologist = 3, + /obj/item/clothing/under/rank/virologist/skirt = 3, /obj/item/clothing/shoes/sneakers/white = 3, /obj/item/clothing/suit/toggle/labcoat/virologist = 3, /obj/item/clothing/mask/surgical = 3, diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 8b56ccf00d..ae53f29a55 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -4,7 +4,7 @@ humans, butchering all other living things to \ sustain the zombie, smashing open airlock doors and opening \ child-safe caps on bottles." - item_flags = NODROP | ABSTRACT | DROPDEL + item_flags = ABSTRACT | DROPDEL resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF icon = 'icons/effects/blood.dmi' icon_state = "bloodhand_left" @@ -13,8 +13,11 @@ hitsound = 'sound/hallucinations/growl1.ogg' force = 21 // Just enough to break airlocks with melee attacks damtype = "brute" + total_mass = TOTAL_MASS_HAND_REPLACEMENT - var/removing_airlock = FALSE +/obj/item/zombie_hand/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) /obj/item/zombie_hand/equipped(mob/user, slot) . = ..() diff --git a/config/admins.txt b/config/admins.txt index 27a2178e2c..1fdf480dd3 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -1,11 +1,11 @@ -############################################################################################### -# Basically, ckey goes first. Rank goes after the "=" # -# Case is not important for ckey. # -# Case IS important for the rank. # -# All punctuation (spaces etc) EXCEPT '-', '_' and '@' will be stripped from rank names. # -# Ranks can be anything defined in admin_ranks.txt # -# NOTE: if the rank-name cannot be found in admin_ranks.txt, they will not be adminned! ~Carn # -# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. # -############################################################################################### - -yourckeygoeshere = Host +############################################################################################### +# Basically, ckey goes first. Rank goes after the "=" # +# Case is not important for ckey. # +# Case IS important for the rank. # +# All punctuation (spaces etc) EXCEPT '-', '_' and '@' will be stripped from rank names. # +# Ranks can be anything defined in admin_ranks.txt # +# NOTE: if the rank-name cannot be found in admin_ranks.txt, they will not be adminned! ~Carn # +# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. # +############################################################################################### + +yourckeygoeshere = Host \ No newline at end of file diff --git a/config/config.txt b/config/config.txt index 3bc9f873a9..a01f5424da 100644 --- a/config/config.txt +++ b/config/config.txt @@ -4,6 +4,7 @@ $include game_options.txt $include dbconfig.txt $include comms.txt $include antag_rep.txt +$include donator_groupings.txt # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: diff --git a/config/donator_groupings.txt b/config/donator_groupings.txt new file mode 100644 index 0000000000..b26d1efe22 --- /dev/null +++ b/config/donator_groupings.txt @@ -0,0 +1,8 @@ +#this is a bad system but I'm lazy so it piggybacks off config loader system. +#Specify group followed by ckey for each ckey. + +#TIER_1_DONATORS test_ckey + +#TIER_2_DONATORS test_ckey + +#TIER_3_DONATORS test_ckey diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt index cba9a01e73..deafa47969 100644 --- a/config/spaceRuinBlacklist.txt +++ b/config/spaceRuinBlacklist.txt @@ -49,3 +49,4 @@ #_maps/RandomRuins/SpaceRuins/bigape.dmm #_maps/RandomRuins/SpaceRuins/arcade.dmm #_maps/RandomRuins/SpaceRuins/spacehermit.dmm +#_maps/RandomRuins/SpaceRuins/advancedlab.dmm diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css new file mode 100644 index 0000000000..58129ac1cb --- /dev/null +++ b/goon/browserassets/css/browserOutput.css @@ -0,0 +1,876 @@ +/***************************************** +* +* GLOBAL STYLES +* +******************************************/ +html, body { + padding: 0; + margin: 0; + height: 100%; + color: #000000; +} +body { + background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/ + font-family: Verdana, sans-serif; + font-size: 9pt; + line-height: 1.2; + overflow-x: hidden; + overflow-y: scroll; + word-wrap: break-word; +} + +em { + font-style: normal; + font-weight: bold; +} + +img { + margin: 0; + padding: 0; + line-height: 1; + -ms-interpolation-mode: nearest-neighbor; + image-rendering: pixelated; +} +img.icon { + height: 1em; + min-height: 16px; + width: auto; + vertical-align: bottom; +} + + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline-block; + min-width: 0.5em; + font-size: 0.7em; + padding: 0.2em 0.3em; + line-height: 1; + color: white; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: crimson; + border-radius: 10px; +} + +a {color: #0000ff;} +a.visited {color: #ff00ff;} +a:visited {color: #ff00ff;} +a.popt {text-decoration: none;} + +/***************************************** +* +* OUTPUT NOT RELATED TO ACTUAL MESSAGES +* +******************************************/ +#loading { + position: fixed; + width: 300px; + height: 150px; + text-align: center; + left: 50%; + top: 50%; + margin: -75px 0 0 -150px; +} +#loading i {display: block; padding-bottom: 3px;} + +#messages { + font-size: 13px; + padding: 3px; + margin: 0; + word-wrap: break-word; +} +#newMessages { + position: fixed; + display: block; + bottom: 0; + right: 0; + padding: 8px; + background: #ddd; + text-decoration: none; + font-variant: small-caps; + font-size: 1.1em; + font-weight: bold; + color: #333; +} +#newMessages:hover {background: #ccc;} +#newMessages i {vertical-align: middle; padding-left: 3px;} +#ping { + position: fixed; + top: 0; + right: 80px; + width: 45px; + background: #ddd; + height: 30px; + padding: 8px 0 2px 0; +} +#ping i {display: block; text-align: center;} +#ping .ms { + display: block; + text-align: center; + font-size: 8pt; + padding-top: 2px; +} +#userBar { + position: fixed; + top: 0; + right: 0; +} +#userBar .subCell { + background: #ddd; + height: 30px; + padding: 5px 0; + display: block; + color: #333; + text-decoration: none; + line-height: 28px; + border-top: 1px solid #b4b4b4; +} +#userBar .subCell:hover {background: #ccc;} +#userBar .toggle { + width: 40px; + background: #ccc; + border-top: 0; + float: right; + text-align: center; +} +#userBar .sub {clear: both; display: none; width: 160px;} +#userBar .sub.scroll {overflow-y: scroll;} +#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#userBar .sub span { + display: block; + line-height: 30px; + float: left; +} +#userBar .sub i { + display: block; + padding: 0 5px; + font-size: 1.1em; + width: 22px; + text-align: center; + line-height: 30px; + float: right; +} +#userBar .sub input { + position: absolute; + padding: 7px 5px; + width: 121px; + line-height: 30px; + float: left; +} +#userBar .topCell {border-top: 0;} + +/* POPUPS */ +.popup { + position: fixed; + top: 50%; + left: 50%; + background: #ddd; +} +.popup .close { + position: absolute; + background: #aaa; + top: 0; + right: 0; + color: #333; + text-decoration: none; + z-index: 2; + padding: 0 10px; + height: 30px; + line-height: 30px; +} +.popup .close:hover {background: #999;} +.popup .head { + background: #999; + color: #ddd; + padding: 0 10px; + height: 30px; + line-height: 30px; + text-transform: uppercase; + font-size: 0.9em; + font-weight: bold; + border-bottom: 2px solid green; +} +.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} +.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} +.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} +.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} + +.changeFont {padding: 10px;} +.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} +.changeFont a:hover {background: #ccc;} + +.highlightPopup {padding: 10px; text-align: center;} +.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} +.highlightPopup input.highlightColor {background-color: #FFFF00;} +.highlightPopup input.highlightTermSubmit {margin-top: 5px;} + +/* ADMIN CONTEXT MENU */ +.contextMenu { + background-color: #ddd; + position: fixed; + margin: 2px; + width: 150px; +} +.contextMenu a { + display: block; + padding: 2px 5px; + text-decoration: none; + color: #333; +} + +.contextMenu a:hover { + background-color: #ccc; +} + +/* ADMIN FILTER MESSAGES MENU */ +.filterMessages {padding: 5px;} +.filterMessages div {padding: 2px 0;} +.filterMessages input {} +.filterMessages label {} + +.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} + + +/***************************************** +* +* OUTPUT ACTUALLY RELATED TO MESSAGES +* +******************************************/ + +/* MOTD */ +.motd {color: #638500; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} + +/* ADD HERE FOR BOLD */ +.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} + +/* ADD HERE FOR ITALIC */ +.italic, .italics, .emote {font-style: italic;} + +/* OUTPUT COLORS */ +.highlight {background: yellow;} + +h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #000000;} + +em {font-style: normal; font-weight: bold;} + +.ooc { font-weight: bold;} +.adminobserverooc {color: #0099cc; font-weight: bold;} +.adminooc {color: #700038; font-weight: bold;} + +.adminobserver {color: #996600; font-weight: bold;} +.admin {color: #386aff; font-weight: bold;} + +.name { font-weight: bold;} + +.say {} +.deadsay {color: #5c00e6;} +.binarysay {color: #20c20e; background-color: #000000; display: block;} +.binarysay a {color: #00ff00;} +.binarysay a:active, .binarysay a:visited {color: #88ff88;} +.radio {color: #008000;} +.sciradio {color: #993399;} +.comradio {color: #948f02;} +.secradio {color: #a30000;} +.medradio {color: #337296;} +.engradio {color: #fb5613;} +.suppradio {color: #a8732b;} +.servradio {color: #6eaa2c;} +.syndradio {color: #6d3f40;} +.centcomradio {color: #686868;} +.aiprivradio {color: #ff00ff;} +.redteamradio {color: #ff0000;} +.blueteamradio {color: #0000ff;} + +.yell { font-weight: bold;} + +.alert {color: #ff0000;} +h1.alert, h2.alert {color: #000000;} + +.emote { font-style: italic;} +.selecteddna {color: #ffffff; background-color: #001B1B} + +.attack {color: #ff0000;} +.disarm {color: #990000;} +.passive {color: #660000;} + +.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} +.danger {color: #ff0000;} +.warning {color: #ff0000; font-style: italic;} +.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} +.announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} +.greenannounce {color: #00ff00; font-weight: bold;} +.rose {color: #ff5050;} +.info {color: #0000CC;} +.notice {color: #000099;} +.boldnotice {color: #000099; font-weight: bold;} +.adminnotice {color: #0000ff;} +.adminhelp {color: #ff0000; font-weight: bold;} +.unconscious {color: #0000ff; font-weight: bold;} +.suicide {color: #ff5050; font-style: italic;} +.green {color: #03ff39;} +.nicegreen {color: #14a833;} +.shadowling {color: #3b2769;} +.cult {color: #960000;} + +.cultitalic {color: #960000; font-style: italic;} +.cultbold {color: #960000; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} + +.cultlarge {color: #960000; font-weight: bold; font-size: 24px;} +.narsie {color: #960000; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;} +.colossus {color: #7F282A; font-size: 40px;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} +.purple {color: #5e2d79;} +.holoparasite {color: #35333a;} + +.revennotice {color: #1d2953;} +.revenboldnotice {color: #1d2953; font-weight: bold;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;} +.revenminor {color: #823abb} +.revenwarning {color: #760fbb; font-style: italic;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;} +.umbra {color: #5000A0;} +.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} +.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;} + +.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;} + +.brass {color: #BE8700;} +.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} +.large_brass {color: #BE8700; font-size: 24px;} +.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;} +.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;} +.alloy {color: #42474D;} +.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;} +.nezbere {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_small {color: #42474D;} +.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;} +.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} +.sevtug_small {color: #AF0AAF;} +.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;} +.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} +.inathneq_small {color: #1E8CE1;} +.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;} +.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;} +.nzcrentr_small {color: #DAAA18;} +.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;} +.neovgre {color: #6E001A; font-weight: bold; font-style: italic;} +.neovgre_small {color: #6E001A;} + +.newscaster {color: #800000;} +.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} + +.alien {color: #543354;} +.noticealien {color: #00c000;} +.alertalien {color: #00c000; font-weight: bold;} +.changeling {color: #800080; font-style: italic;} + +.spider {color: #4d004d;} + +.interface {color: #330033;} + +.sans {font-family: "Comic Sans MS", cursive, sans-serif;} +.papyrus {font-family: "Papyrus", cursive, sans-serif;} +.robot {font-family: "Courier New", cursive, sans-serif;} + +.command_headset {font-weight: bold; font-size: 24px;} +.small {font-size: 8px;} +.big {font-size: 24px;} +.reallybig {font-size: 32px;} +.extremelybig {font-size: 40px;} +.greentext {color: #00FF00; font-size: 24px;} +.redtext {color: #FF0000; font-size: 24px;} +.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} +.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} +@keyframes velvet { + 0% { color: #400020; } + 40% { color: #FF0000; } + 50% { color: #FF8888; } + 60% { color: #FF0000; } + 100% { color: #400020; } +} + +.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;} +@keyframes hypnocolor { + 0% { color: #202020; } + 25% { color: #4b02ac; } + 50% { color: #9f41f1; } + 75% { color: #541c9c; } + 100% { color: #7adbf3; } +} + +.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} +@keyframes phobia { + 0% { color: #f75a5a; } + 50% { color: #dd0000; } + 100% { color: #f75a5a; } +} + +.icon {height: 1em; width: auto;} + +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 16px;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} +.slime {color: #00CED1;} +.drone {color: #848482;} +.monkey {color: #975032;} +.swarmer {color: #2C75FF;} +.resonate {color: #298F85;} + +.monkeyhive {color: #774704;} +.monkeylead {color: #774704; font-size: 2;} + +.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} +.connectionClosed.restored {background: green;} +.internal.boldnshit {color: blue; font-weight: bold;} + +/* HELPER CLASSES */ +.text-normal {font-weight: normal; font-style: normal;} +.hidden {display: none; visibility: hidden;}/***************************************** +* +* GLOBAL STYLES +* +******************************************/ +html, body { + padding: 0; + margin: 0; + height: 100%; + color: #000000; +} +body { + background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/ + font-family: Verdana, sans-serif; + font-size: 9pt; + line-height: 1.2; + overflow-x: hidden; + overflow-y: scroll; + word-wrap: break-word; +} + +em { + font-style: normal; + font-weight: bold; +} + +img { + margin: 0; + padding: 0; + line-height: 1; + -ms-interpolation-mode: nearest-neighbor; + image-rendering: pixelated; +} +img.icon { + height: 1em; + min-height: 16px; + width: auto; + vertical-align: bottom; +} + + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline-block; + min-width: 0.5em; + font-size: 0.7em; + padding: 0.2em 0.3em; + line-height: 1; + color: white; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: crimson; + border-radius: 10px; +} + +a {color: #0000ff;} +a.visited {color: #ff00ff;} +a:visited {color: #ff00ff;} +a.popt {text-decoration: none;} + +/***************************************** +* +* OUTPUT NOT RELATED TO ACTUAL MESSAGES +* +******************************************/ +#loading { + position: fixed; + width: 300px; + height: 150px; + text-align: center; + left: 50%; + top: 50%; + margin: -75px 0 0 -150px; +} +#loading i {display: block; padding-bottom: 3px;} + +#messages { + font-size: 13px; + padding: 3px; + margin: 0; + word-wrap: break-word; +} +#newMessages { + position: fixed; + display: block; + bottom: 0; + right: 0; + padding: 8px; + background: #ddd; + text-decoration: none; + font-variant: small-caps; + font-size: 1.1em; + font-weight: bold; + color: #333; +} +#newMessages:hover {background: #ccc;} +#newMessages i {vertical-align: middle; padding-left: 3px;} +#ping { + position: fixed; + top: 0; + right: 80px; + width: 45px; + background: #ddd; + height: 30px; + padding: 8px 0 2px 0; +} +#ping i {display: block; text-align: center;} +#ping .ms { + display: block; + text-align: center; + font-size: 8pt; + padding-top: 2px; +} +#userBar { + position: fixed; + top: 0; + right: 0; +} +#userBar .subCell { + background: #ddd; + height: 30px; + padding: 5px 0; + display: block; + color: #333; + text-decoration: none; + line-height: 28px; + border-top: 1px solid #b4b4b4; +} +#userBar .subCell:hover {background: #ccc;} +#userBar .toggle { + width: 40px; + background: #ccc; + border-top: 0; + float: right; + text-align: center; +} +#userBar .sub {clear: both; display: none; width: 160px;} +#userBar .sub.scroll {overflow-y: scroll;} +#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#userBar .sub span { + display: block; + line-height: 30px; + float: left; +} +#userBar .sub i { + display: block; + padding: 0 5px; + font-size: 1.1em; + width: 22px; + text-align: center; + line-height: 30px; + float: right; +} +#userBar .sub input { + position: absolute; + padding: 7px 5px; + width: 121px; + line-height: 30px; + float: left; +} +#userBar .topCell {border-top: 0;} + +/* POPUPS */ +.popup { + position: fixed; + top: 50%; + left: 50%; + background: #ddd; +} +.popup .close { + position: absolute; + background: #aaa; + top: 0; + right: 0; + color: #333; + text-decoration: none; + z-index: 2; + padding: 0 10px; + height: 30px; + line-height: 30px; +} +.popup .close:hover {background: #999;} +.popup .head { + background: #999; + color: #ddd; + padding: 0 10px; + height: 30px; + line-height: 30px; + text-transform: uppercase; + font-size: 0.9em; + font-weight: bold; + border-bottom: 2px solid green; +} +.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} +.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} +.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} +.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} + +.changeFont {padding: 10px;} +.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} +.changeFont a:hover {background: #ccc;} + +.highlightPopup {padding: 10px; text-align: center;} +.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} +.highlightPopup input.highlightColor {background-color: #FFFF00;} +.highlightPopup input.highlightTermSubmit {margin-top: 5px;} + +/* ADMIN CONTEXT MENU */ +.contextMenu { + background-color: #ddd; + position: fixed; + margin: 2px; + width: 150px; +} +.contextMenu a { + display: block; + padding: 2px 5px; + text-decoration: none; + color: #333; +} + +.contextMenu a:hover { + background-color: #ccc; +} + +/* ADMIN FILTER MESSAGES MENU */ +.filterMessages {padding: 5px;} +.filterMessages div {padding: 2px 0;} +.filterMessages input {} +.filterMessages label {} + +.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} + + +/***************************************** +* +* OUTPUT ACTUALLY RELATED TO MESSAGES +* +******************************************/ + +/* MOTD */ +.motd {color: #638500; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} + +/* ADD HERE FOR BOLD */ +.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} + +/* ADD HERE FOR ITALIC */ +.italic, .italics, .emote {font-style: italic;} + +/* OUTPUT COLORS */ +.highlight {background: yellow;} + +h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #000000;} + +em {font-style: normal; font-weight: bold;} + +.ooc { font-weight: bold;} +.adminobserverooc {color: #0099cc; font-weight: bold;} +.adminooc {color: #700038; font-weight: bold;} + +.adminsay {color: #FF4500; font-weight: bold;} +.admin {color: #386aff; font-weight: bold;} + +.name { font-weight: bold;} + +.say {} +.deadsay {color: #5c00e6;} +.binarysay {color: #20c20e; background-color: #000000; display: block;} +.binarysay a {color: #00ff00;} +.binarysay a:active, .binarysay a:visited {color: #88ff88;} +.radio {color: #008000;} +.sciradio {color: #993399;} +.comradio {color: #948f02;} +.secradio {color: #a30000;} +.medradio {color: #337296;} +.engradio {color: #fb5613;} +.suppradio {color: #a8732b;} +.servradio {color: #6eaa2c;} +.syndradio {color: #6d3f40;} +.centcomradio {color: #686868;} +.aiprivradio {color: #ff00ff;} +.redteamradio {color: #ff0000;} +.blueteamradio {color: #0000ff;} + +.yell { font-weight: bold;} + +.alert {color: #ff0000;} +h1.alert, h2.alert {color: #000000;} + +.emote { font-style: italic;} +.selecteddna {color: #ffffff; background-color: #001B1B} + +.attack {color: #ff0000;} +.disarm {color: #990000;} +.passive {color: #660000;} + +.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} +.danger {color: #ff0000;} +.warning {color: #ff0000; font-style: italic;} +.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} +.announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} +.greenannounce {color: #00ff00; font-weight: bold;} +.rose {color: #ff5050;} +.info {color: #0000CC;} +.notice {color: #000099;} +.boldnotice {color: #000099; font-weight: bold;} +.adminnotice {color: #0000ff;} +.adminhelp {color: #ff0000; font-weight: bold;} +.unconscious {color: #0000ff; font-weight: bold;} +.suicide {color: #ff5050; font-style: italic;} +.green {color: #03ff39;} +.nicegreen {color: #14a833;} +.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;} +.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;} +.shadowling {color: #3b2769;} +.cult {color: #960000;} + +.cultitalic {color: #960000; font-style: italic;} +.cultbold {color: #960000; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} + +.cultlarge {color: #960000; font-weight: bold; font-size: 24px;} +.narsie {color: #960000; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;} +.colossus {color: #7F282A; font-size: 40px;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} +.purple {color: #5e2d79;} +.holoparasite {color: #35333a;} + +.revennotice {color: #1d2953;} +.revenboldnotice {color: #1d2953; font-weight: bold;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;} +.revenminor {color: #823abb} +.revenwarning {color: #760fbb; font-style: italic;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;} +.umbra {color: #5000A0;} +.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} +.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;} + +.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;} + +.brass {color: #BE8700;} +.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} +.large_brass {color: #BE8700; font-size: 24px;} +.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;} +.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;} +.alloy {color: #42474D;} +.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;} +.nezbere {color: #42474D; font-weight: bold; font-style: italic;} +.nezbere_small {color: #42474D;} +.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;} +.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} +.sevtug_small {color: #AF0AAF;} +.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;} +.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} +.inathneq_small {color: #1E8CE1;} +.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;} +.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;} +.nzcrentr_small {color: #DAAA18;} +.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;} +.neovgre {color: #6E001A; font-weight: bold; font-style: italic;} +.neovgre_small {color: #6E001A;} + +.newscaster {color: #800000;} +.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} + +.alien {color: #543354;} +.noticealien {color: #00c000;} +.alertalien {color: #00c000; font-weight: bold;} +.changeling {color: #800080; font-style: italic;} + +.spider {color: #4d004d;} + +.interface {color: #330033;} + +.sans {font-family: "Comic Sans MS", cursive, sans-serif;} +.papyrus {font-family: "Papyrus", cursive, sans-serif;} +.robot {font-family: "Courier New", cursive, sans-serif;} + +.command_headset {font-weight: bold; font-size: 24px;} +.small {font-size: 8px;} +.big {font-size: 24px;} +.reallybig {font-size: 32px;} +.extremelybig {font-size: 40px;} +.greentext {color: #00FF00; font-size: 24px;} +.redtext {color: #FF0000; font-size: 24px;} +.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;} +@keyframes hypnocolor { + 0% { color: #202020; } + 25% { color: #4b02ac; } + 50% { color: #9f41f1; } + 75% { color: #541c9c; } + 100% { color: #7adbf3; } +} + +.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} +@keyframes phobia { + 0% { color: #f75a5a; } + 50% { color: #dd0000; } + 100% { color: #f75a5a; } +} +.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} + +.icon {height: 1em; width: auto;} + +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 16px;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} +.slime {color: #00CED1;} +.drone {color: #848482;} +.monkey {color: #975032;} +.swarmer {color: #2C75FF;} +.resonate {color: #298F85;} + +.monkeyhive {color: #774704;} +.monkeylead {color: #774704; font-size: 2;} + +.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} +.connectionClosed.restored {background: green;} +.internal.boldnshit {color: blue; font-weight: bold;} + +/* HELPER CLASSES */ +.text-normal {font-weight: normal; font-style: normal;} +.hidden {display: none; visibility: hidden;} diff --git a/html/browser/roundend.css b/html/browser/roundend.css index 865b42999e..e69635e888 100644 --- a/html/browser/roundend.css +++ b/html/browser/roundend.css @@ -10,6 +10,10 @@ color: #ef2f3c; font-weight: bold; } +.bluetext { + color: #517fff; + font-weight: bold; +} .neutraltext { font-weight: bold; /* If you feel these should have some color feel free to change */ } diff --git a/html/changelogs/AutoChangeLog-pr-7544.yml b/html/changelogs/AutoChangeLog-pr-7544.yml new file mode 100644 index 0000000000..f70a0e0e30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7544.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - balance: "Reduced the default/baseline nanite pool amount from 100 nanites to 25 nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. The safety threshold was reduced from 50 nanites to 12 nanites." diff --git a/html/changelogs/AutoChangeLog-pr-8349.yml b/html/changelogs/AutoChangeLog-pr-8349.yml new file mode 100644 index 0000000000..de4c08624a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8349.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "more bountys" + - rscdel: "Nitryl bounty" diff --git a/html/changelogs/AutoChangeLog-pr-8537.yml b/html/changelogs/AutoChangeLog-pr-8537.yml new file mode 100644 index 0000000000..a537ba1c3a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8537.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes emags wasting charges on un-emaggable & co stuff." diff --git a/html/changelogs/AutoChangeLog-pr-8636.yml b/html/changelogs/AutoChangeLog-pr-8636.yml new file mode 100644 index 0000000000..3b291661b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8636.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "fixed airless place" diff --git a/html/changelogs/AutoChangeLog-pr-8649.yml b/html/changelogs/AutoChangeLog-pr-8649.yml new file mode 100644 index 0000000000..c8f61cc24e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8649.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "The default amount of z-levels reserved specifically for space ruin generation has been increased from 1 to 2" diff --git a/html/changelogs/AutoChangeLog-pr-8660.yml b/html/changelogs/AutoChangeLog-pr-8660.yml new file mode 100644 index 0000000000..710c4489ea --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8660.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - code_imp: "Changes some files to be better" diff --git a/html/changelogs/AutoChangeLog-pr-8673.yml b/html/changelogs/AutoChangeLog-pr-8673.yml new file mode 100644 index 0000000000..6ff2c7135c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8673.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "As all things are not" diff --git a/html/changelogs/AutoChangeLog-pr-8676.yml b/html/changelogs/AutoChangeLog-pr-8676.yml new file mode 100644 index 0000000000..e82a965985 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8676.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "rapier" diff --git a/html/changelogs/AutoChangeLog-pr-8693.yml b/html/changelogs/AutoChangeLog-pr-8693.yml new file mode 100644 index 0000000000..1e5e3fda58 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8693.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Tlaltecuhtli)" +delete-after: True +changes: + - bugfix: "Other people's clothes burning no longer spam you" diff --git a/html/changelogs/AutoChangeLog-pr-8709.yml b/html/changelogs/AutoChangeLog-pr-8709.yml new file mode 100644 index 0000000000..4aa6fd9b1d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8709.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "A bunch of minor issues with xenobiology are no more!" diff --git a/html/changelogs/AutoChangeLog-pr-8724.yml b/html/changelogs/AutoChangeLog-pr-8724.yml new file mode 100644 index 0000000000..5fc86dd9c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8724.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "new nodes" + - balance: "points and node gear" diff --git a/html/changelogs/AutoChangeLog-pr-8725.yml b/html/changelogs/AutoChangeLog-pr-8725.yml new file mode 100644 index 0000000000..d42840ef0a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8725.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "stuff n things" diff --git a/html/changelogs/AutoChangeLog-pr-8734.yml b/html/changelogs/AutoChangeLog-pr-8734.yml new file mode 100644 index 0000000000..4f746c4cd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8734.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by coiax)" +delete-after: True +changes: + - code_imp: "Randomly coloured gloves and randomly coloured glowsticks now have +slightly different typepaths, but otherwise function the same." diff --git a/html/changelogs/AutoChangeLog-pr-8740.yml b/html/changelogs/AutoChangeLog-pr-8740.yml new file mode 100644 index 0000000000..1966f34331 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8740.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by Denton)" +delete-after: True +changes: + - tweak: "Nanotrasen has started shipping more types of bedsheets to its stations." + - rscadd: "Added in Runtime, Pirate and Gondola bedsheets. The second one can also be found in some pirate ships, while the last can be crafted from gondola hides." diff --git a/html/changelogs/AutoChangeLog-pr-8750.yml b/html/changelogs/AutoChangeLog-pr-8750.yml new file mode 100644 index 0000000000..a3ff5e8a91 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8750.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - bugfix: "Fixes brain damage/trauma healing nanites so they actually work while there are only traumas." diff --git a/html/changelogs/AutoChangeLog-pr-8752.yml b/html/changelogs/AutoChangeLog-pr-8752.yml new file mode 100644 index 0000000000..243b9695a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8752.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Added the ability to alter your genitalia as a slimeperson more than addition/removal." + - bugfix: "fixed genitalia removal proc in alter form." diff --git a/html/changelogs/AutoChangeLog-pr-8761.yml b/html/changelogs/AutoChangeLog-pr-8761.yml new file mode 100644 index 0000000000..4ee792c3a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8761.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "melee and block harm" + - bugfix: "sprites*" diff --git a/html/changelogs/AutoChangeLog-pr-8763.yml b/html/changelogs/AutoChangeLog-pr-8763.yml new file mode 100644 index 0000000000..d99b529656 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8763.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "bone satchles" diff --git a/html/changelogs/AutoChangeLog-pr-8765.yml b/html/changelogs/AutoChangeLog-pr-8765.yml new file mode 100644 index 0000000000..2cac0773ad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8765.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Merges the end-of-shift and its shuttle autocall announcements into one." + - bugfix: "Prevents the end-of-shift shuttle from being recalled (even if to no avail)." diff --git a/html/changelogs/AutoChangeLog-pr-8774.yml b/html/changelogs/AutoChangeLog-pr-8774.yml new file mode 100644 index 0000000000..7ba01cc6aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8774.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - bugfix: "Removed the human check for cult conversion of captain/chaplain minds." diff --git a/html/changelogs/AutoChangeLog-pr-8785.yml b/html/changelogs/AutoChangeLog-pr-8785.yml new file mode 100644 index 0000000000..0dd9cb0df4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8785.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Joy, Happiness, Honk" diff --git a/html/changelogs/AutoChangeLog-pr-8795.yml b/html/changelogs/AutoChangeLog-pr-8795.yml new file mode 100644 index 0000000000..7fe2250a0b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8795.yml @@ -0,0 +1,7 @@ +author: "Sishen1542, original by @zxaber" +delete-after: True +changes: + - balance: "Utility mechs no longer automatically get beacons." + - balance: "Tracking beacons no longer delete themselves when EMPing a mech, and instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP damage rather than light." + - balance: "Mechs that take EMP damage lose the use of their weapons and equipment temporarily. Movement and abilities are not effected." + - balance: "Mechs taking EMP damage no longer roll for a random malfunction." diff --git a/html/changelogs/AutoChangeLog-pr-8796.yml b/html/changelogs/AutoChangeLog-pr-8796.yml new file mode 100644 index 0000000000..2ffdee9b37 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8796.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "small mix up in terms" diff --git a/html/changelogs/AutoChangeLog-pr-8800.yml b/html/changelogs/AutoChangeLog-pr-8800.yml new file mode 100644 index 0000000000..7b397ec23e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8800.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by Skoglol" +delete-after: True +changes: + - rscadd: "Heaters/freezers now support ctrl clicking to turn on and alt clicking to min/max target temperature." diff --git a/html/changelogs/AutoChangeLog-pr-8802.yml b/html/changelogs/AutoChangeLog-pr-8802.yml new file mode 100644 index 0000000000..b97119c32d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8802.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja)" +delete-after: True +changes: + - rscadd: "Failsafe codes for uplinks are now available for purchase." + - rscadd: "Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as well as a couple different types of rockets for it. you can also suicide rocket jump with them!" + - spellcheck: "Improved Uplink item descriptions and formatting." diff --git a/html/changelogs/AutoChangeLog-pr-8812.yml b/html/changelogs/AutoChangeLog-pr-8812.yml new file mode 100644 index 0000000000..0de67cfe59 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8812.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by XDTM" +delete-after: True +changes: + - rscadd: "Using the wrong surgery tool during surgery no longer attacks the patient, if on help or disarm intent." diff --git a/html/changelogs/AutoChangeLog-pr-8819.yml b/html/changelogs/AutoChangeLog-pr-8819.yml new file mode 100644 index 0000000000..0b750fccb6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8819.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Added public autolathes to all maps." diff --git a/html/changelogs/AutoChangeLog-pr-8820.yml b/html/changelogs/AutoChangeLog-pr-8820.yml new file mode 100644 index 0000000000..3e83e29cc3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8820.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by variableundefined)" +delete-after: True +changes: + - bugfix: "Cancel button to assault pod destination selector." diff --git a/html/changelogs/AutoChangeLog-pr-8821.yml b/html/changelogs/AutoChangeLog-pr-8821.yml new file mode 100644 index 0000000000..f45caba949 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8821.yml @@ -0,0 +1,7 @@ +author: "Ghommie (original PRs by ShizCalev)" +delete-after: True +changes: + - tweak: "Corgi collars can now be removed!" + - tweak: "Updated the corgi & parrot inventory panels to use the same formatting as other mobs" + - bugfix: "Fixed corgi inventory panels not closing properly." + - bugfix: "Fixed the parrot inventory panel not closing properly if you're not able to interact with it." diff --git a/html/changelogs/AutoChangeLog-pr-8823.yml b/html/changelogs/AutoChangeLog-pr-8823.yml new file mode 100644 index 0000000000..b334bfbd7e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8823.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by tralezab)" +delete-after: True +changes: + - bugfix: "Fixes an issue with spontaneous appendicitis picking incompatible mob biotypes." diff --git a/html/changelogs/AutoChangeLog-pr-8824.yml b/html/changelogs/AutoChangeLog-pr-8824.yml new file mode 100644 index 0000000000..6a12573112 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8824.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Mickyan)" +delete-after: True +changes: + - bugfix: "Fixed being unable to smother people using the damp rag" diff --git a/html/changelogs/AutoChangeLog-pr-8825.yml b/html/changelogs/AutoChangeLog-pr-8825.yml new file mode 100644 index 0000000000..a56be4e2ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8825.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PR by MrDoomBringer, AnturK and YPOQ)" +delete-after: True +changes: + - bugfix: "Explosions will no longer damage wizards in rod form, the supermatter monitoring radio and megafauna GPS." + - bugfix: "Supplypods no longer detonate their contents." + - bugfix: "Fixed silicon items (e.g. cyborg modules) being destroyed by explosion epicenters." diff --git a/html/changelogs/AutoChangeLog-pr-8826.yml b/html/changelogs/AutoChangeLog-pr-8826.yml new file mode 100644 index 0000000000..3f7520b84e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8826.yml @@ -0,0 +1,9 @@ +author: "Ghommie (original PR by Skoglol)" +delete-after: True +changes: + - code_imp: "New helper proc for alt-click turf listing, bypasses any interaction overrides." + - code_imp: "Ghosts and revenants now use the new proc." + - bugfix: "Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close laptops" + - bugfix: "Revenant can now alt-click turf to list contents." + - tweak: "Revenant now slightly less nosy, use shift click to examine." + - tweak: "Alt-clicking the same turf again no longer closes the turf listing tab." diff --git a/html/changelogs/AutoChangeLog-pr-8827.yml b/html/changelogs/AutoChangeLog-pr-8827.yml new file mode 100644 index 0000000000..e1aaadd698 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8827.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ninjanomnom)" +delete-after: True +changes: + - bugfix: "Gaps between sounds in some looping sound effects should no longer happen as much under heavy server lag." diff --git a/html/changelogs/AutoChangeLog-pr-8828.yml b/html/changelogs/AutoChangeLog-pr-8828.yml new file mode 100644 index 0000000000..4278a14ae1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8828.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Skoglol)" +delete-after: True +changes: + - bugfix: "Reduced ventcrawl lag greatly." diff --git a/html/changelogs/AutoChangeLog-pr-8829.yml b/html/changelogs/AutoChangeLog-pr-8829.yml new file mode 100644 index 0000000000..6d0dd108dd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8829.yml @@ -0,0 +1,5 @@ +author: "BurgerLUA" +delete-after: True +changes: + - code_imp: "Added a new framework for reagents. Reagents can now have a bool that determines if it can be detected by handheld medical analyzers. Currently only the changeling sting chemical does this." + - balance: "Made changeling transformation string last between 10-15 minutes. Lowered the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation can be removed via high doses of calomel." diff --git a/html/changelogs/AutoChangeLog-pr-8830.yml b/html/changelogs/AutoChangeLog-pr-8830.yml new file mode 100644 index 0000000000..e4cb94374b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8830.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Kmc2000 and actioninja)" +delete-after: True +changes: + - rscadd: "Added darkmode! You can opt-in to this by clicking the new toggle darkmode button just beside the settings one." + - rscadd: "Byond members will now have a new setting for their Antag OOC color, instead of using their OOC one. (Antag OOC still locked under admin discretion though)" + - rscdel: "Default black'n'white windows style." diff --git a/html/changelogs/AutoChangeLog-pr-8834.yml b/html/changelogs/AutoChangeLog-pr-8834.yml new file mode 100644 index 0000000000..0b7a7b30c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8834.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes the space ninja's energy netting." diff --git a/html/changelogs/AutoChangeLog-pr-8835.yml b/html/changelogs/AutoChangeLog-pr-8835.yml new file mode 100644 index 0000000000..cf646b879b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8835.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - tweak: "consistency in hop and cap berets" diff --git a/html/changelogs/AutoChangeLog-pr-8841.yml b/html/changelogs/AutoChangeLog-pr-8841.yml new file mode 100644 index 0000000000..8bb73dac26 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8841.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adding one pAI to the wizard shuttle and ERT prep room" diff --git a/html/changelogs/AutoChangeLog-pr-8842.yml b/html/changelogs/AutoChangeLog-pr-8842.yml new file mode 100644 index 0000000000..8a8903b7e5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8842.yml @@ -0,0 +1,4 @@ +author: "UristMcAstronaut" +delete-after: True +changes: + - bugfix: "allows a pai to activate its holoform while in a pai connector without getting derped." diff --git a/html/changelogs/AutoChangeLog-pr-8843.yml b/html/changelogs/AutoChangeLog-pr-8843.yml new file mode 100644 index 0000000000..74a3cc07e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8843.yml @@ -0,0 +1,4 @@ +author: "Coolgat3" +delete-after: True +changes: + - imageadd: "added combat boots sprite" diff --git a/html/changelogs/AutoChangeLog-pr-8844.yml b/html/changelogs/AutoChangeLog-pr-8844.yml new file mode 100644 index 0000000000..05f0f2fb22 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8844.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes the rocket launcher being unreloadable." + - balance: "Buffed its accuracy a bit." + - tweak: "Replaced the grenade launcher emagged minesweeper loot with the rocket launcher like it was originally supposed to be." diff --git a/html/changelogs/AutoChangeLog-pr-8845.yml b/html/changelogs/AutoChangeLog-pr-8845.yml new file mode 100644 index 0000000000..4fe0319fad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8845.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "Tweaked the :b: emoji." diff --git a/html/changelogs/AutoChangeLog-pr-8846.yml b/html/changelogs/AutoChangeLog-pr-8846.yml new file mode 100644 index 0000000000..26b1dad6d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8846.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Rubber Toolboxes." diff --git a/html/changelogs/AutoChangeLog-pr-8847.yml b/html/changelogs/AutoChangeLog-pr-8847.yml new file mode 100644 index 0000000000..678b3d433b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8847.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Porting in two bar signs: Cyber Sylph's and Meow Mix." diff --git a/html/changelogs/AutoChangeLog-pr-8852.yml b/html/changelogs/AutoChangeLog-pr-8852.yml new file mode 100644 index 0000000000..4d49f26831 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8852.yml @@ -0,0 +1,4 @@ +author: "Tupinambis" +delete-after: True +changes: + - imagedel: "Removes a moth plush from the game." diff --git a/html/changelogs/AutoChangeLog-pr-8853.yml b/html/changelogs/AutoChangeLog-pr-8853.yml new file mode 100644 index 0000000000..1507e8620d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8853.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Naksu and coiax, loser)" +delete-after: True +changes: + - code_imp: "Cleaned up saycode" + - bugfix: "Taking mutadone while having the communication disorder brain trauma will no longer spam your chat with messages." + - rscadd: "IPCs now come with a subtype of robotic tongue without the omnilingual ability, instead of innately having robotic voice spans." diff --git a/html/changelogs/AutoChangeLog-pr-8854.yml b/html/changelogs/AutoChangeLog-pr-8854.yml new file mode 100644 index 0000000000..fc45d2087e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8854.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixing stamina damage melee weaponry being unusable by pacifists, and still damaging objects and triggering electrified grilles when thrown." diff --git a/html/changelogs/AutoChangeLog-pr-8857.yml b/html/changelogs/AutoChangeLog-pr-8857.yml new file mode 100644 index 0000000000..6e32fff883 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8857.yml @@ -0,0 +1,8 @@ +author: "Ghommie" +delete-after: True +changes: + - refactor: "refactored underwears to allow custom color preferences, instead of manually colored sprites." + - rscdel: "The aforementioned manually colored pieces. Some of your char preferences may have been resetted as result." + - rscadd: "More underwear choices, including: Bowling shirts, long johns, a tank top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the latter three by nemvar from /tg/station)." + - tweak: "random bodies will now have random underwear again." + - bugfix: "Dressers will now properly change undergarment again." diff --git a/html/changelogs/AutoChangeLog-pr-8858.yml b/html/changelogs/AutoChangeLog-pr-8858.yml new file mode 100644 index 0000000000..6fc057f88d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8858.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Made unholy water healtoxinlover" diff --git a/html/changelogs/AutoChangeLog-pr-8860.yml b/html/changelogs/AutoChangeLog-pr-8860.yml new file mode 100644 index 0000000000..95593b1dad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8860.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Zelus Oil, brass flasks" diff --git a/html/changelogs/AutoChangeLog-pr-8870.yml b/html/changelogs/AutoChangeLog-pr-8870.yml new file mode 100644 index 0000000000..08c9860a30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8870.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Toned down many species' female chest sprites to fit the smaller cups." + - bugfix: "Fixed some body parts sprites inconsistencies, such as the W/E female and male chest sprites being the same in some species, and jellypeople's legs being one tile off on W/E" diff --git a/html/changelogs/AutoChangeLog-pr-8872.yml b/html/changelogs/AutoChangeLog-pr-8872.yml new file mode 100644 index 0000000000..a79ec48298 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8872.yml @@ -0,0 +1,5 @@ +author: "deathride58" +delete-after: True +changes: + - balance: "Normal mops now only use 2 stamina to mop a tile, nerfed from their previous value of 5 stamina per tile mopped." + - balance: "Advanced mops now only use 1 stamina to mop turfs, from their former value of 2 stam." diff --git a/html/changelogs/AutoChangeLog-pr-8873.yml b/html/changelogs/AutoChangeLog-pr-8873.yml new file mode 100644 index 0000000000..af166d496a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8873.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by YPOQ)" +delete-after: True +changes: + - bugfix: "Fixes clockwork armor not actually having armor." diff --git a/html/changelogs/AutoChangeLog-pr-8874.yml b/html/changelogs/AutoChangeLog-pr-8874.yml new file mode 100644 index 0000000000..0d7b51a941 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8874.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax)" +delete-after: True +changes: + - rscadd: "You can now select what your pills will look like when making pills from the Chem Master" + - rscadd: "Red pills can make you think." diff --git a/html/changelogs/AutoChangeLog-pr-8877.yml b/html/changelogs/AutoChangeLog-pr-8877.yml new file mode 100644 index 0000000000..205ff8f2c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8877.yml @@ -0,0 +1,4 @@ +author: "BurgerLUA" +delete-after: True +changes: + - bugfix: "Fixed most reagents having a placeholder color." diff --git a/html/changelogs/AutoChangeLog-pr-8880.yml b/html/changelogs/AutoChangeLog-pr-8880.yml new file mode 100644 index 0000000000..e720f00ccb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8880.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "air alarms are green now instead of blue when the atmosphere is ideal" diff --git a/html/changelogs/AutoChangeLog-pr-8881.yml b/html/changelogs/AutoChangeLog-pr-8881.yml new file mode 100644 index 0000000000..3599d4fa23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8881.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixing baklava pies a bit." diff --git a/html/changelogs/AutoChangeLog-pr-8883.yml b/html/changelogs/AutoChangeLog-pr-8883.yml new file mode 100644 index 0000000000..715ce5dbfc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8883.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "Hexacrocin overdose no longer causes climaxes" diff --git a/html/changelogs/AutoChangeLog-pr-8884.yml b/html/changelogs/AutoChangeLog-pr-8884.yml new file mode 100644 index 0000000000..c63618a6d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8884.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by duckay)" +delete-after: True +changes: + - rscadd: "Added better names and descriptions for blueshirt officer gear." + - rscadd: "Added the above gear to the premium selection of the sectech" diff --git a/html/changelogs/AutoChangeLog-pr-8885.yml b/html/changelogs/AutoChangeLog-pr-8885.yml new file mode 100644 index 0000000000..1469ccf460 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8885.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by coiax)" +delete-after: True +changes: + - code_imp: "The Squeak subsystem has been renamed to Minor Mapping." diff --git a/html/changelogs/AutoChangeLog-pr-8887.yml b/html/changelogs/AutoChangeLog-pr-8887.yml new file mode 100644 index 0000000000..45826fe571 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8887.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "NT Newscasters have had repeated reports of gang activity and are now looking into it." + - rscadd: "NT Psykers keep mumbling about last words of someone who died. Somehow they even have a newsletter for this..." + - bugfix: "Gangster greeting messages are a batch message rather than 5 laggy to_chats" diff --git a/html/changelogs/AutoChangeLog-pr-8898.yml b/html/changelogs/AutoChangeLog-pr-8898.yml new file mode 100644 index 0000000000..e836d4225e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8898.yml @@ -0,0 +1,4 @@ +author: "WhiteHusky" +delete-after: True +changes: + - tweak: "Checking yourself shouldn't freeze the client anymore." diff --git a/html/changelogs/AutoChangeLog-pr-8900.yml b/html/changelogs/AutoChangeLog-pr-8900.yml new file mode 100644 index 0000000000..cbb910c3d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8900.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - rscadd: "Abductor Replication Lab ruin and advanced tools" diff --git a/html/changelogs/AutoChangeLog-pr-8906.yml b/html/changelogs/AutoChangeLog-pr-8906.yml new file mode 100644 index 0000000000..c988071f3e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8906.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Sweaters now cover groins too." diff --git a/html/changelogs/AutoChangeLog-pr-8908.yml b/html/changelogs/AutoChangeLog-pr-8908.yml new file mode 100644 index 0000000000..d9cbd5abed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8908.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Improved the zelus flask to be more viable for bottle smashing than the average barman's selection." + - code_imp: "Very slight bottle smashing code clean up, stupid const vars." diff --git a/html/changelogs/AutoChangeLog-pr-8909.yml b/html/changelogs/AutoChangeLog-pr-8909.yml new file mode 100644 index 0000000000..bfb1470f71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8909.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes krav maga gloves, wizard spells knockdowns." diff --git a/html/changelogs/AutoChangeLog-pr-8912.yml b/html/changelogs/AutoChangeLog-pr-8912.yml new file mode 100644 index 0000000000..5d5a7c38fc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8912.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by ShizCalev and bobbahbrown)" +delete-after: True +changes: + - rscadd: "Headsets now dynamically show in their description how to speak on any channels they can use when held or worn." + - code_imp: "Radio channels names and keys now use defines." + - tweak: "The head arrival announcement will now be broadcast to the supply for the quartermaster." diff --git a/html/changelogs/AutoChangeLog-pr-8913.yml b/html/changelogs/AutoChangeLog-pr-8913.yml new file mode 100644 index 0000000000..ccac6aef16 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8913.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Added new chairs" diff --git a/html/changelogs/AutoChangeLog-pr-8915.yml b/html/changelogs/AutoChangeLog-pr-8915.yml new file mode 100644 index 0000000000..5e3e0e77a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8915.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Added in an alert pop up to the cult convertees, on top of the older \"click here to become a blood cultist\" chat message." + - tweak: "The convertee's screen will now flash red to fit in the aforementioned message's fluff." + - spellcheck: "Made said message less verbose." diff --git a/html/changelogs/AutoChangeLog-pr-8917.yml b/html/changelogs/AutoChangeLog-pr-8917.yml new file mode 100644 index 0000000000..2b858cad47 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8917.yml @@ -0,0 +1,4 @@ +author: "Bhijn" +delete-after: True +changes: + - bugfix: "Warp whistles no longer grant permanent invulnerability and invisibility" diff --git a/html/changelogs/AutoChangeLog-pr-8920.yml b/html/changelogs/AutoChangeLog-pr-8920.yml new file mode 100644 index 0000000000..6d3ae3ada4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8920.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit and belt slots even without uniform, or laid flat on the floor. Sprites from Baystation and Aurora Station." + - rscadd: "You can combat mode right click people while wielding rags and towels to pat out their flames (to no use for rags) or otherwise drying them out." diff --git a/html/changelogs/AutoChangeLog-pr-8921.yml b/html/changelogs/AutoChangeLog-pr-8921.yml new file mode 100644 index 0000000000..9c1c456f7f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8921.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - admin: "Bugtesting zone upgrades for easy bug/game testing" diff --git a/html/changelogs/AutoChangeLog-pr-8922.yml b/html/changelogs/AutoChangeLog-pr-8922.yml new file mode 100644 index 0000000000..1e641bd424 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8922.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Gamemode voting results are displayed at the end-round screen." diff --git a/html/changelogs/AutoChangeLog-pr-8925.yml b/html/changelogs/AutoChangeLog-pr-8925.yml new file mode 100644 index 0000000000..ddc90eba19 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8925.yml @@ -0,0 +1,4 @@ +author: "BurgerLUA" +delete-after: True +changes: + - bugfix: "Fixed autolathe wires not correctly shocking you when pulsed." diff --git a/html/changelogs/AutoChangeLog-pr-8926.yml b/html/changelogs/AutoChangeLog-pr-8926.yml new file mode 100644 index 0000000000..762318ab21 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8926.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - rscadd: "Added the secbat, a box to hold it and the ability to dispense it from the SecTech vendor." diff --git a/html/changelogs/AutoChangeLog-pr-8927.yml b/html/changelogs/AutoChangeLog-pr-8927.yml new file mode 100644 index 0000000000..3a87d7652e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8927.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "toned down the stamina costs of some of the bulkier weapons." + - code_imp: "repathed hypereutactic blades to be a subtype of dual sabers. Way less copypasta." diff --git a/html/changelogs/AutoChangeLog-pr-8929.yml b/html/changelogs/AutoChangeLog-pr-8929.yml new file mode 100644 index 0000000000..4fed45f1d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8929.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixing CX Shredder guns not accepting standard flechette mags." + - bugfix: "Fixing missing magpistol magazines icon states." diff --git a/html/changelogs/AutoChangeLog-pr-8931.yml b/html/changelogs/AutoChangeLog-pr-8931.yml new file mode 100644 index 0000000000..2bde1025db --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8931.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "more cargo to cargo" diff --git a/html/changelogs/AutoChangeLog-pr-8932.yml b/html/changelogs/AutoChangeLog-pr-8932.yml new file mode 100644 index 0000000000..d9038ef1a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8932.yml @@ -0,0 +1,7 @@ +author: "EmeraldSundisk" +delete-after: True +changes: + - rscadd: "Adds a gun range to Box Station" + - rscadd: "Provides some extra power grid connections" + - rscdel: "Sunglasses and Earmuffs removed from the Warden's Office - they can be found at the range instead" + - tweak: "Rearranges a few objects within the prison as to accommodate the new gun range" diff --git a/html/changelogs/AutoChangeLog-pr-8933.yml b/html/changelogs/AutoChangeLog-pr-8933.yml new file mode 100644 index 0000000000..09d318be08 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8933.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Cloning no longer gives you positive mutations, but a chance for a negative one. Cloning has a chance to \"scramble\" your visual DNA." diff --git a/html/changelogs/AutoChangeLog-pr-8934.yml b/html/changelogs/AutoChangeLog-pr-8934.yml new file mode 100644 index 0000000000..e86e47a45f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8934.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "More loadout gear" diff --git a/html/changelogs/AutoChangeLog-pr-8939.yml b/html/changelogs/AutoChangeLog-pr-8939.yml new file mode 100644 index 0000000000..6041d66721 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8939.yml @@ -0,0 +1,9 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "The syndicate base's bathroom is now fitted with a shower, and a special towel." + - bugfix: "Fixed many issues with towels." + - tweak: "The dry people off with rags/towels action can only be done if the object is NOT moist with reagents now. Also cleans banana creaming." + - rscadd: "Towels deal more damage while soaked with reagents." + - rscadd: "You can now squeeze rags/towels with Alt-Click." + - rscdel: "deleted an old and crappier towel sprite that got in the way." diff --git a/html/changelogs/AutoChangeLog-pr-8942.yml b/html/changelogs/AutoChangeLog-pr-8942.yml new file mode 100644 index 0000000000..a1b80ba839 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8942.yml @@ -0,0 +1,4 @@ +author: "Chayse" +delete-after: True +changes: + - tweak: "Changed the Warden's compact combat shotgun to instead be a regular combat shotgun with a foldable stock and penalties for being folded." diff --git a/html/changelogs/AutoChangeLog-pr-8945.yml b/html/changelogs/AutoChangeLog-pr-8945.yml new file mode 100644 index 0000000000..afa9bdaa95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8945.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner." diff --git a/html/changelogs/AutoChangeLog-pr-8949.yml b/html/changelogs/AutoChangeLog-pr-8949.yml new file mode 100644 index 0000000000..83560d74f2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8949.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Poojawa power creep" diff --git a/html/changelogs/AutoChangeLog-pr-8950.yml b/html/changelogs/AutoChangeLog-pr-8950.yml new file mode 100644 index 0000000000..62b90d2407 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8950.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Not my work not my credit" diff --git a/html/changelogs/AutoChangeLog-pr-8952.yml b/html/changelogs/AutoChangeLog-pr-8952.yml new file mode 100644 index 0000000000..df2ff22d09 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8952.yml @@ -0,0 +1,4 @@ +author: "CdrCross" +delete-after: True +changes: + - rscadd: "Adds the ability for cloning consoles to read and write record lists to the circuit board, and provides a template for giving other machines local circuit board memory." diff --git a/html/changelogs/AutoChangeLog-pr-8953.yml b/html/changelogs/AutoChangeLog-pr-8953.yml new file mode 100644 index 0000000000..2128149556 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8953.yml @@ -0,0 +1,5 @@ +author: "Toriate" +delete-after: True +changes: + - rscadd: "RPD now has inhands" + - imageadd: "New sprites for RCDs and RPDs, inhands included" diff --git a/html/changelogs/AutoChangeLog-pr-8956.yml b/html/changelogs/AutoChangeLog-pr-8956.yml new file mode 100644 index 0000000000..d6d33b3bd2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8956.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "Altered the icons for inventory backplates. Sleek! Stylish! New!" diff --git a/html/changelogs/AutoChangeLog-pr-8958.yml b/html/changelogs/AutoChangeLog-pr-8958.yml new file mode 100644 index 0000000000..a800b1b218 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8958.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Emitter gun" diff --git a/html/changelogs/AutoChangeLog-pr-8959.yml b/html/changelogs/AutoChangeLog-pr-8959.yml new file mode 100644 index 0000000000..87ca24462e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8959.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "suit storage nulling anti magic item protection" diff --git a/html/changelogs/AutoChangeLog-pr-8964.yml b/html/changelogs/AutoChangeLog-pr-8964.yml new file mode 100644 index 0000000000..6675fecc50 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8964.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "rebalanced steal goals restrictions" + - spellcheck: "fixed a few misleading goals" diff --git a/html/changelogs/AutoChangeLog-pr-8965.yml b/html/changelogs/AutoChangeLog-pr-8965.yml new file mode 100644 index 0000000000..138991e507 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8965.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "ports a fix" diff --git a/html/changelogs/AutoChangeLog-pr-8966.yml b/html/changelogs/AutoChangeLog-pr-8966.yml new file mode 100644 index 0000000000..2d63b8356e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8966.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - imageadd: "RCL now show what color is currently in use" diff --git a/html/changelogs/AutoChangeLog-pr-8968.yml b/html/changelogs/AutoChangeLog-pr-8968.yml new file mode 100644 index 0000000000..0a0b0e84d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8968.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "oversight in benos" diff --git a/html/changelogs/AutoChangeLog-pr-8970.yml b/html/changelogs/AutoChangeLog-pr-8970.yml new file mode 100644 index 0000000000..304c9115dc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8970.yml @@ -0,0 +1,6 @@ +author: "original by @randolfthemeh and @twaticus, port by sishen1542" +delete-after: True +changes: + - rscadd: "jumpskirts" + - rscadd: "more jumpskirts" + - rscadd: "jumpskirt/suit prefs" diff --git a/html/changelogs/AutoChangeLog-pr-8971.yml b/html/changelogs/AutoChangeLog-pr-8971.yml new file mode 100644 index 0000000000..c5b5215ff9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8971.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - tweak: "slime people now enjoy eating toxic food and it will not disgust them" diff --git a/html/changelogs/AutoChangeLog-pr-8974.yml b/html/changelogs/AutoChangeLog-pr-8974.yml new file mode 100644 index 0000000000..b71dc88ecd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8974.yml @@ -0,0 +1,4 @@ +author: "EgoSumStultus" +delete-after: True +changes: + - bugfix: "Fixed blood chiller's inhand" diff --git a/html/changelogs/AutoChangeLog-pr-8976.yml b/html/changelogs/AutoChangeLog-pr-8976.yml new file mode 100644 index 0000000000..67e7bbc11a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8976.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "combat pushes will now properly stop targets from using firearms, and will disarm the firearm if performed a second time, and also slow down people by 15%, and won't push people on tables blocked by shutters or other dense object anymore." diff --git a/html/changelogs/AutoChangeLog-pr-8978.yml b/html/changelogs/AutoChangeLog-pr-8978.yml new file mode 100644 index 0000000000..56e3760e9c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8978.yml @@ -0,0 +1,4 @@ +author: "Yakumo Chen" +delete-after: True +changes: + - balance: "Made stealth implant boxes flimsier" diff --git a/html/changelogs/AutoChangeLog-pr-8979.yml b/html/changelogs/AutoChangeLog-pr-8979.yml new file mode 100644 index 0000000000..f826fcd681 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8979.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes CHECK_BITFIELD macro." diff --git a/html/changelogs/AutoChangeLog-pr-8980.yml b/html/changelogs/AutoChangeLog-pr-8980.yml new file mode 100644 index 0000000000..caba11ae69 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8980.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes hypovials being unable to transfer out liquids or be refilled by large dispensers like water tanks." + - bugfix: "Fixes chem-masters machineries not dispensing newly made pills inside loaded in pill bottles." diff --git a/html/changelogs/AutoChangeLog-pr-8982.yml b/html/changelogs/AutoChangeLog-pr-8982.yml new file mode 100644 index 0000000000..8599966d64 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8982.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PR by Skoglol)" +delete-after: True +changes: + - bugfix: "Mining bags will no longer drop ore into backpack." + - bugfix: "Mining bags in backpack no longer interferes with other mining bags." + - bugfix: "Fixes some storage size circumventions." diff --git a/html/changelogs/AutoChangeLog-pr-8984.yml b/html/changelogs/AutoChangeLog-pr-8984.yml new file mode 100644 index 0000000000..31c45cdbc6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8984.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Stunswords now fit in the captain's sabre sheat." diff --git a/html/changelogs/AutoChangeLog-pr-8985.yml b/html/changelogs/AutoChangeLog-pr-8985.yml new file mode 100644 index 0000000000..37aaa4162d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8985.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "hos trenchcloak now properly has a sprite on digi characters" diff --git a/html/changelogs/AutoChangeLog-pr-8986.yml b/html/changelogs/AutoChangeLog-pr-8986.yml new file mode 100644 index 0000000000..810631f5f5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8986.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "reworked ninja's stealth mode. Increased invisibility, but engaging in combat, attacking or throwing things, bumping people will temporarily lower it." + - rscadd: "Ninja shoes are even stealthier." + - code_imp: "cleaned up some 2014 tier processing code horror." diff --git a/html/changelogs/AutoChangeLog-pr-8988.yml b/html/changelogs/AutoChangeLog-pr-8988.yml new file mode 100644 index 0000000000..9145d73c01 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8988.yml @@ -0,0 +1,5 @@ +author: "kiwedespars" +delete-after: True +changes: + - rscadd: "regenerative materia to hallucination sting" + - rscadd: "mindbreaker toxin as an actual chemical to hallucination sting" diff --git a/html/changelogs/AutoChangeLog-pr-8991.yml b/html/changelogs/AutoChangeLog-pr-8991.yml new file mode 100644 index 0000000000..138991e507 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8991.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "ports a fix" diff --git a/html/changelogs/AutoChangeLog-pr-8992.yml b/html/changelogs/AutoChangeLog-pr-8992.yml new file mode 100644 index 0000000000..299792fee3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8992.yml @@ -0,0 +1,5 @@ +author: "Chayse" +delete-after: True +changes: + - rscadd: "Assorted space-worthy helmets can now act as masks for internals." + - refactor: "Internals code can now check any item with the ALLOWSINTERNALS flag through the GET_INTERNAL_SLOTS define. For now this only checks head and mask slots, since those are the most realistically speaking usable ones." diff --git a/html/changelogs/AutoChangeLog-pr-8994.yml b/html/changelogs/AutoChangeLog-pr-8994.yml new file mode 100644 index 0000000000..a3a4fef0b7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8994.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "the oxyloss fullscreen overlays now also take in consideration 1/5 of the user stamina loss." diff --git a/html/changelogs/AutoChangeLog-pr-8995.yml b/html/changelogs/AutoChangeLog-pr-8995.yml new file mode 100644 index 0000000000..76669d7821 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8995.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "When you're jogging, you will only slip on water if you have more than 20% staminaloss, for real this time." diff --git a/html/changelogs/AutoChangeLog-pr-8996.yml b/html/changelogs/AutoChangeLog-pr-8996.yml new file mode 100644 index 0000000000..7c631e3301 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8996.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "Different cuffs now come with different worn overlays instead of a generic one." diff --git a/html/changelogs/AutoChangeLog-pr-8998.yml b/html/changelogs/AutoChangeLog-pr-8998.yml new file mode 100644 index 0000000000..981e746fc9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8998.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "High luminosity eyes can now be properly deactivated and won't illuminate your surroundings again until turned back on." diff --git a/html/changelogs/AutoChangeLog-pr-8999.yml b/html/changelogs/AutoChangeLog-pr-8999.yml new file mode 100644 index 0000000000..182e3a8409 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8999.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Chestbursters no longer give and remove your brain. They just disembowel and kill you now." diff --git a/html/changelogs/AutoChangeLog-pr-9000.yml b/html/changelogs/AutoChangeLog-pr-9000.yml new file mode 100644 index 0000000000..3fa3e8946f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9000.yml @@ -0,0 +1,4 @@ +author: "EgoSumStultus" +delete-after: True +changes: + - bugfix: "FIXED SHIELF" diff --git a/html/changelogs/AutoChangeLog-pr-9001.yml b/html/changelogs/AutoChangeLog-pr-9001.yml new file mode 100644 index 0000000000..be2fd2b833 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9001.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - rscdel: "duplicate definition of hos and sec skirts" diff --git a/html/changelogs/AutoChangeLog-pr-9005.yml b/html/changelogs/AutoChangeLog-pr-9005.yml new file mode 100644 index 0000000000..d65017a00d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9005.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "QM rooms not getting Key Aunths" diff --git a/html/changelogs/AutoChangeLog-pr-9008.yml b/html/changelogs/AutoChangeLog-pr-9008.yml new file mode 100644 index 0000000000..0c73bc8ae9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9008.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "Krav Maga leg sweep now works properly." diff --git a/html/changelogs/AutoChangeLog-pr-9009.yml b/html/changelogs/AutoChangeLog-pr-9009.yml new file mode 100644 index 0000000000..21cf0c8d85 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9009.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - bugfix: "Fixes WarOps miscalculating players." diff --git a/html/changelogs/AutoChangeLog-pr-9010.yml b/html/changelogs/AutoChangeLog-pr-9010.yml new file mode 100644 index 0000000000..52aed38e2c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9010.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Activating the nuclear device during war-ops informs the crew of the nuke's position." diff --git a/html/changelogs/AutoChangeLog-pr-9014.yml b/html/changelogs/AutoChangeLog-pr-9014.yml new file mode 100644 index 0000000000..f217b64afd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9014.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes freshly cloned people starting with undershirts. Fixes random characters possibly rolling with undergarments of the opposite gender (Doesn't affect preferences' freedom of choice)." diff --git a/html/changelogs/AutoChangeLog-pr-9018.yml b/html/changelogs/AutoChangeLog-pr-9018.yml new file mode 100644 index 0000000000..7acb63b426 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9018.yml @@ -0,0 +1,12 @@ +author: "Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860)" +delete-after: True +changes: + - rscadd: "Added Quantum Keycards, devices that can link to a quantum pad, and can be used on any other quantum pad to teleport to its linked pad. +spellchecking: Renamed \"Bluespace Teleportation Tech\" tech node to \"Bluespace Travel\"." + - tweak: "Moved roasting sticks from the \"Bluespace Travel\" to \"Practical Bluespace\"." + - rscadd: "Spraying holy water on tiles will now prevent cult-based teleportation from using them as a destination point." + - tweak: "Quantum, wormhole and magic teleportation is no longer disrupted by bags of holding." + - bugfix: "You are now also blocked from teleporting IN to no-teleport areas, not just out of them." + - tweak: "Quantum teleportation now makes pretty rainbow sparks instead of the normal ones." + - bugfix: "Non-bluespace teleportation (spells etc.) no longer makes sparks." + - bugfix: "Fixed teleportation deleting mob spawners like golem shells and ashwalker eggs." diff --git a/html/changelogs/AutoChangeLog-pr-9019.yml b/html/changelogs/AutoChangeLog-pr-9019.yml new file mode 100644 index 0000000000..8006c134e3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9019.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "MRE menu 3 has cuban nachos instead of a chili now." + - bugfix: "Removed the illustration overlay from MREs, looks pretty weird otherwise." + - rscadd: "MRE menu 4, vegetarian." diff --git a/html/changelogs/AutoChangeLog-pr-9021.yml b/html/changelogs/AutoChangeLog-pr-9021.yml new file mode 100644 index 0000000000..e8809f1d7e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9021.yml @@ -0,0 +1,4 @@ +author: "Ghommie (by Floyd / Qustinnus, Arathian)" +delete-after: True +changes: + - rscadd: "The robotocist now has robe to show his love for toasters" diff --git a/html/changelogs/AutoChangeLog-pr-9022.yml b/html/changelogs/AutoChangeLog-pr-9022.yml new file mode 100644 index 0000000000..4fb48506e4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9022.yml @@ -0,0 +1,4 @@ +author: "Ghommie (by nemvar)" +delete-after: True +changes: + - tweak: "Dwarfs are now more robust." diff --git a/html/changelogs/AutoChangeLog-pr-9024.yml b/html/changelogs/AutoChangeLog-pr-9024.yml new file mode 100644 index 0000000000..1d75959c79 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9024.yml @@ -0,0 +1,4 @@ +author: "Ghommie (by Arkatos)" +delete-after: True +changes: + - bugfix: "Fixed an issue with a Lizardwine drink crafting, where a final product would contain unwated 100u of Ethanol." diff --git a/html/changelogs/AutoChangeLog-pr-9026.yml b/html/changelogs/AutoChangeLog-pr-9026.yml new file mode 100644 index 0000000000..bf8ce9efbe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9026.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "The alert level is displayed at the job selection screen." diff --git a/html/changelogs/AutoChangeLog-pr-9030.yml b/html/changelogs/AutoChangeLog-pr-9030.yml new file mode 100644 index 0000000000..94c797433a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9030.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - bugfix: "Attaching a beaker that contains water to an IV stand no longer causes a visual glitch" diff --git a/html/changelogs/AutoChangeLog-pr-9033.yml b/html/changelogs/AutoChangeLog-pr-9033.yml new file mode 100644 index 0000000000..3e69bc9486 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9033.yml @@ -0,0 +1,4 @@ +author: "EgoSumStultus" +delete-after: True +changes: + - bugfix: "fixed magpistol magazine sprites" diff --git a/html/changelogs/AutoChangeLog-pr-9036.yml b/html/changelogs/AutoChangeLog-pr-9036.yml new file mode 100644 index 0000000000..afd2882fc3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9036.yml @@ -0,0 +1,5 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "shoes can have a different icon used for their item and mob icons" + - bugfix: "combat gloves plus having no mob icon" diff --git a/html/changelogs/AutoChangeLog-pr-9040.yml b/html/changelogs/AutoChangeLog-pr-9040.yml new file mode 100644 index 0000000000..33958a2ece --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9040.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "new books/cooking" diff --git a/html/changelogs/AutoChangeLog-pr-9042.yml b/html/changelogs/AutoChangeLog-pr-9042.yml new file mode 100644 index 0000000000..38c4006383 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9042.yml @@ -0,0 +1,4 @@ +author: "EgoSumStultus" +delete-after: True +changes: + - rscadd: "Added the Femur Breaker" diff --git a/html/changelogs/AutoChangeLog-pr-9043.yml b/html/changelogs/AutoChangeLog-pr-9043.yml new file mode 100644 index 0000000000..14c9331e5b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9043.yml @@ -0,0 +1,7 @@ +author: "chef" +delete-after: True +changes: + - rscadd: "Added main hallway approach to monastery" + - rscadd: "Added Maintenance hallway approach, with some maint loot" + - tweak: "moved the docking arm for the white ship" + - tweak: "changed placement of some grills and windows" diff --git a/html/changelogs/AutoChangeLog-pr-9044.yml b/html/changelogs/AutoChangeLog-pr-9044.yml new file mode 100644 index 0000000000..6133ea45e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9044.yml @@ -0,0 +1,7 @@ +author: "Original by Citinited, port by Sishen1542" +delete-after: True +changes: + - rscadd: "You can now use an airlock electronics on a locker to add a lock, and can screwdriver an unlocked locker to remove its lock." + - rscadd: "You can now remove the locks on broken or emagged lockers." + - tweak: "Removing the lock from a personal locker now wipes that locker's ID details." + - tweak: "Broken lockers have had their appearance changed." diff --git a/html/changelogs/AutoChangeLog-pr-9045.yml b/html/changelogs/AutoChangeLog-pr-9045.yml new file mode 100644 index 0000000000..8917707ae3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9045.yml @@ -0,0 +1,8 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "Fluid-producing sexual organs no longer start full" + - tweak: "Sexual organ fluid capacity decreased from 50 to 15" + - tweak: "Sexual organ production rate decreased from 5u to 0.035u per two seconds." + - tweak: "Sexual fluid decals no longer contain reagents" + - tweak: "Sexual fluids cannot by synthesized (e.g., by the Odysseus)" diff --git a/html/changelogs/AutoChangeLog-pr-9046.yml b/html/changelogs/AutoChangeLog-pr-9046.yml new file mode 100644 index 0000000000..24e7035a88 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9046.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "density = 0" diff --git a/html/changelogs/AutoChangeLog-pr-9050.yml b/html/changelogs/AutoChangeLog-pr-9050.yml new file mode 100644 index 0000000000..3b12a12f17 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9050.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "fixes a few bad touchs on combat mode pushing." diff --git a/html/changelogs/AutoChangeLog-pr-9052.yml b/html/changelogs/AutoChangeLog-pr-9052.yml new file mode 100644 index 0000000000..a75b6c51ae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9052.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "Hierophant now goes sicko mode, but hey, at least you can't be multi-hit by melee waves!" diff --git a/html/changelogs/AutoChangeLog-pr-9054.yml b/html/changelogs/AutoChangeLog-pr-9054.yml new file mode 100644 index 0000000000..5952c9ecfd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9054.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "hugboxing mining loot" diff --git a/html/changelogs/AutoChangeLog-pr-9057.yml b/html/changelogs/AutoChangeLog-pr-9057.yml new file mode 100644 index 0000000000..4df1b23ca7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9057.yml @@ -0,0 +1,4 @@ +author: "EgoSumStultus" +delete-after: True +changes: + - rscadd: "Adds male AI vox." diff --git a/html/changelogs/AutoChangeLog-pr-9061.yml b/html/changelogs/AutoChangeLog-pr-9061.yml new file mode 100644 index 0000000000..4fc9d10ba5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9061.yml @@ -0,0 +1,5 @@ +author: "deathride58" +delete-after: True +changes: + - tweak: "The femur breaker now uses `*scream` instead of forced speech. This means that the femur breaker will no longer spam deadchat with \"AAAAAAAAAHHHHHHHHHH!!\"" + - tweak: "The femur breaker will now guarantee that the victim falls into crit, which will make it harder to perform torture scenes with it since the victim can just succumb." diff --git a/html/changelogs/AutoChangeLog-pr-9062.yml b/html/changelogs/AutoChangeLog-pr-9062.yml new file mode 100644 index 0000000000..12102204c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9062.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - spellcheck: "less bad wording in slime" diff --git a/html/changelogs/AutoChangeLog-pr-9064.yml b/html/changelogs/AutoChangeLog-pr-9064.yml new file mode 100644 index 0000000000..6e775c1eb4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9064.yml @@ -0,0 +1,4 @@ +author: "Cebutris" +delete-after: True +changes: + - rscadd: "Hugs of the North Star! Get them from the arcades (if you're lucky) and hug your friends at INCREDIBLE hihg speeds!" diff --git a/html/changelogs/AutoChangeLog-pr-9069.yml b/html/changelogs/AutoChangeLog-pr-9069.yml new file mode 100644 index 0000000000..0439515dd3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9069.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe. Also fixes blood cult tele runes teleporting you from the source turf to the source turf." diff --git a/html/changelogs/AutoChangeLog-pr-9070.yml b/html/changelogs/AutoChangeLog-pr-9070.yml new file mode 100644 index 0000000000..2013550dd2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9070.yml @@ -0,0 +1,5 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "inhands sprite for rainbow knife" + - tweak: "colour of highlight on the regular knife when held in the right hand" diff --git a/html/changelogs/AutoChangeLog-pr-9071.yml b/html/changelogs/AutoChangeLog-pr-9071.yml new file mode 100644 index 0000000000..40ae43867f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9071.yml @@ -0,0 +1,4 @@ +author: "Yakumo Chen" +delete-after: True +changes: + - balance: "Autocloning now requires tier 4 parts" diff --git a/html/changelogs/AutoChangeLog-pr-9078.yml b/html/changelogs/AutoChangeLog-pr-9078.yml new file mode 100644 index 0000000000..2e202ec43a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9078.yml @@ -0,0 +1,7 @@ +author: "kappa-sama" +delete-after: True +changes: + - rscdel: "Removed racism" + - tweak: "Teleporter calibration actually matters to all roundstart players" + - balance: "Slows down teleportation with the console/hub/teleporter setup if you care for your species." + - balance: "Dedicated non-humans can now get hulk without having to become human." diff --git a/html/changelogs/AutoChangeLog-pr-9079.yml b/html/changelogs/AutoChangeLog-pr-9079.yml new file mode 100644 index 0000000000..42aa732e16 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9079.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "ling blade now has 40 armor pen" diff --git a/html/changelogs/AutoChangeLog-pr-9080.yml b/html/changelogs/AutoChangeLog-pr-9080.yml new file mode 100644 index 0000000000..1ae1e3e2aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9080.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - rscadd: "Adds 3 new music tracks." diff --git a/html/changelogs/AutoChangeLog-pr-9081.yml b/html/changelogs/AutoChangeLog-pr-9081.yml new file mode 100644 index 0000000000..c66148e446 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9081.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Central Command informs you when a Meteor Storm is about to hit 5 to 10 minutes before it happens." diff --git a/html/changelogs/AutoChangeLog-pr-9083.yml b/html/changelogs/AutoChangeLog-pr-9083.yml new file mode 100644 index 0000000000..74b4d95ca3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9083.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "strawbarries and such" diff --git a/html/changelogs/AutoChangeLog-pr-9084.yml b/html/changelogs/AutoChangeLog-pr-9084.yml new file mode 100644 index 0000000000..c2569d10b4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9084.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "fixes clock cult mass recall." diff --git a/html/changelogs/AutoChangeLog-pr-9085.yml b/html/changelogs/AutoChangeLog-pr-9085.yml new file mode 100644 index 0000000000..92f5dc4cf8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9085.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes underwear colors a bit." diff --git a/html/changelogs/AutoChangeLog-pr-9089.yml b/html/changelogs/AutoChangeLog-pr-9089.yml new file mode 100644 index 0000000000..dc1e351f25 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9089.yml @@ -0,0 +1,6 @@ +author: "original by Tlaltecuhtli, port by sishen1542" +delete-after: True +changes: + - rscadd: "rcd disk that gives rcd computer frame and machine frame designs" + - rscadd: "upgraded rcd in CE lockers" + - tweak: "moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded" diff --git a/html/changelogs/AutoChangeLog-pr-9097.yml b/html/changelogs/AutoChangeLog-pr-9097.yml new file mode 100644 index 0000000000..941c0e7b98 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9097.yml @@ -0,0 +1,4 @@ +author: "lolman360" +delete-after: True +changes: + - rscadd: "NT has authorized shipments or Cotton to Megaseed Servitors. It's time to start picking, liggers." diff --git a/html/changelogs/AutoChangeLog-pr-9098.yml b/html/changelogs/AutoChangeLog-pr-9098.yml new file mode 100644 index 0000000000..6e11eaeb90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9098.yml @@ -0,0 +1,4 @@ +author: "Cebutris" +delete-after: True +changes: + - bugfix: "Tea Aspera now properly contains tea powder" diff --git a/html/changelogs/AutoChangeLog-pr-9100.yml b/html/changelogs/AutoChangeLog-pr-9100.yml new file mode 100644 index 0000000000..81141b3b0c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9100.yml @@ -0,0 +1,4 @@ +author: "Cebutris" +delete-after: True +changes: + - tweak: "Breasts no longer lactate by default, lactation is now a preference" diff --git a/html/changelogs/AutoChangeLog-pr-9101.yml b/html/changelogs/AutoChangeLog-pr-9101.yml new file mode 100644 index 0000000000..174619dd49 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9101.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by XDTM" +delete-after: True +changes: + - rscadd: "Surgery steps are now shown in detail only to the surgeon and anyone standing adjacent to them; the patient and people watching from further away get a more vague/ambiguous description." diff --git a/html/changelogs/AutoChangeLog-pr-9107.yml b/html/changelogs/AutoChangeLog-pr-9107.yml new file mode 100644 index 0000000000..65a14b9576 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9107.yml @@ -0,0 +1,4 @@ +author: "Bhijn" +delete-after: True +changes: + - bugfix: "You can now actually use the resist hotkey to resist out of handcuffs. Woah, revolutionary" diff --git a/html/changelogs/AutoChangeLog-pr-9113.yml b/html/changelogs/AutoChangeLog-pr-9113.yml new file mode 100644 index 0000000000..1bdae7cab9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9113.yml @@ -0,0 +1,5 @@ +author: "Fermis" +delete-after: True +changes: + - bugfix: "fixes fermichem reactions for tiny volumes work" + - tweak: "makes quantisation level for chemistry finer" diff --git a/html/changelogs/AutoChangeLog-pr-9115.yml b/html/changelogs/AutoChangeLog-pr-9115.yml new file mode 100644 index 0000000000..32c3109c43 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9115.yml @@ -0,0 +1,4 @@ +author: "Thalpy" +delete-after: True +changes: + - bugfix: "fixes message_admins in SDZF" diff --git a/html/changelogs/AutoChangeLog-pr-9119.yml b/html/changelogs/AutoChangeLog-pr-9119.yml new file mode 100644 index 0000000000..756c3edcb2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9119.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "mining shuttle console can now be printed after computer consoles have been researched" diff --git a/html/changelogs/AutoChangeLog-pr-9126.yml b/html/changelogs/AutoChangeLog-pr-9126.yml new file mode 100644 index 0000000000..c3e54a8f2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9126.yml @@ -0,0 +1,4 @@ +author: "original by Skoglol, port by sishen1542" +delete-after: True +changes: + - balance: "Added lots of new virus cures, made cure difficulty scale more consistently. Cures are now picked from a list of possible cures per resistance level, multiple diseases at the same level no longer always share a cure. Looking at you table salt." diff --git a/html/changelogs/AutoChangeLog-pr-9130.yml b/html/changelogs/AutoChangeLog-pr-9130.yml new file mode 100644 index 0000000000..f10e72a6ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9130.yml @@ -0,0 +1,9 @@ +author: "Owai-Seek" +delete-after: True +changes: + - rscadd: "custodial cruiser cargo crate" + - tweak: "removed light replacer from power designs and moved to misc designs" + - tweak: "added pimpin ride to custodial locator" + - tweak: "added additional items to janibelt whitelist" + - tweak: "made plant DNA manipulator unwrenchable" + - balance: "reduced janitor premium supply costs" diff --git a/html/changelogs/AutoChangeLog-pr-9132.yml b/html/changelogs/AutoChangeLog-pr-9132.yml new file mode 100644 index 0000000000..f9dee17687 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9132.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - imageadd: "Updated the sprites of all the regular crates" diff --git a/html/changelogs/AutoChangeLog-pr-9133.yml b/html/changelogs/AutoChangeLog-pr-9133.yml new file mode 100644 index 0000000000..50bfced879 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9133.yml @@ -0,0 +1,4 @@ +author: "Raptorizer" +delete-after: True +changes: + - tweak: "Doubled peach spawn rate" diff --git a/html/changelogs/AutoChangeLog-pr-9134.yml b/html/changelogs/AutoChangeLog-pr-9134.yml new file mode 100644 index 0000000000..f0be3bdd0a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9134.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - tweak: "Advanced toxin filtration nanites now heal slimes" diff --git a/html/changelogs/AutoChangeLog-pr-9136.yml b/html/changelogs/AutoChangeLog-pr-9136.yml new file mode 100644 index 0000000000..7bb9e3ccf2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9136.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "rebalances strained muscles" diff --git a/html/changelogs/AutoChangeLog-pr-9137.yml b/html/changelogs/AutoChangeLog-pr-9137.yml new file mode 100644 index 0000000000..a61a3dbe6f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9137.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "added in the assistant response team" + - bugfix: "fixed up access on the centcom hangar button" diff --git a/html/changelogs/AutoChangeLog-pr-9138.yml b/html/changelogs/AutoChangeLog-pr-9138.yml new file mode 100644 index 0000000000..b78d505c5a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9138.yml @@ -0,0 +1,4 @@ +author: "kappa-sama" +delete-after: True +changes: + - bugfix: "seed" diff --git a/html/changelogs/AutoChangeLog-pr-9141.yml b/html/changelogs/AutoChangeLog-pr-9141.yml new file mode 100644 index 0000000000..86230537de --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9141.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Fixed another runtime in warp whistles." diff --git a/html/changelogs/AutoChangeLog-pr-9142.yml b/html/changelogs/AutoChangeLog-pr-9142.yml new file mode 100644 index 0000000000..75fbfe4155 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9142.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "glue uplinks" diff --git a/html/changelogs/AutoChangeLog-pr-9145.yml b/html/changelogs/AutoChangeLog-pr-9145.yml new file mode 100644 index 0000000000..27e5712dd0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9145.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "RPDs to drones" diff --git a/html/changelogs/AutoChangeLog-pr-9149.yml b/html/changelogs/AutoChangeLog-pr-9149.yml new file mode 100644 index 0000000000..8a10035d1f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9149.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Armor and such" diff --git a/html/changelogs/AutoChangeLog-pr-9150.yml b/html/changelogs/AutoChangeLog-pr-9150.yml new file mode 100644 index 0000000000..585ea0a149 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9150.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "flavor" + - bugfix: "maybe a runtime" diff --git a/html/changelogs/AutoChangeLog-pr-9151.yml b/html/changelogs/AutoChangeLog-pr-9151.yml new file mode 100644 index 0000000000..ed01c0d137 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9151.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "chameloen clothing" diff --git a/html/changelogs/AutoChangeLog-pr-9155.yml b/html/changelogs/AutoChangeLog-pr-9155.yml new file mode 100644 index 0000000000..ad16ff6276 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9155.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - server: "Poly's speech now echos to the chat bot." diff --git a/html/changelogs/AutoChangeLog-pr-9162.yml b/html/changelogs/AutoChangeLog-pr-9162.yml new file mode 100644 index 0000000000..a415ce8bbc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9162.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "storage tweaks for belt briefcase" + - imageadd: "codersprite for belt briefcase" diff --git a/html/changelogs/AutoChangeLog-pr-9164.yml b/html/changelogs/AutoChangeLog-pr-9164.yml new file mode 100644 index 0000000000..08d7ccec18 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9164.yml @@ -0,0 +1,4 @@ +author: "lolman360" +delete-after: True +changes: + - imageadd: "missing durathread sprites" diff --git a/html/changelogs/AutoChangeLog-pr-9168.yml b/html/changelogs/AutoChangeLog-pr-9168.yml new file mode 100644 index 0000000000..2375f6a28a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9168.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - rscadd: "Added looc hotkey" diff --git a/html/changelogs/AutoChangeLog-pr-9169.yml b/html/changelogs/AutoChangeLog-pr-9169.yml new file mode 100644 index 0000000000..2a9d3ae34b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9169.yml @@ -0,0 +1,8 @@ +author: "EmeraldSundisk" +delete-after: True +changes: + - rscadd: "Adds a mass driver to Delta Station's chapel" + - rscadd: "Adds a second means of entry into the chapel" + - tweak: "Slightly expands the chapel to make room for the driver, slight adjustment to air systems" + - tweak: "Clears a path in the station exterior for the mass driver to work properly" + - tweak: "Nearby maintenance loot has been relocated to accommodate the chapel expansion, surrounding area has been \"cleaned up\" somewhat" diff --git a/html/changelogs/AutoChangeLog-pr-9172.yml b/html/changelogs/AutoChangeLog-pr-9172.yml new file mode 100644 index 0000000000..751cfa6d26 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9172.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - rscadd: "Racking shotguns is now more threatening." diff --git a/html/changelogs/AutoChangeLog-pr-9175.yml b/html/changelogs/AutoChangeLog-pr-9175.yml new file mode 100644 index 0000000000..d3aa92d42d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9175.yml @@ -0,0 +1,5 @@ +author: "lolman360" +delete-after: True +changes: + - rscadd: "Added durathread jumpskirt" + - imageadd: "Duraskirt sprites and rolled down jumpsuit sprites." diff --git a/html/changelogs/AutoChangeLog-pr-9177.yml b/html/changelogs/AutoChangeLog-pr-9177.yml new file mode 100644 index 0000000000..4b8a06c8af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9177.yml @@ -0,0 +1,5 @@ +author: "JTGSZ" +delete-after: True +changes: + - tweak: "Added one more gang boss slot bringing total to 4 from 3" + - bugfix: "Fixed Gang Boss being able to be deconverted" diff --git a/html/changelogs/AutoChangeLog-pr-9178.yml b/html/changelogs/AutoChangeLog-pr-9178.yml new file mode 100644 index 0000000000..2a6de13f5e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9178.yml @@ -0,0 +1,4 @@ +author: "Bhijn" +delete-after: True +changes: + - bugfix: "the `!tgs poly` command now actually works" diff --git a/html/changelogs/AutoChangeLog-pr-9180.yml b/html/changelogs/AutoChangeLog-pr-9180.yml new file mode 100644 index 0000000000..e184ad3205 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9180.yml @@ -0,0 +1,4 @@ +author: "Bhijn" +delete-after: True +changes: + - rscadd: "Poly now has a 0.01% chance per squawk to speak through the TGS relay." diff --git a/html/changelogs/AutoChangeLog-pr-9183.yml b/html/changelogs/AutoChangeLog-pr-9183.yml new file mode 100644 index 0000000000..dc5b5a8bdb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9183.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes Blood Cult conversion prompts" diff --git a/html/changelogs/AutoChangeLog-pr-9184.yml b/html/changelogs/AutoChangeLog-pr-9184.yml new file mode 100644 index 0000000000..d0b4d1fa7e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9184.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscdel: "Removes an obnoxious temporary overlay var." diff --git a/html/changelogs/AutoChangeLog-pr-9186.yml b/html/changelogs/AutoChangeLog-pr-9186.yml new file mode 100644 index 0000000000..f0497ee7c2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9186.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "added pharaoh gear to chaplain vendor" + - spellcheck: "fixed typos in pharaoh items" diff --git a/html/changelogs/AutoChangeLog-pr-9194.yml b/html/changelogs/AutoChangeLog-pr-9194.yml new file mode 100644 index 0000000000..24299209ea --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9194.yml @@ -0,0 +1,4 @@ +author: "kappa-sama" +delete-after: True +changes: + - tweak: "added obj/item/key to wallet whitelist" diff --git a/html/changelogs/AutoChangeLog-pr-9200.yml b/html/changelogs/AutoChangeLog-pr-9200.yml new file mode 100644 index 0000000000..d1be09ee4a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9200.yml @@ -0,0 +1,4 @@ +author: "Owai-Seek" +delete-after: True +changes: + - bugfix: "fixed them strawberries" diff --git a/html/changelogs/AutoChangeLog-pr-9204.yml b/html/changelogs/AutoChangeLog-pr-9204.yml new file mode 100644 index 0000000000..3b70354fd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9204.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "/cursed from a item path" diff --git a/html/changelogs/AutoChangeLog-pr-9208.yml b/html/changelogs/AutoChangeLog-pr-9208.yml new file mode 100644 index 0000000000..1645164266 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9208.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "colorable socks can be colored again." diff --git a/html/changelogs/AutoChangeLog-pr-9209.yml b/html/changelogs/AutoChangeLog-pr-9209.yml new file mode 100644 index 0000000000..5ed81d6856 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9209.yml @@ -0,0 +1,4 @@ +author: "original by redmoogle, port by sishen1542" +delete-after: True +changes: + - rscadd: "Added support for 3 new gasses; Tritium, Pluoxium, and BZ" diff --git a/html/changelogs/AutoChangeLog-pr-9210.yml b/html/changelogs/AutoChangeLog-pr-9210.yml new file mode 100644 index 0000000000..b02811e7a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9210.yml @@ -0,0 +1,7 @@ +author: "EmeraldSundisk" +delete-after: True +changes: + - tweak: "CentCom has noticed the lack of coffins in Delta Station's chapel and provided some, but in exchange for reducing the chapel morgue's capacity." + - tweak: "Fixed a maintenance door the chaplain should have been able to open." + - bugfix: "Fixes space areas outside the driver +removal: CentCom Defense Analysts have ordered the maintenance hatch to the Mass Driver room be removed citing \"security concerns\"." diff --git a/html/changelogs/AutoChangeLog-pr-9212.yml b/html/changelogs/AutoChangeLog-pr-9212.yml new file mode 100644 index 0000000000..48e8b8b4d3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9212.yml @@ -0,0 +1,5 @@ +author: "dapnee" +delete-after: True +changes: + - rscadd: "Plasmaglass tables, spears, tiny plasmaglass shards" + - bugfix: "Plasmaglass structures now drop plasmaglass shards instead of nothing" diff --git a/html/changelogs/AutoChangeLog-pr-9216.yml b/html/changelogs/AutoChangeLog-pr-9216.yml new file mode 100644 index 0000000000..0be9314dbc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9216.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "oops not being blacklisted" diff --git a/html/changelogs/AutoChangeLog-pr-9219.yml b/html/changelogs/AutoChangeLog-pr-9219.yml new file mode 100644 index 0000000000..138991e507 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9219.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "ports a fix" diff --git a/html/changelogs/AutoChangeLog-pr-9221.yml b/html/changelogs/AutoChangeLog-pr-9221.yml new file mode 100644 index 0000000000..0256c4a7c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9221.yml @@ -0,0 +1,9 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "holy lasrifle, hypertool, divine lightblade, and blessed baseball bat. Four new holy weapons!" + - balance: "stamina and force tweaks for most holy weapons." + - tweak: "prayer beads no longer deconvert after a 10 second timer, now just inject holy water for delayed effect" + - tweak: "cultist runes are now destroyed with a bible or a null rod" + - tweak: "bo-staff now functions as a nerfed sleepy carp staff" + - bugfix: "fixed kevinz code to add in non-null rod child items as holy weapons" diff --git a/html/changelogs/AutoChangeLog-pr-9227.yml b/html/changelogs/AutoChangeLog-pr-9227.yml new file mode 100644 index 0000000000..9f6bfabdc4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9227.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Missing sprites with bad ones" diff --git a/html/changelogs/AutoChangeLog-pr-9229.yml b/html/changelogs/AutoChangeLog-pr-9229.yml new file mode 100644 index 0000000000..5c617f6ab0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9229.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "emag charge amount" diff --git a/html/changelogs/AutoChangeLog-pr-9235.yml b/html/changelogs/AutoChangeLog-pr-9235.yml new file mode 100644 index 0000000000..112f34a7f0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9235.yml @@ -0,0 +1,5 @@ +author: "Yakumo Chen" +delete-after: True +changes: + - rscdel: "Removes autoscan" + - balance: "Scanning people now requires someone to operate the cloning computer regardless of part level." diff --git a/html/changelogs/AutoChangeLog-pr-9238.yml b/html/changelogs/AutoChangeLog-pr-9238.yml new file mode 100644 index 0000000000..b2eb8db233 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9238.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Surgerys and spays in bags" diff --git a/html/changelogs/AutoChangeLog-pr-9239.yml b/html/changelogs/AutoChangeLog-pr-9239.yml new file mode 100644 index 0000000000..781dcd82b6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9239.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "earthbloods stam regen" diff --git a/html/changelogs/AutoChangeLog-pr-9242.yml b/html/changelogs/AutoChangeLog-pr-9242.yml new file mode 100644 index 0000000000..1e47385e67 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9242.yml @@ -0,0 +1,4 @@ +author: "kappa-sama" +delete-after: True +changes: + - tweak: "blood cult ritual daggers fit in jack/combat boots" diff --git a/html/changelogs/AutoChangeLog-pr-9248.yml b/html/changelogs/AutoChangeLog-pr-9248.yml new file mode 100644 index 0000000000..3e6eff727c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9248.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - imageadd: "Red to Blue/Black crosses as questioned by Bhijn" diff --git a/html/changelogs/AutoChangeLog-pr-9249.yml b/html/changelogs/AutoChangeLog-pr-9249.yml new file mode 100644 index 0000000000..b2ef0c2d46 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9249.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "clean bot not cleaning basic cleanables" diff --git a/html/changelogs/AutoChangeLog-pr-9256.yml b/html/changelogs/AutoChangeLog-pr-9256.yml new file mode 100644 index 0000000000..dcf039a2a0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9256.yml @@ -0,0 +1,4 @@ +author: "Fermi" +delete-after: True +changes: + - bugfix: "SDGF: Fixes infinite clones." diff --git a/icons/UI_Icons/Pills/pill1.png b/icons/UI_Icons/Pills/pill1.png new file mode 100644 index 0000000000..3412ca9d0e Binary files /dev/null and b/icons/UI_Icons/Pills/pill1.png differ diff --git a/icons/UI_Icons/Pills/pill10.png b/icons/UI_Icons/Pills/pill10.png new file mode 100644 index 0000000000..06829b9b93 Binary files /dev/null and b/icons/UI_Icons/Pills/pill10.png differ diff --git a/icons/UI_Icons/Pills/pill11.png b/icons/UI_Icons/Pills/pill11.png new file mode 100644 index 0000000000..780d7abdfb Binary files /dev/null and b/icons/UI_Icons/Pills/pill11.png differ diff --git a/icons/UI_Icons/Pills/pill12.png b/icons/UI_Icons/Pills/pill12.png new file mode 100644 index 0000000000..587936f748 Binary files /dev/null and b/icons/UI_Icons/Pills/pill12.png differ diff --git a/icons/UI_Icons/Pills/pill13.png b/icons/UI_Icons/Pills/pill13.png new file mode 100644 index 0000000000..226cefdadb Binary files /dev/null and b/icons/UI_Icons/Pills/pill13.png differ diff --git a/icons/UI_Icons/Pills/pill14.png b/icons/UI_Icons/Pills/pill14.png new file mode 100644 index 0000000000..26c0c66ecb Binary files /dev/null and b/icons/UI_Icons/Pills/pill14.png differ diff --git a/icons/UI_Icons/Pills/pill15.png b/icons/UI_Icons/Pills/pill15.png new file mode 100644 index 0000000000..1e338ca26a Binary files /dev/null and b/icons/UI_Icons/Pills/pill15.png differ diff --git a/icons/UI_Icons/Pills/pill16.png b/icons/UI_Icons/Pills/pill16.png new file mode 100644 index 0000000000..e733281709 Binary files /dev/null and b/icons/UI_Icons/Pills/pill16.png differ diff --git a/icons/UI_Icons/Pills/pill17.png b/icons/UI_Icons/Pills/pill17.png new file mode 100644 index 0000000000..0f28a7c28a Binary files /dev/null and b/icons/UI_Icons/Pills/pill17.png differ diff --git a/icons/UI_Icons/Pills/pill18.png b/icons/UI_Icons/Pills/pill18.png new file mode 100644 index 0000000000..4658d7dfc4 Binary files /dev/null and b/icons/UI_Icons/Pills/pill18.png differ diff --git a/icons/UI_Icons/Pills/pill19.png b/icons/UI_Icons/Pills/pill19.png new file mode 100644 index 0000000000..cf74e83ba2 Binary files /dev/null and b/icons/UI_Icons/Pills/pill19.png differ diff --git a/icons/UI_Icons/Pills/pill2.png b/icons/UI_Icons/Pills/pill2.png new file mode 100644 index 0000000000..f996df8536 Binary files /dev/null and b/icons/UI_Icons/Pills/pill2.png differ diff --git a/icons/UI_Icons/Pills/pill20.png b/icons/UI_Icons/Pills/pill20.png new file mode 100644 index 0000000000..4e10a166e9 Binary files /dev/null and b/icons/UI_Icons/Pills/pill20.png differ diff --git a/icons/UI_Icons/Pills/pill21.png b/icons/UI_Icons/Pills/pill21.png new file mode 100644 index 0000000000..9b4450da27 Binary files /dev/null and b/icons/UI_Icons/Pills/pill21.png differ diff --git a/icons/UI_Icons/Pills/pill22.png b/icons/UI_Icons/Pills/pill22.png new file mode 100644 index 0000000000..0d9d5c3c55 Binary files /dev/null and b/icons/UI_Icons/Pills/pill22.png differ diff --git a/icons/UI_Icons/Pills/pill3.png b/icons/UI_Icons/Pills/pill3.png new file mode 100644 index 0000000000..365fa39e7d Binary files /dev/null and b/icons/UI_Icons/Pills/pill3.png differ diff --git a/icons/UI_Icons/Pills/pill4.png b/icons/UI_Icons/Pills/pill4.png new file mode 100644 index 0000000000..d7aa72da3b Binary files /dev/null and b/icons/UI_Icons/Pills/pill4.png differ diff --git a/icons/UI_Icons/Pills/pill5.png b/icons/UI_Icons/Pills/pill5.png new file mode 100644 index 0000000000..ed9a84427a Binary files /dev/null and b/icons/UI_Icons/Pills/pill5.png differ diff --git a/icons/UI_Icons/Pills/pill6.png b/icons/UI_Icons/Pills/pill6.png new file mode 100644 index 0000000000..675adab56d Binary files /dev/null and b/icons/UI_Icons/Pills/pill6.png differ diff --git a/icons/UI_Icons/Pills/pill7.png b/icons/UI_Icons/Pills/pill7.png new file mode 100644 index 0000000000..9961be2878 Binary files /dev/null and b/icons/UI_Icons/Pills/pill7.png differ diff --git a/icons/UI_Icons/Pills/pill8.png b/icons/UI_Icons/Pills/pill8.png new file mode 100644 index 0000000000..879a5bcd5b Binary files /dev/null and b/icons/UI_Icons/Pills/pill8.png differ diff --git a/icons/UI_Icons/Pills/pill9.png b/icons/UI_Icons/Pills/pill9.png new file mode 100644 index 0000000000..235cf5b280 Binary files /dev/null and b/icons/UI_Icons/Pills/pill9.png differ diff --git a/icons/misc/minesweeper_tiles/eight.png b/icons/UI_Icons/minesweeper_tiles/eight.png similarity index 100% rename from icons/misc/minesweeper_tiles/eight.png rename to icons/UI_Icons/minesweeper_tiles/eight.png diff --git a/icons/misc/minesweeper_tiles/empty.png b/icons/UI_Icons/minesweeper_tiles/empty.png similarity index 100% rename from icons/misc/minesweeper_tiles/empty.png rename to icons/UI_Icons/minesweeper_tiles/empty.png diff --git a/icons/misc/minesweeper_tiles/five.png b/icons/UI_Icons/minesweeper_tiles/five.png similarity index 100% rename from icons/misc/minesweeper_tiles/five.png rename to icons/UI_Icons/minesweeper_tiles/five.png diff --git a/icons/misc/minesweeper_tiles/flag.png b/icons/UI_Icons/minesweeper_tiles/flag.png similarity index 100% rename from icons/misc/minesweeper_tiles/flag.png rename to icons/UI_Icons/minesweeper_tiles/flag.png diff --git a/icons/misc/minesweeper_tiles/four.png b/icons/UI_Icons/minesweeper_tiles/four.png similarity index 100% rename from icons/misc/minesweeper_tiles/four.png rename to icons/UI_Icons/minesweeper_tiles/four.png diff --git a/icons/misc/minesweeper_tiles/hidden.png b/icons/UI_Icons/minesweeper_tiles/hidden.png similarity index 100% rename from icons/misc/minesweeper_tiles/hidden.png rename to icons/UI_Icons/minesweeper_tiles/hidden.png diff --git a/icons/misc/minesweeper_tiles/mine.png b/icons/UI_Icons/minesweeper_tiles/mine.png similarity index 100% rename from icons/misc/minesweeper_tiles/mine.png rename to icons/UI_Icons/minesweeper_tiles/mine.png diff --git a/icons/misc/minesweeper_tiles/minehit.png b/icons/UI_Icons/minesweeper_tiles/minehit.png similarity index 100% rename from icons/misc/minesweeper_tiles/minehit.png rename to icons/UI_Icons/minesweeper_tiles/minehit.png diff --git a/icons/misc/minesweeper_tiles/one.png b/icons/UI_Icons/minesweeper_tiles/one.png similarity index 100% rename from icons/misc/minesweeper_tiles/one.png rename to icons/UI_Icons/minesweeper_tiles/one.png diff --git a/icons/misc/minesweeper_tiles/seven.png b/icons/UI_Icons/minesweeper_tiles/seven.png similarity index 100% rename from icons/misc/minesweeper_tiles/seven.png rename to icons/UI_Icons/minesweeper_tiles/seven.png diff --git a/icons/misc/minesweeper_tiles/six.png b/icons/UI_Icons/minesweeper_tiles/six.png similarity index 100% rename from icons/misc/minesweeper_tiles/six.png rename to icons/UI_Icons/minesweeper_tiles/six.png diff --git a/icons/misc/minesweeper_tiles/three.png b/icons/UI_Icons/minesweeper_tiles/three.png similarity index 100% rename from icons/misc/minesweeper_tiles/three.png rename to icons/UI_Icons/minesweeper_tiles/three.png diff --git a/icons/misc/minesweeper_tiles/two.png b/icons/UI_Icons/minesweeper_tiles/two.png similarity index 100% rename from icons/misc/minesweeper_tiles/two.png rename to icons/UI_Icons/minesweeper_tiles/two.png diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 29086033c8..e13ce10347 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index 089c0ff3f8..925b072a5f 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mecha/mecha_mouse-disable.dmi b/icons/mecha/mecha_mouse-disable.dmi new file mode 100644 index 0000000000..48924c58c2 Binary files /dev/null and b/icons/mecha/mecha_mouse-disable.dmi differ diff --git a/icons/member_content.dmi b/icons/member_content.dmi index bb59764627..7744371119 100644 Binary files a/icons/member_content.dmi and b/icons/member_content.dmi differ diff --git a/icons/mob/accessories.dmi b/icons/mob/accessories.dmi index 8e3e48230f..68f13c8875 100644 Binary files a/icons/mob/accessories.dmi and b/icons/mob/accessories.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 65b5733ffe..4e23c102ce 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index c50351eef3..21238366f1 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ diff --git a/icons/mob/alienqueen.dmi b/icons/mob/alienqueen.dmi index 115bd17cb0..1176f43edd 100644 Binary files a/icons/mob/alienqueen.dmi and b/icons/mob/alienqueen.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index c98ca98c42..2a85f8a422 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index e3c80708c3..b22f50623c 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 1ae0b0a2b5..6843bac6bf 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi index d974d0ca6c..1b917d9434 100644 Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index aad4718cbd..6cce82b5f7 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 09d6fe5374..09bfd9e0a2 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_parts.dmi b/icons/mob/human_parts.dmi index 70aeba6a69..fc6fafb275 100644 Binary files a/icons/mob/human_parts.dmi and b/icons/mob/human_parts.dmi differ diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi index 3bb3874d35..7f10d992bc 100644 Binary files a/icons/mob/human_parts_greyscale.dmi and b/icons/mob/human_parts_greyscale.dmi differ diff --git a/icons/mob/inhands/equipment/backpack_lefthand.dmi b/icons/mob/inhands/equipment/backpack_lefthand.dmi index 0e466486c5..3238b98757 100644 Binary files a/icons/mob/inhands/equipment/backpack_lefthand.dmi and b/icons/mob/inhands/equipment/backpack_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/backpack_righthand.dmi b/icons/mob/inhands/equipment/backpack_righthand.dmi index 1c265a4137..a103c1a13f 100644 Binary files a/icons/mob/inhands/equipment/backpack_righthand.dmi and b/icons/mob/inhands/equipment/backpack_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_lefthand.dmi b/icons/mob/inhands/equipment/belt_lefthand.dmi index 366493eebd..beac56725a 100644 Binary files a/icons/mob/inhands/equipment/belt_lefthand.dmi and b/icons/mob/inhands/equipment/belt_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_righthand.dmi b/icons/mob/inhands/equipment/belt_righthand.dmi index 81b075f706..da31cc9710 100644 Binary files a/icons/mob/inhands/equipment/belt_righthand.dmi and b/icons/mob/inhands/equipment/belt_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/briefcase_lefthand.dmi b/icons/mob/inhands/equipment/briefcase_lefthand.dmi index 08bc3814b0..38aaa98254 100644 Binary files a/icons/mob/inhands/equipment/briefcase_lefthand.dmi and b/icons/mob/inhands/equipment/briefcase_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/briefcase_righthand.dmi b/icons/mob/inhands/equipment/briefcase_righthand.dmi index 5cc42559cd..fbcea4580e 100644 Binary files a/icons/mob/inhands/equipment/briefcase_righthand.dmi and b/icons/mob/inhands/equipment/briefcase_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/kitchen_lefthand.dmi b/icons/mob/inhands/equipment/kitchen_lefthand.dmi index 277a7d8f05..93cd988cff 100644 Binary files a/icons/mob/inhands/equipment/kitchen_lefthand.dmi and b/icons/mob/inhands/equipment/kitchen_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/kitchen_righthand.dmi b/icons/mob/inhands/equipment/kitchen_righthand.dmi index 0103bd19b5..075b4c2033 100644 Binary files a/icons/mob/inhands/equipment/kitchen_righthand.dmi and b/icons/mob/inhands/equipment/kitchen_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/security_lefthand.dmi b/icons/mob/inhands/equipment/security_lefthand.dmi index 6ccdfba3fc..01f8e2ca27 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 e3f930a13e..d2126fe22f 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/equipment/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi index e9d0dd0d2b..3f29410f98 100644 Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi index dda17156fe..2c3f291e43 100644 Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/toolbox_lefthand.dmi b/icons/mob/inhands/equipment/toolbox_lefthand.dmi index b2fa42ce5e..801df7abb8 100644 Binary files a/icons/mob/inhands/equipment/toolbox_lefthand.dmi and b/icons/mob/inhands/equipment/toolbox_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/toolbox_righthand.dmi b/icons/mob/inhands/equipment/toolbox_righthand.dmi index ccb15982dd..f38ddfc9a4 100644 Binary files a/icons/mob/inhands/equipment/toolbox_righthand.dmi and b/icons/mob/inhands/equipment/toolbox_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/tools_lefthand.dmi b/icons/mob/inhands/equipment/tools_lefthand.dmi index 5b497afe53..72b994328d 100644 Binary files a/icons/mob/inhands/equipment/tools_lefthand.dmi and b/icons/mob/inhands/equipment/tools_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/tools_righthand.dmi b/icons/mob/inhands/equipment/tools_righthand.dmi index dbed4c43d2..ef1001c438 100644 Binary files a/icons/mob/inhands/equipment/tools_righthand.dmi and b/icons/mob/inhands/equipment/tools_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index f1b125eb20..71c453856a 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 7ef316be17..0ca09ad810 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index f6ac6ca499..8978d17237 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index 504121feba..3f8a876d43 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/polearms_lefthand.dmi b/icons/mob/inhands/weapons/polearms_lefthand.dmi index 5529edfa51..5e04b3daa3 100644 Binary files a/icons/mob/inhands/weapons/polearms_lefthand.dmi and b/icons/mob/inhands/weapons/polearms_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/polearms_righthand.dmi b/icons/mob/inhands/weapons/polearms_righthand.dmi index e902dcdc3b..4b304cfc3e 100644 Binary files a/icons/mob/inhands/weapons/polearms_righthand.dmi and b/icons/mob/inhands/weapons/polearms_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_lefthand.dmi b/icons/mob/inhands/weapons/staves_lefthand.dmi index ecc92c7d20..8b96b84236 100644 Binary files a/icons/mob/inhands/weapons/staves_lefthand.dmi and b/icons/mob/inhands/weapons/staves_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_righthand.dmi b/icons/mob/inhands/weapons/staves_righthand.dmi index 92e5b91323..202bab9e21 100644 Binary files a/icons/mob/inhands/weapons/staves_righthand.dmi and b/icons/mob/inhands/weapons/staves_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index d6950f4e1e..d306e22892 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index 9655829113..3e0c3424d3 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 5f0b665ff4..019ae09517 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 1649706279..9beedfb417 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index 3463065bc7..5eb270d23f 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index fe0146ccc4..10f29f51e4 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ diff --git a/icons/mob/restraints.dmi b/icons/mob/restraints.dmi new file mode 100644 index 0000000000..fa7eb43aa3 Binary files /dev/null and b/icons/mob/restraints.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index c53fa85262..896a87ff3a 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 77450b6ac3..3cd7388378 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 42c32f134a..740ad43d42 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index 5e6725cec7..3174397b54 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 3d281606de..f783331c19 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/advancedtools.dmi b/icons/obj/advancedtools.dmi new file mode 100644 index 0000000000..974202dd58 Binary files /dev/null and b/icons/obj/advancedtools.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 24ede3c513..6282e555fa 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/assemblies/new_assemblies.dmi b/icons/obj/assemblies/new_assemblies.dmi index df9517aeaa..fa0c138d21 100644 Binary files a/icons/obj/assemblies/new_assemblies.dmi and b/icons/obj/assemblies/new_assemblies.dmi differ diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index 50bfbace89..2c4d401088 100644 Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi index 73dcad452b..1cc99e09e9 100644 Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi index 3754ff052c..9e8fb64aba 100644 Binary files a/icons/obj/chairs.dmi and b/icons/obj/chairs.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 93daa6149e..b63e9344f1 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index c35956687d..c62a88c829 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/belt_overlays.dmi b/icons/obj/clothing/belt_overlays.dmi index d7bf32d7b1..717937c034 100644 Binary files a/icons/obj/clothing/belt_overlays.dmi and b/icons/obj/clothing/belt_overlays.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 3e56574fbf..e329720cf7 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index e7bec8dbe4..2cdf97bd37 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 8256c1fc07..e151808cb1 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index a0153b1596..4ec45666c4 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index db0634181b..8d7bd55426 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 568adb69b3..dc5fa1399d 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 3e3a1cefcb..40844c9a29 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 4165719a3c..3ab7f4b510 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index eb4f5813c8..601e32fb63 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 55c33e5e83..032b0c27ad 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index dc3aca6b19..7822cdb8c2 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/femur_breaker.dmi b/icons/obj/femur_breaker.dmi new file mode 100644 index 0000000000..4b36f4b2b8 Binary files /dev/null and b/icons/obj/femur_breaker.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 92b5203f5d..6fda702cb3 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/piecake.dmi b/icons/obj/food/piecake.dmi index 57dda21757..df1e61c849 100644 Binary files a/icons/obj/food/piecake.dmi and b/icons/obj/food/piecake.dmi differ diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index 4dec451008..a6d5c8a5e1 100644 Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ diff --git a/icons/obj/guns/magic.dmi b/icons/obj/guns/magic.dmi index 47d05e3470..0a4152af64 100644 Binary files a/icons/obj/guns/magic.dmi and b/icons/obj/guns/magic.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 7d44d35f55..0831d47577 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index 82dce552a7..dd4d1e1f93 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi index 162c6b047e..e7dee2290d 100644 Binary files a/icons/obj/hydroponics/growing.dmi and b/icons/obj/hydroponics/growing.dmi differ diff --git a/icons/obj/hydroponics/growing_fruits.dmi b/icons/obj/hydroponics/growing_fruits.dmi index d309884be0..029d49e196 100644 Binary files a/icons/obj/hydroponics/growing_fruits.dmi and b/icons/obj/hydroponics/growing_fruits.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index a1ab5b08e5..fe126cadd8 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi index 5a2088c332..a78ce898e0 100644 Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 655d37d4a6..6336669501 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/iv_drip.dmi b/icons/obj/iv_drip.dmi index 016513245e..f530688da7 100644 Binary files a/icons/obj/iv_drip.dmi and b/icons/obj/iv_drip.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 140f6a4d9e..f28b8be5c5 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/machines/harvester.dmi b/icons/obj/machines/harvester.dmi index d6d9b01fc6..ce272c5774 100644 Binary files a/icons/obj/machines/harvester.dmi and b/icons/obj/machines/harvester.dmi differ diff --git a/icons/obj/machines/sleeper.dmi b/icons/obj/machines/sleeper.dmi index b027d0d7b1..ff9e2b197a 100644 Binary files a/icons/obj/machines/sleeper.dmi and b/icons/obj/machines/sleeper.dmi differ diff --git a/icons/obj/monitors.dmi b/icons/obj/monitors.dmi index 9880707010..e38760b84d 100644 Binary files a/icons/obj/monitors.dmi and b/icons/obj/monitors.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 586bca61aa..685b14cee5 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index bff1b631c3..ad1d34836d 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/shards.dmi b/icons/obj/shards.dmi index a575ab292f..e7875efa26 100644 Binary files a/icons/obj/shards.dmi and b/icons/obj/shards.dmi differ diff --git a/icons/obj/smooth_structures/plasmaglass_table.dmi b/icons/obj/smooth_structures/plasmaglass_table.dmi new file mode 100644 index 0000000000..808e79aa43 Binary files /dev/null and b/icons/obj/smooth_structures/plasmaglass_table.dmi differ diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi index 6d2b2b64cd..ac2d42378a 100644 Binary files a/icons/obj/stack_objects.dmi and b/icons/obj/stack_objects.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 9037bfc0d0..fae8134791 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 1a3b344566..eed8ee64e7 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index cfb36bb3ae..c983201d5f 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index cdf6df2dab..2ecd9f9004 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -153,6 +153,30 @@ h1.alert, h2.alert {color: #000000;} .redtext {color: #FF0000; font-size: 3;} .clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} .his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} +.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} +@keyframes velvet { + 0% { color: #400020; } + 40% { color: #FF0000; } + 50% { color: #FF8888; } + 60% { color: #FF0000; } + 100% { color: #400020; } +} + +.hypnophrase {color: #3bb5d3; font-weight: bold; animation: hypnocolor 1500ms infinite;} +@keyframes hypnocolor { + 0% { color: #0d0d0d; } + 25% { color: #410194; } + 50% { color: #7f17d8; } + 75% { color: #410194; } + 100% { color: #3bb5d3; } +} + +.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} + @keyframes phobia { + 0% { color: #0d0d0d; } + 50% { color: #dd0000; } + 100% { color: #0d0d0d; } +} .icon {height: 1em; width: auto;} diff --git a/modular_citadel/code/_onclick/hud/screen_objects.dm b/modular_citadel/code/_onclick/hud/screen_objects.dm index 511627b81f..3a0eb364cb 100644 --- a/modular_citadel/code/_onclick/hud/screen_objects.dm +++ b/modular_citadel/code/_onclick/hud/screen_objects.dm @@ -1,25 +1,3 @@ -/obj/screen/mov_intent - icon = 'modular_citadel/icons/ui/screen_midnight.dmi' - -/obj/screen/sprintbutton - name = "toggle sprint" - icon = 'modular_citadel/icons/ui/screen_midnight.dmi' - icon_state = "act_sprint" - layer = ABOVE_HUD_LAYER - 0.1 - -/obj/screen/sprintbutton/Click() - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - H.togglesprint() - -/obj/screen/sprintbutton/proc/insert_witty_toggle_joke_here(mob/living/carbon/human/H) - if(!H) - return - if(H.sprinting) - icon_state = "act_sprint_on" - else - icon_state = "act_sprint" - /obj/screen/restbutton name = "rest" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/modular_citadel/code/_onclick/hud/sprint.dm b/modular_citadel/code/_onclick/hud/sprint.dm new file mode 100644 index 0000000000..290fcd368e --- /dev/null +++ b/modular_citadel/code/_onclick/hud/sprint.dm @@ -0,0 +1,41 @@ +/obj/screen/mov_intent + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + +/obj/screen/sprintbutton + name = "toggle sprint" + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + icon_state = "act_sprint" + layer = ABOVE_HUD_LAYER - 0.1 + +/obj/screen/sprintbutton/Click() + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + H.togglesprint() + +/obj/screen/sprintbutton/proc/insert_witty_toggle_joke_here(mob/living/carbon/human/H) + if(!H) + return + if(H.sprinting) + icon_state = "act_sprint_on" + else + icon_state = "act_sprint" + +//Sprint buffer onscreen code. +/datum/hud/var/obj/screen/sprint_buffer/sprint_buffer + +/obj/screen/sprint_buffer + name = "sprint buffer" + icon = 'icons/effects/progessbar.dmi' + icon_state = "prog_bar_100" + +/obj/screen/sprint_buffer/Click() + if(isliving(usr)) + var/mob/living/L = usr + to_chat(L, "Your sprint buffer's maximum capacity is [L.sprint_buffer_max]. It is currently at [L.sprint_buffer], regenerating at [L.sprint_buffer_regen_ds * 10] per second. \ + Sprinting while this is empty will incur a [L.sprint_stamina_cost] stamina cost per tile.") + +/obj/screen/sprint_buffer/proc/update_to_mob(mob/living/L) + var/amount = 0 + if(L.sprint_buffer_max > 0) + amount = round(CLAMP((L.sprint_buffer / L.sprint_buffer_max) * 100, 0, 100), 5) + icon_state = "prog_bar_[amount]" diff --git a/modular_citadel/code/_onclick/item_attack.dm b/modular_citadel/code/_onclick/item_attack.dm index dcc9f567e2..80281ee084 100644 --- a/modular_citadel/code/_onclick/item_attack.dm +++ b/modular_citadel/code/_onclick/item_attack.dm @@ -17,9 +17,3 @@ /obj/item/proc/altafterattack(atom/target, mob/user, proximity_flag, click_parameters) return FALSE - -/obj/item/proc/getweight() - if(total_mass) - return max(total_mass,MIN_MELEE_STAMCOST) - else - return w_class*1.25 diff --git a/modular_citadel/code/controllers/subsystem/job.dm b/modular_citadel/code/controllers/subsystem/job.dm index c433042ae6..46aef6f529 100644 --- a/modular_citadel/code/controllers/subsystem/job.dm +++ b/modular_citadel/code/controllers/subsystem/job.dm @@ -13,7 +13,7 @@ var/permitted = TRUE if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles)) permitted = FALSE - if(G.ckeywhitelist && G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist)) + if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey)) permitted = FALSE if(!equipbackpackstuff && G.category == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs permitted = FALSE diff --git a/modular_citadel/code/controllers/subsystem/shuttle.dm b/modular_citadel/code/controllers/subsystem/shuttle.dm index bb4592f819..ce3f062bdd 100644 --- a/modular_citadel/code/controllers/subsystem/shuttle.dm +++ b/modular_citadel/code/controllers/subsystem/shuttle.dm @@ -1,6 +1,7 @@ -/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 3 hours has passed. - if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //3 hours - SSshuttle.emergency.request() - priority_announce("The shift has come to an end and the shuttle called.") +/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 2 hours have passed. + if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //2 hours + SSshuttle.emergency.request(silent = TRUE) + priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority") log_game("Round time limit reached. Shuttle has been auto-called.") message_admins("Round time limit reached. Shuttle called.") + emergencyNoRecall = TRUE diff --git a/modular_citadel/code/datums/mood_events/chem_events.dm b/modular_citadel/code/datums/mood_events/chem_events.dm new file mode 100644 index 0000000000..c496a0fa27 --- /dev/null +++ b/modular_citadel/code/datums/mood_events/chem_events.dm @@ -0,0 +1,59 @@ +/datum/mood_event/eigenstate + mood_change = -3 + description = "Where the hell am I? Is this an alternative dimension ?\n" + +/datum/mood_event/enthrall + mood_change = 5 + +/datum/mood_event/enthrall/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallpraise + mood_change = 10 + timeout = 1 MINUTES + +/datum/mood_event/enthrallpraise/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallscold + mood_change = -10 + timeout = 1 MINUTES + +/datum/mood_event/enthrallscold/add_effects(message) + description = "[message]\n"//aaa I'm not kinky enough for this + +/datum/mood_event/enthrallmissing1 + mood_change = -5 + +/datum/mood_event/enthrallmissing1/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing2 + mood_change = -10 + +/datum/mood_event/enthrallmissing2/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing3 + mood_change = -15 + +/datum/mood_event/enthrallmissing3/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing4 + mood_change = -25 + +/datum/mood_event/enthrallmissing4/add_effects(message) + description = "[message]\n" + +/datum/mood_event/InLove + mood_change = 10 + +/datum/mood_event/InLove/add_effects(message) + description = "[message]\n" + +/datum/mood_event/MissingLove + mood_change = -10 + +/datum/mood_event/MissingLove/add_effects(message) + description = "[message]\n" diff --git a/modular_citadel/code/datums/mood_events/generic_negative_events.dm b/modular_citadel/code/datums/mood_events/generic_negative_events.dm index c0f2591656..bb04b0b283 100644 --- a/modular_citadel/code/datums/mood_events/generic_negative_events.dm +++ b/modular_citadel/code/datums/mood_events/generic_negative_events.dm @@ -3,19 +3,19 @@ /datum/mood_event/plushjack description = "I have butchered a plush recently.\n" mood_change = -1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/plush_nostuffing description = "A plush I tried to pet had no stuffing...\n" mood_change = -1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/emptypred description = "I had to let someone out.\n" mood_change = -2 - timeout = 600 + timeout = 1 MINUTES /datum/mood_event/emptyprey description = "It feels quite cold out here.\n" mood_change = -2 - timeout = 600 \ No newline at end of file + timeout = 1 MINUTES diff --git a/modular_citadel/code/datums/mood_events/generic_positive_events.dm b/modular_citadel/code/datums/mood_events/generic_positive_events.dm index 7b989d7700..ffa661e6e9 100644 --- a/modular_citadel/code/datums/mood_events/generic_positive_events.dm +++ b/modular_citadel/code/datums/mood_events/generic_positive_events.dm @@ -3,12 +3,12 @@ /datum/mood_event/headpat description = "Headpats are nice.\n" mood_change = 2 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/hugbox description = "I hugged a box of hugs recently.\n" mood_change = 1 - timeout = 1200 + timeout = 2 MINUTES /datum/mood_event/plushpet description = "I pet a plush recently.\n" diff --git a/modular_citadel/code/datums/mood_events/moodular.dm b/modular_citadel/code/datums/mood_events/moodular.dm index b53ce417e8..aa87f1b97a 100644 --- a/modular_citadel/code/datums/mood_events/moodular.dm +++ b/modular_citadel/code/datums/mood_events/moodular.dm @@ -3,9 +3,7 @@ // box of hugs /obj/item/storage/box/hug/attack_self(mob/user) . = ..() - GET_COMPONENT_FROM(mood, /datum/component/mood, user) - if(mood) - mood.add_event("hugbox", /datum/mood_event/hugbox) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"hugbox", /datum/mood_event/hugbox) //Removed headpats here, duplicate code? @@ -13,25 +11,17 @@ /obj/item/toy/plush/attack_self(mob/user) . = ..() if(stuffed || grenade) - GET_COMPONENT_FROM(mood, /datum/component/mood, user) - if(mood) - mood.add_event("plushpet", /datum/mood_event/plushpet) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushpet", /datum/mood_event/plushpet) else - GET_COMPONENT_FROM(mood, /datum/component/mood, user) - if(mood) - mood.add_event("plush_nostuffing", /datum/mood_event/plush_nostuffing) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plush_nostuffing", /datum/mood_event/plush_nostuffing) // Jack the Ripper starring plush /obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params) . = ..() if(I.is_sharp()) if(!grenade) - GET_COMPONENT_FROM(mood, /datum/component/mood, user) - if(mood) - mood.add_event("plushjack", /datum/mood_event/plushjack) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushjack", /datum/mood_event/plushjack) // plush playing (plush-on-plush action) if(istype(I, /obj/item/toy/plush)) - GET_COMPONENT_FROM(mood, /datum/component/mood, user) - if(mood) - mood.add_event("plushplay", /datum/mood_event/plushplay) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushplay", /datum/mood_event/plushplay) diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm new file mode 100644 index 0000000000..4bc83d2af6 --- /dev/null +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -0,0 +1,760 @@ +#define DICK_MOVEMENT_SPEED "hugedick" +#define BREAST_MOVEMENT_SPEED "megamilk" + +/datum/status_effect/chem/SGDF + id = "SGDF" + var/mob/living/fermi_Clone + var/mob/living/original + var/datum/mind/originalmind + var/status_set = FALSE + alert_type = null + +/datum/status_effect/chem/SGDF/on_apply() + log_game("FERMICHEM: SGDF status appied on [owner], ID: [owner.key]") + fermi_Clone = owner + return ..() + +/datum/status_effect/chem/SGDF/tick() + if(!status_set) + return ..() + if(original.stat == DEAD || original == null || !original) + if((fermi_Clone && fermi_Clone.stat != DEAD) || (fermi_Clone == null)) + if(originalmind) + owner.remove_status_effect(src) + ..() + +/datum/status_effect/chem/SGDF/on_remove(mob/living/carbon/M) + log_game("FERMICHEM: SGDF mind shift applied. [owner] is now playing as their clone and should not have memories after their clone split (look up SGDF status applied). ID: [owner.key]") + originalmind.transfer_to(fermi_Clone) + to_chat(owner, "Lucidity shoots to your previously blank mind as your mind suddenly finishes the cloning process. You marvel for a moment at yourself, as your mind subconciously recollects all your memories up until the point when you cloned yourself. curiously, you find that you memories are blank after you ingested the sythetic serum, leaving you to wonder where the other you is.") + to_chat(M, "Lucidity shoots to your previously blank mind as your mind suddenly finishes the cloning process. You marvel for a moment at yourself, as your mind subconciously recollects all your memories up until the point when you cloned yourself. curiously, you find that you memories are blank after you ingested the sythetic serum, leaving you to wonder where the other you is.") + fermi_Clone = null + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/status_effect/chem/breast_enlarger + id = "breast_enlarger" + alert_type = null + var/moveCalc = 1 + var/cachedmoveCalc = 1 + +/datum/status_effect/chem/breast_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now. + log_game("FERMICHEM: [owner]'s breasts has reached comical sizes. ID: [owner.key]") + var/mob/living/carbon/human/o = owner + var/items = o.get_contents() + for(var/obj/item/W in items) + if(W == o.w_uniform || W == o.wear_suit) + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!") + o.visible_message("[o]'s chest suddenly bursts forth, ripping their clothes off!'") + else + to_chat(o, "Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.") + return ..() + +/datum/status_effect/chem/breast_enlarger/tick(mob/living/carbon/human/H)//If you try to wear clothes, you fail. Slows you down if you're comically huge + var/mob/living/carbon/human/o = owner + var/obj/item/organ/genital/breasts/B = o.getorganslot("breasts") + moveCalc = 1+((round(B.cached_size) - 9)/3) //Afffects how fast you move, and how often you can click. + if(!B) + o.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED) + sizeMoveMod(1) + owner.remove_status_effect(src) + var/items = o.get_contents() + for(var/obj/item/W in items) + if(W == o.w_uniform || W == o.wear_suit) + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(owner, "Your enormous breasts are way too large to fit anything over them!") + if (B.size == "huge") + if(prob(1)) + to_chat(owner, "Your back is feeling sore.") + var/target = o.get_bodypart(BODY_ZONE_CHEST) + o.apply_damage(0.1, BRUTE, target) + if(!B.cached_size == B.breast_values[B.prev_size]) + o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + sizeMoveMod(moveCalc) + return ..() + else if (B.breast_values[B.size] > B.breast_values[B.prev_size]) + o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + sizeMoveMod(moveCalc) + else if (B.breast_values[B.size] < B.breast_values[B.prev_size]) + o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + sizeMoveMod(moveCalc) + if((B.cached_size) < 16) + switch(round(B.cached_size)) + if(9) + if (B.breast_values[B.prev_size] != B.breast_values[B.size]) + to_chat(o, "Your expansive chest has become a more managable size, liberating your movements.") + if(10 to INFINITY) + if (B.breast_values[B.prev_size] != B.breast_values[B.size]) + to_chat(H, "Your indulgent busom is so substantial, it's affecting your movements!") + if(prob(1)) + to_chat(owner, "Your back is feeling a little sore.") + ..() + +/datum/status_effect/chem/breast_enlarger/on_remove(mob/living/carbon/M) + log_game("FERMICHEM: [owner]'s breasts has reduced to an acceptable size. ID: [owner.key]") + owner.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED) + sizeMoveMod(1) + +/datum/status_effect/chem/breast_enlarger/proc/sizeMoveMod(var/value) + if(cachedmoveCalc == value) + return + owner.next_move_modifier /= cachedmoveCalc + owner.next_move_modifier *= value + cachedmoveCalc = value + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/status_effect/chem/penis_enlarger + id = "penis_enlarger" + alert_type = null + var/bloodCalc + var/moveCalc + +/datum/status_effect/chem/penis_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now. + log_game("FERMICHEM: [owner]'s dick has reached comical sizes. ID: [owner.key]") + var/mob/living/carbon/human/o = owner + var/items = o.get_contents() + if(o.w_uniform || o.wear_suit) + to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!") + owner.visible_message("[o]'s schlong suddenly bursts forth, ripping their clothes off!'") + else + to_chat(o, "Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it.") + for(var/obj/item/W in items) + if(W == o.w_uniform || W == o.wear_suit) + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + return ..() + + +/datum/status_effect/chem/penis_enlarger/tick(mob/living/carbon/M) + var/mob/living/carbon/human/o = owner + var/obj/item/organ/genital/penis/P = o.getorganslot("penis") + moveCalc = 1+((round(P.length) - 21)/3) //effects how fast you can move + bloodCalc = 1+((round(P.length) - 21)/15) //effects how much blood you need (I didn' bother adding an arousal check because I'm spending too much time on this organ already.) + if(!P) + o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED) + o.ResetBloodVol() + owner.remove_status_effect(src) + var/items = o.get_contents() + for(var/obj/item/W in items) + if(W == o.w_uniform || W == o.wear_suit) + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(owner, "Your enormous package is way to large to fit anything over!") + switch(round(P.cached_length)) + if(21) + to_chat(o, "Your rascally willy has become a more managable size, liberating your movements.") + o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED) + o.AdjustBloodVol(bloodCalc) + if(22 to INFINITY) + if(prob(2)) + to_chat(o, "Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements!") + o.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + o.AdjustBloodVol(bloodCalc) + ..() + +/datum/status_effect/chem/penis_enlarger/on_remove(mob/living/carbon/human/o) + log_game("FERMICHEM: [owner]'s dick has reduced to an acceptable size. ID: [owner.key]") + owner.remove_movespeed_modifier(DICK_MOVEMENT_SPEED) + owner.ResetBloodVol() + + +/*////////////////////////////////////////// + Mind control functions +/////////////////////////////////////////// +*/ + +//Preamble +/* +/mob/living + var/lewd = TRUE +*/ + +/mob/living/verb/toggle_lewd() + set category = "IC" + set name = "Toggle Lewdchem" + set desc = "Allows you to toggle if you'd like lewd flavour messages." + client.prefs.lewdchem = !(client.prefs.lewdchem) + to_chat(usr, "You [(client.prefs.lewdchem?"will":"no longer")] receive lewdchem messages.") + +/datum/status_effect/chem/enthrall + id = "enthrall" + alert_type = null + //examine_text TODO + var/enthrallTally = 1 //Keeps track of the enthralling process + var/resistanceTally = 0 //Keeps track of the resistance + var/deltaResist //The total resistance added per resist click + + var/phase = 1 //-1: resisted state, due to be removed.0: sleeper agent, no effects unless triggered 1: initial, 2: 2nd stage - more commands, 3rd: fully enthralled, 4th Mindbroken + + var/status = null //status effects + var/statusStrength = 0 //strength of status effect + + var/mob/living/master //Enchanter's person + var/enthrallID //Enchanter's ckey + var/enthrallGender //Use master or mistress + + var/mental_capacity //Higher it is, lower the cooldown on commands, capacity reduces with resistance. + var/datum/weakref/redirect_component //resistance + + var/distancelist = list(2,1.5,1,0.8,0.6,0.5,0.4,0.3,0.2) //Distance multipliers + + var/withdrawal = FALSE //withdrawl + var/withdrawalTick = 0 //counts how long withdrawl is going on for + + var/list/customTriggers = list() //the list of custom triggers + + var/cooldown = 0 //cooldown on commands + var/cooldownMsg = TRUE //If cooldown message has been sent + var/cTriggered = FALSE //If someone is triggered (so they can't trigger themselves with what they say for infinite loops) + var/resistGrowth = 0 //Resistance accrues over time + var/DistApart = 1 //Distance between master and owner + var/tranceTime = 0 //how long trance effects apply on trance status + + var/customEcho //Custom looping text in owner + var/customSpan //Custom spans for looping text + +/datum/status_effect/chem/enthrall/on_apply() + var/mob/living/carbon/M = owner + var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in M.reagents.reagent_list + if(!E) + message_admins("WARNING: FermiChem: No master found in thrall, did you bus in the status? You need to set up the vars manually in the chem if it's not reacted/bussed. Someone set up the reaction/status proc incorrectly if not (Don't use donor blood). Console them with a chemcat plush maybe?") + owner.remove_status_effect(src) + enthrallID = E.creatorID + enthrallGender = E.creatorGender + master = get_mob_by_key(enthrallID) + //if(M.ckey == enthrallID) + // owner.remove_status_effect(src)//At the moment, a user can enthrall themselves, toggle this back in if that should be removed. + redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) //Do resistance calc if resist is pressed# + RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/owner_hear) + var/obj/item/organ/brain/B = M.getorganslot(ORGAN_SLOT_BRAIN) //It's their brain! + mental_capacity = 500 - B.get_brain_damage() + var/mob/living/carbon/human/H = owner + if(H)//Prefs + if(!H.canbearoused) + H.client?.prefs.lewdchem = FALSE + var/message = "[(owner.client?.prefs.lewdchem?"I am a good pet for [enthrallGender].":"[master] is a really inspirational person!")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "enthrall", /datum/mood_event/enthrall, message) + to_chat(owner, "You feel inexplicably drawn towards [master], their words having a demonstrable effect on you. It seems the closer you are to them, the stronger the effect is. However you aren't fully swayed yet and can resist their effects by repeatedly resisting as much as you can!") + log_game("FERMICHEM: MKULTRA: Status applied on [owner] ckey: [owner.key] with a master of [master] ckey: [enthrallID].") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Enthrall attempts") + return ..() + +/datum/status_effect/chem/enthrall/tick() + var/mob/living/carbon/M = owner + + //chem calculations + if(!owner.reagents.has_reagent("enthrall") && !owner.reagents.has_reagent("enthrallTest")) + if (phase < 3 && phase != 0) + deltaResist += 3//If you've no chem, then you break out quickly + if(prob(5)) + to_chat(owner, "Your mind starts to restore some of it's clarity as you feel the effects of the drug wain.") + if (mental_capacity <= 500 || phase == 4) + if (owner.reagents.has_reagent("mannitol")) + mental_capacity += 5 + if (owner.reagents.has_reagent("neurine")) + mental_capacity += 10 + + //mindshield check + if(HAS_TRAIT(M, TRAIT_MINDSHIELD))//If you manage to enrapture a head, wow, GJ. (resisting gives a bigger bonus with a mindshield) From what I can tell, this isn't possible. + resistanceTally += 2 + if(prob(10)) + to_chat(owner, "You feel lucidity returning to your mind as the mindshield buzzes, attempting to return your brain to normal function.") + if(phase == 4) + mental_capacity += 5 + + //phase specific events + switch(phase) + if(-1)//fully removed + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "enthrall") + log_game("FERMICHEM: MKULTRA: Status REMOVED from [owner] ckey: [owner.key] with a master of [master] ckey: [enthrallID].") + owner.remove_status_effect(src) + return + if(0)// sleeper agent + if (cooldown > 0) + cooldown -= 1 + return + if(1)//Initial enthrallment + if (enthrallTally > 125) + phase += 1 + mental_capacity -= resistanceTally//leftover resistance per step is taken away from mental_capacity. + resistanceTally /= 2 + enthrallTally = 0 + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Enthralled to state 2") + if(owner.client?.prefs.lewdchem) + to_chat(owner, "Your conciousness slips, as you sink deeper into trance and servitude.") + else + to_chat(owner, "Your conciousness slips, as you feel more drawn to following [master].") + + else if (resistanceTally > 125) + phase = -1 + to_chat(owner, "You break free of the influence in your mind, your thoughts suddenly turning lucid!") + if(DistApart < 10) + to_chat(master, "[(master.client?.prefs.lewdchem?"Your pet":"Your thrall")] seems to have broken free of your enthrallment!
    ") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Thralls broken free") + owner.remove_status_effect(src) //If resisted in phase 1, effect is removed. + if(prob(10)) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "[pick("It feels so good to listen to [master].", "You can't keep your eyes off [master].", "[master]'s voice is making you feel so sleepy.", "You feel so comfortable with [master]", "[master] is so dominant, it feels right to obey them.")].") + if (2) //partially enthralled + if(enthrallTally > 200) + phase += 1 + mental_capacity -= resistanceTally//leftover resistance per step is taken away from mental_capacity. + enthrallTally = 0 + resistanceTally /= 2 + if(owner.client?.prefs.lewdchem) + to_chat(owner, "Your mind gives, eagerly obeying and serving [master].") + to_chat(owner, "You are now fully enthralled to [master], and eager to follow their commands. However you find that in your intoxicated state you are unable to resort to violence. Equally you are unable to commit suicide, even if ordered to, as you cannot serve your [enthrallGender] in death. ")//If people start using this as an excuse to be violent I'll just make them all pacifists so it's not OP. + else + to_chat(owner, "You are unable to put up a resistance any longer, and now are under the influence of [master]. However you find that in your intoxicated state you are unable to resort to violence. Equally you are unable to commit suicide, even if ordered to, as you cannot follow [master] in death. ") + to_chat(master, "Your [(master.client?.prefs.lewdchem?"pet":"follower")] [owner] appears to have fully fallen under your sway.") + log_game("FERMICHEM: MKULTRA: Status on [owner] ckey: [owner.key] has been fully entrhalled (state 3) with a master of [master] ckey: [enthrallID].") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "thralls fully enthralled.") + else if (resistanceTally > 200) + enthrallTally *= 0.5 + phase -= 1 + resistanceTally = 0 + resistGrowth = 0 + to_chat(owner, "You manage to shake some of the effects from your addled mind, however you can still feel yourself drawn towards [master].") + if(prob(10)) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "[pick("It feels so good to listen to [enthrallGender].", "You can't keep your eyes off [enthrallGender].", "[enthrallGender]'s voice is making you feel so sleepy.", "You feel so comfortable with [enthrallGender]", "[enthrallGender] is so dominant, it feels right to obey them.")].") + if (3)//fully entranced + if ((resistanceTally >= 200 && withdrawalTick >= 150) || (HAS_TRAIT(M, TRAIT_MINDSHIELD) && (resistanceTally >= 100))) + enthrallTally = 0 + phase -= 1 + resistanceTally = 0 + resistGrowth = 0 + to_chat(owner, "The separation from [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")] sparks a small flame of resistance in yourself, as your mind slowly starts to return to normal.") + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra") + if(prob(1)) + if(owner.client?.prefs.lewdchem && !customEcho) + to_chat(owner, "[pick("I belong to [enthrallGender].", "[enthrallGender] knows whats best for me.", "Obedence is pleasure.", "I exist to serve [enthrallGender].", "[enthrallGender] is so dominant, it feels right to obey them.")].") + if (4) //mindbroken + if (mental_capacity >= 499 && (owner.getBrainLoss() <=0 || HAS_TRAIT(M, TRAIT_MINDSHIELD)) && !owner.reagents.has_reagent("MKUltra")) + phase = 2 + mental_capacity = 500 + customTriggers = list() + to_chat(owner, "Your mind starts to heal, fixing the damage caused by the massive amounts of chem injected into your system earlier, returning clarity to your mind. Though, you still feel drawn towards [master]'s words...'") + M.slurring = 0 + M.confused = 0 + resistGrowth = 0 + else + if (cooldown > 0) + cooldown -= (0.8 + (mental_capacity/500)) + cooldownMsg = FALSE + else if (cooldownMsg == FALSE) + if(DistApart < 10) + if(master.client?.prefs.lewdchem) + to_chat(master, "Your pet [owner] appears to have finished internalising your last command.") + cooldownMsg = TRUE + else + to_chat(master, "Your thrall [owner] appears to have finished internalising your last command.") + cooldownMsg = TRUE + if(get_dist(master, owner) > 10) + if(prob(10)) + to_chat(owner, "You feel [(owner.client?.prefs.lewdchem?"a deep NEED to return to your [enthrallGender]":"like you have to return to [master]")].") + M.throw_at(get_step_towards(master,owner), 5, 1) + return//If you break the mind of someone, you can't use status effects on them. + + + //distance calculations + DistApart = get_dist(master, owner) + switch(DistApart) + if(0 to 8)//If the enchanter is within range, increase enthrallTally, remove withdrawal subproc and undo withdrawal effects. + if(phase <= 2) + enthrallTally += distancelist[get_dist(master, owner)+1] + if(withdrawalTick > 0) + withdrawalTick -= 1 + //calming effects + M.hallucination = max(0, M.hallucination - 5) + M.stuttering = max(0, M.stuttering - 5) + M.jitteriness = max(0, M.jitteriness - 5) + if(owner.getBrainLoss() >=20) + owner.adjustBrainLoss(-0.2) + if(withdrawal == TRUE) + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing4") + withdrawal = FALSE + if(9 to INFINITY)//If they're not nearby, enable withdrawl effects. + withdrawal = TRUE + + //Withdrawal subproc: + if (withdrawal == TRUE)//Your minions are really REALLY needy. + switch(withdrawalTick)//denial + if(5)//To reduce spam + to_chat(owner, "You are unable to complete [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")]'s orders without their presence, and any commands and objectives given to you prior are not in effect until you are back with them.") + ADD_TRAIT(owner, TRAIT_PACIFISM, "MKUltra") //IMPORTANT + if(10 to 35)//Gives wiggle room, so you're not SUPER needy + if(prob(5)) + to_chat(owner, "You're starting to miss [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")].") + if(prob(5)) + owner.adjustBrainLoss(0.1) + to_chat(owner, "[(owner.client?.prefs.lewdchem?"[enthrallGender]":"[master]")] will surely be back soon") //denial + if(36) + var/message = "[(owner.client?.prefs.lewdchem?"I feel empty when [enthrallGender]'s not around..":"I miss [master]'s presence")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing1", /datum/mood_event/enthrallmissing1, message) + if(37 to 65)//barganing + if(prob(10)) + to_chat(owner, "They are coming back, right...?") + owner.adjustBrainLoss(0.5) + if(prob(10)) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "I just need to be a good pet for [enthrallGender], they'll surely return if I'm a good pet.") + owner.adjustBrainLoss(-1.5) + if(66) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1") + var/message = "[(owner.client?.prefs.lewdchem?"I feel so lost in this complicated world without [enthrallGender]..":"I have to return to [master]!")]" + to_chat(owner, "You start to feel really angry about how you're not with [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")]!") + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing2", /datum/mood_event/enthrallmissing2, message) + owner.stuttering += 50 + owner.jitteriness += 250 + if(67 to 89) //anger + if(prob(10)) + addtimer(CALLBACK(M, /mob/verb/a_intent_change, INTENT_HARM), 2) + addtimer(CALLBACK(M, /mob/proc/click_random_mob), 2) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "You are overwhelmed with anger at the lack of [enthrallGender]'s presence and suddenly lash out!") + else + to_chat(owner, "You are overwhelmed with anger and suddenly lash out!") + if(90) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2") + var/message = "[(owner.client?.prefs.lewdchem?"Where are you [enthrallGender]??!":"I need to find [master]!")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing3", /datum/mood_event/enthrallmissing3, message) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "You need to find your [enthrallGender] at all costs, you can't hold yourself back anymore!") + else + to_chat(owner, "You need to find [master] at all costs, you can't hold yourself back anymore!") + if(91 to 100)//depression + if(prob(10)) + M.gain_trauma_type(BRAIN_TRAUMA_MILD) + owner.stuttering += 35 + owner.jitteriness += 35 + else if(prob(25)) + M.hallucination += 10 + if(101) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3") + var/message = "[(owner.client?.prefs.lewdchem?"I'm all alone, It's so hard to continute without [enthrallGender]...":"I really need to find [master]!!!")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing4", /datum/mood_event/enthrallmissing4, message) + to_chat(owner, "You can hardly find the strength to continue without [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")].") + M.gain_trauma_type(BRAIN_TRAUMA_SEVERE) + if(102 to 140) //depression 2, revengeance + if(prob(20)) + owner.Stun(50) + owner.emote("cry")//does this exist? + if(owner.client?.prefs.lewdchem) + to_chat(owner, "You're unable to hold back your tears, suddenly sobbing as the desire to see your [enthrallGender] oncemore overwhelms you.") + else + to_chat(owner, "You are overwheled with withdrawl from [master].") + owner.adjustBrainLoss(1) + owner.stuttering += 35 + owner.jitteriness += 35 + if(prob(10))//2% chance + switch(rand(1,5))//Now let's see what hopefully-not-important part of the brain we cut off + if(1 to 3) + M.gain_trauma_type(BRAIN_TRAUMA_MILD) + if(4) + M.gain_trauma_type(BRAIN_TRAUMA_SEVERE) + if(5)//0.4% chance + M.gain_trauma_type(BRAIN_TRAUMA_SPECIAL) + if(prob(5)) + deltaResist += 5 + if(140 to INFINITY) //acceptance + if(prob(15)) + deltaResist += 5 + owner.adjustBrainLoss(-1) + if(prob(20)) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "Maybe you'll be okay without your [enthrallGender].") + else + to_chat(owner, "You feel your mental functions slowly begin to return.") + if(prob(5)) + owner.adjustBrainLoss(1) + M.hallucination += 30 + + withdrawalTick += 0.5//Enough to leave you with a major brain trauma, but not kill you. + + //Status subproc - statuses given to you from your Master + //currently 3 statuses; antiresist -if you press resist, increases your enthrallment instead, HEAL - which slowly heals the pet, CHARGE - which breifly increases speed, PACIFY - makes pet a pacifist, ANTIRESIST - frustrates resist presses. + if (status) + + if(status == "Antiresist") + if (statusStrength < 0) + status = null + to_chat(owner, "Your mind feels able to resist oncemore.") + else + statusStrength -= 1 + + else if(status == "heal") + if (statusStrength < 0) + status = null + to_chat(owner, "You finish licking your wounds.") + else + statusStrength -= 1 + owner.heal_overall_damage(1, 1, 0, FALSE, FALSE) + cooldown += 1 //Cooldown doesn't process till status is done + + else if(status == "charge") + ADD_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra") + status = "charged" + if(master.client?.prefs.lewdchem) + to_chat(owner, "Your [enthrallGender]'s order fills you with a burst of speed!") + else + to_chat(owner, "[master]'s command fills you with a burst of speed!") + + else if (status == "charged") + if (statusStrength < 0) + status = null + REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra") + owner.Knockdown(50) + to_chat(owner, "Your body gives out as the adrenaline in your system runs out.") + else + statusStrength -= 1 + cooldown += 1 //Cooldown doesn't process till status is done + + else if (status == "pacify") + ADD_TRAIT(owner, TRAIT_PACIFISM, "MKUltraStatus") + status = null + + //Truth serum? + //adrenals? + + //customEcho + if(customEcho && withdrawal == FALSE && owner.client?.prefs.lewdchem) + if(prob(2)) + if(!customSpan) //just in case! + customSpan = "notice" + to_chat(owner, "[customEcho].") + + //final tidying + resistanceTally += deltaResist + deltaResist = 0 + if(cTriggered >= 0) + cTriggered -= 1 + if (cooldown > 0) + cooldown -= (0.8 + (mental_capacity/500)) + cooldownMsg = FALSE + else if (cooldownMsg == FALSE) + if(DistApart < 10) + if(master.client?.prefs.lewdchem) + to_chat(master, "Your pet [owner] appears to have finished internalising your last command.") + else + to_chat(master, "Your thrall [owner] appears to have finished internalising your last command.") + cooldownMsg = TRUE + cooldown = 0 + if (tranceTime > 0 && tranceTime != 51) //custom trances only last 50 ticks. + tranceTime -= 1 + else if (tranceTime == 0) //remove trance after. + M.cure_trauma_type(/datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY) + M.remove_status_effect(/datum/status_effect/trance) + tranceTime = 51 + //..() + +//Remove all stuff +/datum/status_effect/chem/enthrall/on_remove() + var/mob/living/carbon/M = owner + M.mind.remove_antag_datum(/datum/antagonist/brainwashed) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "enthrall") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "enthrallpraise") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "enthrallscold") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing4") + qdel(redirect_component.resolve()) + redirect_component = null + UnregisterSignal(owner, COMSIG_MOVABLE_HEAR) + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra") + to_chat(owner, "You're now free of [master]'s influence, and fully independent!'") + UnregisterSignal(owner, COMSIG_GLOB_LIVING_SAY_SPECIAL) + + +/datum/status_effect/chem/enthrall/proc/owner_hear(var/hearer, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + if(owner.client?.prefs.lewdchem == FALSE) + return + if (cTriggered > 0) + return + var/mob/living/carbon/C = owner + raw_message = lowertext(raw_message) + for (var/trigger in customTriggers) + var/cached_trigger = lowertext(trigger) + if (findtext(raw_message, cached_trigger))//if trigger1 is the message + cTriggered = 5 //Stops triggerparties and as a result, stops servercrashes. + log_game("FERMICHEM: MKULTRA: [owner] ckey: [owner.key] has been triggered with [cached_trigger] from [speaker] saying: \"[message]\". (their master being [master] ckey: [enthrallID].)") + + //Speak (Forces player to talk) + if (lowertext(customTriggers[trigger][1]) == "speak")//trigger2 + var/saytext = "Your mouth moves on it's own before you can even catch it." + if(HAS_TRAIT(C, TRAIT_NYMPHO)) + saytext += " You find yourself fully believing in the validity of what you just said and don't think to question it." + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "[saytext]"), 5) + addtimer(CALLBACK(C, /atom/movable/proc/say, "[customTriggers[trigger][2]]"), 5) + //(C.say(customTriggers[trigger][2]))//trigger3 + log_game("FERMICHEM: MKULTRA: [owner] ckey: [owner.key] has been forced to say: \"[customTriggers[trigger][2]]\" from previous trigger.") + + + //Echo (repeats message!) allows customisation, but won't display var calls! Defaults to hypnophrase. + else if (lowertext(customTriggers[trigger][1]) == "echo")//trigger2 + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "[customTriggers[trigger][2]]"), 5) + //(to_chat(owner, "[customTriggers[trigger][2]]"))//trigger3 + + //Shocking truth! + else if (lowertext(customTriggers[trigger]) == "shock") + if (C.canbearoused && C.client?.prefs.lewdchem) + C.adjustArousalLoss(5) + C.jitteriness += 100 + C.stuttering += 25 + C.Knockdown(60) + C.Stun(60) + to_chat(owner, "Your muscles seize up, then start spasming wildy!") + + //wah intensifies wah-rks + else if (lowertext(customTriggers[trigger]) == "cum")//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if (HAS_TRAIT(C, TRAIT_NYMPHO) && C.client?.prefs.lewdchem) + if (C.getArousalLoss() > 80) + C.mob_climax(forced_climax=TRUE) + C.SetStun(10)//We got your stun effects in somewhere, Kev. + else + C.adjustArousalLoss(10) + to_chat(C, "You feel a surge of arousal!") + else + C.throw_at(get_step_towards(speaker,C), 3, 1) //cut this if it's too hard to get working + + //kneel (knockdown) + else if (lowertext(customTriggers[trigger]) == "kneel")//as close to kneeling as you can get, I suppose. + to_chat(owner, "You drop to the ground unsurreptitiously.") + C.lay_down() + + //strip (some) clothes + else if (lowertext(customTriggers[trigger]) == "strip")//This wasn't meant to just be a lewd thing oops. + var/mob/living/carbon/human/o = owner + var/items = o.get_contents() + for(var/obj/item/W in items) + if(W == o.w_uniform || W == o.wear_suit) + o.dropItemToGround(W, TRUE) + to_chat(owner,"You feel compelled to strip your clothes.") + + //trance + else if (lowertext(customTriggers[trigger]) == "trance")//Maaaybe too strong. Weakened it, only lasts 50 ticks. + var/mob/living/carbon/human/o = owner + o.apply_status_effect(/datum/status_effect/trance, 200, TRUE) + tranceTime = 50 + log_game("FERMICHEM: MKULTRA: [owner] ckey: [owner.key] has been tranced from previous trigger.") + + return + +/datum/status_effect/chem/enthrall/proc/owner_resist() + var/mob/living/carbon/M = owner + to_chat(owner, "You attempt to fight against [master]'s influence!") + + //Able to resist checks + if (status == "Sleeper" || phase == 0) + return + else if (phase == 4) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "Your mind is too far gone to even entertain the thought of resisting. Unless you can fix the brain damage, you won't be able to break free of your [enthrallGender]'s control.") + else + to_chat(owner, "Your brain is too overwhelmed with from the high volume of chemicals in your system, rendering you unable to resist, unless you can fix the brain damage.") + return + else if (phase == 3 && withdrawal == FALSE) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "The presence of your [enthrallGender] fully captures the horizon of your mind, removing any thoughts of resistance. If you get split up from them, then you might be able to entertain the idea of resisting.") + else + to_chat(owner, "You are unable to resist [master] in your current state. If you get split up from them, then you might be able to resist.") + return + else if (status == "Antiresist")//If ordered to not resist; resisting while ordered to not makes it last longer, and increases the rate in which you are enthralled. + if (statusStrength > 0) + if(owner.client?.prefs.lewdchem) + to_chat(owner, "The order from your [enthrallGender] to give in is conflicting with your attempt to resist, drawing you deeper into trance! You'll have to wait a bit before attemping again, lest your attempts become frustrated again.") + else + to_chat(owner, "The order from your [master] to give in is conflicting with your attempt to resist. You'll have to wait a bit before attemping again, lest your attempts become frustrated again.") + statusStrength += 1 + enthrallTally += 1 + return + else + status = null + + //base resistance + if (deltaResist != 0)//So you can't spam it, you get one deltaResistance per tick. + deltaResist += 0.1 //Though I commend your spamming efforts. + return + else + deltaResist = 1.8 + resistGrowth + resistGrowth += 0.05 + + //distance modifer + switch(DistApart) + if(0) + deltaResist *= 0.8 + if(1 to 8)//If they're far away, increase resistance. + deltaResist *= (1+(DistApart/10)) + if(9 to INFINITY)//If + deltaResist *= 2 + + + if(prob(5)) + M.emote("me",1,"squints, shaking their head for a moment.")//shows that you're trying to resist sometimes + deltaResist *= 1.5 + //nymphomania + if (M.canbearoused && HAS_TRAIT(M, TRAIT_NYMPHO))//I'm okay with this being removed. + deltaResist*= 0.5-(((2/200)*M.arousalloss)/1)//more aroused you are, the weaker resistance you can give, the less you are, the more you gain. (+/- 0.5) + + //chemical resistance, brain and annaphros are the key to undoing, but the subject has to to be willing to resist. + if (owner.reagents.has_reagent("mannitol")) + deltaResist *= 1.25 + if (owner.reagents.has_reagent("neurine")) + deltaResist *= 1.5 + if (!HAS_TRAIT(owner, TRAIT_CROCRIN_IMMUNE) && M.canbearoused) + if (owner.reagents.has_reagent("anaphro")) + deltaResist *= 1.5 + if (owner.reagents.has_reagent("anaphro+")) + deltaResist *= 2 + if (owner.reagents.has_reagent("aphro")) + deltaResist *= 0.75 + if (owner.reagents.has_reagent("aphro+")) + deltaResist *= 0.5 + + //Antag resistance + //cultists are already brainwashed by their god + if(iscultist(owner)) + deltaResist *= 1.3 + else if (is_servant_of_ratvar(owner)) + deltaResist *= 1.3 + //antags should be able to resist, so they can do their other objectives. This chem does frustrate them, but they've all the tools to break free when an oportunity presents itself. + else if (owner.mind.assigned_role in GLOB.antagonists) + deltaResist *= 1.2 + + //role resistance + //Chaplains are already brainwashed by their god + if(owner.mind.assigned_role == "Chaplain") + deltaResist *= 1.2 + //Command staff has authority, + if(owner.mind.assigned_role in GLOB.command_positions) + deltaResist *= 1.1 + //Chemists should be familiar with drug effects + if(owner.mind.assigned_role == "Chemist") + deltaResist *= 1.2 + + //Happiness resistance + //Your Thralls are like pets, you need to keep them happy. + if(owner.nutrition < 300) + deltaResist += (300-owner.nutrition)/6 + if(owner.health < 100)//Harming your thrall will make them rebel harder. + deltaResist *= ((120-owner.health)/100)+1 + //if(owner.mood.mood) //datum/component/mood TO ADD in FERMICHEM 2 + //Add cold/hot, oxygen, sanity, happiness? (happiness might be moot, since the mood effects are so strong) + //Mental health could play a role too in the other direction + + //If you've a collar, you get a sense of pride + if(istype(M.wear_neck, /obj/item/clothing/neck/petcollar)) + deltaResist *= 0.5 + if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) + deltaResist += 5//even faster! + + return diff --git a/modular_citadel/code/datums/traits/negative.dm b/modular_citadel/code/datums/traits/negative.dm new file mode 100644 index 0000000000..c0cbe57b5a --- /dev/null +++ b/modular_citadel/code/datums/traits/negative.dm @@ -0,0 +1 @@ +// Citadel-specific Negative Traits diff --git a/modular_citadel/code/datums/traits/neutral.dm b/modular_citadel/code/datums/traits/neutral.dm index 05aeb27361..197c9b94e1 100644 --- a/modular_citadel/code/datums/traits/neutral.dm +++ b/modular_citadel/code/datums/traits/neutral.dm @@ -31,3 +31,13 @@ mob_trait = TRAIT_MASO gain_text = "You desire to be hurt." lose_text = "Pain has become less exciting for you." + +/datum/quirk/pharmacokinesis //Prevents unwanted organ additions. + name = "Acute hepatic pharmacokinesis" + desc = "You've a rare genetic disorder that causes Incubus draft and Sucubus milk to be absorbed by your liver instead." + value = 0 + mob_trait = TRAIT_PHARMA + lose_text = "Your liver feels different." + var/active = FALSE + var/power = 0 + var/cachedmoveCalc = 1 diff --git a/modular_citadel/code/game/gamemodes/gangs/dominator.dm b/modular_citadel/code/game/gamemodes/gangs/dominator.dm index 0d89c78010..5ad740ed2e 100644 --- a/modular_citadel/code/game/gamemodes/gangs/dominator.dm +++ b/modular_citadel/code/game/gamemodes/gangs/dominator.dm @@ -108,6 +108,7 @@ else Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending. gang.winner = TRUE + SSticker.news_report = GANG_VICTORY SSticker.force_ending = TRUE if(!.) diff --git a/modular_citadel/code/game/gamemodes/gangs/gang.dm b/modular_citadel/code/game/gamemodes/gangs/gang.dm index 00ce3f81a9..fa25701ac4 100644 --- a/modular_citadel/code/game/gamemodes/gangs/gang.dm +++ b/modular_citadel/code/game/gamemodes/gangs/gang.dm @@ -343,11 +343,12 @@ return "

    [report.Join("
    ")]
    " /datum/team/gang/proc/greet_gangster(datum/mind/gangster) //The text a person receives when recruited. - to_chat(gangster, "You are now a member of the [name] Gang!") - to_chat(gangster, "Help your bosses take over the station by claiming territory with spraycans. Simply spray on any unclaimed area of the station.") - to_chat(gangster, "You can also use recruitment pens to recruit more to your cause, If your boss provides you one.") - to_chat(gangster, "Their ultimate objective is to take over the station with a Dominator machine.") - to_chat(gangster, "You can identify your mates by their large, \[G\] icon.") + var/message = "You are now a member of the [name] Gang!" + message += "Help your bosses take over the station by claiming territory with spraycans. Simply spray on any unclaimed area of the station." + message += "You can also use recruitment pens to recruit more to your cause, If your boss provides you one." + message += "Their ultimate objective is to take over the station with a Dominator machine." + message += "You can identify your mates by their large, \[G\] icon." + to_chat(gangster, message) gangster.store_memory("You are a member of the [name] Gang!") /datum/team/gang/proc/handle_territories() diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm index 334d6bf423..1653b8d314 100644 --- a/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm +++ b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm @@ -64,7 +64,7 @@ name = "Cyber" color = "#00f904" //Cyber and waffle shared colors, I made these guys green and made weed darker green. inner_outfits = list(/obj/item/clothing/under/color/lightbrown) - outer_outfits = list(/obj/item/clothing/suit/nemes) + outer_outfits = list(/obj/item/clothing/suit/pharaoh) /datum/team/gang/donk name = "Donk" @@ -136,4 +136,4 @@ name = "Weed" color = "#6cd648" inner_outfits = list(/obj/item/clothing/under/color/darkgreen) - outer_outfits = list(/obj/item/clothing/suit/vapeshirt) \ No newline at end of file + outer_outfits = list(/obj/item/clothing/suit/vapeshirt) diff --git a/modular_citadel/code/game/machinery/plasmacases.dm b/modular_citadel/code/game/machinery/plasmacases.dm index ac3621b58a..c45eb48caa 100644 --- a/modular_citadel/code/game/machinery/plasmacases.dm +++ b/modular_citadel/code/game/machinery/plasmacases.dm @@ -19,5 +19,6 @@ return MouseDrop(user) /obj/structure/guncase/plasma/emag_act() - to_chat(usr, "The locking mechanism is fitted with old style parts, The card has no effect.") - return \ No newline at end of file + . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) + if(!.) + to_chat(usr, "The locking mechanism is fitted with old style parts, The card has no effect.") \ No newline at end of file diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm index bdca91b0e6..2de98a3171 100755 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -1,7 +1,3 @@ -/obj/machinery/vending/security - contraband = list(/obj/item/clothing/glasses/sunglasses = 2, /obj/item/storage/fancy/donut_box = 2, /obj/item/ssword_kit = 1) - premium = list(/obj/item/coin/antagtoken = 1, /obj/item/ssword_kit = 1) - /obj/machinery/vending/medical products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, @@ -26,12 +22,13 @@ /obj/item/storage/hypospraykit/toxin = 2, /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, + /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5) - + /obj/machinery/vending/wardrobe/chap_wardrobe premium = list(/obj/item/toy/plush/plushvar = 1, /obj/item/toy/plush/narplush = 1) - + #define STANDARD_CHARGE 1 #define CONTRABAND_CHARGE 2 #define COIN_CHARGE 3 diff --git a/modular_citadel/code/game/machinery/wishgranter.dm b/modular_citadel/code/game/machinery/wishgranter.dm index f7c2c57d08..f24062a126 100644 --- a/modular_citadel/code/game/machinery/wishgranter.dm +++ b/modular_citadel/code/game/machinery/wishgranter.dm @@ -95,7 +95,7 @@ killwish.grasp_range = 6 killwish.melee_damage_upper = 30 killwish.grasp_chance = 50 - killwish.loot = list(/obj/item/twohanded/hypereutactic) + killwish.loot = list(/obj/item/twohanded/dualsaber/hypereutactic) charges-- insisting = FALSE if(!charges) diff --git a/modular_citadel/code/game/objects/ids.dm b/modular_citadel/code/game/objects/ids.dm index 89a3c0f0c2..8ef724581e 100644 --- a/modular_citadel/code/game/objects/ids.dm +++ b/modular_citadel/code/game/objects/ids.dm @@ -49,7 +49,7 @@ /obj/item/emagrecharge name = "electromagnet charging device" - desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices." + desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell." icon = 'icons/obj/module.dmi' icon_state = "cell_mini" item_flags = NOBLUDGEON @@ -63,7 +63,7 @@ to_chat(user, "It has a small, red, blinking light coming from inside of it. It's spent.") /obj/item/card/emag - var/uses = 10 + var/uses = 15 /obj/item/card/emag/examine(mob/user) . = ..() diff --git a/modular_citadel/code/game/objects/items.dm b/modular_citadel/code/game/objects/items.dm index 337db986b0..c94923f9de 100644 --- a/modular_citadel/code/game/objects/items.dm +++ b/modular_citadel/code/game/objects/items.dm @@ -1,6 +1,4 @@ /obj/item - var/total_mass //Total mass in arbitrary pound-like values. If there's no balance reasons for an item to have otherwise, this var should be the item's weight in pounds. - var/list/alternate_screams = list() //REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE // lazy for screaming. diff --git a/modular_citadel/code/game/objects/items/handcuffs.dm b/modular_citadel/code/game/objects/items/handcuffs.dm deleted file mode 100644 index ed5e8a191e..0000000000 --- a/modular_citadel/code/game/objects/items/handcuffs.dm +++ /dev/null @@ -1,5 +0,0 @@ -/obj/item/restraints/handcuffs/fake/kinky - name = "kinky handcuffs" - desc = "Fake handcuffs meant for erotic roleplay." - icon = 'modular_citadel/icons/obj/items_and_weapons.dmi' - icon_state = "handcuffgag" diff --git a/modular_citadel/code/game/objects/items/holy_weapons.dm b/modular_citadel/code/game/objects/items/holy_weapons.dm index 3ecc6cc31b..06cdb0f5fd 100644 --- a/modular_citadel/code/game/objects/items/holy_weapons.dm +++ b/modular_citadel/code/game/objects/items/holy_weapons.dm @@ -30,24 +30,16 @@ "You kneel[M == user ? null : " next to [M]"] and begin a prayer to [deity_name].") praying = TRUE - if(do_after(user, 100, target = M)) + if(do_after(user, 20, target = M)) if(istype(M, /mob/living/carbon/human)) // This probably should not work on catpeople. They're unholy abominations. var/mob/living/carbon/human/target = M - - if(iscultist(M) || is_servant_of_ratvar(M)) //ripped from holywater code. - if(iscultist(M)) - SSticker.mode.remove_cultist(M.mind, FALSE, TRUE) - else if(is_servant_of_ratvar(M)) - remove_servant_of_ratvar(M) - + M.reagents.add_reagent("holywater", 5) to_chat(target, "[user]'s prayer to [deity_name] has eased your pain!") target.adjustToxLoss(-5, TRUE, TRUE) target.adjustOxyLoss(-5) target.adjustBruteLoss(-5) target.adjustFireLoss(-5) - praying = FALSE - else to_chat(user, "Your prayer to [deity_name] was interrupted.") praying = FALSE diff --git a/modular_citadel/code/game/objects/items/melee/energy.dm b/modular_citadel/code/game/objects/items/melee/energy.dm deleted file mode 100644 index c37f88eacf..0000000000 --- a/modular_citadel/code/game/objects/items/melee/energy.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj/item/melee/transforming/energy/sword - total_mass = 0.375 //Survival flashlights typically weigh around 5 ounces. - total_mass_on = 3.4 //The typical medieval sword, on the other hand, weighs roughly 3 pounds. diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index ce6aada0fc..4cf1d326a2 100644 --- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -119,26 +119,17 @@ /obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/melee/transforming/energy/sword/cx)) - if((W.item_flags & NODROP) || (item_flags & NODROP)) - to_chat(user, "\the [item_flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [item_flags & NODROP ? W : src]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool.") - new /obj/item/twohanded/hypereutactic(user.drop_location()) + new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location()) qdel(W) qdel(src) else return ..() -/obj/item/melee/transforming/energy/sword/cx/chaplain - name = "divine lightblade" - force_on = 20 //haha i'll regret this - block_chance = 50 - -/obj/item/melee/transforming/energy/sword/cx/chaplain/Initialize() - . = ..() - AddComponent(/datum/component/anti_magic, TRUE, TRUE) - //OBLIGATORY TOY MEMES ///////////////////////////////////// /obj/item/toy/sword/cx @@ -228,12 +219,12 @@ /obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/toy/sword/cx)) - if((W.item_flags & NODROP) || (item_flags & NODROP)) - to_chat(user, "\the [item_flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [item_flags & NODROP ? W : src]!") + if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP)) + to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!") return else to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") - new /obj/item/twohanded/hypereutactic/toy(user.loc) + new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc) qdel(W) qdel(src) else @@ -247,7 +238,7 @@ // HYPEREUTACTIC Blades ///////////////////////// ///////////////////////////////////////////////////// -/obj/item/twohanded/hypereutactic +/obj/item/twohanded/dualsaber/hypereutactic icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi' icon_state = "hypereutactic" lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi' @@ -258,58 +249,44 @@ name = "hypereutactic blade" desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter." force = 7 - throwforce = 5 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - var/w_class_on = WEIGHT_CLASS_BULKY force_unwielded = 7 force_wielded = 40 wieldsound = 'sound/weapons/nebon.ogg' unwieldsound = 'sound/weapons/neboff.ogg' - hitsound = "swing_hit" + hitsound_on = 'sound/weapons/nebhit.ogg' + slowdown_wielded = 1 armour_penetration = 60 light_color = "#37FFF7" + rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00") attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded") - block_chance = 75 - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) - resistance_flags = FIRE_PROOF - var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD - item_flags = SLOWS_WHILE_IN_HAND + spinnable = FALSE + total_mass_on = 4 -/obj/item/twohanded/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes +/obj/item/twohanded/dualsaber/hypereutactic/chaplain + name = "\improper divine lightblade" + desc = "A giant blade of bright and holy light, said to cut down the wicked with ease." + force = 5 + force_unwielded = 5 + force_wielded = 20 + block_chance = 50 + armour_penetration = 0 + var/chaplain_spawnable = TRUE + obj_flags = UNIQUE_RENAME + +/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + +/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes altafterattack(A, user, TRUE, params) return TRUE -/obj/item/twohanded/hypereutactic/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes +/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes if(istype(user)) user.visible_message("[user] points the tip of [src] at [target].", "You point the tip of [src] at [target].") return TRUE -/obj/item/twohanded/hypereutactic/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. - if(M.has_dna()) - if(M.dna.check_mutation(HULK)) - to_chat(M, "You lack the grace to wield this!") - return - ..() - if(wielded) - sharpness = IS_SHARP - w_class = w_class_on - hitsound = 'sound/weapons/nebhit.ogg' - START_PROCESSING(SSobj, src) - set_light(brightness_on) - -/obj/item/twohanded/hypereutactic/unwield() //Specific unwield () to switch hitsounds. - sharpness = initial(sharpness) - w_class = initial(w_class) - ..() - hitsound = "swing_hit" - STOP_PROCESSING(SSobj, src) - set_light(0) - slowdown = initial(slowdown) - -/obj/item/twohanded/hypereutactic/update_icon() +/obj/item/twohanded/dualsaber/hypereutactic/update_icon() var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade") var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem") @@ -329,21 +306,21 @@ SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) -/obj/item/twohanded/hypereutactic/AltClick(mob/living/user) - if(!in_range(src, user)) //Basic checks to prevent abuse +/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user) + if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked) return if(user.incapacitated() || !istype(user)) to_chat(user, "You can't do that right now!") return - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked) + return + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) update_icon() update_light() -/obj/item/twohanded/hypereutactic/worn_overlays(isinhands, icon_file) +/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file) . = ..() if(isinhands) var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem") @@ -354,70 +331,19 @@ blade_inhand.color = light_color . += blade_inhand -/obj/item/twohanded/hypereutactic/examine(mob/user) +/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user) ..() - to_chat(user, "Alt-click to recolor it.") + if(!hacked) + to_chat(user, "Alt-click to recolor it.") -////////// stuff beneath this is all taken from the desword //////////// wow very professional such OOP wow - -/obj/item/twohanded/hypereutactic/attack(mob/target, mob/living/carbon/human/user) - if(user.has_dna()) - if(user.dna.check_mutation(HULK)) - to_chat(user, "You grip the blade too hard and accidentally close it!") - unwield() - return - ..() - if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40)) - impale(user) - return - -/obj/item/twohanded/hypereutactic/Destroy() - STOP_PROCESSING(SSobj, src) +/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process() . = ..() - -/obj/item/twohanded/hypereutactic/proc/impale(mob/living/user) - to_chat(user, "You spin around a bit before losing your balance and impaling yourself on [src].") - if (force_wielded) - user.take_bodypart_damage(20,25) - else - user.adjustStaminaLoss(25) - -/obj/item/twohanded/hypereutactic/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(wielded) - return ..() - return FALSE - -/obj/item/twohanded/hypereutactic/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up - if(wielded) - to_chat(user, "You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!") - return TRUE - -/obj/item/twohanded/hypereutactic/process() - if(wielded) - open_flame() - else - STOP_PROCESSING(SSobj, src) - -/obj/item/twohanded/hypereutactic/IsReflect() - if(wielded) - return TRUE - -/obj/item/twohanded/hypereutactic/ignition_effect(atom/A, mob/user) - // same as /obj/item/melee/transforming/energy, mostly - if(!wielded) - return "" - var/in_mouth = "" - if(iscarbon(user)) - var/mob/living/carbon/C = user - if(C.wear_mask == src) - in_mouth = ", barely missing their nose" - . = "[user] swings [user.p_their()] [src][in_mouth]. [user.p_they()] light[user.p_s()] [A] in the process." - playsound(loc, hitsound, get_clamped_volume(), 1, -1) - add_fingerprint(user) + update_icon() + update_light() ////////////////// TOY VERSION ///////////////////////////// -/obj/item/twohanded/hypereutactic/toy +/obj/item/twohanded/dualsaber/hypereutactic/toy name = "\improper DX Hyper-Euplastic LightSword" desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up." force = 0 @@ -427,11 +353,13 @@ force_unwielded = 0 force_wielded = 0 attack_verb = list("attacked", "struck", "hit") + total_mass_on = TOTAL_MASS_TOY_SWORD + slowdown_wielded = 0 -/obj/item/twohanded/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) return FALSE -/obj/item/twohanded/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles +/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles return FALSE //////// Tatortot NEB /////////////// (same stats as regular esword) @@ -455,17 +383,7 @@ //RAINBOW MEMES -/obj/item/twohanded/hypereutactic/toy/rainbow +/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander" desc = "A custom-built toy with fancy rainbow lights built-in." - var/list/rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00") - -/obj/item/twohanded/hypereutactic/toy/rainbow/process() - . = ..() - var/set_color = pick(rainbow_colors) - light_color = set_color - update_light() - update_icon() - -/obj/item/twohanded/hypereutactic/toy/rainbow/AltClick(mob/living/user) - return + hacked = TRUE diff --git a/modular_citadel/code/game/objects/items/melee/misc.dm b/modular_citadel/code/game/objects/items/melee/misc.dm index 6a53adcc1f..48c221696e 100644 --- a/modular_citadel/code/game/objects/items/melee/misc.dm +++ b/modular_citadel/code/game/objects/items/melee/misc.dm @@ -4,7 +4,7 @@ var/hardstun_ds = 1 var/softstun_ds = 0 var/stam_dmg = 30 - cooldown = 20 + cooldown = 0 total_mass = 3.75 /obj/item/melee/classic_baton/attack(mob/living/target, mob/living/user) diff --git a/modular_citadel/code/game/objects/items/melee/transforming.dm b/modular_citadel/code/game/objects/items/melee/transforming.dm deleted file mode 100644 index 46610f4e54..0000000000 --- a/modular_citadel/code/game/objects/items/melee/transforming.dm +++ /dev/null @@ -1,15 +0,0 @@ -/obj/item/melee/transforming - var/total_mass_on //Total mass in ounces when transformed. Primarily for balance purposes. Don't think about it too hard. - -/obj/item/melee/transforming/getweight() - if(total_mass && total_mass_on) - if(active) - return max(total_mass_on,MIN_MELEE_STAMCOST) - else - return max(total_mass,MIN_MELEE_STAMCOST) - else - return initial(w_class)*1.25 - -/obj/item/melee/transforming/cleaving_saw - total_mass = 2.75 - total_mass_on = 5 diff --git a/modular_citadel/code/game/objects/items/storage/firstaid.dm b/modular_citadel/code/game/objects/items/storage/firstaid.dm index 6ff1bfbe2c..125330a9b9 100755 --- a/modular_citadel/code/game/objects/items/storage/firstaid.dm +++ b/modular_citadel/code/game/objects/items/storage/firstaid.dm @@ -103,6 +103,22 @@ new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin(src) new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin(src) +/obj/item/storage/hypospraykit/enlarge + name = "organomegaly trauma hypospray kit" + icon_state = "enlarge-mini" + item_state = "firstaid-brute" + +/obj/item/storage/hypospraykit/enlarge/PopulateContents() + if(empty) + return + new /obj/item/hypospray/mkii/enlarge(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src) + /obj/item/storage/hypospraykit/brute name = "brute trauma hypospray kit" icon_state = "brute-mini" diff --git a/modular_citadel/code/game/objects/items/stunsword.dm b/modular_citadel/code/game/objects/items/stunsword.dm index 1262b0018a..7a5398f7d2 100644 --- a/modular_citadel/code/game/objects/items/stunsword.dm +++ b/modular_citadel/code/game/objects/items/stunsword.dm @@ -7,6 +7,14 @@ lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' +/obj/item/melee/baton/stunsword/get_belt_overlay() + if(istype(loc, /obj/item/storage/belt/sabre)) + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "stunsword") + return ..() + +/obj/item/melee/baton/stunsword/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "-stunsword") + /obj/item/ssword_kit name = "stunsword kit" desc = "a modkit for making a stunbaton into a stunsword" diff --git a/modular_citadel/code/init.dm b/modular_citadel/code/init.dm index 2c2b5b811f..ce80580af2 100644 --- a/modular_citadel/code/init.dm +++ b/modular_citadel/code/init.dm @@ -22,4 +22,4 @@ GLOB.cock_shapes_icons[K] = value.icon_state init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + //GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. This is defined twice? diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm index deb3de589e..501e0fa25a 100644 --- a/modular_citadel/code/modules/admin/chat_commands.dm +++ b/modular_citadel/code/modules/admin/chat_commands.dm @@ -4,7 +4,7 @@ /datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Jecca Qua","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" + var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]" if(prob(10)) saltresult += "@here for your salt, all day every day" @@ -20,3 +20,20 @@ /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/arousal/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm index 1223f0b616..3df2218766 100644 --- a/modular_citadel/code/modules/arousal/organs/breasts.dm +++ b/modular_citadel/code/modules/arousal/organs/breasts.dm @@ -5,20 +5,22 @@ icon = 'modular_citadel/icons/obj/genitals/breasts.dmi' zone = "chest" slot = "breasts" - size = BREASTS_SIZE_DEF + w_class = 3 + size = BREASTS_SIZE_DEF //SHOULD BE A LETTER, starts as a number...??? + var/cached_size = null //for enlargement SHOULD BE A NUMBER + var/prev_size //For flavour texts SHOULD BE A LETTER + //var/breast_sizes = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "huge", "flat") + var/breast_values = list ("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0) + var/statuscheck = FALSE fluid_id = "milk" var/amount = 2 producing = TRUE - shape = "pair" + shape = "Pair" can_masturbate_with = TRUE masturbation_verb = "massage" can_climax = TRUE fluid_transfer_factor = 0.5 -/obj/item/organ/genital/breasts/Initialize() - . = ..() - reagents.add_reagent(fluid_id, fluid_max_volume) - /obj/item/organ/genital/breasts/on_life() if(QDELETED(src)) return @@ -26,6 +28,14 @@ return reagents.maximum_volume = fluid_max_volume if(fluid_id && producing) + if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank. + fluid_rate = 0.1 + else + fluid_rate = CUM_RATE + if(reagents.total_volume >= 5) + fluid_mult = 0.5 + else + fluid_mult = 1 generate_milk() /obj/item/organ/genital/breasts/proc/generate_milk() @@ -45,10 +55,15 @@ desc = "You see three sets of breasts, running from their chest to their belly." else desc = "You see some breasts, they seem to be quite exotic." - if (size) - desc += " You estimate that they're [uppertext(size)]-cups." - else - desc += " You wouldn't measure them in cup sizes." + if(cached_size > 16) + desc = "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(cached_size)]cm in diameter." + else if (!isnum(size)) + if (size == "flat") + desc += " They're very small and flatchested, however." + else + desc += " You estimate that they're [uppertext(size)]-cups." + //string = "breasts_[lowertext(shape)]_[size]-s" + if(producing && aroused_state) desc += " They're leaking [fluid_id]." var/string @@ -65,3 +80,57 @@ var/mob/living/carbon/human/H = owner icon_state = sanitize_text(string) H.update_genitals() + + icon_state = sanitize_text(string) + + +//Allows breasts to grow and change size, with sprite changes too. +//maximum wah +//Comical sizes slow you down in movement and actions. +//Rediculous sizes makes you more cumbersome. +//this is far too lewd wah + +/obj/item/organ/genital/breasts/update_size()//wah + + if(!ishuman(owner) || !owner) + return + if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed + to_chat(owner, "You feel your breasts shrinking away from your body as your chest flattens out.") + src.Remove(owner) + switch(round(cached_size)) + if(0) //If flatchested + size = "flat" + if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger)) + owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger) + statuscheck = FALSE + if(1 to 8) //If modest size + size = breast_values[round(cached_size)] + if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger)) + owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger) + statuscheck = FALSE + if(9 to 15) //If massive + size = breast_values[round(cached_size)] + if(!owner.has_status_effect(/datum/status_effect/chem/breast_enlarger)) + owner.apply_status_effect(/datum/status_effect/chem/breast_enlarger) + statuscheck = TRUE + if(16 to INFINITY) //if Rediculous + size = cached_size + + if(round(cached_size) < 16)//Because byond doesn't count from 0, I have to do this. + if (prev_size == 0) + prev_size = "flat" + if(size == 0)//Bloody byond with it's counting from 1 + size = "flat" + if(isnum(prev_size)) + prev_size = breast_values[prev_size] + if (breast_values[size] > breast_values[prev_size]) + to_chat(owner, "Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.") + var/mob/living/carbon/human/H = owner + H.Force_update_genitals() + else if ((breast_values[size] < breast_values[prev_size]) && (breast_values[size] > 0.5)) + to_chat(owner, "Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.") + var/mob/living/carbon/human/H = owner + H.Force_update_genitals() + prev_size = size + else if (cached_size >= 16) + size = "huge" diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm index 63d6834409..3abe7ecb1f 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals.dm @@ -1,7 +1,7 @@ /obj/item/organ/genital color = "#fcccb3" w_class = WEIGHT_CLASS_NORMAL - var/shape = "human" + var/shape = "Human" //Changed to be uppercase, let me know if this breaks everything..!! var/sensitivity = AROUSAL_START_VALUE var/list/genital_flags = list() var/can_masturbate_with = FALSE @@ -10,7 +10,7 @@ var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this? var/size = 2 //can vary between num or text, just used in icon_state strings var/fluid_id = null - var/fluid_max_volume = 50 + var/fluid_max_volume = 15 var/fluid_efficiency = 1 var/fluid_rate = 1 var/fluid_mult = 1 @@ -172,6 +172,8 @@ P.length = dna.features["cock_length"] P.girth_ratio = dna.features["cock_girth_ratio"] P.shape = dna.features["cock_shape"] + P.prev_length = P.length + P.cached_length = P.length P.update() /mob/living/carbon/human/proc/give_balls() @@ -214,8 +216,21 @@ else B.color = "#[dna.features["breasts_color"]]" B.size = dna.features["breasts_size"] + if(!isnum(B.size)) + if(B.size == "flat") + B.cached_size = 0 + B.prev_size = 0 + else if (B.cached_size == "huge") + B.prev_size = "huge" + else + B.cached_size = B.breast_values[B.size] + B.prev_size = B.size + else + B.cached_size = B.size + B.prev_size = B.size B.shape = dna.features["breasts_shape"] B.fluid_id = dna.features["breasts_fluid"] + B.producing = dna.features["breasts_producing"] B.update() @@ -256,8 +271,8 @@ switch(layer) if(GENITALS_BEHIND_LAYER) return "BEHIND" - if(GENITALS_ADJ_LAYER) - return "ADJ" + /*if(GENITALS_ADJ_LAYER) + return "ADJ"*/ if(GENITALS_FRONT_LAYER) return "FRONT" @@ -279,27 +294,65 @@ if(src && !QDELETED(src)) dna.species.handle_genitals(src) -/datum/species/proc/handle_genitals(mob/living/carbon/human/H) +//fermichem procs +/mob/living/carbon/human/proc/Force_update_genitals(mob/living/carbon/human/H) //called in fermiChem + dna.species.handle_genitals(src)//should work. + //dna.species.handle_breasts(src) + +//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours. +/mob/living/carbon/human/proc/emergent_genital_call() + var/organCheck = FALSE + var/breastCheck = FALSE + var/willyCheck = FALSE + if(!canbearoused) + ADD_TRAIT(src, TRAIT_PHARMA, "pharma")//Prefs prevent unwanted organs. + return + for(var/obj/item/organ/O in internal_organs) + if(istype(O, /obj/item/organ/genital)) + organCheck = TRUE + if(/obj/item/organ/genital/penis) + //dna.features["has_cock"] = TRUE + willyCheck = TRUE + if(/obj/item/organ/genital/breasts) + //dna.features["has_breasts"] = TRUE//Goddamnit get in there. + breastCheck = TRUE + if(organCheck == FALSE) + if(ishuman(src) && dna.species.id == "human") + dna.features["genitals_use_skintone"] = TRUE + dna.species.use_skintones = TRUE + if(MUTCOLORS) + if(src.dna.species.fixed_mut_color) + dna.features["cock_color"] = "[src.dna.species.fixed_mut_color]" + dna.features["breasts_color"] = "[src.dna.species.fixed_mut_color]" + return + //So people who haven't set stuff up don't get rainbow surprises. + dna.features["cock_color"] = "[dna.features["mcolor"]]" + dna.features["breasts_color"] = "[dna.features["mcolor"]]" + else //If there's a new organ, make it the same colour. + if(breastCheck == FALSE) + dna.features["breasts_color"] = dna.features["cock_color"] + else if (willyCheck == FALSE) + dna.features["cock_color"] = dna.features["breasts_color"] + return + +/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness if(!H)//no args CRASH("H = null") if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done return - if(NOGENITALS in species_traits)//golems and such + if((NOGENITALS in species_traits) && (H.genital_override = FALSE))//golems and such - things that shouldn't return if(HAS_TRAIT(H, TRAIT_HUSK)) return - var/list/genitals_to_add = list() - var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER) + var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER) //GENITALS_ADJ_LAYER removed var/list/standing = list() var/size var/aroused_state for(var/L in relevant_layers) //Less hardcode H.remove_overlay(L) - //start scanning for genitals - //var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again for(var/obj/item/organ/O in H.internal_organs) if(isgenital(O)) var/obj/item/organ/genital/G = O @@ -308,7 +361,6 @@ if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes genitals_to_add += H.getorganslot(G.slot) //Now we added all genitals that aren't internal and should be rendered - //start applying overlays for(var/layer in relevant_layers) var/layertext = genitals_layertext(layer) @@ -326,6 +378,9 @@ if(/obj/item/organ/genital/breasts) S = GLOB.breasts_shapes_list[G.shape] + + + if(!S || S.icon_state == "none") continue diff --git a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm index b913a90fb6..f4af8a40ba 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm @@ -31,6 +31,19 @@ icon_state = "tapered" name = "Tapered" +/datum/sprite_accessory/penis/tentacle + icon_state = "tentacle" + name = "Tentacled" + +/datum/sprite_accessory/penis/hemi + icon_state = "hemi" + name = "Hemi" + +/datum/sprite_accessory/penis/hemiknot + icon_state = "hemiknot" + name = "Knotted Hemi" + + //////////////////////// // Taur cocks go here // //////////////////////// @@ -111,6 +124,10 @@ icon_state = "furred" name = "Furred" +/datum/sprite_accessory/vagina/gaping + icon_state = "gaping" + name = "Gaping" + //BREASTS BE HERE /datum/sprite_accessory/breasts icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi' diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm index b6cb8fa4b2..43a512acf6 100644 --- a/modular_citadel/code/modules/arousal/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -12,28 +12,61 @@ size = 2 //arbitrary value derived from length and girth for sprites. var/length = 6 //inches var/cached_length //used to detect a change in length - var/girth = 0 + var/girth = 4.38 var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF var/list/dickflags = list() var/list/knotted_types = list("knotted", "barbed, knotted") + var/prev_length = 6 //really should be renamed to prev_length + +/obj/item/organ/genital/penis/Initialize() + . = ..() + /* I hate genitals.*/ /obj/item/organ/genital/penis/update_size() - if(length == cached_length) + var/mob/living/carbon/human/o = owner + if(!ishuman(o) || !o) return - switch(length) - if(-INFINITY to 5) + if(cached_length < 0)//I don't actually know what round() does to negative numbers, so to be safe!! + var/obj/item/organ/genital/penis/P = o.getorganslot("penis") + to_chat(o, "You feel your tallywacker shrinking away from your body as your groin flattens out!") + P.Remove(o) + switch(round(cached_length)) + if(0 to 4) //If modest size + length = cached_length size = 1 - if(5 to 9) + if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) + o.remove_status_effect(/datum/status_effect/chem/penis_enlarger) + if(5 to 10) //If modest size + length = cached_length size = 2 - if(15 to INFINITY) - size = 3//no new sprites for anything larger yet -/* if(9 to 15) + if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) + o.remove_status_effect(/datum/status_effect/chem/penis_enlarger) + if(11 to 20) //If massive + length = cached_length size = 3 - if(15 to INFINITY) - size = 3*/ - girth = (length * girth_ratio) - cached_length = length + if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) + o.remove_status_effect(/datum/status_effect/chem/penis_enlarger) + if(21 to 35) //If massive and due for large effects + length = cached_length + size = 3 + if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) + o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) + if(36 to INFINITY) //If comical + length = cached_length + size = 4 //no new sprites for anything larger yet + if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) + o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) + + if (round(length) > round(prev_length)) + to_chat(o, "Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.") + else if ((round(length) < round(prev_length)) && (length > 0.5)) + to_chat(o, "Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.") + prev_length = length + icon_state = sanitize_text("penis_[shape]_[size]") + girth = (length * girth_ratio)//Is it just me or is this ludicous, why not make it exponentially decay? + + //I have no idea on how to update sprites and I hate it /obj/item/organ/genital/penis/update_appearance() var/string diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm index 1e6b4d62d4..f4ef4b5064 100644 --- a/modular_citadel/code/modules/arousal/organs/testicles.dm +++ b/modular_citadel/code/modules/arousal/organs/testicles.dm @@ -16,14 +16,18 @@ can_climax = TRUE var/sent_full_message = TRUE //defaults to 1 since they're full to start -/obj/item/organ/genital/testicles/Initialize() - . = ..() - reagents.add_reagent(fluid_id, fluid_max_volume) - /obj/item/organ/genital/testicles/on_life() if(QDELETED(src)) return if(reagents && producing) + if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank. + fluid_rate = 0.1 + else + fluid_rate = CUM_RATE + if(reagents.total_volume >= 5) + fluid_mult = 0.5 + else + fluid_mult = 1 generate_cum() /obj/item/organ/genital/testicles/proc/generate_cum() diff --git a/modular_citadel/code/modules/arousal/organs/womb.dm b/modular_citadel/code/modules/arousal/organs/womb.dm index 686d9059a0..3f190b72ac 100644 --- a/modular_citadel/code/modules/arousal/organs/womb.dm +++ b/modular_citadel/code/modules/arousal/organs/womb.dm @@ -9,14 +9,18 @@ fluid_id = "femcum" producing = TRUE -/obj/item/organ/genital/womb/Initialize() - . = ..() - reagents.add_reagent(fluid_id, fluid_max_volume) - /obj/item/organ/genital/womb/on_life() if(QDELETED(src)) return if(reagents && producing) + if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank. + fluid_rate = 0.1 + else + fluid_rate = CUM_RATE + if(reagents.total_volume >= 5) + fluid_mult = 0.5 + else + fluid_mult = 1 generate_femcum() /obj/item/organ/genital/womb/proc/generate_femcum() diff --git a/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm b/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm index f6991f1d9f..ccbf9a42fe 100644 --- a/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm +++ b/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm @@ -49,7 +49,7 @@ /datum/outfit/lavaknight/captain name ="Cydonian Knight Captain" - l_pocket = /obj/item/twohanded/hypereutactic + l_pocket = /obj/item/twohanded/dualsaber/hypereutactic /datum/outfit/lavaknight/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) if(visualsOnly) diff --git a/modular_citadel/code/modules/cargo/console.dm b/modular_citadel/code/modules/cargo/console.dm index 490f72d1d1..f54a6c577a 100644 --- a/modular_citadel/code/modules/cargo/console.dm +++ b/modular_citadel/code/modules/cargo/console.dm @@ -1,13 +1,9 @@ /obj/machinery/computer/cargo req_access = list(ACCESS_CARGO) - + /obj/machinery/computer/cargo/request req_access = list() -/obj/machinery/computer/cargo/emag_act(mob/user) - req_access = list() - . = ..() - /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) if(!allowed(usr)) to_chat(usr, "Access denied.") diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 347f1fffea..cc75e1bff9 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -220,13 +220,13 @@ /datum/gear/torisword name = "Rainbow Zweihander" category = SLOT_IN_BACKPACK - path = /obj/item/twohanded/hypereutactic/toy/rainbow + path = /obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow ckeywhitelist = list("annoymous35") /datum/gear/darksabre name = "Dark Sabre" category = SLOT_IN_BACKPACK - path = /obj/item/toy/sword/darksabre + path = /obj/item/toy/darksabre ckeywhitelist = list("inferno707") datum/gear/darksabresheath @@ -407,8 +407,8 @@ datum/gear/darksabresheath /datum/gear/mw2_russian_para name = "Russian Paratrooper Jumper" - category = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/mw2_russian_para + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/mw2_russian_para ckeywhitelist = list("investigator77") /datum/gear/longblackgloves @@ -435,3 +435,16 @@ datum/gear/darksabresheath path = /obj/item/bedsheet/captain ckeywhitelist = list("tikibomb") +/datum/gear/borgplush + name = "Robot Plush" + category = SLOT_IN_BACKPACK + path = /obj/item/toy/plush/borgplushie + ckeywhitelist = list("nicholaiavenicci") + +/datum/gear/donorberet + name = "Atmos Beret" + category = SLOT_HEAD + path = /obj/item/clothing/head/blueberet + ckeywhitelist = list("foxystalin") + + diff --git a/modular_citadel/code/modules/client/loadout/loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm similarity index 79% rename from modular_citadel/code/modules/client/loadout/loadout.dm rename to modular_citadel/code/modules/client/loadout/_loadout.dm index 2e11519d0b..d48da1b863 100644 --- a/modular_citadel/code/modules/client/loadout/loadout.dm +++ b/modular_citadel/code/modules/client/loadout/_loadout.dm @@ -50,12 +50,32 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) var/path //item-to-spawn path var/cost = 1 //normally, each loadout costs a single point. var/geargroupID //defines the ID that the gear inherits from the config + + //NEW DONATOR SYTSEM STUFF + var/donoritem //autoset on new if null + var/donator_group_id //New donator group ID system. + //END + var/list/restricted_roles + + //Old donator system/snowflake ckey whitelist, used for single ckeys/exceptions var/list/ckeywhitelist + //END + var/restricted_desc /datum/gear/New() - ..() + if(isnull(donoritem)) + if(donator_group_id || ckeywhitelist) + donoritem = TRUE if(!description && path) var/obj/O = path description = initial(O.desc) + +//a comprehensive donator check proc is intentionally not implemented due to the fact that we (((might))) have job-whitelists for donator items in the future and I like to stay on the safe side. + +//ckey only check +/datum/gear/proc/donator_ckey_check(key) + if(ckeywhitelist && ckeywhitelist.Find(key)) + return TRUE + return IS_CKEY_DONATOR_GROUP(key, donator_group_id) diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index bb12fc8ac9..c2713b49be 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -79,8 +79,24 @@ path = /obj/item/toy/katana cost = 3 -//datum/gear/lumeyes -// name = "Luminescent eye auto surgeon" -// category = SLOT_IN_BACKPACK -// path = /obj/item/autosurgeon/gloweyes -// cost = 4 +/datum/gear/box + name = "Spare box" + category = SLOT_IN_BACKPACK + path = /obj/item/storage/box + cost = 2 + +/datum/gear/crowbar + name = "Pocket Crowbar" + category = SLOT_IN_BACKPACK + path = /obj/item/crowbar + cost = 2 + +/datum/gear/tapeplayer + name = "Taperecorder" + category = SLOT_IN_BACKPACK + path = /obj/item/taperecorder + +/datum/gear/tape + name = "Spare cassette tape" + category = SLOT_IN_BACKPACK + path = /obj/item/tape/random \ No newline at end of file diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm index dfe419964e..1caa4cfed7 100644 --- a/modular_citadel/code/modules/client/preferences.dm +++ b/modular_citadel/code/modules/client/preferences.dm @@ -15,6 +15,7 @@ var/arousable = TRUE var/widescreenpref = TRUE var/autostand = TRUE + var/lewdchem = TRUE //vore prefs var/toggleeatingnoise = TRUE @@ -53,5 +54,6 @@ datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates = 1) character.give_genitals(TRUE) character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially character.canbearoused = arousable + character.client?.prefs.lewdchem = lewdchem if(icon_updates) character.update_genitals() diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index 2921f70684..0a353e3f5d 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -65,6 +65,7 @@ WRITE_FILE(S["feature_breasts_shape"], features["breasts_shape"]) WRITE_FILE(S["feature_breasts_color"], features["breasts_color"]) WRITE_FILE(S["feature_breasts_fluid"], features["breasts_fluid"]) + WRITE_FILE(S["feature_breasts_producing"], features["breasts_producing"]) //vagina features WRITE_FILE(S["feature_has_vag"], features["has_vag"]) WRITE_FILE(S["feature_vag_shape"], features["vag_shape"]) diff --git a/modular_citadel/code/modules/clothing/under/trek_under.dm b/modular_citadel/code/modules/clothing/under/trek_under.dm index 8e2b94372d..a60f7653c5 100644 --- a/modular_citadel/code/modules/clothing/under/trek_under.dm +++ b/modular_citadel/code/modules/clothing/under/trek_under.dm @@ -5,7 +5,8 @@ *////////////////////////////////////////////////////////////////////////////////// // <3 Nienhaus && Joan. // I made the Voy and DS9 stuff tho. - Poojy - +// Armor lists for even Heads of Staff is Nulled out do round start armor as well most armor going onto the suit itself rather then a armor slot - Trilby +/////////////////////////////////////////////////////////////////////////////////// /obj/item/clothing/under/rank/trek @@ -22,7 +23,7 @@ desc = "The uniform worn by command officers in the mid 2260s." icon_state = "trek_command" item_state = "trek_command" - armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 10, "rad" = 10, "fire" = 0, "acid" = 0) // Considering only staff heads get to pick it + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/under/rank/trek/engsec name = "Operations Uniform" @@ -104,7 +105,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/suit/storage/trek/ds9/admiral // Only for adminuz name = "Admiral Overcoat" @@ -135,7 +136,6 @@ /obj/item/clothing/suit/storage/fluff/fedcoat name = "Federation Uniform Jacket" desc = "A uniform jacket from the United Federation. Set phasers to awesome." - icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi' icon_state = "fedcoat" @@ -160,7 +160,7 @@ /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/taperecorder) - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) var/unbuttoned = 0 verb/toggle() @@ -214,7 +214,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) //Variants /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci @@ -231,6 +231,7 @@ /obj/item/clothing/head/caphat/formal/fedcover name = "Federation Officer's Cap" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) desc = "An officer's cap that demands discipline from the one who wears it." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' icon_state = "fedcapofficer" diff --git a/modular_citadel/code/modules/clothing/under/turtlenecks.dm b/modular_citadel/code/modules/clothing/under/turtlenecks.dm index f4e1ba8bd9..fd13da11e9 100644 --- a/modular_citadel/code/modules/clothing/under/turtlenecks.dm +++ b/modular_citadel/code/modules/clothing/under/turtlenecks.dm @@ -43,8 +43,8 @@ icon_state = "bb_turtle" item_state = "w_suit" item_color = "bb_turtle" - body_parts_covered = CHEST|ARMS - can_adjust = 1 + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = TRUE icon = 'modular_citadel/icons/obj/clothing/turtlenecks.dmi' alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' mutantrace_variation = NO_MUTANTRACE_VARIATION diff --git a/modular_citadel/code/modules/clothing/under/under.dm b/modular_citadel/code/modules/clothing/under/under.dm index 1796df01be..dcc6323f62 100644 --- a/modular_citadel/code/modules/clothing/under/under.dm +++ b/modular_citadel/code/modules/clothing/under/under.dm @@ -5,26 +5,6 @@ *////////////////////////////////////////////////////////////////////////////////// -/obj/item/clothing/under/rank/security/skirt - name = "security skirt" - desc = "A tactical security skirt for officers complete with Nanotrasen belt buckle." - icon = 'modular_citadel/icons/obj/clothing/cit_clothes.dmi' - icon_state = "secskirt" - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - item_state = "r_suit" - item_color = "secskirt" - body_parts_covered = CHEST|GROIN|ARMS - -/obj/item/clothing/under/rank/head_of_security/skirt - name = "head of security's skirt" - desc = "A security skirt decorated for those few with the dedication to achieve the position of Head of Security." - icon = 'modular_citadel/icons/obj/clothing/cit_clothes.dmi' - icon_state = "hosskirt" - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - item_state = "gy_suit" - item_color = "hosskirt" - body_parts_covered = CHEST|GROIN|ARMS - /obj/item/clothing/under/corporateuniform name = "corporate uniform" desc = "A comfortable, tight fitting jumpsuit made of premium materials. Not space-proof." diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index 4fd628f9d3..42363e9e07 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -49,7 +49,7 @@ item_color = "steele" medaltype = "medal-silver" -/obj/item/toy/sword/darksabre +/obj/item/toy/darksabre name = "Kiara's Sabre" desc = "This blade looks as dangerous as its owner." icon = 'icons/obj/custom.dmi' @@ -58,9 +58,13 @@ item_state = "darksabre" lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' - w_class = WEIGHT_CLASS_SMALL attack_verb = list("attacked", "struck", "hit") +/obj/item/toy/darksabre/get_belt_overlay() + return mutable_appearance('icons/obj/custom.dmi', "darksheath-darksabre") + +/obj/item/toy/darksabre/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "darksheath-darksabre") /obj/item/storage/belt/sabre/darksabre name = "Ornate Sheathe" @@ -69,32 +73,8 @@ alternate_worn_icon = 'icons/mob/custom_w.dmi' icon_state = "darksheath" item_state = "darksheath" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/belt/sabre/darksabre/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.max_items = 1 - STR.rustle_sound = FALSE - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.can_hold = typecacheof(list( - /obj/item/toy/sword/darksabre - )) - -/obj/item/storage/belt/sabre/darksabre/update_icon() - icon_state = "darksheath" - item_state = "darksheath" - if(contents.len) - icon_state += "-darksabre" - item_state += "-darksabre" - if(loc && isliving(loc)) - var/mob/living/L = loc - L.regenerate_icons() - ..() - -/obj/item/storage/belt/sabre/darksabre/PopulateContents() - new /obj/item/toy/sword/darksabre(src) - update_icon() + fitting_swords = list(/obj/item/toy/darksabre) + starting_sword = /obj/item/toy/darksabre /obj/item/clothing/suit/armor/vest/darkcarapace name = "Dark Armor" @@ -342,31 +322,6 @@ name = "worn pet collar" desc = "a pet collar that looks well used." -/obj/item/clothing/neck/petcollar/naomi/examine(mob/user) - . = ..() - if(usr.ckey != "technicalmagi") - to_chat(user, "There's something odd about the it. You probably shouldn't wear it...")//warn people not to wear it if they're not Naomi, lest they become as crazy as she is - -/obj/item/clothing/neck/petcollar/naomi/equipped() - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/clothing/neck/petcollar/naomi/dropped() - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/clothing/neck/petcollar/naomi/process() - var/mob/living/carbon/human/H - if(ishuman(loc)) - H = loc - if(!H) - return - else if(H.get_item_by_slot(SLOT_NECK) == src) - if(H.arousalloss < H.max_arousal / 3) - H.arousalloss = H.max_arousal / 3 - if(prob(5) && H.hallucination < 15) - H.hallucination += 10 - /obj/item/clothing/neck/cloak/green name = "Generic Green Cloak" desc = "This cloak doesn't seem too special." @@ -503,7 +458,7 @@ alternate_worn_icon = 'icons/mob/custom_w.dmi' mutantrace_variation = NO_MUTANTRACE_VARIATION -/obj/item/clothing/suit/mw2_russian_para +/obj/item/clothing/under/mw2_russian_para name = "Russian Paratrooper Jumper" desc = "A Russian made old paratrooper jumpsuit, has many pockets for easy storage of gear from a by gone era. As bulky as it looks, its shockingly light!" icon_state = "mw2_russian_para" @@ -527,4 +482,12 @@ item_state = "trendy_fit" icon = 'icons/obj/custom.dmi' alternate_worn_icon = 'icons/mob/custom_w.dmi' - mutantrace_variation = NO_MUTANTRACE_VARIATION \ No newline at end of file + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/head/blueberet + name = "Atmos Beret" + desc = "A fitted beret designed to be worn by Atmos Techs." + icon_state = "blueberet" + item_state = "blueberet" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' diff --git a/modular_citadel/code/modules/jobs/job_types/captain.dm b/modular_citadel/code/modules/jobs/job_types/captain.dm index 674cd9d09e..7135e86507 100644 --- a/modular_citadel/code/modules/jobs/job_types/captain.dm +++ b/modular_citadel/code/modules/jobs/job_types/captain.dm @@ -4,7 +4,6 @@ /datum/job/hop minimal_player_age = 20 - head_announce = list("Service") exp_type_department = EXP_TYPE_SERVICE access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS, diff --git a/modular_citadel/code/modules/mentor/mentorpm.dm b/modular_citadel/code/modules/mentor/mentorpm.dm index 34ace6f002..4c9a4766ec 100644 --- a/modular_citadel/code/modules/mentor/mentorpm.dm +++ b/modular_citadel/code/modules/mentor/mentorpm.dm @@ -3,7 +3,7 @@ set category = "Mentor" set name = "Mentor PM" if(!is_mentor()) - to_chat(src, "Error: Mentor-PM-Panel: Only Mentors and Admins may use this command.") + to_chat(src, "Error: Mentor-PM-Panel: Only Mentors and Admins may use this command.") return var/list/client/targets[0] for(var/client/T) @@ -27,24 +27,24 @@ else if(istype(whom,/client)) C = whom if(!C) - if(is_mentor()) to_chat(src, "Error: Mentor-PM: Client not found.") + if(is_mentor()) to_chat(src, "Error: Mentor-PM: Client not found.") else mentorhelp(msg) //Mentor we are replying to left. Mentorhelp instead(check below) return if(is_mentor(whom)) - to_chat(GLOB.admins | GLOB.mentors, "[src] has started replying to [whom]'s mhelp.") + to_chat(GLOB.admins | GLOB.mentors, "[src] has started replying to [whom]'s mhelp.") //get message text, limit it's length.and clean/escape html if(!msg) msg = input(src,"Message:", "Private message") as text|null - + if(!msg && is_mentor(whom)) - to_chat(GLOB.admins | GLOB.mentors, "[src] has stopped their reply to [whom]'s mhelp.") + to_chat(GLOB.admins | GLOB.mentors, "[src] has stopped their reply to [whom]'s mhelp.") return if(!C) if(is_mentor()) - to_chat(src, "Error: Mentor-PM: Client not found.") + to_chat(src, "Error: Mentor-PM: Client not found.") else mentorhelp(msg) //Mentor we are replying to has vanished, Mentorhelp instead (how the fuck does this work?let's hope it works,shrug) return @@ -54,8 +54,8 @@ return msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) - if(!msg && is_mentor(whom)) - to_chat(GLOB.admins | GLOB.mentors, "[src] has stopped their reply to [whom]'s mhelp.") + if(!msg && is_mentor(whom)) + to_chat(GLOB.admins | GLOB.mentors, "[src] has stopped their reply to [whom]'s mhelp.") return log_mentor("Mentor PM: [key_name(src)]->[key_name(C)]: [msg]") @@ -65,21 +65,21 @@ var/show_char = CONFIG_GET(flag/mentors_mobname_only) if(C.is_mentor()) if(is_mentor())//both are mentors - to_chat(C, "Mentor PM from-[key_name_mentor(src, C, 1, 0, 0)]: [msg]") - to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]") + to_chat(C, "Mentor PM from-[key_name_mentor(src, C, 1, 0, 0)]: [msg]") + to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]
    ") - else //recipient is an mentor but sender is not - to_chat(C, "Reply PM from-[key_name_mentor(src, C, 1, 0, show_char)]: [msg]") - to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]") + else //recipient is a mentor but sender is not + to_chat(C, "Reply PM from-[key_name_mentor(src, C, 1, 0, show_char)]: [msg]") + to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]") else - if(is_mentor()) //sender is an mentor but recipient is not. - to_chat(C, "Mentor PM from-[key_name_mentor(src, C, 1, 0, 0)]: [msg]") - to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, show_char)]: [msg]") + if(is_mentor()) //sender is a mentor but recipient is not. + to_chat(C, "Mentor PM from-[key_name_mentor(src, C, 1, 0, 0)]: [msg]") + to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, show_char)]: [msg]") //we don't use message_Mentors here because the sender/receiver might get it too var/show_char_sender = !is_mentor() && CONFIG_GET(flag/mentors_mobname_only) var/show_char_recip = !C.is_mentor() && CONFIG_GET(flag/mentors_mobname_only) for(var/client/X in GLOB.mentors | GLOB.admins) if(X.key!=key && X.key!=C.key) //check client/X is an Mentor and isn't the sender or recipient - to_chat(X, "Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]->[key_name_mentor(C, X, 0, 0, show_char_recip)]: [msg]") //inform X + to_chat(X, "Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]->[key_name_mentor(C, X, 0, 0, show_char_recip)]: [msg]") //inform X diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index aff1739ae4..a34b7b0526 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -185,22 +185,6 @@ emote_type = EMOTE_AUDIBLE restraint_check = TRUE - - -/datum/emote/living/dab/run_emote(mob/living/user, params) - if (ishuman(user)) - var/def_zone = BODY_ZONE_CHEST - var/luck = (rand(1,100)) - if(luck >= 65) - user.adjustStaminaLoss(70) - if(luck >= 80) - def_zone = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) - user.apply_damage(20, BRUTE, def_zone) - if(luck >= 95) - user.adjustBrainLoss(100) - . = ..() - - /datum/emote/living/mothsqueak key = "msqueak" key_third_person = "lets out a tiny squeak" diff --git a/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm b/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm index c2c581d282..7264d95bae 100644 --- a/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm +++ b/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm @@ -18,3 +18,21 @@ if(recoveringstam && amount > 20) incomingstammult = max(0.01, incomingstammult/(amount*0.05)) return amount + +/mob/living/carbon/doSprintLossTiles(tiles) + doSprintBufferRegen(FALSE) //first regen. + if(sprint_buffer) + var/use = min(tiles, sprint_buffer) + sprint_buffer -= use + tiles -= use + update_hud_sprint_bar() + if(!tiles) //we had enough, we're done! + return + adjustStaminaLoss(tiles * sprint_stamina_cost) //use stamina to cover deficit. + +/mob/living/carbon/proc/doSprintBufferRegen(updating = TRUE) + var/diff = world.time - sprint_buffer_regen_last + sprint_buffer_regen_last = world.time + sprint_buffer = min(sprint_buffer_max, sprint_buffer + sprint_buffer_regen_ds * diff) + if(updating) + update_hud_sprint_bar() diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human.dm b/modular_citadel/code/modules/mob/living/carbon/human/human.dm index 70bac64825..bb8d4a5f4a 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human.dm @@ -13,18 +13,19 @@ /mob/living/carbon/human/species/xeno race = /datum/species/xeno -/mob/living/carbon/human/resist() - . = ..() - if(wear_suit && wear_suit.breakouttime)//added in human cuff breakout proc +/mob/living/proc/resist_embedded() + return + +/mob/living/carbon/human/resist_embedded() + if(handcuffed || legcuffed || (wear_suit && wear_suit.breakouttime)) return - if(.) - if(canmove && !on_fire) - for(var/obj/item/bodypart/L in bodyparts) - if(istype(L) && L.embedded_objects.len) - for(var/obj/item/I in L.embedded_objects) - if(istype(I) && I.w_class >= WEIGHT_CLASS_NORMAL) //minimum weight class to insta-ripout via resist - remove_embedded_unsafe(L, I, src, 1.5) //forcefully call the remove embedded unsafe proc but with extra pain multiplier. if you want to remove it less painfully, examine and remove it carefully. - return FALSE //Hands are occupied + if(canmove && !on_fire) + for(var/obj/item/bodypart/L in bodyparts) + if(istype(L) && L.embedded_objects.len) + for(var/obj/item/I in L.embedded_objects) + if(istype(I) && I.w_class >= WEIGHT_CLASS_NORMAL) //minimum weight class to insta-ripout via resist + remove_embedded_unsafe(L, I, src, 1.5) //forcefully call the remove embedded unsafe proc but with extra pain multiplier. if you want to remove it less painfully, examine and remove it carefully. + return TRUE //Hands are occupied return /mob/living/carbon/human/proc/remove_embedded_unsafe(obj/item/bodypart/L, obj/item/I, mob/user, painmul = 1) diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm index 2a1c790b2a..409864c900 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm @@ -5,7 +5,7 @@ var/oldpseudoheight = pseudo_z_axis . = ..() if(. && sprinting && !(movement_type & FLYING) && canmove && !resting && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby) - adjustStaminaLossBuffered(0.3) + doSprintLossTiles(1) if((oldpseudoheight - pseudo_z_axis) >= 8) to_chat(src, "You trip off of the elevated surface!") for(var/obj/item/I in held_items) diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species.dm b/modular_citadel/code/modules/mob/living/carbon/human/species.dm index fcc60fbe81..1c7456a8d8 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species.dm @@ -80,10 +80,23 @@ else target.Move(target_shove_turf, shove_dir) if(get_turf(target) == target_oldturf) - target_table = locate(/obj/structure/table) in target_shove_turf.contents - shove_blocked = TRUE + if(target_shove_turf.density) + shove_blocked = TRUE + else + var/thoushallnotpass = FALSE + for(var/obj/O in target_shove_turf) + if(istype(O, /obj/structure/table)) + target_table = O + else if(!O.CanPass(src, target_shove_turf)) + shove_blocked = TRUE + thoushallnotpass = TRUE + if(thoushallnotpass) + target_table = null - if(shove_blocked && !target.is_shove_knockdown_blocked()) + if(target.is_shove_knockdown_blocked()) + return + + if(shove_blocked || target_table) var/directional_blocked = FALSE if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that var/target_turf = get_turf(target) diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm index bbbe863ec2..25b8daf2cb 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -11,6 +11,7 @@ mutant_bodyparts = list("ipc_screen", "ipc_antenna") default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None") meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc + mutanttongue = /obj/item/organ/tongue/robot/ipc exotic_blood = "oil" @@ -27,9 +28,6 @@ screen.Remove(C) ..() -/datum/species/ipc/get_spans() - return SPAN_ROBOT - /datum/action/innate/monitor_change name = "Screen Change" check_flags = AB_CHECK_CONSCIOUS diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index b4eec5786a..c18303ad84 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -15,7 +15,6 @@ say_mod = "says" hair_color = "mutcolor" hair_alpha = 160 //a notch brighter so it blends better. - liked_food = MEAT coldmod = 3 heatmod = 1 burnmod = 1 @@ -69,7 +68,7 @@ /datum/action/innate/slime_change/proc/change_form() var/mob/living/carbon/human/H = owner - var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Cancel") + var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") if(select_alteration == "Hair Style") if(H.gender == MALE) var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list @@ -114,7 +113,7 @@ O.Remove(H) organ.forceMove(get_turf(H)) qdel(organ) - H.update_body() + H.update_genitals() else if (select_alteration == "Ears") var/list/snowflake_ears_list = list("Normal" = null) @@ -194,5 +193,65 @@ if(new_taur != "None") H.dna.features["mam_tail"] = "None" H.update_body() + + else if (select_alteration == "Penis") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list + if(new_shape) + H.dna.features["cock_shape"] = new_shape + H.update_genitals() + H.give_balls() + H.give_penis() + H.apply_overlay() + + + else if (select_alteration == "Vagina") + for(var/obj/item/organ/genital/vagina/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list + if(new_shape) + H.dna.features["vag_shape"] = new_shape + H.update_genitals() + H.give_womb() + H.give_vagina() + H.apply_overlay() + + else if (select_alteration == "Penis Length") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_length + new_length = input(owner, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Genital Alteration") as num|null + if(new_length) + H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) + H.update_genitals() + H.apply_overlay() + H.give_balls() + H.give_penis() + + else if (select_alteration == "Breast Size") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_size + new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in GLOB.breasts_size_list + if(new_size) + H.dna.features["breasts_size"] = new_size + H.update_genitals() + H.apply_overlay() + H.give_breasts() + + else if (select_alteration == "Breast Shape") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Breast Shape", "Genital Alteration") as null|anything in GLOB.breasts_shapes_list + if(new_shape) + H.dna.features["breasts_shape"] = new_shape + H.update_genitals() + H.apply_overlay() + H.give_breasts() + else return diff --git a/modular_citadel/code/modules/mob/living/carbon/life.dm b/modular_citadel/code/modules/mob/living/carbon/life.dm new file mode 100644 index 0000000000..e94bd75985 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/life.dm @@ -0,0 +1,3 @@ +/mob/living/carbon/Life() + . = ..() + doSprintBufferRegen() diff --git a/modular_citadel/code/modules/mob/living/damage_procs.dm b/modular_citadel/code/modules/mob/living/damage_procs.dm index 8323386eff..ce81c7aae7 100644 --- a/modular_citadel/code/modules/mob/living/damage_procs.dm +++ b/modular_citadel/code/modules/mob/living/damage_procs.dm @@ -1,2 +1,5 @@ /mob/living/proc/adjustStaminaLossBuffered(amount, updating_stamina = TRUE, forced = FALSE) return + +/mob/living/proc/doSprintLossTiles(amount) + return diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm index b07b8ed64b..ac79ea7f25 100644 --- a/modular_citadel/code/modules/mob/living/living.dm +++ b/modular_citadel/code/modules/mob/living/living.dm @@ -8,6 +8,14 @@ var/intentionalresting = FALSE var/attemptingcrawl = FALSE + //Sprint buffer--- + var/sprint_buffer = 42 //Tiles + var/sprint_buffer_max = 42 + var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond + var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math. + var/sprint_stamina_cost = 0.55 //stamina loss per tile while insufficient sprint buffer. + //---End + /mob/living/movement_delay(ignorewalk = 0) . = ..() if(resting) @@ -118,3 +126,7 @@ filters -= CIT_FILTER_STAMINACRIT update_canmove() update_health_hud() + +/mob/living/proc/update_hud_sprint_bar() + if(hud_used && hud_used.sprint_buffer) + hud_used.sprint_buffer.update_to_mob(src) diff --git a/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm b/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm new file mode 100644 index 0000000000..b1e112aac5 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm @@ -0,0 +1,633 @@ +// List is required to compile the resources into the game when it loads. +// Dynamically loading it has bad results with sounds overtaking each other, even with the wait variable. +#ifdef AI_VOX + +GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'modular_citadel/sound/vox/_comma.ogg', +"." = 'modular_citadel/sound/vox/_period.ogg', +"a" = 'modular_citadel/sound/vox/a.ogg', +"accelerating" = 'modular_citadel/sound/vox/accelerating.ogg', +"accelerator" = 'modular_citadel/sound/vox/accelerator.ogg', +"accepted" = 'modular_citadel/sound/vox/accepted.ogg', +"access" = 'modular_citadel/sound/vox/access.ogg', +"acknowledge" = 'modular_citadel/sound/vox/acknowledge.ogg', +"acknowledged" = 'modular_citadel/sound/vox/acknowledged.ogg', +"acquired" = 'modular_citadel/sound/vox/acquired.ogg', +"acquisition" = 'modular_citadel/sound/vox/acquisition.ogg', +"across" = 'modular_citadel/sound/vox/across.ogg', +"activate" = 'modular_citadel/sound/vox/activate.ogg', +"activated" = 'modular_citadel/sound/vox/activated.ogg', +"activity" = 'modular_citadel/sound/vox/activity.ogg', +"adios" = 'modular_citadel/sound/vox/adios.ogg', +"administration" = 'modular_citadel/sound/vox/administration.ogg', +"advanced" = 'modular_citadel/sound/vox/advanced.ogg', +"after" = 'modular_citadel/sound/vox/after.ogg', +"agent" = 'modular_citadel/sound/vox/agent.ogg', +"alarm" = 'modular_citadel/sound/vox/alarm.ogg', +"alert" = 'modular_citadel/sound/vox/alert.ogg', +"alien" = 'modular_citadel/sound/vox/alien.ogg', +"aligned" = 'modular_citadel/sound/vox/aligned.ogg', +"all" = 'modular_citadel/sound/vox/all.ogg', +"alpha" = 'modular_citadel/sound/vox/alpha.ogg', +"am" = 'modular_citadel/sound/vox/am.ogg', +"amigo" = 'modular_citadel/sound/vox/amigo.ogg', +"ammunition" = 'modular_citadel/sound/vox/ammunition.ogg', +"an" = 'modular_citadel/sound/vox/an.ogg', +"and" = 'modular_citadel/sound/vox/and.ogg', +"announcement" = 'modular_citadel/sound/vox/announcement.ogg', +"anomalous" = 'modular_citadel/sound/vox/anomalous.ogg', +"antenna" = 'modular_citadel/sound/vox/antenna.ogg', +"any" = 'modular_citadel/sound/vox/any.ogg', +"apprehend" = 'modular_citadel/sound/vox/apprehend.ogg', +"approach" = 'modular_citadel/sound/vox/approach.ogg', +"are" = 'modular_citadel/sound/vox/are.ogg', +"area" = 'modular_citadel/sound/vox/area.ogg', +"arm" = 'modular_citadel/sound/vox/arm.ogg', +"armed" = 'modular_citadel/sound/vox/armed.ogg', +"armor" = 'modular_citadel/sound/vox/armor.ogg', +"armory" = 'modular_citadel/sound/vox/armory.ogg', +"arrest" = 'modular_citadel/sound/vox/arrest.ogg', +"ass" = 'modular_citadel/sound/vox/ass.ogg', +"at" = 'modular_citadel/sound/vox/at.ogg', +"atomic" = 'modular_citadel/sound/vox/atomic.ogg', +"attention" = 'modular_citadel/sound/vox/attention.ogg', +"authorize" = 'modular_citadel/sound/vox/authorize.ogg', +"authorized" = 'modular_citadel/sound/vox/authorized.ogg', +"automatic" = 'modular_citadel/sound/vox/automatic.ogg', +"away" = 'modular_citadel/sound/vox/away.ogg', +"b" = 'modular_citadel/sound/vox/b.ogg', +"back" = 'modular_citadel/sound/vox/back.ogg', +"backman" = 'modular_citadel/sound/vox/backman.ogg', +"bad" = 'modular_citadel/sound/vox/bad.ogg', +"bag" = 'modular_citadel/sound/vox/bag.ogg', +"bailey" = 'modular_citadel/sound/vox/bailey.ogg', +"barracks" = 'modular_citadel/sound/vox/barracks.ogg', +"base" = 'modular_citadel/sound/vox/base.ogg', +"bay" = 'modular_citadel/sound/vox/bay.ogg', +"be" = 'modular_citadel/sound/vox/be.ogg', +"been" = 'modular_citadel/sound/vox/been.ogg', +"before" = 'modular_citadel/sound/vox/before.ogg', +"beyond" = 'modular_citadel/sound/vox/beyond.ogg', +"biohazard" = 'modular_citadel/sound/vox/biohazard.ogg', +"biological" = 'modular_citadel/sound/vox/biological.ogg', +"birdwell" = 'modular_citadel/sound/vox/birdwell.ogg', +"bizwarn" = 'modular_citadel/sound/vox/bizwarn.ogg', +"black" = 'modular_citadel/sound/vox/black.ogg', +"blast" = 'modular_citadel/sound/vox/blast.ogg', +"blocked" = 'modular_citadel/sound/vox/blocked.ogg', +"bloop" = 'modular_citadel/sound/vox/bloop.ogg', +"blue" = 'modular_citadel/sound/vox/blue.ogg', +"bottom" = 'modular_citadel/sound/vox/bottom.ogg', +"bravo" = 'modular_citadel/sound/vox/bravo.ogg', +"breach" = 'modular_citadel/sound/vox/breach.ogg', +"breached" = 'modular_citadel/sound/vox/breached.ogg', +"break" = 'modular_citadel/sound/vox/break.ogg', +"bridge" = 'modular_citadel/sound/vox/bridge.ogg', +"bust" = 'modular_citadel/sound/vox/bust.ogg', +"but" = 'modular_citadel/sound/vox/but.ogg', +"button" = 'modular_citadel/sound/vox/button.ogg', +"buzwarn" = 'modular_citadel/sound/vox/buzwarn.ogg', +"bypass" = 'modular_citadel/sound/vox/bypass.ogg', +"c" = 'modular_citadel/sound/vox/c.ogg', +"cable" = 'modular_citadel/sound/vox/cable.ogg', +"call" = 'modular_citadel/sound/vox/call.ogg', +"called" = 'modular_citadel/sound/vox/called.ogg', +"canal" = 'modular_citadel/sound/vox/canal.ogg', +"cap" = 'modular_citadel/sound/vox/cap.ogg', +"captain" = 'modular_citadel/sound/vox/captain.ogg', +"capture" = 'modular_citadel/sound/vox/capture.ogg', +"captured" = 'modular_citadel/sound/vox/captured.ogg', +"ceiling" = 'modular_citadel/sound/vox/ceiling.ogg', +"celsius" = 'modular_citadel/sound/vox/celsius.ogg', +"center" = 'modular_citadel/sound/vox/center.ogg', +"centi" = 'modular_citadel/sound/vox/centi.ogg', +"central" = 'modular_citadel/sound/vox/central.ogg', +"chamber" = 'modular_citadel/sound/vox/chamber.ogg', +"charlie" = 'modular_citadel/sound/vox/charlie.ogg', +"check" = 'modular_citadel/sound/vox/check.ogg', +"checkpoint" = 'modular_citadel/sound/vox/checkpoint.ogg', +"chemical" = 'modular_citadel/sound/vox/chemical.ogg', +"cleanup" = 'modular_citadel/sound/vox/cleanup.ogg', +"clear" = 'modular_citadel/sound/vox/clear.ogg', +"clearance" = 'modular_citadel/sound/vox/clearance.ogg', +"close" = 'modular_citadel/sound/vox/close.ogg', +"clown" = 'modular_citadel/sound/vox/clown.ogg', +"code" = 'modular_citadel/sound/vox/code.ogg', +"coded" = 'modular_citadel/sound/vox/coded.ogg', +"collider" = 'modular_citadel/sound/vox/collider.ogg', +"command" = 'modular_citadel/sound/vox/command.ogg', +"communication" = 'modular_citadel/sound/vox/communication.ogg', +"complex" = 'modular_citadel/sound/vox/complex.ogg', +"computer" = 'modular_citadel/sound/vox/computer.ogg', +"condition" = 'modular_citadel/sound/vox/condition.ogg', +"containment" = 'modular_citadel/sound/vox/containment.ogg', +"contamination" = 'modular_citadel/sound/vox/contamination.ogg', +"control" = 'modular_citadel/sound/vox/control.ogg', +"coolant" = 'modular_citadel/sound/vox/coolant.ogg', +"coomer" = 'modular_citadel/sound/vox/coomer.ogg', +"core" = 'modular_citadel/sound/vox/core.ogg', +"correct" = 'modular_citadel/sound/vox/correct.ogg', +"corridor" = 'modular_citadel/sound/vox/corridor.ogg', +"crew" = 'modular_citadel/sound/vox/crew.ogg', +"cross" = 'modular_citadel/sound/vox/cross.ogg', +"cryogenic" = 'modular_citadel/sound/vox/cryogenic.ogg', +"d" = 'modular_citadel/sound/vox/d.ogg', +"dadeda" = 'modular_citadel/sound/vox/dadeda.ogg', +"damage" = 'modular_citadel/sound/vox/damage.ogg', +"damaged" = 'modular_citadel/sound/vox/damaged.ogg', +"danger" = 'modular_citadel/sound/vox/danger.ogg', +"day" = 'modular_citadel/sound/vox/day.ogg', +"deactivated" = 'modular_citadel/sound/vox/deactivated.ogg', +"decompression" = 'modular_citadel/sound/vox/decompression.ogg', +"decontamination" = 'modular_citadel/sound/vox/decontamination.ogg', +"deeoo" = 'modular_citadel/sound/vox/deeoo.ogg', +"defense" = 'modular_citadel/sound/vox/defense.ogg', +"degrees" = 'modular_citadel/sound/vox/degrees.ogg', +"delta" = 'modular_citadel/sound/vox/delta.ogg', +"denied" = 'modular_citadel/sound/vox/denied.ogg', +"deploy" = 'modular_citadel/sound/vox/deploy.ogg', +"deployed" = 'modular_citadel/sound/vox/deployed.ogg', +"destroy" = 'modular_citadel/sound/vox/destroy.ogg', +"destroyed" = 'modular_citadel/sound/vox/destroyed.ogg', +"detain" = 'modular_citadel/sound/vox/detain.ogg', +"detected" = 'modular_citadel/sound/vox/detected.ogg', +"detonation" = 'modular_citadel/sound/vox/detonation.ogg', +"device" = 'modular_citadel/sound/vox/device.ogg', +"did" = 'modular_citadel/sound/vox/did.ogg', +"die" = 'modular_citadel/sound/vox/die.ogg', +"dimensional" = 'modular_citadel/sound/vox/dimensional.ogg', +"dirt" = 'modular_citadel/sound/vox/dirt.ogg', +"disengaged" = 'modular_citadel/sound/vox/disengaged.ogg', +"dish" = 'modular_citadel/sound/vox/dish.ogg', +"disposal" = 'modular_citadel/sound/vox/disposal.ogg', +"distance" = 'modular_citadel/sound/vox/distance.ogg', +"distortion" = 'modular_citadel/sound/vox/distortion.ogg', +"do" = 'modular_citadel/sound/vox/do.ogg', +"doctor" = 'modular_citadel/sound/vox/doctor.ogg', +"doop" = 'modular_citadel/sound/vox/doop.ogg', +"door" = 'modular_citadel/sound/vox/door.ogg', +"down" = 'modular_citadel/sound/vox/down.ogg', +"dual" = 'modular_citadel/sound/vox/dual.ogg', +"duct" = 'modular_citadel/sound/vox/duct.ogg', +"e" = 'modular_citadel/sound/vox/e.ogg', +"east" = 'modular_citadel/sound/vox/east.ogg', +"echo" = 'modular_citadel/sound/vox/echo.ogg', +"ed" = 'modular_citadel/sound/vox/ed.ogg', +"effect" = 'modular_citadel/sound/vox/effect.ogg', +"egress" = 'modular_citadel/sound/vox/egress.ogg', +"eight" = 'modular_citadel/sound/vox/eight.ogg', +"eighteen" = 'modular_citadel/sound/vox/eighteen.ogg', +"eighty" = 'modular_citadel/sound/vox/eighty.ogg', +"electric" = 'modular_citadel/sound/vox/electric.ogg', +"electromagnetic" = 'modular_citadel/sound/vox/electromagnetic.ogg', +"elevator" = 'modular_citadel/sound/vox/elevator.ogg', +"eleven" = 'modular_citadel/sound/vox/eleven.ogg', +"eliminate" = 'modular_citadel/sound/vox/eliminate.ogg', +"emergency" = 'modular_citadel/sound/vox/emergency.ogg', +"enemy" = 'modular_citadel/sound/vox/enemy.ogg', +"energy" = 'modular_citadel/sound/vox/energy.ogg', +"engage" = 'modular_citadel/sound/vox/engage.ogg', +"engaged" = 'modular_citadel/sound/vox/engaged.ogg', +"engine" = 'modular_citadel/sound/vox/engine.ogg', +"enter" = 'modular_citadel/sound/vox/enter.ogg', +"entry" = 'modular_citadel/sound/vox/entry.ogg', +"environment" = 'modular_citadel/sound/vox/environment.ogg', +"error" = 'modular_citadel/sound/vox/error.ogg', +"escape" = 'modular_citadel/sound/vox/escape.ogg', +"evacuate" = 'modular_citadel/sound/vox/evacuate.ogg', +"exchange" = 'modular_citadel/sound/vox/exchange.ogg', +"exit" = 'modular_citadel/sound/vox/exit.ogg', +"expect" = 'modular_citadel/sound/vox/expect.ogg', +"experiment" = 'modular_citadel/sound/vox/experiment.ogg', +"experimental" = 'modular_citadel/sound/vox/experimental.ogg', +"explode" = 'modular_citadel/sound/vox/explode.ogg', +"explosion" = 'modular_citadel/sound/vox/explosion.ogg', +"exposure" = 'modular_citadel/sound/vox/exposure.ogg', +"exterminate" = 'modular_citadel/sound/vox/exterminate.ogg', +"extinguish" = 'modular_citadel/sound/vox/extinguish.ogg', +"extinguisher" = 'modular_citadel/sound/vox/extinguisher.ogg', +"extreme" = 'modular_citadel/sound/vox/extreme.ogg', +"f" = 'modular_citadel/sound/vox/f.ogg', +"face" = 'modular_citadel/sound/vox/face.ogg', +"facility" = 'modular_citadel/sound/vox/facility.ogg', +"fahrenheit" = 'modular_citadel/sound/vox/fahrenheit.ogg', +"failed" = 'modular_citadel/sound/vox/failed.ogg', +"failure" = 'modular_citadel/sound/vox/failure.ogg', +"farthest" = 'modular_citadel/sound/vox/farthest.ogg', +"fast" = 'modular_citadel/sound/vox/fast.ogg', +"feet" = 'modular_citadel/sound/vox/feet.ogg', +"field" = 'modular_citadel/sound/vox/field.ogg', +"fifteen" = 'modular_citadel/sound/vox/fifteen.ogg', +"fifth" = 'modular_citadel/sound/vox/fifth.ogg', +"fifty" = 'modular_citadel/sound/vox/fifty.ogg', +"final" = 'modular_citadel/sound/vox/final.ogg', +"fine" = 'modular_citadel/sound/vox/fine.ogg', +"fire" = 'modular_citadel/sound/vox/fire.ogg', +"first" = 'modular_citadel/sound/vox/first.ogg', +"five" = 'modular_citadel/sound/vox/five.ogg', +"flag" = 'modular_citadel/sound/vox/flag.ogg', +"flooding" = 'modular_citadel/sound/vox/flooding.ogg', +"floor" = 'modular_citadel/sound/vox/floor.ogg', +"fool" = 'modular_citadel/sound/vox/fool.ogg', +"for" = 'modular_citadel/sound/vox/for.ogg', +"forbidden" = 'modular_citadel/sound/vox/forbidden.ogg', +"force" = 'modular_citadel/sound/vox/force.ogg', +"forms" = 'modular_citadel/sound/vox/forms.ogg', +"found" = 'modular_citadel/sound/vox/found.ogg', +"four" = 'modular_citadel/sound/vox/four.ogg', +"fourteen" = 'modular_citadel/sound/vox/fourteen.ogg', +"fourth" = 'modular_citadel/sound/vox/fourth.ogg', +"fourty" = 'modular_citadel/sound/vox/fourty.ogg', +"foxtrot" = 'modular_citadel/sound/vox/foxtrot.ogg', +"freeman" = 'modular_citadel/sound/vox/freeman.ogg', +"freezer" = 'modular_citadel/sound/vox/freezer.ogg', +"from" = 'modular_citadel/sound/vox/from.ogg', +"front" = 'modular_citadel/sound/vox/front.ogg', +"fuel" = 'modular_citadel/sound/vox/fuel.ogg', +"g" = 'modular_citadel/sound/vox/g.ogg', +"gay" = 'modular_citadel/sound/vox/gay.ogg', +"get" = 'modular_citadel/sound/vox/get.ogg', +"go" = 'modular_citadel/sound/vox/go.ogg', +"going" = 'modular_citadel/sound/vox/going.ogg', +"good" = 'modular_citadel/sound/vox/good.ogg', +"goodbye" = 'modular_citadel/sound/vox/goodbye.ogg', +"gordon" = 'modular_citadel/sound/vox/gordon.ogg', +"got" = 'modular_citadel/sound/vox/got.ogg', +"government" = 'modular_citadel/sound/vox/government.ogg', +"granted" = 'modular_citadel/sound/vox/granted.ogg', +"great" = 'modular_citadel/sound/vox/great.ogg', +"green" = 'modular_citadel/sound/vox/green.ogg', +"grenade" = 'modular_citadel/sound/vox/grenade.ogg', +"guard" = 'modular_citadel/sound/vox/guard.ogg', +"gulf" = 'modular_citadel/sound/vox/gulf.ogg', +"gun" = 'modular_citadel/sound/vox/gun.ogg', +"guthrie" = 'modular_citadel/sound/vox/guthrie.ogg', +"handling" = 'modular_citadel/sound/vox/handling.ogg', +"hangar" = 'modular_citadel/sound/vox/hangar.ogg', +"has" = 'modular_citadel/sound/vox/has.ogg', +"have" = 'modular_citadel/sound/vox/have.ogg', +"hazard" = 'modular_citadel/sound/vox/hazard.ogg', +"head" = 'modular_citadel/sound/vox/head.ogg', +"health" = 'modular_citadel/sound/vox/health.ogg', +"heat" = 'modular_citadel/sound/vox/heat.ogg', +"helicopter" = 'modular_citadel/sound/vox/helicopter.ogg', +"helium" = 'modular_citadel/sound/vox/helium.ogg', +"hello" = 'modular_citadel/sound/vox/hello.ogg', +"help" = 'modular_citadel/sound/vox/help.ogg', +"here" = 'modular_citadel/sound/vox/here.ogg', +"hide" = 'modular_citadel/sound/vox/hide.ogg', +"high" = 'modular_citadel/sound/vox/high.ogg', +"highest" = 'modular_citadel/sound/vox/highest.ogg', +"hit" = 'modular_citadel/sound/vox/hit.ogg', +"holds" = 'modular_citadel/sound/vox/holds.ogg', +"hole" = 'modular_citadel/sound/vox/hole.ogg', +"hostile" = 'modular_citadel/sound/vox/hostile.ogg', +"hot" = 'modular_citadel/sound/vox/hot.ogg', +"hotel" = 'modular_citadel/sound/vox/hotel.ogg', +"hour" = 'modular_citadel/sound/vox/hour.ogg', +"hours" = 'modular_citadel/sound/vox/hours.ogg', +"hundred" = 'modular_citadel/sound/vox/hundred.ogg', +"hydro" = 'modular_citadel/sound/vox/hydro.ogg', +"i" = 'modular_citadel/sound/vox/i.ogg', +"idiot" = 'modular_citadel/sound/vox/idiot.ogg', +"illegal" = 'modular_citadel/sound/vox/illegal.ogg', +"immediate" = 'modular_citadel/sound/vox/immediate.ogg', +"immediately" = 'modular_citadel/sound/vox/immediately.ogg', +"in" = 'modular_citadel/sound/vox/in.ogg', +"inches" = 'modular_citadel/sound/vox/inches.ogg', +"india" = 'modular_citadel/sound/vox/india.ogg', +"ing" = 'modular_citadel/sound/vox/ing.ogg', +"inoperative" = 'modular_citadel/sound/vox/inoperative.ogg', +"inside" = 'modular_citadel/sound/vox/inside.ogg', +"inspection" = 'modular_citadel/sound/vox/inspection.ogg', +"inspector" = 'modular_citadel/sound/vox/inspector.ogg', +"interchange" = 'modular_citadel/sound/vox/interchange.ogg', +"intruder" = 'modular_citadel/sound/vox/intruder.ogg', +"invallid" = 'modular_citadel/sound/vox/invallid.ogg', +"invasion" = 'modular_citadel/sound/vox/invasion.ogg', +"is" = 'modular_citadel/sound/vox/is.ogg', +"it" = 'modular_citadel/sound/vox/it.ogg', +"johnson" = 'modular_citadel/sound/vox/johnson.ogg', +"juliet" = 'modular_citadel/sound/vox/juliet.ogg', +"key" = 'modular_citadel/sound/vox/key.ogg', +"kill" = 'modular_citadel/sound/vox/kill.ogg', +"kilo" = 'modular_citadel/sound/vox/kilo.ogg', +"kit" = 'modular_citadel/sound/vox/kit.ogg', +"lab" = 'modular_citadel/sound/vox/lab.ogg', +"lambda" = 'modular_citadel/sound/vox/lambda.ogg', +"laser" = 'modular_citadel/sound/vox/laser.ogg', +"last" = 'modular_citadel/sound/vox/last.ogg', +"launch" = 'modular_citadel/sound/vox/launch.ogg', +"leak" = 'modular_citadel/sound/vox/leak.ogg', +"leave" = 'modular_citadel/sound/vox/leave.ogg', +"left" = 'modular_citadel/sound/vox/left.ogg', +"legal" = 'modular_citadel/sound/vox/legal.ogg', +"level" = 'modular_citadel/sound/vox/level.ogg', +"lever" = 'modular_citadel/sound/vox/lever.ogg', +"lie" = 'modular_citadel/sound/vox/lie.ogg', +"lieutenant" = 'modular_citadel/sound/vox/lieutenant.ogg', +"life" = 'modular_citadel/sound/vox/life.ogg', +"light" = 'modular_citadel/sound/vox/light.ogg', +"lima" = 'modular_citadel/sound/vox/lima.ogg', +"liquid" = 'modular_citadel/sound/vox/liquid.ogg', +"loading" = 'modular_citadel/sound/vox/loading.ogg', +"locate" = 'modular_citadel/sound/vox/locate.ogg', +"located" = 'modular_citadel/sound/vox/located.ogg', +"location" = 'modular_citadel/sound/vox/location.ogg', +"lock" = 'modular_citadel/sound/vox/lock.ogg', +"locked" = 'modular_citadel/sound/vox/locked.ogg', +"locker" = 'modular_citadel/sound/vox/locker.ogg', +"lockout" = 'modular_citadel/sound/vox/lockout.ogg', +"lower" = 'modular_citadel/sound/vox/lower.ogg', +"lowest" = 'modular_citadel/sound/vox/lowest.ogg', +"magnetic" = 'modular_citadel/sound/vox/magnetic.ogg', +"main" = 'modular_citadel/sound/vox/main.ogg', +"maintenance" = 'modular_citadel/sound/vox/maintenance.ogg', +"malfunction" = 'modular_citadel/sound/vox/malfunction.ogg', +"man" = 'modular_citadel/sound/vox/man.ogg', +"mass" = 'modular_citadel/sound/vox/mass.ogg', +"materials" = 'modular_citadel/sound/vox/materials.ogg', +"maximum" = 'modular_citadel/sound/vox/maximum.ogg', +"may" = 'modular_citadel/sound/vox/may.ogg', +"med" = 'modular_citadel/sound/vox/med.ogg', +"medical" = 'modular_citadel/sound/vox/medical.ogg', +"men" = 'modular_citadel/sound/vox/men.ogg', +"mercy" = 'modular_citadel/sound/vox/mercy.ogg', +"mesa" = 'modular_citadel/sound/vox/mesa.ogg', +"message" = 'modular_citadel/sound/vox/message.ogg', +"meter" = 'modular_citadel/sound/vox/meter.ogg', +"micro" = 'modular_citadel/sound/vox/micro.ogg', +"middle" = 'modular_citadel/sound/vox/middle.ogg', +"mike" = 'modular_citadel/sound/vox/mike.ogg', +"miles" = 'modular_citadel/sound/vox/miles.ogg', +"military" = 'modular_citadel/sound/vox/military.ogg', +"milli" = 'modular_citadel/sound/vox/milli.ogg', +"million" = 'modular_citadel/sound/vox/million.ogg', +"minefield" = 'modular_citadel/sound/vox/minefield.ogg', +"minimum" = 'modular_citadel/sound/vox/minimum.ogg', +"minutes" = 'modular_citadel/sound/vox/minutes.ogg', +"mister" = 'modular_citadel/sound/vox/mister.ogg', +"mode" = 'modular_citadel/sound/vox/mode.ogg', +"motor" = 'modular_citadel/sound/vox/motor.ogg', +"motorpool" = 'modular_citadel/sound/vox/motorpool.ogg', +"move" = 'modular_citadel/sound/vox/move.ogg', +"must" = 'modular_citadel/sound/vox/must.ogg', +"nearest" = 'modular_citadel/sound/vox/nearest.ogg', +"nice" = 'modular_citadel/sound/vox/nice.ogg', +"nine" = 'modular_citadel/sound/vox/nine.ogg', +"nineteen" = 'modular_citadel/sound/vox/nineteen.ogg', +"ninety" = 'modular_citadel/sound/vox/ninety.ogg', +"no" = 'modular_citadel/sound/vox/no.ogg', +"nominal" = 'modular_citadel/sound/vox/nominal.ogg', +"north" = 'modular_citadel/sound/vox/north.ogg', +"not" = 'modular_citadel/sound/vox/not.ogg', +"november" = 'modular_citadel/sound/vox/november.ogg', +"now" = 'modular_citadel/sound/vox/now.ogg', +"number" = 'modular_citadel/sound/vox/number.ogg', +"objective" = 'modular_citadel/sound/vox/objective.ogg', +"observation" = 'modular_citadel/sound/vox/observation.ogg', +"of" = 'modular_citadel/sound/vox/of.ogg', +"officer" = 'modular_citadel/sound/vox/officer.ogg', +"ok" = 'modular_citadel/sound/vox/ok.ogg', +"on" = 'modular_citadel/sound/vox/on.ogg', +"one" = 'modular_citadel/sound/vox/one.ogg', +"open" = 'modular_citadel/sound/vox/open.ogg', +"operating" = 'modular_citadel/sound/vox/operating.ogg', +"operations" = 'modular_citadel/sound/vox/operations.ogg', +"operative" = 'modular_citadel/sound/vox/operative.ogg', +"option" = 'modular_citadel/sound/vox/option.ogg', +"order" = 'modular_citadel/sound/vox/order.ogg', +"organic" = 'modular_citadel/sound/vox/organic.ogg', +"oscar" = 'modular_citadel/sound/vox/oscar.ogg', +"out" = 'modular_citadel/sound/vox/out.ogg', +"outside" = 'modular_citadel/sound/vox/outside.ogg', +"over" = 'modular_citadel/sound/vox/over.ogg', +"overload" = 'modular_citadel/sound/vox/overload.ogg', +"override" = 'modular_citadel/sound/vox/override.ogg', +"pacify" = 'modular_citadel/sound/vox/pacify.ogg', +"pain" = 'modular_citadel/sound/vox/pain.ogg', +"pal" = 'modular_citadel/sound/vox/pal.ogg', +"panel" = 'modular_citadel/sound/vox/panel.ogg', +"percent" = 'modular_citadel/sound/vox/percent.ogg', +"perimeter" = 'modular_citadel/sound/vox/perimeter.ogg', +"permitted" = 'modular_citadel/sound/vox/permitted.ogg', +"personnel" = 'modular_citadel/sound/vox/personnel.ogg', +"pipe" = 'modular_citadel/sound/vox/pipe.ogg', +"plant" = 'modular_citadel/sound/vox/plant.ogg', +"platform" = 'modular_citadel/sound/vox/platform.ogg', +"please" = 'modular_citadel/sound/vox/please.ogg', +"point" = 'modular_citadel/sound/vox/point.ogg', +"portal" = 'modular_citadel/sound/vox/portal.ogg', +"power" = 'modular_citadel/sound/vox/power.ogg', +"presence" = 'modular_citadel/sound/vox/presence.ogg', +"press" = 'modular_citadel/sound/vox/press.ogg', +"primary" = 'modular_citadel/sound/vox/primary.ogg', +"proceed" = 'modular_citadel/sound/vox/proceed.ogg', +"processing" = 'modular_citadel/sound/vox/processing.ogg', +"progress" = 'modular_citadel/sound/vox/progress.ogg', +"proper" = 'modular_citadel/sound/vox/proper.ogg', +"propulsion" = 'modular_citadel/sound/vox/propulsion.ogg', +"prosecute" = 'modular_citadel/sound/vox/prosecute.ogg', +"protective" = 'modular_citadel/sound/vox/protective.ogg', +"push" = 'modular_citadel/sound/vox/push.ogg', +"quantum" = 'modular_citadel/sound/vox/quantum.ogg', +"quebec" = 'modular_citadel/sound/vox/quebec.ogg', +"question" = 'modular_citadel/sound/vox/question.ogg', +"questioning" = 'modular_citadel/sound/vox/questioning.ogg', +"quick" = 'modular_citadel/sound/vox/quick.ogg', +"quit" = 'modular_citadel/sound/vox/quit.ogg', +"radiation" = 'modular_citadel/sound/vox/radiation.ogg', +"radioactive" = 'modular_citadel/sound/vox/radioactive.ogg', +"rads" = 'modular_citadel/sound/vox/rads.ogg', +"rapid" = 'modular_citadel/sound/vox/rapid.ogg', +"reach" = 'modular_citadel/sound/vox/reach.ogg', +"reached" = 'modular_citadel/sound/vox/reached.ogg', +"reactor" = 'modular_citadel/sound/vox/reactor.ogg', +"red" = 'modular_citadel/sound/vox/red.ogg', +"relay" = 'modular_citadel/sound/vox/relay.ogg', +"released" = 'modular_citadel/sound/vox/released.ogg', +"remaining" = 'modular_citadel/sound/vox/remaining.ogg', +"renegade" = 'modular_citadel/sound/vox/renegade.ogg', +"repair" = 'modular_citadel/sound/vox/repair.ogg', +"report" = 'modular_citadel/sound/vox/report.ogg', +"reports" = 'modular_citadel/sound/vox/reports.ogg', +"required" = 'modular_citadel/sound/vox/required.ogg', +"research" = 'modular_citadel/sound/vox/research.ogg', +"reset" = 'modular_citadel/sound/vox/reset.ogg', +"resevoir" = 'modular_citadel/sound/vox/resevoir.ogg', +"resistance" = 'modular_citadel/sound/vox/resistance.ogg', +"returned" = 'modular_citadel/sound/vox/returned.ogg', +"right" = 'modular_citadel/sound/vox/right.ogg', +"rocket" = 'modular_citadel/sound/vox/rocket.ogg', +"roger" = 'modular_citadel/sound/vox/roger.ogg', +"romeo" = 'modular_citadel/sound/vox/romeo.ogg', +"room" = 'modular_citadel/sound/vox/room.ogg', +"round" = 'modular_citadel/sound/vox/round.ogg', +"run" = 'modular_citadel/sound/vox/run.ogg', +"safe" = 'modular_citadel/sound/vox/safe.ogg', +"safety" = 'modular_citadel/sound/vox/safety.ogg', +"sargeant" = 'modular_citadel/sound/vox/sargeant.ogg', +"satellite" = 'modular_citadel/sound/vox/satellite.ogg', +"save" = 'modular_citadel/sound/vox/save.ogg', +"science" = 'modular_citadel/sound/vox/science.ogg', +"scores" = 'modular_citadel/sound/vox/scores.ogg', +"scream" = 'modular_citadel/sound/vox/scream.ogg', +"screen" = 'modular_citadel/sound/vox/screen.ogg', +"search" = 'modular_citadel/sound/vox/search.ogg', +"second" = 'modular_citadel/sound/vox/second.ogg', +"secondary" = 'modular_citadel/sound/vox/secondary.ogg', +"seconds" = 'modular_citadel/sound/vox/seconds.ogg', +"sector" = 'modular_citadel/sound/vox/sector.ogg', +"secure" = 'modular_citadel/sound/vox/secure.ogg', +"secured" = 'modular_citadel/sound/vox/secured.ogg', +"security" = 'modular_citadel/sound/vox/security.ogg', +"select" = 'modular_citadel/sound/vox/select.ogg', +"selected" = 'modular_citadel/sound/vox/selected.ogg', +"service" = 'modular_citadel/sound/vox/service.ogg', +"seven" = 'modular_citadel/sound/vox/seven.ogg', +"seventeen" = 'modular_citadel/sound/vox/seventeen.ogg', +"seventy" = 'modular_citadel/sound/vox/seventy.ogg', +"severe" = 'modular_citadel/sound/vox/severe.ogg', +"sewage" = 'modular_citadel/sound/vox/sewage.ogg', +"sewer" = 'modular_citadel/sound/vox/sewer.ogg', +"shield" = 'modular_citadel/sound/vox/shield.ogg', +"shipment" = 'modular_citadel/sound/vox/shipment.ogg', +"shock" = 'modular_citadel/sound/vox/shock.ogg', +"shoot" = 'modular_citadel/sound/vox/shoot.ogg', +"shower" = 'modular_citadel/sound/vox/shower.ogg', +"shut" = 'modular_citadel/sound/vox/shut.ogg', +"side" = 'modular_citadel/sound/vox/side.ogg', +"sierra" = 'modular_citadel/sound/vox/sierra.ogg', +"sight" = 'modular_citadel/sound/vox/sight.ogg', +"silo" = 'modular_citadel/sound/vox/silo.ogg', +"six" = 'modular_citadel/sound/vox/six.ogg', +"sixteen" = 'modular_citadel/sound/vox/sixteen.ogg', +"sixty" = 'modular_citadel/sound/vox/sixty.ogg', +"slime" = 'modular_citadel/sound/vox/slime.ogg', +"slow" = 'modular_citadel/sound/vox/slow.ogg', +"soldier" = 'modular_citadel/sound/vox/soldier.ogg', +"some" = 'modular_citadel/sound/vox/some.ogg', +"someone" = 'modular_citadel/sound/vox/someone.ogg', +"something" = 'modular_citadel/sound/vox/something.ogg', +"son" = 'modular_citadel/sound/vox/son.ogg', +"sorry" = 'modular_citadel/sound/vox/sorry.ogg', +"south" = 'modular_citadel/sound/vox/south.ogg', +"squad" = 'modular_citadel/sound/vox/squad.ogg', +"square" = 'modular_citadel/sound/vox/square.ogg', +"stairway" = 'modular_citadel/sound/vox/stairway.ogg', +"status" = 'modular_citadel/sound/vox/status.ogg', +"sterile" = 'modular_citadel/sound/vox/sterile.ogg', +"sterilization" = 'modular_citadel/sound/vox/sterilization.ogg', +"stolen" = 'modular_citadel/sound/vox/stolen.ogg', +"storage" = 'modular_citadel/sound/vox/storage.ogg', +"sub" = 'modular_citadel/sound/vox/sub.ogg', +"subsurface" = 'modular_citadel/sound/vox/subsurface.ogg', +"sudden" = 'modular_citadel/sound/vox/sudden.ogg', +"suit" = 'modular_citadel/sound/vox/suit.ogg', +"superconducting" = 'modular_citadel/sound/vox/superconducting.ogg', +"supercooled" = 'modular_citadel/sound/vox/supercooled.ogg', +"supply" = 'modular_citadel/sound/vox/supply.ogg', +"surface" = 'modular_citadel/sound/vox/surface.ogg', +"surrender" = 'modular_citadel/sound/vox/surrender.ogg', +"surround" = 'modular_citadel/sound/vox/surround.ogg', +"surrounded" = 'modular_citadel/sound/vox/surrounded.ogg', +"switch" = 'modular_citadel/sound/vox/switch.ogg', +"system" = 'modular_citadel/sound/vox/system.ogg', +"systems" = 'modular_citadel/sound/vox/systems.ogg', +"tactical" = 'modular_citadel/sound/vox/tactical.ogg', +"take" = 'modular_citadel/sound/vox/take.ogg', +"talk" = 'modular_citadel/sound/vox/talk.ogg', +"tango" = 'modular_citadel/sound/vox/tango.ogg', +"tank" = 'modular_citadel/sound/vox/tank.ogg', +"target" = 'modular_citadel/sound/vox/target.ogg', +"team" = 'modular_citadel/sound/vox/team.ogg', +"temperature" = 'modular_citadel/sound/vox/temperature.ogg', +"temporal" = 'modular_citadel/sound/vox/temporal.ogg', +"ten" = 'modular_citadel/sound/vox/ten.ogg', +"terminal" = 'modular_citadel/sound/vox/terminal.ogg', +"terminated" = 'modular_citadel/sound/vox/terminated.ogg', +"termination" = 'modular_citadel/sound/vox/termination.ogg', +"test" = 'modular_citadel/sound/vox/test.ogg', +"that" = 'modular_citadel/sound/vox/that.ogg', +"the" = 'modular_citadel/sound/vox/the.ogg', +"then" = 'modular_citadel/sound/vox/then.ogg', +"there" = 'modular_citadel/sound/vox/there.ogg', +"third" = 'modular_citadel/sound/vox/third.ogg', +"thirteen" = 'modular_citadel/sound/vox/thirteen.ogg', +"thirty" = 'modular_citadel/sound/vox/thirty.ogg', +"this" = 'modular_citadel/sound/vox/this.ogg', +"those" = 'modular_citadel/sound/vox/those.ogg', +"thousand" = 'modular_citadel/sound/vox/thousand.ogg', +"threat" = 'modular_citadel/sound/vox/threat.ogg', +"three" = 'modular_citadel/sound/vox/three.ogg', +"through" = 'modular_citadel/sound/vox/through.ogg', +"time" = 'modular_citadel/sound/vox/time.ogg', +"to" = 'modular_citadel/sound/vox/to.ogg', +"top" = 'modular_citadel/sound/vox/top.ogg', +"topside" = 'modular_citadel/sound/vox/topside.ogg', +"touch" = 'modular_citadel/sound/vox/touch.ogg', +"towards" = 'modular_citadel/sound/vox/towards.ogg', +"track" = 'modular_citadel/sound/vox/track.ogg', +"train" = 'modular_citadel/sound/vox/train.ogg', +"transportation" = 'modular_citadel/sound/vox/transportation.ogg', +"truck" = 'modular_citadel/sound/vox/truck.ogg', +"tunnel" = 'modular_citadel/sound/vox/tunnel.ogg', +"turn" = 'modular_citadel/sound/vox/turn.ogg', +"turret" = 'modular_citadel/sound/vox/turret.ogg', +"twelve" = 'modular_citadel/sound/vox/twelve.ogg', +"twenty" = 'modular_citadel/sound/vox/twenty.ogg', +"two" = 'modular_citadel/sound/vox/two.ogg', +"unauthorized" = 'modular_citadel/sound/vox/unauthorized.ogg', +"under" = 'modular_citadel/sound/vox/under.ogg', +"uniform" = 'modular_citadel/sound/vox/uniform.ogg', +"unlocked" = 'modular_citadel/sound/vox/unlocked.ogg', +"until" = 'modular_citadel/sound/vox/until.ogg', +"up" = 'modular_citadel/sound/vox/up.ogg', +"upper" = 'modular_citadel/sound/vox/upper.ogg', +"uranium" = 'modular_citadel/sound/vox/uranium.ogg', +"us" = 'modular_citadel/sound/vox/us.ogg', +"usa" = 'modular_citadel/sound/vox/usa.ogg', +"use" = 'modular_citadel/sound/vox/use.ogg', +"used" = 'modular_citadel/sound/vox/used.ogg', +"user" = 'modular_citadel/sound/vox/user.ogg', +"vacate" = 'modular_citadel/sound/vox/vacate.ogg', +"valid" = 'modular_citadel/sound/vox/valid.ogg', +"vapor" = 'modular_citadel/sound/vox/vapor.ogg', +"vent" = 'modular_citadel/sound/vox/vent.ogg', +"ventillation" = 'modular_citadel/sound/vox/ventillation.ogg', +"victor" = 'modular_citadel/sound/vox/victor.ogg', +"violated" = 'modular_citadel/sound/vox/violated.ogg', +"violation" = 'modular_citadel/sound/vox/violation.ogg', +"voltage" = 'modular_citadel/sound/vox/voltage.ogg', +"vox_login" = 'modular_citadel/sound/vox/vox_login.ogg', +"walk" = 'modular_citadel/sound/vox/walk.ogg', +"wall" = 'modular_citadel/sound/vox/wall.ogg', +"want" = 'modular_citadel/sound/vox/want.ogg', +"wanted" = 'modular_citadel/sound/vox/wanted.ogg', +"warm" = 'modular_citadel/sound/vox/warm.ogg', +"warn" = 'modular_citadel/sound/vox/warn.ogg', +"warning" = 'modular_citadel/sound/vox/warning.ogg', +"waste" = 'modular_citadel/sound/vox/waste.ogg', +"water" = 'modular_citadel/sound/vox/water.ogg', +"we" = 'modular_citadel/sound/vox/we.ogg', +"weapon" = 'modular_citadel/sound/vox/weapon.ogg', +"west" = 'modular_citadel/sound/vox/west.ogg', +"whiskey" = 'modular_citadel/sound/vox/whiskey.ogg', +"white" = 'modular_citadel/sound/vox/white.ogg', +"wilco" = 'modular_citadel/sound/vox/wilco.ogg', +"will" = 'modular_citadel/sound/vox/will.ogg', +"with" = 'modular_citadel/sound/vox/with.ogg', +"without" = 'modular_citadel/sound/vox/without.ogg', +"woop" = 'modular_citadel/sound/vox/woop.ogg', +"xeno" = 'modular_citadel/sound/vox/xeno.ogg', +"yankee" = 'modular_citadel/sound/vox/yankee.ogg', +"yards" = 'modular_citadel/sound/vox/yards.ogg', +"year" = 'modular_citadel/sound/vox/year.ogg', +"yellow" = 'modular_citadel/sound/vox/yellow.ogg', +"yes" = 'modular_citadel/sound/vox/yes.ogg', +"you" = 'modular_citadel/sound/vox/you.ogg', +"your" = 'modular_citadel/sound/vox/your.ogg', +"yourself" = 'modular_citadel/sound/vox/yourself.ogg', +"zero" = 'modular_citadel/sound/vox/zero.ogg', +"zone" = 'modular_citadel/sound/vox/zone.ogg', +"zulu" = 'modular_citadel/sound/vox/zulu.ogg',)) +#endif \ No newline at end of file diff --git a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm b/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm index 2bfd63a25d..78e18fdb5e 100644 --- a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm +++ b/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm @@ -41,6 +41,10 @@ devourable = TRUE digestable = TRUE +/mob/living/simple_animal/kiwi + devourable = TRUE + digestable = TRUE + //STATION PETS /mob/living/simple_animal/pet devourable = TRUE @@ -65,7 +69,6 @@ /mob/living/simple_animal/sloth devourable = TRUE digestable = TRUE - feeding = TRUE /mob/living/simple_animal/parrot devourable = TRUE @@ -84,57 +87,48 @@ /mob/living/simple_animal/hostile/lizard devourable = TRUE digestable = TRUE + feeding = TRUE + vore_active = TRUE + isPredator = TRUE + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/alien - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/bear - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/poison/giant_spider - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE + isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/retaliate/poison/snake - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/gorilla - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/asteroid/goliath - devourable = TRUE - digestable = TRUE - feeding = TRUE + feeding = TRUE //for pet Goliaths I guess or something. vore_active = TRUE isPredator = TRUE vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/carp - devourable = TRUE - digestable = TRUE feeding = TRUE vore_active = TRUE isPredator = TRUE diff --git a/modular_citadel/code/modules/mob/living/status_procs.dm b/modular_citadel/code/modules/mob/living/status_procs.dm deleted file mode 100644 index 851c7438a7..0000000000 --- a/modular_citadel/code/modules/mob/living/status_procs.dm +++ /dev/null @@ -1,10 +0,0 @@ -/mob/living/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) //Can't go below remaining duration - if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) - if(absorb_stun(isnull(override_hardstun)? amount : override_hardstun, ignore_canknockdown)) - return - var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() - if(K) - K.duration = max(world.time + (isnull(override_hardstun)? amount : override_hardstun), K.duration) - else if((amount || override_hardstun) > 0) - K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating, override_hardstun, override_stamdmg) - return K diff --git a/modular_citadel/code/modules/projectiles/gun.dm b/modular_citadel/code/modules/projectiles/gun.dm index ea8af7c74c..317f68b4c4 100644 --- a/modular_citadel/code/modules/projectiles/gun.dm +++ b/modular_citadel/code/modules/projectiles/gun.dm @@ -9,13 +9,3 @@ return 0 else return ..() - -/obj/item/gun/proc/getinaccuracy(mob/living/user) - if(!iscarbon(user)) - return 0 - else - var/mob/living/carbon/holdingdude = user - if(istype(holdingdude) && holdingdude.combatmode) - return max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0) - else - return weapon_weight * 25 diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm deleted file mode 100644 index f70ec76f04..0000000000 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm +++ /dev/null @@ -1,117 +0,0 @@ -//////Flechette Launcher////// - -///projectiles/// - -/obj/item/projectile/bullet/cflechetteap //shreds armor - name = "flechette (armor piercing)" - damage = 8 - armour_penetration = 80 - -/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding - name = "flechette (serrated)" - damage = 15 - dismemberment = 10 - armour_penetration = -80 - -/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE) - if((blocked != 100) && iscarbon(target)) - var/mob/living/carbon/C = target - C.bleed(10) - return ..() - -///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)/// - -/obj/item/ammo_casing/caseless/flechetteap - name = "flechette (armor piercing)" - desc = "A flechette made with a tungsten alloy." - projectile_type = /obj/item/projectile/bullet/cflechetteap - caliber = "flechette" - throwforce = 1 - throw_speed = 3 - -/obj/item/ammo_casing/caseless/flechettes - name = "flechette (serrated)" - desc = "A serrated flechette made of a special alloy intended to deform drastically upon penetration of human flesh." - projectile_type = /obj/item/projectile/bullet/cflechettes - caliber = "flechette" - throwforce = 2 - throw_speed = 3 - embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 40, "embedded_fall_chance" = 10) - -///magazine/// - -/obj/item/ammo_box/magazine/flechette - name = "flechette magazine (armor piercing)" - icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' - icon_state = "flechettemag" - ammo_type = /obj/item/ammo_casing/caseless/flechetteap - caliber = "flechette" - max_ammo = 40 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/flechette/s - name = "flechette magazine (serrated)" - ammo_type = /obj/item/ammo_casing/caseless/flechettes - -///the gun itself/// - -/obj/item/gun/ballistic/automatic/flechette - name = "\improper CX Flechette Launcher" - desc = "A flechette launching machine pistol with an unconventional bullpup frame." - icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' - icon_state = "flechettegun" - item_state = "gun" - w_class = WEIGHT_CLASS_NORMAL - slot_flags = 0 - /obj/item/firing_pin/implant/pindicate - mag_type = /obj/item/ammo_box/magazine/flechette/ - fire_sound = 'sound/weapons/gunshot_smg.ogg' - can_suppress = 0 - burst_size = 5 - fire_delay = 1 - casing_ejector = 0 - spread = 10 - recoil = 0.05 - -/obj/item/gun/ballistic/automatic/flechette/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("flechettegun-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -///unique variant/// - -/obj/item/projectile/bullet/cflechetteshredder - name = "flechette (shredder)" - damage = 5 - dismemberment = 40 - -/obj/item/ammo_casing/caseless/flechetteshredder - name = "flechette (shredder)" - desc = "A serrated flechette made of a special alloy that forms a monofilament edge." - projectile_type = /obj/item/projectile/bullet/cflechettes - -/obj/item/ammo_box/magazine/flechette/shredder - name = "flechette magazine (shredder)" - icon_state = "shreddermag" - ammo_type = /obj/item/ammo_casing/caseless/flechetteshredder - -/obj/item/gun/ballistic/automatic/flechette/shredder - name = "\improper CX Shredder" - desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes." - w_class = WEIGHT_CLASS_SMALL - mag_type = /obj/item/ammo_box/magazine/flechette/shredder - spread = 15 - recoil = 0.1 - -/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("shreddergun-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm index b3af722332..70d3bee5af 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm @@ -86,7 +86,7 @@ /obj/item/ammo_box/magazine/mmag/small name = "magpistol magazine (non-lethal disabler)" icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' - icon_state = "nlmagmag" + icon_state = "smallmagmag" ammo_type = /obj/item/ammo_casing/caseless/anlmags caliber = "mags" max_ammo = 15 diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm index 8d08937f55..8786eb6dc9 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm @@ -56,7 +56,7 @@ /obj/item/ammo_box/magazine/mmag_e/small name = "magpistol magazine (non-lethal disabler)" icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' - icon_state = "nlmagmag" + icon_state = "smallmagmag" ammo_type = /obj/item/ammo_casing/caseless/mag_e/anlmags caliber = "mag_e" max_ammo = 16 diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm index 3df77c4951..1e0e0afc87 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm @@ -123,8 +123,8 @@ item_state = "gun" w_class = WEIGHT_CLASS_NORMAL slot_flags = 0 - /obj/item/firing_pin/implant/pindicate - mag_type = /obj/item/ammo_box/magazine/flechette/ + pin = /obj/item/firing_pin/implant/pindicate + mag_type = /obj/item/ammo_box/magazine/flechette fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = 0 burst_size = 5 @@ -134,12 +134,9 @@ recoil = 0.05 /obj/item/gun/ballistic/automatic/flechette/update_icon() - ..() + cut_overlays() if(magazine) - cut_overlays() add_overlay("flechettegun-magazine") - else - cut_overlays() icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" ///unique variant/// @@ -163,17 +160,13 @@ name = "\improper CX Shredder" desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes." w_class = WEIGHT_CLASS_SMALL - mag_type = /obj/item/ammo_box/magazine/flechette/shredder spread = 15 recoil = 0.1 /obj/item/gun/ballistic/automatic/flechette/shredder/update_icon() - ..() + cut_overlays() if(magazine) - cut_overlays() add_overlay("shreddergun-magazine") - else - cut_overlays() icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" /*///////////////////////////////////////////////////////////// diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm new file mode 100644 index 0000000000..1508a5d519 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -0,0 +1,373 @@ +/* +//////////////////////////////////////// +// MKULTA // +//////////////////////////////////////// +The magnum opus of FermiChem - +Long and complicated, I highly recomend you look at the two other files heavily involved in this +modular_citadel/code/datums/status_effects/chems.dm - handles the subject's reactions +code/modules/surgery/organs/vocal_cords.dm - handles the enchanter speaking + +HOW IT WORKS +Fermis_Reagent.dm +There's 3 main ways this chemical works; I'll start off with discussing how it's set up. +Upon reacting with blood as a catalyst, the blood is used to define who the enthraller is - thus only the creator is/can choose who the master will be. As a side note, you can't adminbus this chem, even admins have to earn it. +This uses the fermichem only proc; FermiCreate, which is basically the same as On_new, except it doesn't require "data" which is something to do with blood and breaks everything so I said bugger it and made my own proc. It basically sets up vars. +When it's first made, the creator has to drink some of it, in order to give them the vocal chords needed. +When it's given to someone, it gives them the status effect and kicks off that side of things. For every metabolism tick, it increases the enthrall tally. +Finally, if you manage to pump 100u into some poor soul, you overload them, and mindbreak them. Making them your willing, but broken slave. Which can only be reversed by; fixing their brain with mannitol and neurine (100 / 50u respectively) (or less with both), + +vocal_cords.dm +This handles when the enchanter speaks - basically uses code from voice of god, but only for people with the staus effect. Most of the words are self explainitory, and has a smaller range of commands. If you're not sure what one does, it likely affects the enthrall tally, or the resist tally. +list of commands: + +-mixables- +enthral_words +reward_words +punish_words +0 +saymyname_words +wakeup_words +1 +silence_words +antiresist_words +resist_words +forget_words +attract_words +orgasm_words +2 +awoo_words +nya_words +sleep_words +strip_words +walk_words +run_words +knockdown_words +3 +statecustom_words +custom_words +objective_words +heal_words +stun_words +hallucinate_words +hot_words +cold_words +getup_words +pacify_words +charge_words + +Mixables can be used intersperced with other commands, 0 is commands that work on sleeper against (i.e. players enthralled to state 3, then ordered to wake up and forget, they can be triggered back instantly) +1 is for players who immediately are injected with the chem - no stuns, only a silence and something that draws them towrds them. This is the best time to try to fight it and you're likely to win by spamming resist, unless the enchantress has plans. +2 is the seconds stage, which allows removal of clothes, slowdown and light stunning. You can also make them nya and awoo, because cute. +3 is the finaly state, which allows application of a few status effects (see chem.dm) and allows custom triggers to be installed (kind of like nanites), again, see chem.dm +In a nutshell, this is the way you enthrall people, by typing messages into chat and managing cooldowns on the stronger words. You have to type words and your message strength is increases with the number of characters - if you type short messages the cooldown will be too much and the other player will overcome the chem. +I suppose people could spam gdjshogndjoadphgiuaodp but, the truth of this chem is that it mostly allows a casus beli for subs to give in, and everyones a sub on cit (mostly), so if you aujigbnadjgipagdsjk then they might resist harder cause you're a baddie and baddies don't deserve pets. +Also, the use of this chem as a murder aid is antithetic to it's design, the subject gains bonus resistance if they're hurt or hungry (I'd like to expland this more, I like the idea that you have to look after all of them otherwise they aren't as effective, kind of like tamagachis!). If this becomes a problem, I'll deal with it, I'm not happy with people abusing this chem for an easy murder. (I might make it so you an't strike your pet when health is too low.) +Additionaly, in lieu of previous statement - the pet is ordered to not kill themselves, even if ordered to. + +chem.dm +oof +There's a few basic things that have to be understood with this status effect +1. There is a min loop which calculates the enthrall state of the subject, when the entrall tally is over a certain amount, it will push you up 1 phase. +0 - Sleeper +1 - initial +2 - enthralled +3 - Fully entranced +4 - mindbroken +4 can only be reached via OD, whereas you can increment up from 1 > 2 > 3. 0 is only obtainable on a state 3 pet, and it toggles between the two. + +1.5 Chem warfare +Since this is a chem, it's expected that you will use all of the chemicals at your disposal. Using aphro and aphro+ will weaken the resistance of the subject, while ananphro, anaphro+, mannitol and neurine will strengthen it. +Additionally, the more aroused you are, the weaker your resistance will be, as a result players immune to aphro and anaphro give a flat bonus to the enthraller. +using furranium and hatmium on the enchanter weakens their power considerably, because they sound rediculous. "Youwe fweewing wery sweepy uwu" This completely justifies their existance. +The impure toxin for this chem increases resistance too, so if they're a bad chemist it'll be unlikely they have a good ratio (and as a secret bonus, really good chemists cann purposely make the impure chem, to use either to combat the use of it against them, or as smoke grenades to deal with a large party) + +2. There is a resistance proc which occurs whenever the player presses resist. You have to press it a lot, this is intentional. If you're trying to fight the enchanter, then you can't click both. You usually will win if you just mash resist and the enchanter does nothing, so you've got to react. +Each step futher it becomes harder to resist, in state 2 it's longer, but resisting is still worthwhile. If you're not in state 3, and you've not got MKultra inside of you, you generate resistance very fast. So in some cases the better option will be to stall out any attempts to entrance you. +At the moment, resistance doesn't affect the commands - mostly because it's a way to tell if a state 3 is trying to resist. But this might change if it gets too hard to fight them off. +Durign state 3, it's impossible to resist if the enthraller is in your presence (8 tiles), you generate no resistance if so. If they're out of your range, then you start to go into the addiction processed +As your resistance is tied to your arousal, sometimes your best option is to wah + +3. The addition process starts when the enthraller is out of range, it roughtly follows the five stages of grief; denial, anger, bargaining, depression and acceptance. +What it mostly does makes you sad, hurts your brain, and sometimes you lash out in anger. +Denial - minor brain damaged +bargaining - 50:50 chance of brain damage and brain healing +anger - randomly lashing out and hitting people +depression - massive mood loss, stuttering, jittering, hallucinations and brain damage +depression, again - random stunning and crying, brain damage, and resistance +acceptance - minor brain damage and resistance. +You can also resist while out of range, but you can only break free of a stange 3 enthrallment by hitting the acceptance phase with a high enough resistance. +Finally, being near your enthraller reverts the damages caused. +It is expected that if you intend to break free you'll need to use psicodine and mannitol or you'll end up in a bad, but not dead, state. This gives more work for medical!! Finally the true rational of this complicated chem comes out. + +4. Status effects in status effects. +There's a few commands that give status effects, such as antiresist, which will cause resistance presses to increase the enthrallment instead, theses are called from the vocal chords. +They're mostly self explainitory; antiresist, charge, pacify and heal. Heals quite weak for obvious reasons. I'd like to add more, maybe some weak adneals with brute/exhaustion costs after the status is over. A truth serum might be neat too. +State 4 pets don't get status effects. + +5. Custom triggers +Because it wasnt complicated enough already. +Custom triggers are set by stating a trigger word, which will call a sub proc, which is also defined when the trigger is Called +The effects avalible at the moment are: +Speak - forces pet to say a preallocated phrase in response to the trigger +Echo - sends a message to that player only (i.e. makes them think something) +Shock - gives them a seizure/zaps them +You can look this one up yourself - it's what you expect, it's cit +kneel - gives a short knockdown +strip - strips jumpsuit only +objective - gives the pet a new objective. This requires a high ammount of mental capasity - which is determined by how much you resist. If you resist enough during phase 1 and 2, then they can't give you an objective. +Feel free to add more. +triggers work when said by ANYONE, not just the enchanter. +This is only state 3 pets, state 4 pets cannot get custom triggers, you broke them you bully. + +7. If you're an antage you get a bonus to resistance AND to enthralling. Thus it can be worth using this on both sides. It shouldn't be hard to resist as an antag. There are futher bonuses to command, Chaplains and chemist. +If you give your pet a collar then their resistance reduced too. +(I think thats everything?) + +Failstates: +Blowing up the reaction produces a gas that causes everyone to fall in love with one another. + +Creating a chem with a low purity will make you permanently fall in love with someone, and tasked with keeping them safe. If someone else drinks it, you fall for them. +*/ + +/datum/reagent/fermi/enthrall + name = "MKUltra" + id = "enthrall" + description = "A forbidden deep red mixture that overwhelms a foreign body with waves of pleasure, intoxicating them into servitude. When taken by the creator, it will enhance the draw of their voice to those affected by it." + color = "#660015" // rgb: , 0, 255 + taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses" + overdose_threshold = 100 //If this is too easy to get 100u of this, then double it please. + DoNotSplit = TRUE + metabolization_rate = 0.1//It has to be slow, so there's time for the effect. + data = list("creatorID" = null, "creatorGender" = null, "creatorName" = null) + var/creatorID //ckey + var/creatorGender + var/creatorName + var/mob/living/creator + pH = 10 + OnMobMergeCheck = TRUE //Procs on_mob_add when merging into a human + can_synth = FALSE + + +/datum/reagent/fermi/enthrall/test + name = "MKUltraTest" + id = "enthrallTest" + description = "A forbidden deep red mixture that overwhelms a foreign body with waves of joy, intoxicating them into servitude. When taken by the creator, it will enhance the draw of their voice to those affected by it." + data = list("creatorID" = "honkatonkbramblesnatch", "creatorGender" = "Mistress", "creatorName" = "Fermis Yakumo") + creatorID = "honkatonkbramblesnatch"//ckey + creatorGender = "Mistress" + creatorName = "Fermis Yakumo" + purity = 1 + DoNotSplit = TRUE + +/datum/reagent/fermi/enthrall/test/on_new() + id = "enthrall" + ..() + creator = get_mob_by_key(creatorID) + +/datum/reagent/fermi/enthrall/on_new(list/data) + creatorID = data.["creatorID"] + creatorGender = data.["creatorGender"] + creatorName = data.["creatorName"] + creator = get_mob_by_key(creatorID) + +/datum/reagent/fermi/enthrall/on_mob_add(mob/living/carbon/M) + . = ..() + if(!ishuman(M))//Just to make sure screwy stuff doesn't happen. + return + if(!creatorID) + //This happens when the reaction explodes. + return + if(purity < 0.5)//Impure chems don't function as you expect + return + var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall) + if(E) + if(E.enthrallID == M.ckey && creatorID != M.ckey)//If you're enthralled to yourself (from OD) and someone else tries to enthrall you, you become thralled to them instantly. + E.enthrallID = creatorID + E.enthrallGender = creatorGender + E.master = get_mob_by_key(creatorID) + to_chat(M, to_chat(M, "Your aldled, plastic, mind bends under the chemical influence of a new [(M.client?.prefs.lewdchem?"master":"leader")]. Your highest priority is now to stay by [creatorName]'s side, following and aiding them at all costs.")) //THIS SHOULD ONLY EVER APPEAR IF YOU MINDBREAK YOURSELF AND THEN GET INJECTED FROM SOMEONE ELSE. + log_game("FERMICHEM: Narcissist [M] ckey: [M.key] been rebound to [creatorName], ID: [creatorID]") + return + if((M.ckey == creatorID) && (creatorName == M.real_name)) //same name AND same player - same instance of the player. (should work for clones?) + log_game("FERMICHEM: [M] ckey: [M.key] has been given velvetspeech") + var/obj/item/organ/vocal_cords/Vc = M.getorganslot(ORGAN_SLOT_VOICE) + var/obj/item/organ/vocal_cords/nVc = new /obj/item/organ/vocal_cords/velvet + if(Vc) + Vc.Remove(M) + nVc.Insert(M) + qdel(Vc) + to_chat(M, "You feel your vocal chords tingle as your voice comes out in a more sultry tone.") + else + log_game("FERMICHEM: MKUltra: [creatorName], [creatorID], is enthralling [M.name], [M.ckey]") + M.apply_status_effect(/datum/status_effect/chem/enthrall) + log_game("FERMICHEM: [M] ckey: [M.key] has taken MKUltra") + +/datum/reagent/fermi/enthrall/on_mob_life(mob/living/carbon/M) + . = ..() + if(purity < 0.5)//DO NOT SPLIT INTO DIFFERENT CHEM: This relies on DoNotSplit - has to be done this way. + if(volume < 0.5)//You don't get to escape that easily + FallInLove(pick(GLOB.player_list), M) + M.reagents.remove_reagent(id, volume) + + if (M.ckey == creatorID && creatorName == M.real_name)//If the creator drinks it, they fall in love randomly. If someone else drinks it, the creator falls in love with them. + if(M.has_status_effect(STATUS_EFFECT_INLOVE))//Can't be enthralled when enthralled, so to speak. + return + var/list/seen = viewers(7, get_turf(M)) + for(var/victim in seen) + if(ishuman(victim)) + var/mob/living/carbon/V = victim + if((V == M) || (!V.client) || (V.stat == DEAD)) + seen = seen - victim + else + seen = seen - victim + + if(LAZYLEN(seen)) + return + M.reagents.remove_reagent(id, volume) + FallInLove(M, pick(seen)) + return + + else // If someone else drinks it, the creator falls in love with them! + var/mob/living/carbon/C = get_mob_by_key(creatorID) + if(M.has_status_effect(STATUS_EFFECT_INLOVE)) + return + if((C in viewers(7, get_turf(M))) && (C.client)) + M.reagents.remove_reagent(id, volume) + FallInLove(C, M) + return + + if (M.ckey == creatorID && creatorName == M.real_name)//If you yourself drink it, it supresses the vocal effects, for stealth. NEVERMIND ADD THIS LATER I CAN'T GET IT TO WORK + return + if(!M.client) + metabolization_rate = 0 //Stops powergamers from quitting to avoid affects. but prevents affects on players that don't exist for performance. + return + if(metabolization_rate == 0) + metabolization_rate = 0.1 + var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall)//If purity is over 5, works as intended + if(!E) + return + else + E.enthrallTally += 1 + ..() + +/datum/reagent/fermi/enthrall/overdose_start(mob/living/carbon/M)//I made it so the creator is set to gain the status for someone random. + . = ..() + metabolization_rate = 1//Mostly to manage brain damage and reduce server stress + if (M.ckey == creatorID && creatorName == M.real_name)//If the creator drinks 100u, then you get the status for someone random (They don't have the vocal chords though, so it's limited.) + if (!M.has_status_effect(/datum/status_effect/chem/enthrall)) + to_chat(M, "You are unable to resist your own charms anymore, and become a full blown narcissist.") + /*Old way of handling, left in as an option B + var/list/seen = viewers(7, get_turf(M))//Sound and sight checkers + for(var/mob/living/carbon/victim in seen) + if(victim == M)//as much as I want you to fall for beepsky, he doesn't have a ckey + seen = seen - victim + if(!victim.ckey) + seen = seen - victim + var/mob/living/carbon/chosen = pick(seen) + creatorID = chosen.ckey + if (chosen.gender == "female") + creatorGender = "Mistress" + else + creatorGender = "Master" + creatorName = chosen.real_name + creator = get_mob_by_key(creatorID) + */ + ADD_TRAIT(M, TRAIT_PACIFISM, "MKUltra") + var/datum/status_effect/chem/enthrall/E + if (!M.has_status_effect(/datum/status_effect/chem/enthrall)) + M.apply_status_effect(/datum/status_effect/chem/enthrall) + E = M.has_status_effect(/datum/status_effect/chem/enthrall) + E.enthrallID = creatorID + E.enthrallGender = creatorGender + E.master = creator + else + E = M.has_status_effect(/datum/status_effect/chem/enthrall) + if(M.client?.prefs.lewdchem) + to_chat(M, "Your mind shatters under the volume of the mild altering chem inside of you, breaking all will and thought completely. Instead the only force driving you now is the instinctual desire to obey and follow [creatorName]. Your highest priority is now to stay by their side and protect them at all costs.") + else + to_chat(M, "The might volume of chemicals in your system overwhelms your mind, and you suddenly agree with what [creatorName] has been saying. Your highest priority is now to stay by their side and protect them at all costs.") + log_game("FERMICHEM: [M] ckey: [M.key] has been mindbroken for [creatorName] ckey: [creatorID]") + M.slurring = 100 + M.confused = 100 + E.phase = 4 + E.mental_capacity = 0 + E.customTriggers = list() + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Thralls mindbroken") + +/datum/reagent/fermi/enthrall/overdose_process(mob/living/carbon/M) + M.adjustBrainLoss(0.2)//should be ~30 in total + ..() + +//Creates a gas cloud when the reaction blows up, causing everyone in it to fall in love with someone/something while it's in their system. +/datum/reagent/fermi/enthrallExplo//Created in a gas cloud when it explodes + name = "MKUltra" + id = "enthrallExplo" + description = "A forbidden deep red mixture that overwhelms a foreign body with waves of desire, inducing a chemial love for another. Also, how the HECC did you get this?" + color = "#2C051A" // rgb: , 0, 255 + metabolization_rate = 0.1 + taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses." + DoNotSplit = TRUE + can_synth = FALSE + var/mob/living/carbon/love + +/datum/reagent/fermi/enthrallExplo/on_mob_life(mob/living/carbon/M)//Love gas, only affects while it's in your system,Gives a positive moodlet if close, gives brain damagea and a negative moodlet if not close enough. + if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) + return ..() + if(!M.has_status_effect(STATUS_EFFECT_INLOVE)) + var/list/seen = viewers(7, get_turf(M))//Sound and sight checkers + for(var/victim in seen) + if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (M.stat == DEAD) || (!isliving(victim))) + seen = seen - victim + if(seen.len == 0) + return + love = pick(seen) + if(!love) + return + M.apply_status_effect(STATUS_EFFECT_INLOVE, love) + to_chat(M, "[(M.client?.prefs.lewdchem?"":"")][(M.client?.prefs.lewdchem?"You develop a sudden crush on [love], your heart beginning to race as you look upon them with new eyes.":"You suddenly feel like making friends with [love].")] You feel strangely drawn towards them.") + log_game("FERMICHEM: [M] ckey: [M.key] has temporarily bonded with [love] ckey: [love.key]") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have bonded") + else + if(get_dist(M, love) < 8) + if(HAS_TRAIT(M, TRAIT_NYMPHO)) //Add this back when merged/updated. + M.adjustArousalLoss(5) + var/message = "[(M.client?.prefs.lewdchem?"I'm next to my crush..! Eee!":"I'm making friends with [love]!")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "InLove", /datum/mood_event/InLove, message) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "MissingLove") + else + var/message = "[(M.client?.prefs.lewdchem?"I can't keep my crush off my mind, I need to see them again!":"I really want to make friends with [love]!")]" + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "MissingLove", /datum/mood_event/MissingLove, message) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "InLove") + if(prob(5)) + M.Stun(10) + M.emote("whimper")//does this exist? + to_chat(M, "[(M.client?.prefs.lewdchem?"":"")] You're overcome with a desire to see [love].") + M.adjustBrainLoss(0.5)//I found out why everyone was so damaged! + ..() + +/datum/reagent/fermi/enthrallExplo/on_mob_delete(mob/living/carbon/M) + if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) + return ..() + M.remove_status_effect(STATUS_EFFECT_INLOVE) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "InLove") + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "MissingLove") + to_chat(M, "[(M.client?.prefs.lewdchem?"":"")]Your feelings for [love] suddenly vanish!") + log_game("FERMICHEM: [M] ckey: [M.key] is no longer in temp bond") + ..() + +/datum/reagent/fermi/proc/FallInLove(mob/living/carbon/Lover, mob/living/carbon/Love) + if(Lover.has_status_effect(STATUS_EFFECT_INLOVE)) + to_chat(Lover, "You are already fully devoted to someone else!") + return + to_chat(Lover, "[(Lover.client?.prefs.lewdchem?"":"")]You develop a deep and sudden bond with [Love][(Lover.client?.prefs.lewdchem?", your heart beginning to race as your mind filles with thoughts about them.":".")] You are determined to keep them safe and happy, and feel drawn towards them.") + if(Lover.mind) + Lover.mind.store_memory("You are in love with [Love].") + Lover.faction |= "[REF(Love)]" + Lover.apply_status_effect(STATUS_EFFECT_INLOVE, Love) + forge_valentines_objective(Lover, Love, TRUE) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have become infatuated.") + log_game("FERMICHEM: [Lover] ckey: [Lover.key] has been chemically made to fall for [Love] ckey: [Love.key]") + return + +//For addiction see chem.dm +//For vocal commands see vocal_cords.dm diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm new file mode 100644 index 0000000000..8af3176746 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -0,0 +1,374 @@ +/*SDGF +//////////////////////////////////////////////////// +// synthetic-derived growth factor // +////////////////////////////////////////////////// +other files that are relivant: +modular_citadel/code/datums/status_effects/chems.dm - SDGF +WHAT IT DOES + +Several outcomes are possible (in priority order): + +Before the chem is even created, there is a risk of the reaction "exploding", which produces an angry teratoma that attacks the player. +0. Before the chem is activated, the purity is checked, if the purity of the reagent is less than 0.5, then sythetic-derived zombie factor is metabolised instead + 0.1 If SDZF is injected, the chem appears to act the same as normal, with nutrition gain, until the end, where it becomes toxic instead, giving a short window of warning to the player + 0.1.2 If the player can take pent in time, the player will spawn a hostile teratoma on them (less damaging), if they don't, then a zombie is spawned instead, with a small defence increase propotional to the volume + 0.2 If the purity is above 0.5, then the remaining impure volume created SDGFtox instead, which reduces blood volume and causes clone damage +1.Normal function creates a (another)player controlled clone of the player, which is spawned nude, with damage to the clone + 1.1 The remaining volume is transferred to the clone, which heals it over time, thus the player has to make a substantial ammount of the chem in order to produce a healthy clone + 1.2 If the player is infected with a zombie tumor, the tumor is transferred to the ghost controlled clone ONLY. +2. If no player can be found, a brainless clone is created over a long period of time, this body has no controller. + 2.1 If the player dies with a clone, then they play as the clone instead. However no memories are retained after splitting. +3. If there is already a clone, then SDGF heals clone, fire and brute damage slowly. This shouldn't normalise this chem as the de facto clone healing chem, as it will always try to make a ghost clone, and then a brainless clone first. +4. If there is insuffient volume to complete the cloning process, there are two outcomes + 4.1 At lower volumes, the players nutrition and blood is refunded, with light healing + 4.2 At higher volumes a stronger heal is applied to the user + +IMPORTANT FACTORS TO CONSIDER WHILE BALANCING +1. The most important factor is the required volume, this is easily edited with the metabolism rate, this chem is HARD TO MAKE, You need to make a lot of it and it's a substantial effort on the players part. There is also a substantial risk; you could spawn a hotile teratoma during the reation, you could damage yourself with clone damage, you could accidentally spawn a zombie... Basically, you've a good chance of killing yourself. + 1.1 Additionally, if you're trying to make SDZF purposely, you've no idea if you have or not, and that reaction is even harder to do. Plus, the player has a huge time window to get to medical to deal with it. If you take pent while it's in you, it'll be removed before it can spawn, and only spawns a teratoma if it's late stage. +2. The rate in which the clone is made, This thing takes time to produce fruits, it slows you down and makes you useless in combat/working. Basically you can't do anything during it. It will only get you killed if you use it in combat, If you do use it and you spawn a player clone, they're gimped for a long time, as they have to heal off the clone damage. +3. The healing - it's pretty low and a cyropod is more Useful +4. If you're an antag, you've a 50% chance of making a clone that will help you with your efforts, and you've no idea if they will or not. While clones can't directly harm you and care for you, they can hinder your efforts. +5. If people are being arses when they're a clone, slap them for it, they are told to NOT bugger around with someone else character, if it gets bad I'll add a blacklist, or do a check to see if you've played X amount of hours. + 5.1 Another solution I'm okay with is to rename the clone to [M]'s clone, so it's obvious, this obviously ruins anyone trying to clone themselves to get an alibi however. I'd prefer this to not be the case. + 5.2 Additionally, this chem is a soft buff to changelings, which apparently need a buff! + 5.3 Other similar things exist already though in the codebase; impostors, split personalites, abductors, ect. +6. Giving this to someone without concent is against space law and gets you sent to gulag. +*/ + +//Clone serum #chemClone +/datum/reagent/fermi/SDGF //vars, mostly only care about keeping track if there's a player in the clone or not. + name = "synthetic-derived growth factor" + id = "SDGF" + description = "A rapidly diving mass of Embryonic stem cells. These cells are missing a nucleus and quickly replicate a host’s DNA before growing to form an almost perfect clone of the host. In some cases neural replication takes longer, though the underlying reason underneath has yet to be determined." + color = "#a502e0" // rgb: 96, 0, 255 + var/playerClone = FALSE + var/unitCheck = FALSE + metabolization_rate = 0.5 * REAGENTS_METABOLISM + taste_description = "a weird chemical fleshy flavour" + //var/datum/status_effect/chem/SDGF/candidates/candies + var/list/candies = list() + //var/polling = FALSE + var/list/result = list() + var/list/group = null + var/pollStarted = FALSE + var/location_created + var/startHunger + ImpureChem = "SDGFtox" + InverseChemVal = 0.5 + InverseChem = "SDZF" + can_synth = TRUE + + +//Main SDGF chemical +/datum/reagent/fermi/SDGF/on_mob_life(mob/living/carbon/M) //Clones user, then puts a ghost in them! If that fails, makes a braindead clone. + //Setup clone + switch(current_cycle) + if(1) + startHunger = M.nutrition + if(pollStarted == FALSE) + pollStarted = TRUE + candies = pollGhostCandidates("Do you want to play as a clone of [M], and do you agree to respect their character and act in a similar manner to them? Do not engage in ERP as them unless you have LOOC permission from them, and ensure it is permission from the original, not a clone.") + log_game("FERMICHEM: [M] ckey: [M.key] has taken SDGF, and ghosts have been polled.") + if(20 to INFINITY) + if(LAZYLEN(candies) && playerClone == FALSE) //If there's candidates, clone the person and put them in there! + log_game("FERMICHEM: [M] ckey: [M.key] is creating a clone, controlled by [candies]") + to_chat(M, "The cells reach a critical micelle concentration, nucleating rapidly within your body!") + var/typepath = M.type + var/mob/living/carbon/human/fermi_Gclone = new typepath(M.loc) + var/mob/living/carbon/human/SM = fermi_Gclone + if(istype(SM) && istype(M)) + SM.real_name = M.real_name + M.dna.transfer_identity(SM) + SM.updateappearance(mutcolor_update=1) + + + candies = shuffle(candies)//Shake those ghosts up! + for(var/mob/dead/observer/C2 in candies) + if(C2.key && C2) + SM.key = C2.key + message_admins("Ghost candidate found! [C2] key [C2.key] is becoming a clone of [M] key: [M.key] (They agreed to respect the character they're becoming, and agreed to not ERP without express permission from the original.)") + log_game("FERMICHEM: [M] ckey: [M.key] is creating a clone, controlled by [C2]") + break + else + candies =- C2 + if(!SM.mind) //Something went wrong, use alt mechanics + return ..() + SM.mind.enslave_mind_to_creator(M) + + //If they're a zombie, they can try to negate it with this. + //I seriously wonder if anyone will ever use this function. + if(M.getorganslot(ORGAN_SLOT_ZOMBIE))//sure, it "treats" it, but "you've" still got it. Doesn't always work as well; needs a ghost. + var/obj/item/organ/zombie_infection/ZI = M.getorganslot(ORGAN_SLOT_ZOMBIE) + ZI.Remove(M) + ZI.Insert(SM) + log_game("FERMICHEM: [M] ckey: [M.key]'s zombie_infection has been transferred to their clone") + + to_chat(SM, "You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with your original, a perfect clone of your origin.") + + if(prob(50)) + to_chat(SM, "While you find your newfound existence strange, you share the same memories as [M.real_name]. However, You find yourself indifferent to the goals you previously had, and take more interest in your newfound independence, but still have an indescribable care for the safety of your original.") + log_game("FERMICHEM: [SM] ckey: [SM.key]'s is not bound by [M] ckey [M.key]'s will, and is free to determine their own goals, while respecting and acting as their origin.") + else + to_chat(SM, "While you find your newfound existence strange, you share the same memories as [M.real_name]. Your mind has not deviated from the tasks you set out to do, and now that there's two of you the tasks should be much easier.") + log_game("FERMICHEM: [SM] ckey: [SM.key]'s is bound by [M] ckey [M.key]'s objectives, and is encouraged to help them complete them.") + + to_chat(M, "You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with yourself.") + M.visible_message("[M] suddenly shudders, and splits into two identical twins!") + SM.copy_known_languages_from(M, FALSE) + playerClone = TRUE + M.next_move_modifier = 1 + M.nutrition -= 500 + + //Damage the clone + SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/2 + SM.adjustCloneLoss(60, 0) + SM.setBrainLoss(40) + SM.nutrition = startHunger/2 + + //Transfer remaining reagent to clone. I think around 30u will make a healthy clone, otherwise they'll have clone damage, blood loss, brain damage and hunger. + SM.reagents.add_reagent("SDGFheal", volume) + M.reagents.remove_reagent(id, volume) + log_game("FERMICHEM: [volume]u of SDGFheal has been transferred to the clone") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Sentient clones made") + return + + else if(playerClone == FALSE) //No candidates leads to two outcomes; if there's already a braincless clone, it heals the user, as well as being a rare souce of clone healing (thematic!). + unitCheck = TRUE + if(M.has_status_effect(/datum/status_effect/chem/SGDF)) // Heal the user if they went to all this trouble to make it and can't get a clone, the poor fellow. + switch(current_cycle) + if(21) + to_chat(M, "The cells fail to catalyse around a nucleation event, instead merging with your cells.") //This stuff is hard enough to make to rob a user of some benefit. Shouldn't replace Rezadone as it requires the user to not only risk making a player controlled clone, but also requires them to have split in two (which also requires 30u of SGDF). + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) + log_game("FERMICHEM: [M] ckey: [M.key] is being healed by SDGF") + if(22 to INFINITY) + M.adjustCloneLoss(-1, 0) + M.adjustBruteLoss(-1, 0) + M.adjustFireLoss(-1, 0) + M.heal_bodypart_damage(1,1) + M.reagents.remove_reagent(id, 1)//faster rate of loss. + else //If there's no ghosts, but they've made a large amount, then proceed to make flavourful clone, where you become fat and useless until you split. + switch(current_cycle) + if(21) + to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") + if(22 to 29) + M.nutrition = M.nutrition + (M.nutrition/10) + if(30) + to_chat(M, "You feel the synethic cells grow and expand within yourself, bloating your body outwards.") + if(31 to 49) + M.nutrition = M.nutrition + (M.nutrition/5) + if(50) + to_chat(M, "The synthetic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") + M.next_move_modifier += 4//If this makes you fast then please fix it, it should make you slow!! + //candidates = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies + if(51 to 79) + M.nutrition = M.nutrition + (M.nutrition/2) + if(80) + to_chat(M, "The cells begin to precipitate outwards of your body, you feel like you'll split soon...") + if (M.nutrition < 20000) + M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI + if(86)//Upon splitting, you get really hungry and are capable again. Deletes the chem after you're done. + M.nutrition = 15//YOU BEST BE EATTING AFTER THIS YOU CUTIE + M.next_move_modifier -= 4 + to_chat(M, "Your body splits away from the cell clone of yourself, leaving you with a drained and hollow feeling inside.") + + //clone + var/typepath = M.type + var/mob/living/fermi_Clone = new typepath(M.loc) + var/mob/living/carbon/C = fermi_Clone + + if(istype(C) && istype(M)) + C.real_name = M.real_name + M.dna.transfer_identity(C, transfer_SE=1) + C.updateappearance(mutcolor_update=1) + C.apply_status_effect(/datum/status_effect/chem/SGDF) + var/datum/status_effect/chem/SGDF/S = C.has_status_effect(/datum/status_effect/chem/SGDF) + S.original = M + S.originalmind = M.mind + S.status_set = TRUE + + log_game("FERMICHEM: [M] ckey: [M.key] has created a mindless clone of themselves") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Braindead clones made") + if(87 to INFINITY) + M.reagents.remove_reagent(id, volume)//removes SGDF on completion. Has to do it this way because of how i've coded it. If some madlab gets over 1k of SDGF, they can have the clone healing. + + + ..() + +/datum/reagent/fermi/SDGF/on_mob_delete(mob/living/M) //When the chem is removed, a few things can happen, mostly consolation prizes. + pollStarted = FALSE + if (playerClone == TRUE)//If the player made a clone with it, then thats all they get. + playerClone = FALSE + return + if (M.next_move_modifier == 4 && !M.has_status_effect(/datum/status_effect/chem/SGDF))//checks if they're ingested over 20u of the stuff, but fell short of the required 30u to make a clone. + to_chat(M, "You feel the cells begin to merge with your body, unable to reach nucleation, they instead merge with your body, healing any wounds.") + M.adjustCloneLoss(-10, 0) //I don't want to make Rezadone obsolete. + M.adjustBruteLoss(-25, 0)// Note that this takes a long time to apply and makes you fat and useless when it's in you, I don't think this small burst of healing will be useful considering how long it takes to get there. + M.adjustFireLoss(-25, 0) + M.blood_volume += 250 + M.heal_bodypart_damage(1,1) + M.next_move_modifier = 1 + if (M.nutrition < 1500) + M.nutrition += 250 + else if (unitCheck == TRUE && !M.has_status_effect(/datum/status_effect/chem/SGDF))// If they're ingested a little bit (10u minimum), then give them a little healing. + unitCheck = FALSE + to_chat(M, "the cells fail to hold enough mass to generate a clone, instead diffusing into your system.") + M.adjustBruteLoss(-10, 0) + M.adjustFireLoss(-10, 0) + M.blood_volume += 100 + M.next_move_modifier = 1 + if (M.nutrition < 1500) + M.nutrition += 500 + +/datum/reagent/fermi/SDGF/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume) + if(volume<5) + M.visible_message("The growth factor froths upon [M]'s body, failing to do anything of note.") + return + if(M.stat == DEAD) + if(M.suiciding || (HAS_TRAIT(M, TRAIT_NOCLONE)) || M.hellbound) + M.visible_message("The growth factor inertly sticks to [M]'s body, failing to do anything of note.") + return + if(!M.mind) + M.visible_message("The growth factor shudders, merging with [M]'s body, but is unable to replicate properly.") + + var/bodydamage = (M.getBruteLoss() + M.getFireLoss()) + var/typepath = M.type + volume =- 5 + + var/mob/living/carbon/human/fermi_Gclone = new typepath(M.loc) + var/mob/living/carbon/human/SM = fermi_Gclone + if(istype(SM) && istype(M)) + SM.real_name = M.real_name + M.dna.transfer_identity(SM) + SM.updateappearance(mutcolor_update=1) + M.mind.transfer_to(SM) + M.visible_message("[M]'s body shudders, the growth factor rapidly splitting into a new clone of [M].") + + if(bodydamage>50) + SM.adjustOxyLoss(-(bodydamage/10), 0) + SM.adjustToxLoss(-(bodydamage/10), 0) + SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/1.5 + SM.adjustCloneLoss((bodydamage/10), 0) + SM.setBrainLoss((bodydamage/10)) + SM.nutrition = 400 + if(bodydamage>200) + SM.gain_trauma_type(BRAIN_TRAUMA_MILD) + if(bodydamage>300) + var/obj/item/bodypart/l_arm = SM.get_bodypart(BODY_ZONE_L_ARM) //We get the body parts we want this way. + var/obj/item/bodypart/r_arm = SM.get_bodypart(BODY_ZONE_R_ARM) + l_arm.drop_limb() + r_arm.drop_limb() + if(bodydamage>400) + var/obj/item/bodypart/l_leg = SM.get_bodypart(BODY_ZONE_L_LEG) //We get the body parts we want this way. + var/obj/item/bodypart/r_leg = SM.get_bodypart(BODY_ZONE_R_LEG) + l_leg.drop_limb() + r_leg.drop_limb() + if(bodydamage>500) + SM.gain_trauma_type(BRAIN_TRAUMA_SEVERE) + if(bodydamage>600) + var/datum/species/mutation = pick(subtypesof(/datum/species)) + SM.set_species(mutation) + + //Transfer remaining reagent to clone. I think around 30u will make a healthy clone, otherwise they'll have clone damage, blood loss, brain damage and hunger. + SM.reagents.add_reagent("SDGFheal", volume) + M.reagents.remove_reagent(id, volume) + + SM.updatehealth() + SM.emote("gasp") + log_combat(M, M, "SDGF clone-vived", src) + ..() + +//Unobtainable, used in clone spawn. +/datum/reagent/fermi/SDGFheal + name = "synthetic-derived growth factor" + id = "SDGFheal" + metabolization_rate = 1 + can_synth = FALSE + +/datum/reagent/fermi/SDGFheal/on_mob_life(mob/living/carbon/M)//Used to heal the clone after splitting, the clone spawns damaged. (i.e. insentivies players to make more than required, so their clone doesn't have to be treated) + if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) + M.blood_volume += 10 + M.adjustCloneLoss(-2, 0) + M.setBrainLoss(-1) + M.nutrition += 10 + ..() + +//Unobtainable, used if SDGF is impure but not too impure +/datum/reagent/fermi/SDGFtox + name = "synthetic-derived growth factor" + id = "SDGFtox" + description = "A chem that makes a certain chemcat angry at you if you're reading this, how did you get this???"//i.e. tell me please, figure it's a good way to get pinged for bugfixes. + metabolization_rate = 1 + can_synth = FALSE + +/datum/reagent/fermi/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) + M.blood_volume -= 10 + M.adjustCloneLoss(2, 0) + ..() + +//Fail state of SDGF +/datum/reagent/fermi/SDZF + name = "synthetic-derived growth factor" + id = "SDZF" + description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. This message should never appear, how did you manage to get a hold of this?" + color = "#a502e0" // rgb: 96, 0, 255 + metabolization_rate = 0.5 * REAGENTS_METABOLISM + var/startHunger + can_synth = TRUE + +/datum/reagent/fermi/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. + switch(current_cycle)//Pretends to be normal + if(20) + to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") + startHunger = M.nutrition + if(21 to 29) + M.nutrition = M.nutrition + (M.nutrition/10) + if(30) + to_chat(M, "You feel the synethic cells grow and expand within yourself, bloating your body outwards.") + if(31 to 49) + M.nutrition = M.nutrition + (M.nutrition/5) + if(50) + to_chat(M, "The synethic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") + M.next_move_modifier = 4//If this makes you fast then please fix it, it should make you slow!! + if(51 to 73) + M.nutrition = M.nutrition + (M.nutrition/2) + if(74) + to_chat(M, "The cells begin to precipitate outwards of your body, but... something is wrong, the sythetic cells are beginnning to rot...") + if (M.nutrition < 20000) //whoever knows the maxcap, please let me know, this seems a bit low. + M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI + if(75 to 85) + M.adjustToxLoss(1, 0)// the warning! + + if(86)//mean clone time! + if (!M.reagents.has_reagent("pen_acid"))//Counterplay is pent.) + message_admins("(non-infectious) SDZF: Zombie spawned at [M] [COORD(M)]!") + M.nutrition = startHunger - 500//YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE + M.next_move_modifier = 1 + to_chat(M, "Your body splits away from the cell clone of yourself, your attempted clone birthing itself violently from you as it begins to shamble around, a terrifying abomination of science.") + M.visible_message("[M] suddenly shudders, and splits into a funky smelling copy of themselves!") + M.emote("scream") + M.adjustToxLoss(30, 0) + var/mob/living/simple_animal/hostile/unemployedclone/ZI = new(get_turf(M.loc)) + ZI.damage_coeff = list(BRUTE = ((1 / volume)**0.25) , BURN = ((1 / volume)**0.1), TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + ZI.real_name = M.real_name//Give your offspring a big old kiss. + ZI.name = M.real_name + ZI.desc = "[M]'s clone, gone horribly wrong." + log_game("FERMICHEM: [M] ckey: [M.key]'s clone has become a horrifying zombie instead") + M.reagents.remove_reagent(id, 20) + + else//easier to deal with + to_chat(M, "The pentetic acid seems to have stopped the decay for now, clumping up the cells into a horrifying tumour!") + M.nutrition = startHunger - 500 + var/mob/living/simple_animal/slime/S = new(get_turf(M.loc),"grey") //TODO: replace slime as own simplemob/add tumour slime cores for science/chemistry interplay + S.damage_coeff = list(BRUTE = ((1 / volume)**0.1) , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + S.name = "Living teratoma" + S.real_name = "Living teratoma"//horrifying!! + S.rabid = 1//Make them an angery boi + M.reagents.remove_reagent(id, volume) + to_chat(M, "A large glob of the tumour suddenly splits itself from your body. You feel grossed out and slimey...") + log_game("FERMICHEM: [M] ckey: [M.key]'s clone has become a horrifying teratoma instead") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Zombie clones made!") + + if(87 to INFINITY) + M.adjustToxLoss(1, 0) + ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm new file mode 100644 index 0000000000..d05cfb552e --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm @@ -0,0 +1,152 @@ +/* +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ASTROGEN +/////////////////////////////////////////////////////////////////////////////////////////////////// +More fun chems! +When you take it, it spawns a ghost that the player controls. (No access to deadchat) +This ghost moves pretty quickly and is mostly invisible, but is still visible for people with eyes. +When it's out of your system, you return back to yourself. It doesn't last long and metabolism of the chem is exponential. +Addiction is particularlly brutal, it slowly turns you invisible with flavour text, then kills you at a low enough alpha. (i've also added something to prevent geneticists speeding this up) +There's afairly major catch regarding the death though. I'm not gonna say here, go read the code, it explains it and puts my comments on it in context. I know that anyone reading it without understanding it is going to freak out so, this is my attempt to get you to read it and understand it. +I'd like to point out from my calculations it'll take about 60-80 minutes to die this way too. Plenty of time to visit me and ask for some pills to quench your addiction. +*/ + + + +/datum/reagent/fermi/astral // Gives you the ability to astral project for a moment! + name = "Astrogen" + id = "astral" + description = "An opalescent murky liquid that is said to distort your soul from your being." + color = "#A080H4" // rgb: , 0, 255 + taste_description = "your mind" + metabolization_rate = 0//Removal is exponential, see code + overdose_threshold = 20 + addiction_threshold = 24.5 + addiction_stage1_end = 9999//Should never end. There is no escape make your time + var/mob/living/carbon/origin + var/mob/living/simple_animal/astral/G = null + var/datum/mind/originalmind + var/antiGenetics = 255 + var/sleepytime = 0 + InverseChemVal = 0.25 + can_synth = FALSE + +/datum/action/chem/astral + name = "Return to body" + var/mob/living/carbon/origin = null + var/mob/living/simple_animal/hostile/retaliate/ghost = null + +/datum/action/chem/astral/Trigger() + ghost.mind.transfer_to(origin) + qdel(src) + +/datum/reagent/fermi/astral/reaction_turf(turf/T, reac_volume) + if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel)) + var/turf/open/floor/F = T + F.PlaceOnTop(/turf/open/floor/fakespace) + ..() + +/datum/reagent/fermi/astral/reaction_obj(obj/O, reac_volume) + if(istype(O, /obj/item/bedsheet)) + new /obj/item/bedsheet/cosmos(get_turf(O)) + qdel(O) + + +/datum/reagent/fermi/astral/on_mob_life(mob/living/carbon/M) // Gives you the ability to astral project for a moment! + M.alpha = 255 + if(current_cycle == 0) + originalmind = M.mind + log_game("FERMICHEM: [M] ckey: [M.key] became an astral ghost") + origin = M + if (G == null) + G = new(get_turf(M.loc)) + G.name = "[M]'s astral projection" + var/datum/action/chem/astral/AS = new(G) + AS.origin = M + AS.ghost = G + if(M.mind) + M.mind.transfer_to(G) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Astral projections") + if(overdosed) + if(prob(50)) + to_chat(G, "The high conentration of Astrogen in your blood causes you to lapse your concentration for a moment, bringing your projection back to yourself!") + do_teleport(G, M.loc) + M.reagents.remove_reagent(id, current_cycle/10, FALSE)//exponent + sleepytime+=5 + if(G)//This is a mess because of how slow qdel is, so this is all to stop runtimes. + if(G.mind) + if(G.stat == DEAD || G.pseudo_death == TRUE) + G.mind.transfer_to(M) + qdel(G) + ..() + +/datum/reagent/fermi/astral/on_mob_delete(mob/living/carbon/M) + if(!G) + if(M.mind) + var/mob/living/simple_animal/astral/G = new(get_turf(M.loc)) + M.mind.transfer_to(G)//Just in case someone else is inside of you, it makes them a ghost and should hopefully bring them home at the end. + to_chat(G, "[M]'s conciousness snaps back to them as their astrogen runs out, kicking your projected mind out!'") + log_game("FERMICHEM: [M]'s possesser has been booted out into a astral ghost!") + originalmind.transfer_to(M) + else if(G.mind) + G.mind.transfer_to(origin) + qdel(G) + if(overdosed) + to_chat(M, "The high volume of astrogen you just took causes you to black out momentarily as your mind snaps back to your body.") + M.Sleeping(sleepytime, 0) + antiGenetics = 255 + if(G)//just in case + qdel(G) + log_game("FERMICHEM: [M] has astrally returned to their body!") + ..() + +//Okay so, this might seem a bit too good, but my counterargument is that it'll likely take all round to eventually kill you this way, then you have to be revived without a body. It takes approximately 50-80 minutes to die from this. +/datum/reagent/fermi/astral/addiction_act_stage1(mob/living/carbon/M) + if(addiction_stage < 2) + antiGenetics = 255 + M.alpha = 255 //Antigenetics is to do with stopping geneticists from turning people invisible to kill them. + if(prob(70)) + M.alpha-- + antiGenetics-- + switch(antiGenetics) + if(245) + to_chat(M, "You notice your body starting to disappear, maybe you took too much Astrogen...?") + M.alpha-- + antiGenetics-- + log_game("FERMICHEM: [M] ckey: [M.key] has become addicted to Astrogen") + if(220) + to_chat(M, "Your addiction is only getting worse as your body disappears. Maybe you should get some more, and fast?") + M.alpha-- + antiGenetics-- + if(200) + to_chat(M, "You feel a substantial part of your soul flake off into the ethereal world, rendering yourself unclonable.") + M.alpha-- + antiGenetics-- + ADD_TRAIT(M, TRAIT_NOCLONE, "astral") //So you can't scan yourself, then die, to metacomm. You can only use your memories if you come back as something else. + M.hellbound = TRUE + if(180) + to_chat(M, "You feel fear build up in yourself as more and more of your body and consciousness begins to fade.") + M.alpha-- + antiGenetics-- + if(120) + to_chat(M, "As you lose more and more of yourself, you start to think that maybe shedding your mortality isn't too bad.") + M.alpha-- + antiGenetics-- + if(80) + to_chat(M, "You feel a thrill shoot through your body as what's left of your mind contemplates your forthcoming oblivion.") + M.alpha-- + antiGenetics-- + if(45) + to_chat(M, "The last vestiges of your mind eagerly await your imminent annihilation.") + M.alpha-- + antiGenetics-- + if(-INFINITY to 30) + to_chat(M, "Your body disperses from existence, as you become one with the universe.") + to_chat(M, "As your body disappears, your consciousness doesn't. Should you find a way back into the mortal coil, your memories of your previous life remain with you. (At the cost of staying in character while dead. Failure to do this may get you banned from this chem. You are still obligated to follow your directives if you play a midround antag, you do not remember the afterlife IC)")//Legalised IC OOK? I have a suspicion this won't make it past the review. At least it'll be presented as a neat idea! If this is unacceptable how about the player can retain living memories across lives if they die in this way only. + deadchat_broadcast("[M] has become one with the universe, meaning that their IC conciousness is continuous in a new life. If they find a way back to life, they are allowed to remember their previous life. Be careful what you say. If they abuse this, bwoink the FUCK outta them.") + M.visible_message("[M] suddenly disappears, their body evaporating from existence, freeing [M] from their mortal coil.") + message_admins("[M] (ckey: [M.ckey]) has become one with the universe, and have continuous memories thoughout their lives should they find a way to come back to life (such as an inteligence potion, midround antag, ghost role).") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Astral obliterations") + qdel(M) //Approx 60minutes till death from initial addiction + log_game("FERMICHEM: [M] ckey: [M.key] has been obliterated from Astrogen addiction") + ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm new file mode 100644 index 0000000000..bf915d5b6f --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm @@ -0,0 +1,203 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// EIGENSTASIUM +/////////////////////////////////////////////////////////////////////////////////////////////////// +//eigenstate Chem +//Teleports you to chemistry and back +//OD teleports you randomly around the Station +//Addiction send you on a wild ride and replaces you with an alternative reality version of yourself. +//During the process you get really hungry, then your items start teleporting randomly, +//then alternative versions of yourself are brought in from a different universe and they yell at you. +//and finally you yourself get teleported to an alternative universe, and character your playing is replaced with said alternative + +/datum/reagent/fermi/eigenstate + name = "Eigenstasium" + id = "eigenstate" + description = "A strange mixture formed from a controlled reaction of bluespace with plasma, that causes localised eigenstate fluxuations within the patient" + taste_description = "wiggly cosmic dust." + color = "#5020F4" // rgb: 50, 20, 255 + overdose_threshold = 15 + addiction_threshold = 15 + metabolization_rate = 1.2 * REAGENTS_METABOLISM + addiction_stage2_end = 30 + addiction_stage3_end = 41 + addiction_stage4_end = 44 //Incase it's too long + data = list("location_created" = null) + var/turf/location_created + var/obj/effect/overlay/holo_pad_hologram/Eigenstate + var/turf/open/location_return = null + var/addictCyc3 = 0 + var/mob/living/carbon/fermi_Tclone = null + var/teleBool = FALSE + pH = 3.7 + can_synth = TRUE + +/datum/reagent/fermi/eigenstate/on_new(list/data) + location_created = data.["location_created"] + +//Main functions +/datum/reagent/fermi/eigenstate/on_mob_life(mob/living/M) //Teleports to chemistry! + if(current_cycle == 0) + log_game("FERMICHEM: [M] ckey: [M.key] took eigenstasium") + + //make hologram at return point + Eigenstate = new(loc) + Eigenstate.appearance = M.appearance + Eigenstate.alpha = 170 + Eigenstate.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Eigenstate.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. + Eigenstate.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Eigenstate.setAnchored(TRUE)//So space wind cannot drag it. + Eigenstate.name = "[M]'s' eigenstate"//If someone decides to right click. + Eigenstate.set_light(2) //hologram lighting + + location_return = get_turf(M) //sets up return point + to_chat(M, "You feel your wavefunction split!") + if(purity > 0.9) //Teleports you home if it's pure enough + if(!location_created && data) //Just in case + location_created = data.["location_created"] + log_game("FERMICHEM: [M] ckey: [M.key] returned to [location_created] using eigenstasium") + do_sparks(5,FALSE,M) + do_teleport(M, location_created, 0, asoundin = 'sound/effects/phasein.ogg') + do_sparks(5,FALSE,M) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Pure eigentstate jumps") + + + if(prob(20)) + do_sparks(5,FALSE,M) + ..() + +/datum/reagent/fermi/eigenstate/on_mob_delete(mob/living/M) //returns back to original location + do_sparks(5,FALSE,M) + to_chat(M, "You feel your wavefunction collapse!") + do_teleport(M, location_return, 0, asoundin = 'sound/effects/phasein.ogg') //Teleports home + do_sparks(5,FALSE,M) + qdel(Eigenstate) + ..() + +/datum/reagent/fermi/eigenstate/overdose_start(mob/living/M) //Overdose, makes you teleport randomly + . = ..() + to_chat(M, "Oh god, you feel like your wavefunction is about to tear.") + log_game("FERMICHEM: [M] ckey: [M.key] has overdosed on eigenstasium") + M.Jitter(20) + metabolization_rate += 0.5 //So you're not stuck forever teleporting. + +/datum/reagent/fermi/eigenstate/overdose_process(mob/living/M) //Overdose, makes you teleport randomly, probably one of my favourite effects. Sometimes kills you. + do_sparks(5,FALSE,M) + do_teleport(M, get_turf(M), 10, asoundin = 'sound/effects/phasein.ogg') + do_sparks(5,FALSE,M) + ..() + +//Addiction +/datum/reagent/fermi/eigenstate/addiction_act_stage1(mob/living/M) //Welcome to Fermis' wild ride. + if(addiction_stage == 1) + to_chat(M, "Your wavefunction feels like it's been ripped in half. You feel empty inside.") + log_game("FERMICHEM: [M] ckey: [M.key] has become addicted to eigenstasium") + M.Jitter(10) + M.nutrition = M.nutrition - (M.nutrition/15) + ..() + +/datum/reagent/fermi/eigenstate/addiction_act_stage2(mob/living/M) + if(addiction_stage == 11) + to_chat(M, "You start to convlse violently as you feel your consciousness split and merge across realities as your possessions fly wildy off your body.") + M.Jitter(200) + M.Knockdown(200) + M.Stun(80) + var/items = M.get_contents() + if(!LAZYLEN(items)) + return ..() + var/obj/item/I = pick(items) + if(istype(I, /obj/item/implant)) + qdel(I) + to_chat(M, "You feel your implant rip itself out of you, sent flying off to another dimention!") + else + M.dropItemToGround(I, TRUE) + do_sparks(5,FALSE,I) + do_teleport(I, get_turf(I), 5, no_effects=TRUE); + do_sparks(5,FALSE,I) + ..() + +/datum/reagent/fermi/eigenstate/addiction_act_stage3(mob/living/M)//Pulls multiple copies of the character from alternative realities while teleporting them around! + //Clone function - spawns a clone then deletes it - simulates multiple copies of the player teleporting in + switch(addictCyc3) //Loops 0 -> 1 -> 2 -> 1 -> 2 -> 1 ...ect. + if(0) + M.Jitter(100) + to_chat(M, "Your eigenstate starts to rip apart, causing a localised collapsed field as you're ripped from alternative universes, trapped around the densisty of the event horizon.") + if(1) + var/typepath = M.type + fermi_Tclone = new typepath(M.loc) + var/mob/living/carbon/C = fermi_Tclone + fermi_Tclone.appearance = M.appearance + C.real_name = M.real_name + M.visible_message("[M] collapses in from an alternative reality!") + do_teleport(C, get_turf(C), 2, no_effects=TRUE) //teleports clone so it's hard to find the real one! + do_sparks(5,FALSE,C) + C.emote("spin") + M.emote("spin") + M.emote("me",1,"flashes into reality suddenly, gasping as they gaze around in a bewildered and highly confused fashion!",TRUE) + C.emote("me",1,"[pick("says", "cries", "mewls", "giggles", "shouts", "screams", "gasps", "moans", "whispers", "announces")], \"[pick("Bugger me, whats all this then?", "Hot damn, where is this?", "sacre bleu! Ou suis-je?!", "Yee haw! This is one hell of a hootenanny!", "WHAT IS HAPPENING?!", "Picnic!", "Das ist nicht deutschland. Das ist nicht akzeptabel!!!", "I've come from the future to warn you to not take eigenstasium! Oh no! I'm too late!", "You fool! You took too much eigenstasium! You've doomed us all!", "What...what's with these teleports? It's like one of my Japanese animes...!", "Ik stond op het punt om mehki op tafel te zetten, en nu, waar ben ik?", "This must be the will of Stein's gate.", "Fermichem was a mistake", "This is one hell of a beepsky smash.", "Now neither of us will be virgins!")]\"") + if(2) + var/mob/living/carbon/C = fermi_Tclone + do_sparks(5,FALSE,C) + qdel(C) //Deletes CLONE, or at least I hope it is. + M.visible_message("[M] is snapped across to a different alternative reality!") + addictCyc3 = 0 //counter + fermi_Tclone = null + addictCyc3++ + do_teleport(M, get_turf(M), 2, no_effects=TRUE) //Teleports player randomly + do_sparks(5,FALSE,M) + ..() + +/datum/reagent/fermi/eigenstate/addiction_act_stage4(mob/living/M) //Thanks for riding Fermis' wild ride. Mild jitter and player buggery. + if(addiction_stage == 42) + do_sparks(5,FALSE,M) + do_teleport(M, get_turf(M), 2, no_effects=TRUE) //teleports clone so it's hard to find the real one! + do_sparks(5,FALSE,M) + M.Sleeping(100, 0) + M.Jitter(50) + M.Knockdown(100) + to_chat(M, "You feel your eigenstate settle, snapping an alternative version of yourself into reality. All your previous memories are lost and replaced with the alternative version of yourself. This version of you feels more [pick("affectionate", "happy", "lusty", "radical", "shy", "ambitious", "frank", "voracious", "sensible", "witty")] than your previous self, sent to god knows what universe.") + M.emote("me",1,"flashes into reality suddenly, gasping as they gaze around in a bewildered and highly confused fashion!",TRUE) + log_game("FERMICHEM: [M] ckey: [M.key] has become an alternative universe version of themselves.") + M.reagents.remove_all_type(/datum/reagent, 100, 0, 1) + /* + for(var/datum/mood_event/Me in M) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, Me) //Why does this not work? + */ + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "Alternative dimension", /datum/mood_event/eigenstate) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Wild rides ridden") + + if(prob(20)) + do_sparks(5,FALSE,M) + SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "[id]_overdose")//holdover until above fix works + ..() + +/datum/reagent/fermi/eigenstate/reaction_turf(turf/T, reac_volume) + //if(cached_purity < 0.99) To add with next batch of fixes and tweaks. + var/obj/structure/closet/First + var/obj/structure/closet/Previous + for(var/obj/structure/closet/C in T.contents) + if(C.eigen_teleport == TRUE) + C.visible_message("[C] fizzes, it's already linked to something else!") + continue + if(!Previous) + First = C + Previous = C + continue + C.eigen_teleport = TRUE + C.eigen_target = Previous + C.color = "#9999FF" //Tint the locker slightly. + C.alpha = 200 + do_sparks(5,FALSE,C) + Previous = C + if(!First) + return + if(Previous == First) + return + First.eigen_teleport = TRUE + First.eigen_target = Previous + First.color = "#9999FF" + First.alpha = 200 + do_sparks(5,FALSE,First) + First.visible_message("The lockers' eigenstates spilt and merge, linking each of their contents together.") + +//eigenstate END diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm new file mode 100644 index 0000000000..d603f3ba10 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -0,0 +1,365 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// BREAST ENLARGE +/////////////////////////////////////////////////////////////////////////////////////////////////// +//Other files that are relivant: +//modular_citadel/code/datums/status_effects/chems.dm +//modular_citadel/code/modules/arousal/organs/breasts.dm + +//breast englargement +//Honestly the most requested chems +//I'm not a very kinky person, sorry if it's not great +//I tried to make it interesting..!! + +//Normal function increases your breast size by 0.05, 10units = 1 cup. +//If you get stupid big, it presses against your clothes, causing brute and oxydamage. Then rips them off. +//If you keep going, it makes you slower, in speed and action. +//decreasing your size will return you to normal. +//(see the status effect in chem.dm) +//Overdosing on (what is essentially space estrogen) makes you female, removes balls and shrinks your dick. +//OD is low for a reason. I'd like fermichems to have low ODs, and dangerous ODs, and since this is a meme chem that everyone will rush to make, it'll be a lesson learnt early. + +/datum/reagent/fermi/breast_enlarger + name = "Succubus milk" + id = "breast_enlarger" + description = "A volatile collodial mixture derived from milk that encourages mammary production via a potent estrogen mix." + color = "#E60584" // rgb: 96, 0, 255 + taste_description = "a milky ice cream like flavour." + overdose_threshold = 17 + metabolization_rate = 0.25 + ImpureChem = "BEsmaller" //If you make an inpure chem, it stalls growth + InverseChemVal = 0.35 + InverseChem = "BEsmaller" //At really impure vols, it just becomes 100% inverse + can_synth = FALSE + +/datum/reagent/fermi/breast_enlarger/on_mob_add(mob/living/carbon/M) + . = ..() + if(!ishuman(M)) //The monkey clause + if(volume >= 15) //To prevent monkey breast farms + var/turf/T = get_turf(M) + var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(T) + var/list/seen = viewers(8, T) + for(var/mob/S in seen) + to_chat(S, "A pair of breasts suddenly fly out of the [M]!") + //var/turf/T2 = pick(turf in view(5, M)) + var/T2 = get_random_station_turf() + M.adjustBruteLoss(25) + M.Knockdown(50) + M.Stun(50) + B.throw_at(T2, 8, 1) + M.reagents.remove_reagent(id, volume) + return + log_game("FERMICHEM: [M] ckey: [M.key] has ingested Sucubus milk") + var/mob/living/carbon/human/H = M + H.genital_override = TRUE + var/obj/item/organ/genital/breasts/B = H.getorganslot("breasts") + if(!B) + H.emergent_genital_call() + return + if(!B.size == "huge") + var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5) + B.prev_size = B.size + B.cached_size = sizeConv[B.size] + +/datum/reagent/fermi/breast_enlarger/on_mob_life(mob/living/carbon/M) //Increases breast size + if(!ishuman(M))//Just in case + return..() + + var/mob/living/carbon/human/H = M + var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts") + if(!B) //If they don't have breasts, give them breasts. + + //If they have Acute hepatic pharmacokinesis, then route processing though liver. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + if(L) + L.swelling+= 0.05 + return..() + else + M.adjustToxLoss(1) + return..() + + //otherwise proceed as normal + var/obj/item/organ/genital/breasts/nB = new + nB.Insert(M) + if(nB) + if(M.dna.species.use_skintones && M.dna.features["genitals_use_skintone"]) + nB.color = skintone2hex(H.skin_tone) + else if(M.dna.features["breasts_color"]) + nB.color = "#[M.dna.features["breasts_color"]]" + else + nB.color = skintone2hex(H.skin_tone) + nB.size = "flat" + nB.cached_size = 0 + nB.prev_size = 0 + to_chat(M, "Your chest feels warm, tingling with newfound sensitivity.") + M.reagents.remove_reagent(id, 5) + B = nB + //If they have them, increase size. If size is comically big, limit movement and rip clothes. + B.cached_size = B.cached_size + 0.05 + if (B.cached_size >= 8.5 && B.cached_size < 9) + if(H.w_uniform || H.wear_suit) + var/target = M.get_bodypart(BODY_ZONE_CHEST) + to_chat(M, "Your breasts begin to strain against your clothes tightly!") + M.adjustOxyLoss(5, 0) + M.apply_damage(1, BRUTE, target) + B.update() + ..() + +/datum/reagent/fermi/breast_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a female if male and ODing, doesn't touch nonbinary and object genders. + + //Acute hepatic pharmacokinesis. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + L.swelling+= 0.05 + return ..() + + var/obj/item/organ/genital/penis/P = M.getorganslot("penis") + var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles") + var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina") + var/obj/item/organ/genital/womb/W = M.getorganslot("womb") + + if(M.gender == MALE) + M.gender = FEMALE + M.visible_message("[M] suddenly looks more feminine!", "You suddenly feel more feminine!") + + if(P) + P.cached_length = P.cached_length - 0.05 + P.update() + if(T) + T.Remove(M) + if(!V) + var/obj/item/organ/genital/vagina/nV = new + nV.Insert(M) + V = nV + if(!W) + var/obj/item/organ/genital/womb/nW = new + nW.Insert(M) + W = nW + ..() + +/datum/reagent/fermi/BEsmaller + name = "Modesty milk" + id = "BEsmaller" + description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix." + color = "#E60584" // rgb: 96, 0, 255 + taste_description = "a milky ice cream like flavour." + metabolization_rate = 0.25 + can_synth = FALSE + +/datum/reagent/fermi/BEsmaller/on_mob_life(mob/living/carbon/M) + var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts") + if(!B) + //Acute hepatic pharmacokinesis. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + L.swelling-= 0.05 + return ..() + + //otherwise proceed as normal + return..() + B.cached_size = B.cached_size - 0.05 + B.update() + ..() + +/datum/reagent/fermi/BEsmaller_hypo + name = "Rectify milk" //Rectify + id = "BEsmaller_hypo" + color = "#E60584" + taste_description = "a milky ice cream like flavour." + metabolization_rate = 0.25 + description = "A medicine used to treat organomegaly in a patient's breasts." + var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5) + can_synth = TRUE + +/datum/reagent/fermi/BEsmaller_hypo/on_mob_add(mob/living/carbon/M) + . = ..() + if(!M.getorganslot("vagina")) + if(M.dna.features["has_vag"]) + var/obj/item/organ/genital/vagina/nV = new + nV.Insert(M) + if(!M.getorganslot("womb")) + if(M.dna.features["has_womb"]) + var/obj/item/organ/genital/womb/nW = new + nW.Insert(M) + +/datum/reagent/fermi/BEsmaller_hypo/on_mob_life(mob/living/carbon/M) + var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts") + if(!B) + return..() + if(!M.dna.features["has_breasts"])//Fast fix for those who don't want it. + B.cached_size = B.cached_size - 0.1 + B.update() + else if(B.cached_size > (sizeConv[M.dna.features["breasts_size"]]+0.1)) + B.cached_size = B.cached_size - 0.05 + B.update() + else if(B.cached_size < (sizeConv[M.dna.features["breasts_size"]])+0.1) + B.cached_size = B.cached_size + 0.05 + B.update() + ..() + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PENIS ENLARGE +/////////////////////////////////////////////////////////////////////////////////////////////////// +//See breast explanation, it's the same but with taliwhackers +//instead of slower movement and attacks, it slows you and increases the total blood you need in your system. +//Since someone else made this in the time it took me to PR it, I merged them. +/datum/reagent/fermi/penis_enlarger // Due to popular demand...! + name = "Incubus draft" + id = "penis_enlarger" + description = "A volatile collodial mixture derived from various masculine solutions that encourages a larger gentleman's package via a potent testosterone mix, formula derived from a collaboration from Fermichem and Doctor Ronald Hyatt, who is well known for his phallus palace." //The toxic masculinity thing is a joke because I thought it would be funny to include it in the reagents, but I don't think many would find it funny? dumb + color = "#888888" // This is greyish..? + taste_description = "chinese dragon powder" + overdose_threshold = 17 //ODing makes you male and removes female genitals + metabolization_rate = 0.5 + ImpureChem = "PEsmaller" //If you make an inpure chem, it stalls growth + InverseChemVal = 0.35 + InverseChem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead. + can_synth = FALSE + +/datum/reagent/fermi/penis_enlarger/on_mob_add(mob/living/carbon/M) + . = ..() + if(!ishuman(M)) //Just monkeying around. + if(volume >= 15) //to prevent monkey penis farms + var/turf/T = get_turf(M) + var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(T) + var/list/seen = viewers(8, T) + for(var/mob/S in seen) + to_chat(S, "A penis suddenly flies out of the [M]!") + var/T2 = get_random_station_turf() + M.adjustBruteLoss(25) + M.Knockdown(50) + M.Stun(50) + P.throw_at(T2, 8, 1) + M.reagents.remove_reagent(id, volume) + return + var/mob/living/carbon/human/H = M + H.genital_override = TRUE + var/obj/item/organ/genital/penis/P = M.getorganslot("penis") + if(!P) + H.emergent_genital_call() + return + P.prev_length = P.length + P.cached_length = P.length + +/datum/reagent/fermi/penis_enlarger/on_mob_life(mob/living/carbon/M) //Increases penis size, 5u = +1 inch. + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + var/obj/item/organ/genital/penis/P = M.getorganslot("penis") + if(!P)//They do have a preponderance for escapism, or so I've heard. + + //If they have Acute hepatic pharmacokinesis, then route processing though liver. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + if(L) + L.swelling+= 0.05 + return..() + else + M.adjustToxLoss(1) + return..() + + //otherwise proceed as normal + var/obj/item/organ/genital/penis/nP = new + nP.Insert(M) + if(nP) + nP.length = 1 + to_chat(M, "Your groin feels warm, as you feel a newly forming bulge down below.") + nP.cached_length = 1 + nP.prev_length = 1 + M.reagents.remove_reagent(id, 5) + P = nP + + P.cached_length = P.cached_length + 0.1 + if (P.cached_length >= 20.5 && P.cached_length < 21) + if(H.w_uniform || H.wear_suit) + var/target = M.get_bodypart(BODY_ZONE_CHEST) + to_chat(M, "Your cock begin to strain against your clothes tightly!") + M.apply_damage(2.5, BRUTE, target) + + P.update() + ..() + +/datum/reagent/fermi/penis_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders. + //Acute hepatic pharmacokinesis. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + L.swelling+= 0.05 + return..() + + var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts") + var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles") + var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina") + var/obj/item/organ/genital/womb/W = M.getorganslot("womb") + + if(M.gender == FEMALE) + M.gender = MALE + M.visible_message("[M] suddenly looks more masculine!", "You suddenly feel more masculine!") + + if(B) + B.cached_size = B.cached_size - 0.05 + B.update() + if(V) + V.Remove(M) + if(W) + W.Remove(M) + if(!T) + var/obj/item/organ/genital/testicles/nT = new + nT.Insert(M) + T = nT + ..() + +/datum/reagent/fermi/PEsmaller // Due to cozmo's request...! + name = "Chastity draft" + id = "PEsmaller" + description = "A volatile collodial mixture derived from various masculine solutions that encourages a smaller gentleman's package via a potent testosterone mix, formula derived from a collaboration from Fermichem and Doctor Ronald Hyatt, who is well known for his phallus palace." + color = "#888888" // This is greyish..? + taste_description = "chinese dragon powder" + metabolization_rate = 0.5 + can_synth = FALSE + +/datum/reagent/fermi/PEsmaller/on_mob_life(mob/living/carbon/M) + var/mob/living/carbon/human/H = M + var/obj/item/organ/genital/penis/P = H.getorganslot("penis") + if(!P) + //Acute hepatic pharmacokinesis. + if(HAS_TRAIT(M, TRAIT_PHARMA)) + var/obj/item/organ/liver/L = M.getorganslot("liver") + L.swelling-= 0.05 + return..() + + //otherwise proceed as normal + return..() + P.cached_length = P.cached_length - 0.1 + P.update() + ..() + +/datum/reagent/fermi/PEsmaller_hypo + name = "Rectify draft" + id = "PEsmaller_hypo" + color = "#888888" // This is greyish..? + taste_description = "chinese dragon powder" + description = "A medicine used to treat organomegaly in a patient's penis." + metabolization_rate = 0.5 + can_synth = TRUE + +/datum/reagent/fermi/PEsmaller_hypo/on_mob_add(mob/living/carbon/M) + . = ..() + if(!M.getorganslot("testicles")) + if(M.dna.features["has_balls"]) + var/obj/item/organ/genital/testicles/nT = new + nT.Insert(M) + +/datum/reagent/fermi/PEsmaller_hypo/on_mob_life(mob/living/carbon/M) + var/obj/item/organ/genital/penis/P = M.getorganslot("penis") + if(!P) + return ..() + if(!M.dna.features["has_cock"])//Fast fix for those who don't want it. + P.cached_length = P.cached_length - 0.2 + P.update() + else if(P.cached_length > (M.dna.features["cock_length"]+0.1)) + P.cached_length = P.cached_length - 0.1 + P.update() + else if(P.cached_length < (M.dna.features["cock_length"]+0.1)) + P.cached_length = P.cached_length + 0.1 + P.update() + ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm new file mode 100644 index 0000000000..275c244a83 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm @@ -0,0 +1,462 @@ + //Fermichem!! +//Fun chems for all the family + +/datum/reagent/fermi + name = "Fermi" //This should never exist, but it does so that it can exist in the case of errors.. + id = "fermi" + taste_description = "affection and love!" + can_synth = FALSE + +//This should process fermichems to find out how pure they are and what effect to do. +/datum/reagent/fermi/on_mob_add(mob/living/carbon/M, amount) + . = ..() + if(!M) + return + if(purity < 0) + CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") + if (purity == 1 || DoNotSplit == TRUE) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]") + return + else if (InverseChemVal > purity)//Turns all of a added reagent into the inverse chem + M.reagents.remove_reagent(id, amount, FALSE) + M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [InverseChem]") + return + else + var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem + M.reagents.remove_reagent(id, (impureVol), FALSE) + M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]") + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [ImpureChem]") + return + +//When merging two fermichems, see above +/datum/reagent/fermi/on_merge(data, amount, mob/living/carbon/M, purity)//basically on_mob_add but for merging + . = ..() + if(!ishuman(M)) + return + if (purity < 0) + CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") + if (purity == 1 || DoNotSplit == TRUE) + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [id] in themselves") + return + else if (InverseChemVal > purity) + M.reagents.remove_reagent(id, amount, FALSE) + M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1) + for(var/datum/reagent/fermi/R in M.reagents.reagent_list) + if(R.name == "") + R.name = name//Negative effects are hidden + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [InverseChem]") + return + else + var/impureVol = amount * (1 - purity) + M.reagents.remove_reagent(id, impureVol, FALSE) + M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1) + for(var/datum/reagent/fermi/R in M.reagents.reagent_list) + if(R.name == "") + R.name = name//Negative effects are hidden + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]") + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [ImpureChem]") + return + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// HATIMUIM +/////////////////////////////////////////////////////////////////////////////////////////////////// +//Adds a heat upon your head, and tips their hat +//Also has a speech alteration effect when the hat is there +//Increase armour; 1 armour per 10u +//but if you OD it becomes negative. + + +/datum/reagent/fermi/hatmium //for hatterhat + name = "Hat growth serium" + id = "hatmium" + description = "A strange substance that draws in a hat from the hat dimention." + color = "#7c311a" // rgb: , 0, 255 + taste_description = "like jerky, whiskey and an off aftertaste of a crypt." + metabolization_rate = 0.2 + overdose_threshold = 25 + DoNotSplit = TRUE + pH = 4 + can_synth = TRUE + + +/datum/reagent/fermi/hatmium/on_mob_add(mob/living/carbon/human/M) + . = ..() + if(M.head) + var/obj/item/W = M.head + if(istype(W, /obj/item/clothing/head/hattip)) + qdel(W) + else + M.dropItemToGround(W, TRUE) + var/hat = new /obj/item/clothing/head/hattip() + M.equip_to_slot(hat, SLOT_HEAD, 1, 1) + + +/datum/reagent/fermi/hatmium/on_mob_life(mob/living/carbon/human/M) + if(!istype(M.head, /obj/item/clothing/head/hattip)) + return ..() + var/hatArmor = 0 + if(!overdosed) + hatArmor = (purity/10) + else + hatArmor = - (purity/10) + if(hatArmor > 90) + return ..() + var/obj/item/W = M.head + W.armor = W.armor.modifyAllRatings(hatArmor) + ..() + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FURRANIUM +/////////////////////////////////////////////////////////////////////////////////////////////////// +//OwO whats this? +//Makes you nya and awoo +//At a certain amount of time in your system it gives you a fluffy tongue, if pure enough, it's permanent. + +/datum/reagent/fermi/furranium + name = "Furranium" + id = "furranium" + description = "OwO whats this?" + color = "#f9b9bc" // rgb: , 0, 255 + taste_description = "dewicious degenyewacy" + metabolization_rate = 0.5 * REAGENTS_METABOLISM + InverseChemVal = 0 + var/obj/item/organ/tongue/nT + DoNotSplit = TRUE + pH = 5 + var/obj/item/organ/tongue/T + can_synth = TRUE + +/datum/reagent/fermi/furranium/reaction_mob(mob/living/carbon/human/M, method=INJECT, reac_volume) + if(method == INJECT) + var/turf/T = get_turf(M) + M.adjustOxyLoss(15) + M.Knockdown(50) + M.Stun(50) + M.emote("cough") + var/obj/item/toy/plush/P = pick(subtypesof(/obj/item/toy/plush)) + new P(T) + to_chat(M, "You feel a lump form in your throat, as you suddenly cough up what seems to be a hairball?") + var/list/seen = viewers(8, T) + for(var/mob/S in seen) + to_chat(S, "[M] suddenly coughs up a [P.name]!") + var/T2 = get_random_station_turf() + P.throw_at(T2, 8, 1) + ..() + +/datum/reagent/fermi/furranium/on_mob_life(mob/living/carbon/M) + + switch(current_cycle) + if(1 to 9) + if(prob(20)) + to_chat(M, "Your tongue feels... fluffy") + if(10 to 15) + if(prob(10)) + to_chat(M, "You find yourself unable to supress the desire to meow!") + M.emote("nya") + if(prob(10)) + to_chat(M, "You find yourself unable to supress the desire to howl!") + M.emote("awoo") + if(prob(20)) + var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers + for(var/victim in seen) + if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (!isliving(victim))) + seen = seen - victim + if(LAZYLEN(seen)) + to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]") + if(16) + T = M.getorganslot(ORGAN_SLOT_TONGUE) + var/obj/item/organ/tongue/nT = new /obj/item/organ/tongue/fluffy + T.Remove(M) + nT.Insert(M) + T.moveToNullspace()//To valhalla + to_chat(M, "Your tongue feels... weally fwuffy!!") + if(17 to INFINITY) + if(prob(5)) + to_chat(M, "You find yourself unable to supress the desire to meow!") + M.emote("nya") + if(prob(5)) + to_chat(M, "You find yourself unable to supress the desire to howl!") + M.emote("awoo") + if(prob(5)) + var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers + for(var/victim in seen) + if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (!isliving(victim))) + seen = seen - victim + if(LAZYLEN(seen)) + to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]") + ..() + +/datum/reagent/fermi/furranium/on_mob_delete(mob/living/carbon/M) + if(purity < 1)//Only permanent if you're a good chemist. + nT = M.getorganslot(ORGAN_SLOT_TONGUE) + nT.Remove(M) + qdel(nT) + T.Insert(M) + to_chat(M, "You feel your tongue.... unfluffify...?") + M.say("Pleh!") + else + log_game("FERMICHEM: [M] ckey: [M.key]'s tongue has been made permanent") + + +/////////////////////////////////////////////////////////////////////////////////////////////// +//Nanite removal +//Writen by Trilby!! Embellsished a little by me. + +/datum/reagent/fermi/nanite_b_gone + name = "Naninte bane" + id = "nanite_b_gone" + description = "A stablised EMP that is highly volatile, shocking small nano machines that will kill them off at a rapid rate in a patient's system." + color = "#708f8f" + overdose_threshold = 15 + ImpureChem = "nanite_b_goneTox" //If you make an inpure chem, it stalls growth + InverseChemVal = 0.25 + InverseChem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse + taste_description = "what can only be described as licking a battery." + pH = 9 + can_synth = FALSE + +/datum/reagent/fermi/nanite_b_gone/on_mob_life(mob/living/carbon/C) + //var/component/nanites/N = M.GetComponent(/datum/component/nanites) + GET_COMPONENT_FROM(N, /datum/component/nanites, C) + if(isnull(N)) + return ..() + N.nanite_volume = -purity//0.5 seems to be the default to me, so it'll neuter them. + ..() + +/datum/reagent/fermi/nanite_b_gone/overdose_process(mob/living/carbon/C) + //var/component/nanites/N = M.GetComponent(/datum/component/nanites) + GET_COMPONENT_FROM(N, /datum/component/nanites, C) + if(prob(5)) + to_chat(C, "The residual voltage from the nanites causes you to seize up!") + C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE) + if(prob(10)) + //empulse((get_turf(C)), 3, 2)//So the nanites randomize + var/atom/T = C + T.emp_act(EMP_HEAVY) + to_chat(C, "The nanites short circuit within your system!") + if(isnull(N)) + return ..() + N.nanite_volume = -2 + ..() + +/datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume) + O.emp_act(EMP_HEAVY) + +/datum/reagent/fermi/nanite_b_goneTox + name = "Naninte bain" + id = "nanite_b_goneTox" + description = "Poorly made, and shocks you!" + metabolization_rate = 1 + +//Increases shock events. +/datum/reagent/fermi/nanite_b_goneTox/on_mob_life(mob/living/carbon/C)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) + if(prob(15)) + to_chat(C, "The residual voltage in your system causes you to seize up!") + C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE) + if(prob(50)) + var/atom/T = C + T.emp_act(EMP_HEAVY) + to_chat(C, "You feel your hair stand on end as you glow brightly for a moment!") + ..() + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// MISC FERMICHEM CHEMS FOR SPECIFIC INTERACTIONS ONLY +/////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/reagent/fermi/fermiAcid + name = "Acid vapour" + id = "fermiAcid" + description = "Someone didn't do like an otter, and add acid to water." + taste_description = "acid burns, ow" + color = "#FFFFFF" + pH = 0 + can_synth = FALSE + +/datum/reagent/fermi/fermiAcid/reaction_mob(mob/living/carbon/C, method) + var/target = C.get_bodypart(BODY_ZONE_CHEST) + var/acidstr + if(!C.reagents.pH || C.reagents.pH >5) + acidstr = 3 + else + acidstr = ((5-C.reagents.pH)*2) //runtime - null.pH ? + C.adjustFireLoss(acidstr/2, 0) + if((method==VAPOR) && (!C.wear_mask)) + if(prob(20)) + to_chat(C, "You can feel your lungs burning!") + var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS) + L.adjustLungLoss(acidstr*2, C) + C.apply_damage(acidstr/5, BURN, target) + C.acid_act(acidstr, volume) + ..() + +/datum/reagent/fermi/fermiAcid/reaction_obj(obj/O, reac_volume) + if(ismob(O.loc)) //handled in human acid_act() + return + if((holder.pH > 5) || (volume < 0.1)) //Shouldn't happen, but just in case + return + reac_volume = round(volume,0.1) + var/acidstr = (5-holder.pH)*2 //(max is 10) + O.acid_act(acidstr, volume) + ..() + +/datum/reagent/fermi/fermiAcid/reaction_turf(turf/T, reac_volume) + if (!istype(T)) + return + reac_volume = round(volume,0.1) + var/acidstr = (5-holder.pH) + T.acid_act(acidstr, volume) + ..() + +/datum/reagent/fermi/fermiTest + name = "Fermis Test Reagent" + id = "fermiTest" + description = "You should be really careful with this...! Also, how did you get this?" + addProc = TRUE + can_synth = FALSE + +/datum/reagent/fermi/fermiTest/on_new(datum/reagents/holder) + ..() + if(LAZYLEN(holder.reagent_list) == 1) + return + else + holder.remove_reagent("fermiTest", volume)//Avoiding recurrsion + var/location = get_turf(holder.my_atom) + if(purity < 0.34 || purity == 1) + var/datum/effect_system/foam_spread/s = new() + s.set_up(volume*2, location, holder) + s.start() + if((purity < 0.67 && purity >= 0.34)|| purity == 1) + var/datum/effect_system/smoke_spread/chem/s = new() + s.set_up(holder, volume*2, location) + s.start() + if(purity >= 0.67) + for (var/datum/reagent/reagent in holder.reagent_list) + if (istype(reagent, /datum/reagent/fermi)) + var/datum/chemical_reaction/fermi/Ferm = GLOB.chemical_reagents_list[reagent.id] + Ferm.FermiExplode(src, holder.my_atom, holder, holder.total_volume, holder.chem_temp, holder.pH) + else + var/datum/chemical_reaction/Ferm = GLOB.chemical_reagents_list[reagent.id] + Ferm.on_reaction(holder, reagent.volume) + for(var/mob/M in viewers(8, location)) + to_chat(M, "The solution reacts dramatically, with a meow!") + playsound(get_turf(M), 'modular_citadel/sound/voice/merowr.ogg', 50, 1) + holder.clear_reagents() + +/datum/reagent/fermi/fermiTox + name = "FermiTox" + id = "fermiTox" + description = "You should be really careful with this...! Also, how did you get this? You shouldn't have this!" + data = "merge" + color = "FFFFFF" + can_synth = FALSE + +//I'm concerned this is too weak, but I also don't want deathmixes. +/datum/reagent/fermi/fermiTox/on_mob_life(mob/living/carbon/C, method) + if(C.dna && istype(C.dna.species, /datum/species/jelly)) + C.adjustToxLoss(-2) + else + C.adjustToxLoss(2) + ..() + +/datum/reagent/fermi/acidic_buffer + name = "Acidic buffer" + id = "acidic_buffer" + description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another." + color = "#fbc314" + pH = 0 + can_synth = TRUE + +//Consumes self on addition and shifts pH +/datum/reagent/fermi/acidic_buffer/on_new(datapH) + data = datapH + if(LAZYLEN(holder.reagent_list) == 1) + return + holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) + var/list/seen = viewers(5, get_turf(holder)) + for(var/mob/M in seen) + to_chat(M, "The beaker fizzes as the pH changes!") + playsound(get_turf(holder.my_atom), 'sound/FermiChem/bufferadd.ogg', 50, 1) + holder.remove_reagent(id, volume, ignore_pH = TRUE) + ..() + +/datum/reagent/fermi/basic_buffer + name = "Basic buffer" + id = "basic_buffer" + description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another." + color = "#3853a4" + pH = 14 + can_synth = TRUE + +/datum/reagent/fermi/basic_buffer/on_new(datapH) + data = datapH + if(LAZYLEN(holder.reagent_list) == 1) + return + holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) + var/list/seen = viewers(5, get_turf(holder)) + for(var/mob/M in seen) + to_chat(M, "The beaker froths as the pH changes!") + playsound(get_turf(holder.my_atom), 'sound/FermiChem/bufferadd.ogg', 50, 1) + holder.remove_reagent(id, volume, ignore_pH = TRUE) + ..() + +//Turns you into a cute catto while it's in your system. +//If you manage to gamble perfectly, makes you have cat ears after you transform back. But really, you shouldn't end up with that with how random it is. +/datum/reagent/fermi/secretcatchem //Should I hide this from code divers? A secret cit chem? + name = "secretcatchem" //an attempt at hiding it + id = "secretcatchem" + description = "An illegal and hidden chem that turns people into cats. It's said that it's so rare and unstable that having it means you've been blessed." + taste_description = "hairballs and cream" + color = "#ffc224" + var/catshift = FALSE + var/mob/living/simple_animal/pet/cat/custom_cat/catto = null + can_synth = FALSE + +/datum/reagent/fermi/secretcatchem/New() + name = "Catbalti[pick("a","u","e","y")]m [pick("apex", "prime", "meow")]"//rename + +/datum/reagent/fermi/secretcatchem/on_mob_add(mob/living/carbon/human/H) + . = ..() + if(purity >= 0.8)//ONLY if purity is high, and given the stuff is random. It's very unlikely to get this to 1. It already requires felind too, so no new functionality there. + //exception(al) handler: + H.dna.features["ears"] = "Cat" + H.dna.features["mam_ears"] = "Cat" + H.verb_say = "mewls" + catshift = TRUE + playsound(get_turf(H), 'modular_citadel/sound/voice/merowr.ogg', 50, 1, -1) + to_chat(H, "You suddenly turn into a cat!") + catto = new(get_turf(H.loc)) + H.mind.transfer_to(catto) + catto.name = H.name + catto.desc = "A cute catto! They remind you of [H] somehow." + catto.color = "#[H.dna.features["mcolor"]]" + catto.pseudo_death = TRUE + H.forceMove(catto) + log_game("FERMICHEM: [H] ckey: [H.key] has been made into a cute catto.") + SSblackbox.record_feedback("tally", "fermi_chem", 1, "cats") + //Just to deal with rascally ghosts + //ADD_TRAIT(catto, TRAIT_NODEATH, "catto")//doesn't work + //catto.health = 1000 //To simulate fake death, while preventing ghosts escaping. + +/datum/reagent/fermi/secretcatchem/on_mob_life(mob/living/carbon/H) + if(catto.health <= 0) //So the dead can't ghost + if(prob(10)) + to_chat(H, "You feel your body start to slowly shift back from it's dead form.") + else if(prob(5)) + playsound(get_turf(catto), 'modular_citadel/sound/voice/merowr.ogg', 50, 1, -1) + catto.say("lets out a meowrowr!*") + ..() + +/datum/reagent/fermi/secretcatchem/on_mob_delete(mob/living/carbon/H) + var/words = "Your body shifts back to normal." + H.forceMove(catto.loc) + catto.mind.transfer_to(H) + if(catshift == TRUE) + words += " ...But wait, are those cat ears?" + H.say("*wag")//force update sprites. + to_chat(H, "[words]") + qdel(catto) + log_game("FERMICHEM: [H] ckey: [H.key] has returned to normal") diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm new file mode 100644 index 0000000000..b717948a20 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm @@ -0,0 +1,95 @@ +/datum/reagent/fermi/yamerol + name = "Yamerol" + id = "yamerol" + description = "For when you've trouble speaking or breathing, just yell YAMEROL! A chem that helps soothe any congestion problems and at high concentrations restores damaged lungs and tongues!" + taste_description = "a weird, syrupy flavour, yamero" + color = "#68e83a" + pH = 8.6 + overdose_threshold = 35 + ImpureChem = "yamerol_tox" + InverseChemVal = 0.4 + InverseChem = "yamerol_tox" + can_synth = TRUE + +/datum/reagent/fermi/yamerol/on_mob_life(mob/living/carbon/C) + var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE) + var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS) + + if(T) + T.adjustTongueLoss(C, -2)//Fix the inputs me! + if(L) + L.adjustLungLoss(-5, C) + C.adjustOxyLoss(-2) + else + C.adjustOxyLoss(-10) + + if(T) + if(T.name == "fluffy tongue") + var/obj/item/organ/tongue/nT + if(C.dna && C.dna.species && C.dna.species.mutanttongue) + nT = new C.dna.species.mutanttongue() + else + nT = new() + T.Remove(C) + qdel(T) + nT.Insert(C) + to_chat(C, "You feel your tongue.... unfluffify...?") + holder.remove_reagent(src.id, "10") + ..() + +/datum/reagent/fermi/yamerol/overdose_process(mob/living/carbon/C) + var/obj/item/organ/tongue/oT = C.getorganslot(ORGAN_SLOT_TONGUE) + if(current_cycle == 1) + to_chat(C, "You feel the Yamerol sooth your tongue and lungs.") + if(current_cycle > 10) + if(!C.getorganslot(ORGAN_SLOT_TONGUE)) + var/obj/item/organ/tongue/T + if(C.dna && C.dna.species && C.dna.species.mutanttongue) + T = new C.dna.species.mutanttongue() + else + T = new() + T.Insert(C) + to_chat(C, "You feel your tongue reform in your mouth.") + holder.remove_reagent(src.id, "10") + else + if((oT.name == "fluffy tongue") && (purity == 1)) + var/obj/item/organ/tongue/T + if(C.dna && C.dna.species && C.dna.species.mutanttongue) + T = new C.dna.species.mutanttongue() + else + T = new() + oT.Remove(C) + qdel(oT) + T.Insert(C) + to_chat(C, "You feel your tongue.... unfluffify...?") + holder.remove_reagent(src.id, "10") + + if(!C.getorganslot(ORGAN_SLOT_LUNGS)) + var/obj/item/organ/lungs/L = new() + L.Insert(C) + to_chat(C, "You feel your lungs reform in your chest.") + holder.remove_reagent(src.id, "10") + + C.adjustOxyLoss(-3) + ..() + +/datum/reagent/fermi/yamerol_tox + name = "Yamerol" + id = "yamerol_tox" + description = "For when you've trouble speaking or breathing, just yell YAMEROL! A chem that helps soothe any congestion problems and at high concentrations restores damaged lungs and tongues!" + taste_description = "a weird, syrupy flavour, yamero" + color = "#68e83a" + pH = 8.6 + +/datum/reagent/fermi/yamerol_tox/on_mob_life(mob/living/carbon/C) + var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE) + var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS) + + if(T) + T.adjustTongueLoss(C, 1) + if(L) + L.adjustLungLoss(4, C) + C.adjustOxyLoss(3) + else + C.adjustOxyLoss(10) + ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/FermiCalc.Py b/modular_citadel/code/modules/reagents/chemistry/recipes/FermiCalc.Py new file mode 100644 index 0000000000..9ffc057743 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/FermiCalc.Py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri May 17 05:12:17 2019 + +@author: Fermi +""" + +import numpy +import matplotlib as mpl +import matplotlib.pyplot as plt + diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm new file mode 100644 index 0000000000..078e1c8a71 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm @@ -0,0 +1,541 @@ +/datum/chemical_reaction/fermi + mix_sound = 'sound/effects/bubbles.ogg' + +//Called for every reaction step +/datum/chemical_reaction/fermi/proc/FermiCreate(holder) + return + +//Called when reaction STOP_PROCESSING +/datum/chemical_reaction/fermi/proc/FermiFinish(datum/reagents/holder) + return + +//Called when temperature is above a certain threshold, or if purity is too low. +/datum/chemical_reaction/fermi/proc/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH, Exploding = FALSE) + if (Exploding == TRUE) + return + + if(!pH)//Dunno how things got here without a pH, but just in case + pH = 7 + var/ImpureTot = 0 + var/turf/T = get_turf(my_atom) + + if(temp>500)//if hot, start a fire + switch(temp) + if (500 to 750) + for(var/turf/turf in range(1,T)) + new /obj/effect/hotspot(turf) + + if (751 to 1100) + for(var/turf/turf in range(2,T)) + new /obj/effect/hotspot(turf) + + if (1101 to 1500) //If you're crafty + for(var/turf/turf in range(3,T)) + new /obj/effect/hotspot(turf) + + if (1501 to 2500) //requested + for(var/turf/turf in range(4,T)) + new /obj/effect/hotspot(turf) + + if (2501 to 5000) + for(var/turf/turf in range(5,T)) + new /obj/effect/hotspot(turf) + + if (5001 to INFINITY) + for(var/turf/turf in range(6,T)) + new /obj/effect/hotspot(turf) + + + message_admins("Fermi explosion at [T], with a temperature of [temp], pH of [pH], Impurity tot of [ImpureTot].") + log_game("Fermi explosion at [T], with a temperature of [temp], pH of [pH], Impurity tot of [ImpureTot].") + var/datum/reagents/R = new/datum/reagents(3000)//Hey, just in case. + var/datum/effect_system/smoke_spread/chem/s = new() + R.my_atom = my_atom //Give the gas a fingerprint + + for (var/datum/reagent/reagent in my_atom.reagents.reagent_list) //make gas for reagents, has to be done this way, otherwise it never stops Exploding + R.add_reagent(reagent.id, reagent.volume/3) //Seems fine? I think I fixed the infinite explosion bug. + + if (reagent.purity < 0.6) + ImpureTot = (ImpureTot + (1-reagent.purity)) / 2 + + if(pH < 4) //if acidic, make acid spray + R.add_reagent("fermiAcid", (volume/3)) + if(R.reagent_list) + s.set_up(R, (volume/5), my_atom) + s.start() + + if (pH > 10) //if alkaline, small explosion. + var/datum/effect_system/reagents_explosion/e = new() + e.set_up(round((volume/30)*(pH-9)), T, 0, 0) + e.start() + + if(!ImpureTot == 0) //If impure, v.small emp (0.6 or less) + ImpureTot *= volume + var/empVol = CLAMP (volume/10, 0, 15) + empulse(T, empVol, ImpureTot/10, 1) + + my_atom.reagents.clear_reagents() //just in case + return + +/datum/chemical_reaction/fermi/eigenstate + name = "Eigenstasium" + id = "eigenstate" + results = list("eigenstate" = 0.1) + required_reagents = list("bluespace" = 0.1, "stable_plasma" = 0.1, "sugar" = 0.1) + mix_message = "the reaction zaps suddenly!" + //FermiChem vars: + OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions + OptimalTempMax = 600 // Upper end for above + ExplodeTemp = 650 //Temperature at which reaction explodes + OptimalpHMin = 7 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase) + OptimalpHMax = 9 // Higest value for above + ReactpHLim = 5 // How far out pH wil react, giving impurity place (Exponential phase) + CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst) + CurveSharpT = 1.5 // How sharp the temperature exponential curve is (to the power of value) + CurveSharppH = 3 // How sharp the pH exponential curve is (to the power of value) + ThermicConstant = 10 //Temperature change per 1u produced + HIonRelease = -0.02 //pH change per 1u reaction + RateUpLim = 3 //Optimal/max rate possible if all conditions are perfect + FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics + FermiExplode = FALSE //If the chemical explodes in a special way + PurityMin = 0.4 //The minimum purity something has to be above, otherwise it explodes. + +/datum/chemical_reaction/fermi/eigenstate/FermiFinish(datum/reagents/holder, var/atom/my_atom)//Strange how this doesn't work but the other does. + if(!locate(/datum/reagent/fermi/eigenstate) in my_atom.reagents.reagent_list) + return + var/turf/open/location = get_turf(my_atom) + var/datum/reagent/fermi/eigenstate/E = locate(/datum/reagent/fermi/eigenstate) in my_atom.reagents.reagent_list + if(location) + E.location_created = location + E.data.["location_created"] = location + + +//serum +/datum/chemical_reaction/fermi/SDGF + name = "Synthetic-derived growth factor" + id = "SDGF" + results = list("SDGF" = 0.3) + required_reagents = list("stable_plasma" = 0.15, "clonexadone" = 0.15, "uranium" = 0.15, "synthflesh" = 0.15) + mix_message = "the reaction gives off a blorble!" + required_temp = 1 + //FermiChem vars: + OptimalTempMin = 600 // Lower area of bell curve for determining heat based rate reactions + OptimalTempMax = 630 // Upper end for above + ExplodeTemp = 635 // Temperature at which reaction explodes + OptimalpHMin = 3 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase) + OptimalpHMax = 3.5 // Higest value for above + ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase) + CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst) + CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value) + CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value) + ThermicConstant = -10 // Temperature change per 1u produced + HIonRelease = 0.02 // pH change per 1u reaction (inverse for some reason) + RateUpLim = 1 // Optimal/max rate possible if all conditions are perfect + FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics + FermiExplode = TRUE // If the chemical explodes in a special way + PurityMin = 0.2 + +/datum/chemical_reaction/fermi/SDGF/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH)//Spawns an angery teratoma! + var/turf/T = get_turf(my_atom) + var/mob/living/simple_animal/slime/S = new(T,"green") + S.damage_coeff = list(BRUTE = 0.9 , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + S.name = "Living teratoma" + S.real_name = "Living teratoma" + S.rabid = 1//Make them an angery boi + S.color = "#810010" + my_atom.reagents.clear_reagents() + var/list/seen = viewers(8, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The cells clump up into a horrifying tumour!") + +/datum/chemical_reaction/fermi/breast_enlarger + name = "Sucubus milk" + id = "breast_enlarger" + results = list("breast_enlarger" = 0.8) + required_reagents = list("salglu_solution" = 0.1, "milk" = 0.1, "synthflesh" = 0.2, "silicon" = 0.3, "aphro" = 0.3) + mix_message = "the reaction gives off a mist of milk." + //FermiChem vars: + OptimalTempMin = 200 + OptimalTempMax = 800 + ExplodeTemp = 900 + OptimalpHMin = 6 + OptimalpHMax = 10 + ReactpHLim = 3 + CatalystFact = 0 + CurveSharpT = 2 + CurveSharppH = 1 + ThermicConstant = 1 + HIonRelease = -0.1 + RateUpLim = 5 + FermiChem = TRUE + FermiExplode = TRUE + PurityMin = 0.1 + +/datum/chemical_reaction/fermi/breast_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom) + var/datum/reagent/fermi/breast_enlarger/BE = locate(/datum/reagent/fermi/breast_enlarger) in my_atom.reagents.reagent_list + var/cached_volume = BE.volume + if(BE.purity < 0.35) + holder.remove_reagent(src.id, cached_volume) + holder.add_reagent("BEsmaller", cached_volume) + + +/datum/chemical_reaction/fermi/breast_enlarger/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) + var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(get_turf(my_atom)) + var/list/seen = viewers(8, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The reaction suddenly condenses, creating a pair of breasts!") + var/datum/reagent/fermi/breast_enlarger/BE = locate(/datum/reagent/fermi/breast_enlarger) in my_atom.reagents.reagent_list + B.size = ((BE.volume * BE.purity) / 10) //half as effective. + my_atom.reagents.clear_reagents() + +/datum/chemical_reaction/fermi/penis_enlarger + name = "Incubus draft" + id = "penis_enlarger" + results = list("penis_enlarger" = 0.8) + required_reagents = list("blood" = 0.5, "synthflesh" = 0.2, "carbon" = 0.2, "aphro" = 0.2, "salglu_solution" = 0.1,) + mix_message = "the reaction gives off a spicy mist." + //FermiChem vars: + OptimalTempMin = 200 + OptimalTempMax = 800 + ExplodeTemp = 900 + OptimalpHMin = 2 + OptimalpHMax = 6 + ReactpHLim = 3 + CatalystFact = 0 + CurveSharpT = 2 + CurveSharppH = 1 + ThermicConstant = 1 + HIonRelease = 0.1 + RateUpLim = 5 + FermiChem = TRUE + FermiExplode = TRUE + PurityMin = 0.1 + +/datum/chemical_reaction/fermi/penis_enlarger/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) + var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(get_turf(my_atom)) + var/list/seen = viewers(8, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The reaction suddenly condenses, creating a penis!") + var/datum/reagent/fermi/penis_enlarger/PE = locate(/datum/reagent/fermi/penis_enlarger) in my_atom.reagents.reagent_list + P.length = ((PE.volume * PE.purity) / 10)//half as effective. + my_atom.reagents.clear_reagents() + +/datum/chemical_reaction/fermi/penis_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom) + var/datum/reagent/fermi/penis_enlarger/PE = locate(/datum/reagent/fermi/penis_enlarger) in my_atom.reagents.reagent_list + var/cached_volume = PE.volume + if(PE.purity < 0.35) + holder.remove_reagent(src.id, cached_volume) + holder.add_reagent("PEsmaller", cached_volume) + +/datum/chemical_reaction/fermi/astral + name = "Astrogen" + id = "astral" + results = list("astral" = 0.5) + required_reagents = list("eigenstate" = 0.1, "plasma" = 0.3, "synaptizine" = 0.1, "aluminium" = 0.5) + //FermiChem vars: + OptimalTempMin = 700 + OptimalTempMax = 800 + ExplodeTemp = 1150 + OptimalpHMin = 10 + OptimalpHMax = 13 + ReactpHLim = 2 + CatalystFact = 0 + CurveSharpT = 1 + CurveSharppH = 1 + ThermicConstant = 25 + HIonRelease = 0.02 + RateUpLim = 15 + FermiChem = TRUE + FermiExplode = TRUE + PurityMin = 0.25 + + +/datum/chemical_reaction/fermi/enthrall/ //check this + name = "MKUltra" + id = "enthrall" + results = list("enthrall" = 0.5) + //required_reagents = list("iron" = 1, "iodine" = 1) Test vars + //required_reagents = list("cocoa" = 0.1, "astral" = 0.1, "mindbreaker" = 0.1, "psicodine" = 0.1, "happiness" = 0.1) + required_reagents = list("cocoa" = 0.1, "bluespace" = 0.1, "mindbreaker" = 0.1, "psicodine" = 0.1, "happiness" = 0.1) //TEMPORARY UNTIL HEADMINS GIVE THE OKAY FOR MK USE. + required_catalysts = list("blood" = 1) + mix_message = "the reaction gives off a burgundy plume of smoke!" + //FermiChem vars: + OptimalTempMin = 780 + OptimalTempMax = 820 + ExplodeTemp = 840 + OptimalpHMin = 12 + OptimalpHMax = 13 + ReactpHLim = 2 + //CatalystFact = 0 + CurveSharpT = 0.5 + CurveSharppH = 4 + ThermicConstant = 15 + HIonRelease = 0.1 + RateUpLim = 1 + FermiChem = TRUE + FermiExplode = TRUE + PurityMin = 0.2 + +/datum/chemical_reaction/fermi/enthrall/FermiFinish(datum/reagents/holder, var/atom/my_atom) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in my_atom.reagents.reagent_list + var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list + if(!B) + return + if(!B.data) + var/list/seen = viewers(5, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The reaction splutters and fails to react properly.") //Just in case + E.purity = 0 + if (B.data.["gender"] == "female") + E.data.["creatorGender"] = "Mistress" + E.creatorGender = "Mistress" + else + E.data.["creatorGender"] = "Master" + E.creatorGender = "Master" + E.data["creatorName"] = B.data.["real_name"] + E.creatorName = B.data.["real_name"] + E.data.["creatorID"] = B.data.["ckey"] + E.creatorID = B.data.["ckey"] + +//So slimes can play too. +/datum/chemical_reaction/fermi/enthrall/slime + required_catalysts = list("slimejelly" = 1) + +/datum/chemical_reaction/fermi/enthrall/slime/FermiFinish(datum/reagents/holder, var/atom/my_atom) + var/datum/reagent/toxin/slimejelly/B = locate(/datum/reagent/toxin/slimejelly) in my_atom.reagents.reagent_list//The one line change. + var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list + if(!B.data) + var/list/seen = viewers(5, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The reaction splutters and fails to react.") //Just in case + E.purity = 0 + if (B.data.["gender"] == "female") + E.data.["creatorGender"] = "Mistress" + E.creatorGender = "Mistress" + else + E.data.["creatorGender"] = "Master" + E.creatorGender = "Master" + E.data["creatorName"] = B.data.["real_name"] + E.creatorName = B.data.["real_name"] + E.data.["creatorID"] = B.data.["ckey"] + E.creatorID = B.data.["ckey"] + +/datum/chemical_reaction/fermi/enthrall/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) + var/turf/T = get_turf(my_atom) + var/datum/reagents/R = new/datum/reagents(1000) + var/datum/effect_system/smoke_spread/chem/s = new() + R.add_reagent("enthrallExplo", volume) + s.set_up(R, volume/2, T) + s.start() + my_atom.reagents.clear_reagents() + +/datum/chemical_reaction/fermi/hatmium // done + name = "Hat growth serum" + id = "hatmium" + results = list("hatmium" = 0.5) + required_reagents = list("ethanol" = 0.1, "nutriment" = 0.3, "cooking_oil" = 0.2, "iron" = 0.1, "gold" = 0.3) + //mix_message = "" + //FermiChem vars: + OptimalTempMin = 500 + OptimalTempMax = 700 + ExplodeTemp = 750 + OptimalpHMin = 2 + OptimalpHMax = 5 + ReactpHLim = 3 + //CatalystFact = 0 //To do 1 + CurveSharpT = 8 + CurveSharppH = 0.5 + ThermicConstant = -2 + HIonRelease = -0.1 + RateUpLim = 2 + FermiChem = TRUE + FermiExplode = TRUE + PurityMin = 0.5 + +/datum/chemical_reaction/fermi/hatmium/FermiExplode(src, var/atom/my_atom, volume, temp, pH) + var/obj/item/clothing/head/hattip/hat = new /obj/item/clothing/head/hattip(get_turf(my_atom)) + hat.animate_atom_living() + var/list/seen = viewers(8, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The makes an off sounding pop, as a hat suddenly climbs out of the beaker!") + my_atom.reagents.clear_reagents() + +/datum/chemical_reaction/fermi/furranium + name = "Furranium" + id = "furranium" + results = list("furranium" = 0.5) + required_reagents = list("aphro" = 0.1, "moonsugar" = 0.1, "silver" = 0.2, "salglu_solution" = 0.1) + mix_message = "You think you can hear a howl come from the beaker." + //FermiChem vars: + OptimalTempMin = 350 + OptimalTempMax = 600 + ExplodeTemp = 700 + OptimalpHMin = 8 + OptimalpHMax = 10 + ReactpHLim = 2 + //CatalystFact = 0 //To do 1 + CurveSharpT = 2 + CurveSharppH = 0.5 + ThermicConstant = -10 + HIonRelease = -0.1 + RateUpLim = 2 + FermiChem = TRUE + PurityMin = 0.3 + +//FOR INSTANT REACTIONS - DO NOT MULTIPLY LIMIT BY 10. +//There's a weird rounding error or something ugh. + +//Nano-b-gone +/datum/chemical_reaction/fermi/nanite_b_gone//done test + name = "Naninte bain" + id = "nanite_b_gone" + results = list("nanite_b_gone" = 4) + required_reagents = list("synthflesh" = 1, "uranium" = 1, "iron" = 1, "salglu_solution" = 1) + mix_message = "the reaction gurgles, encapsulating the reagents in flesh before the emp can be set off." + required_temp = 450//To force fermireactions before EMP. + //FermiChem vars: + OptimalTempMin = 500 + OptimalTempMax = 600 + ExplodeTemp = 700 + OptimalpHMin = 6 + OptimalpHMax = 6.25 + ReactpHLim = 3 + //CatalystFact = 0 //To do 1 + CurveSharpT = 0 + CurveSharppH = 1 + ThermicConstant = 5 + HIonRelease = 0.01 + RateUpLim = 1 + FermiChem = TRUE + +/datum/chemical_reaction/fermi/acidic_buffer//done test + name = "Acetic acid buffer" + id = "acidic_buffer" + results = list("acidic_buffer" = 2) //acetic acid + required_reagents = list("salglu_solution" = 0.2, "ethanol" = 0.6, "oxygen" = 0.6, "water" = 0.6) + //FermiChem vars: + OptimalTempMin = 250 + OptimalTempMax = 500 + ExplodeTemp = 9999 //check to see overflow doesn't happen! + OptimalpHMin = 2 + OptimalpHMax = 6 + ReactpHLim = 0 + //CatalystFact = 0 //To do 1 + CurveSharpT = 4 + CurveSharppH = 0 + ThermicConstant = 0 + HIonRelease = -0.01 + RateUpLim = 20 + FermiChem = TRUE + + +/datum/chemical_reaction/fermi/acidic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this + if(!locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list) + return + var/datum/reagent/fermi/acidic_buffer/Fa = locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list + Fa.data = 0.1//setting it to 0 means byond thinks it's not there. + +/datum/chemical_reaction/fermi/basic_buffer//done test + name = "Ethyl Ethanoate buffer" + id = "basic_buffer" + results = list("basic_buffer" = 1.5) + required_reagents = list("acidic_buffer" = 0.5, "ethanol" = 0.5, "water" = 0.5) + required_catalysts = list("sacid" = 1) //vagely acetic + //FermiChem vars:x + OptimalTempMin = 250 + OptimalTempMax = 500 + ExplodeTemp = 9999 //check to see overflow doesn't happen! + OptimalpHMin = 5 + OptimalpHMax = 12 + ReactpHLim = 0 + //CatalystFact = 0 //To do 1 + CurveSharpT = 4 + CurveSharppH = 0 + ThermicConstant = 0 + HIonRelease = 0.01 + RateUpLim = 15 + FermiChem = TRUE + + +/datum/chemical_reaction/fermi/basic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this + if(!locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list) + return + var/datum/reagent/fermi/basic_buffer/Fb = locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list + Fb.data = 14 + +//secretcatchemcode, shh!! Of couse I hide it amongst cats. Though, I moved it with your requests. +//I'm not trying to be sneaky, I'm trying to keep it a secret! +//I don't know how to do hidden chems like Aurora +//ChemReactionVars: +/datum/chemical_reaction/fermi/secretcatchem //DONE + name = "secretcatchem" + id = "secretcatchem" + results = list("secretcatchem" = 0.5) + required_reagents = list("stable_plasma" = 0.1, "sugar" = 0.1, "cream" = 0.1, "clonexadone" = 0.1)//Yes this will make a plushie if you don't lucky guess. It'll eat all your reagents too. + required_catalysts = list("SDGF" = 1) + required_temp = 600 + mix_message = "the reaction gives off a meow!" + mix_sound = "modular_citadel/sound/voice/merowr.ogg" + //FermiChem vars: + OptimalTempMin = 650 + OptimalpHMin = 0 + ReactpHLim = 2 + CurveSharpT = 0 + CurveSharppH = 0 + ThermicConstant = 0 + HIonRelease = 0 + RateUpLim = 0.1 + FermiChem = TRUE + FermiExplode = FALSE + PurityMin = 0.2 + +/datum/chemical_reaction/fermi/secretcatchem/New() + //rand doesn't seem to work with n^-e + OptimalTempMin += rand(-100, 100) + OptimalTempMax = (OptimalTempMin+rand(20, 200)) + ExplodeTemp = (OptimalTempMax+rand(20, 200)) + OptimalpHMin += rand(1, 10) + OptimalpHMax = (OptimalpHMin + rand(1, 5)) + ReactpHLim += rand(-1.5, 2.5) + CurveSharpT += (rand(1, 500)/100) + CurveSharppH += (rand(1, 500)/100) + ThermicConstant += rand(-20, 20) + HIonRelease += (rand(-25, 25)/100) + RateUpLim += (rand(1, 1000)/100) + PurityMin += (rand(-1, 1)/10) + var/additions = list("aluminium", "silver", "gold", "plasma", "silicon", "uranium", "milk") + required_reagents[pick(additions)] = rand(0.1, 0.5)//weird + +/datum/chemical_reaction/fermi/secretcatchem/FermiFinish(datum/reagents/holder, var/atom/my_atom) + SSblackbox.record_feedback("tally", "catgirlium")//log + +/datum/chemical_reaction/fermi/secretcatchem/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) + var/mob/living/simple_animal/pet/cat/custom_cat/catto = new(get_turf(my_atom)) + var/list/seen = viewers(8, get_turf(my_atom)) + for(var/mob/M in seen) + to_chat(M, "The reaction suddenly gives out a meow, condensing into a chemcat!")//meow! + playsound(get_turf(my_atom), 'modular_citadel/sound/voice/merowr.ogg', 50, 1, -1) + catto.name = "Chemcat" + catto.desc = "A cute chem cat, created by a lot of compicated and confusing chemistry!" + catto.color = "#770000" + my_atom.reagents.remove_all(5) + +/datum/chemical_reaction/fermi/yamerol//done test + name = "Yamerol" + id = "yamerol" + results = list("yamerol" = 1.5) + required_reagents = list("perfluorodecalin" = 0.5, "salbutamol" = 0.5, "water" = 0.5) + //FermiChem vars: + OptimalTempMin = 300 + OptimalTempMax = 500 + ExplodeTemp = 800 //check to see overflow doesn't happen! + OptimalpHMin = 6.8 + OptimalpHMax = 7.2 + ReactpHLim = 4 + //CatalystFact = 0 //To do 1 + CurveSharpT = 5 + CurveSharppH = 0.5 + ThermicConstant = -15 + HIonRelease = 0.1 + RateUpLim = 2 + FermiChem = TRUE diff --git a/modular_citadel/code/modules/reagents/objects/clothes.dm b/modular_citadel/code/modules/reagents/objects/clothes.dm new file mode 100644 index 0000000000..708f1f59f8 --- /dev/null +++ b/modular_citadel/code/modules/reagents/objects/clothes.dm @@ -0,0 +1,69 @@ +//Fermiclothes! +//Clothes made from FermiChem + +/obj/item/clothing/head/hattip //I wonder if anyone else has played cryptworlds + name = "Sythetic hat" + icon = 'icons/obj/clothing/hats.dmi' + icon_state = "cowboy" + desc = "A sythesized hat, you can't seem to take it off. And tips their hat." + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + //item_flags = NODROP //Tips their hat! + +/obj/item/clothing/head/hattip/attack_hand(mob/user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + if(is_ninja(C)) + to_chat(C, "Using your superior ninja reflexes, you take the hat off before tipping.") + return ..() + + if(src == C.head) + C.emote("me",1,"tips their hat.",TRUE) + return + else + user.emote("me",1,"admires such a spiffy hat.",TRUE) + return ..() + +/obj/item/clothing/head/hattip/MouseDrop(atom/over_object) + //You sure do love tipping your hat. + if(usr) + var/mob/living/carbon/C = usr + if(is_ninja(C)) + to_chat(C, "Using your superior ninja reflexes, you take the hat off before tipping.") + return ..() + + if(src == C.head) + C.emote("me",1,"tips their hat.",TRUE) + return + ..() + +/obj/item/clothing/head/hattip/equipped(mob/M, slot) + . = ..() + if (slot == SLOT_HEAD) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + else + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/hattip/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) + +/obj/item/clothing/head/hattip/proc/handle_speech(datum/source, mob/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/mob/living/carbon/C = get_wearer()//user + var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE) + if (T.name == "fluffy tongue") + if(prob(0.01)) + message += "\" and tips their hat. \"swpy's sappin' my chem dispwencer uwu!!" + else + message += "\" and tips their hat. \"[pick("weehaw!", "bwoy howdy.", "dawn tuutin'.", "weww don't that beat aww.", "whoooowee, wouwd ya wook at that!", "whoooowee! makin' bwacon!", "cweam gwavy!", "yippekeeyah-heeyapeeah-kwayoh!", "mwove 'em uut!", "gwiddy up!")]" + speech_args[SPEECH_MESSAGE] = trim(message) + return + if(prob(0.01)) + message += "\" and tips their hat. \"Spy's sappin' my chem dispenser!"//How did I not think of this earlier + message_admins("I really appreciate all the hard work you put into adminning citadel, I hope you're all having a good day and I hope this hidden and rare message_admins brightens up your day.") + else + message += "\" and tips their hat. \"[pick("Yeehaw!", "Boy howdy.", "Darn tootin'.", "Well don't that beat all.", "Whoooowee, would ya look at that!", "Whoooowee! Makin' bacon!", "Cream Gravy!", "Yippekeeyah-heeyapeeah-kayoh!", "Move 'em out!", "Giddy up!")]" + speech_args[SPEECH_MESSAGE] = trim(message) + +/obj/item/clothing/head/hattip/proc/get_wearer() + return loc diff --git a/modular_citadel/code/modules/reagents/objects/items.dm b/modular_citadel/code/modules/reagents/objects/items.dm new file mode 100644 index 0000000000..02f2db7c1e --- /dev/null +++ b/modular_citadel/code/modules/reagents/objects/items.dm @@ -0,0 +1,147 @@ +/obj/item/fermichem/pHbooklet + name = "pH indicator booklet" + desc = "A booklet containing paper soaked in universal indicator." + icon_state = "pHbooklet" + icon = 'modular_citadel/icons/obj/FermiChem.dmi' + item_flags = NOBLUDGEON + var/numberOfPages = 50 + resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_TINY + +//A little janky with pockets +/obj/item/fermichem/pHbooklet/attack_hand(mob/user) + if(user.get_held_index_of_item(src))//Does this check pockets too..? + if(numberOfPages == 50) + icon_state = "pHbookletOpen" + if(numberOfPages >= 1) + var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper + P.add_fingerprint(user) + P.forceMove(user.loc) + user.put_in_active_hand(P) + to_chat(user, "You take [P] out of \the [src].") + numberOfPages-- + playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1) + add_fingerprint(user) + if(numberOfPages == 0) + icon_state = "pHbookletEmpty" + return + else + to_chat(user, "[src] is empty!") + add_fingerprint(user) + return + . = ..() + if(. & COMPONENT_NO_INTERACT) + return + var/I = user.get_active_held_item() + if(!I) + user.put_in_active_hand(src) + +/obj/item/fermichem/pHbooklet/MouseDrop() + var/mob/living/user = usr + if(numberOfPages >= 1) + var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper + P.add_fingerprint(user) + P.forceMove(user) + user.put_in_active_hand(P) + to_chat(user, "You take [P] out of \the [src].") + numberOfPages-- + playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1) + add_fingerprint(user) + if(numberOfPages == 0) + icon_state = "pHbookletEmpty" + return + else + to_chat(user, "[src] is empty!") + add_fingerprint(user) + return + ..() + +/obj/item/fermichem/pHpaper + name = "pH indicator strip" + desc = "A piece of paper that will change colour depending on the pH of a solution." + icon_state = "pHpaper" + icon = 'modular_citadel/icons/obj/FermiChem.dmi' + item_flags = NOBLUDGEON + color = "#f5c352" + var/used = FALSE + resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_TINY + +/obj/item/fermichem/pHpaper/afterattack(obj/item/reagent_containers/cont, mob/user, proximity) + if(!istype(cont)) + return + if(used == TRUE) + to_chat(user, "[user] has already been used!") + return + if(!LAZYLEN(cont.reagents.reagent_list)) + return + switch(round(cont.reagents.pH, 1)) + if(14 to INFINITY) + color = "#462c83" + if(13 to 14) + color = "#63459b" + if(12 to 13) + color = "#5a51a2" + if(11 to 12) + color = "#3853a4" + if(10 to 11) + color = "#3f93cf" + if(9 to 10) + color = "#0bb9b7" + if(8 to 9) + color = "#23b36e" + if(7 to 8) + color = "#3aa651" + if(6 to 7) + color = "#4cb849" + if(5 to 6) + color = "#b5d335" + if(4 to 5) + color = "#f7ec1e" + if(3 to 4) + color = "#fbc314" + if(2 to 3) + color = "#f26724" + if(1 to 2) + color = "#ef1d26" + if(-INFINITY to 1) + color = "#c6040c" + desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]" + used = TRUE + +/obj/item/fermichem/pHmeter + name = "Chemistry Analyser" + desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution. The screen currently displays nothing." + icon_state = "pHmeter" + icon = 'modular_citadel/icons/obj/FermiChem.dmi' + resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_TINY + var/scanmode = 1 + +/obj/item/fermichem/pHmeter/attack_self(mob/user) + if(!scanmode) + to_chat(user, "You switch the chemical analyzer to give a detailed report.") + scanmode = 1 + else + to_chat(user, "You switch the chemical analyzer to give a reduced report.") + scanmode = 0 + +/obj/item/fermichem/pHmeter/afterattack(atom/A, mob/user, proximity) + . = ..() + if(!istype(A, /obj/item/reagent_containers)) + return + var/obj/item/reagent_containers/cont = A + if(LAZYLEN(cont.reagents.reagent_list) == null) + return + var/out_message + to_chat(user, "The chemistry meter beeps and displays:") + out_message += "Total volume: [round(cont.volume, 0.01)] Total pH: [round(cont.reagents.pH, 0.1)]\n" + if(cont.reagents.fermiIsReacting) + out_message += "A reaction appears to be occuring currently.\n" + out_message += "Chemicals found in the beaker:\n" + for(var/datum/reagent/R in cont.reagents.reagent_list) + out_message += "[R.volume]u of [R.name], Purity: [R.purity], [(scanmode?"[(R.overdose_threshold?"Overdose: [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"Addiction: [R.addiction_threshold]u, ":"")]Base pH: [R.pH].":".")]\n" + if(scanmode) + out_message += "Analysis: [R.description]\n" + to_chat(user, "[out_message]") + desc = "An electrode attached to a small circuit box that will analyse a beaker. It can be toggled to give a reduced or extended report. The screen currently displays [round(cont.reagents.pH, 0.1)]." diff --git a/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm b/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm index bee56cde15..9e7da03f9b 100755 --- a/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm @@ -50,6 +50,9 @@ /obj/item/hypospray/mkii/tricord start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/tricord +/obj/item/hypospray/mkii/enlarge + spawnwithvial = FALSE + /obj/item/hypospray/mkii/CMO name = "hypospray mk.II deluxe" allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small, /obj/item/reagent_containers/glass/bottle/vial/large) @@ -138,12 +141,18 @@ // Gunna allow this for now, still really don't approve - Pooj /obj/item/hypospray/mkii/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + to_chat(user, "[src] happens to be already overcharged.") + return inject_wait = COMBAT_WAIT_INJECT spray_wait = COMBAT_WAIT_SPRAY spray_self = COMBAT_SELF_INJECT inject_self = COMBAT_SELF_SPRAY penetrates = TRUE to_chat(user, "You overcharge [src]'s control circuit.") + obj_flags |= EMAGGED + return TRUE /obj/item/hypospray/mkii/attack_hand(mob/user) . = ..() //Don't bother changing this or removing it from containers will break. diff --git a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm index 4b7972d0a7..c1e0d6ff01 100755 --- a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm @@ -14,7 +14,8 @@ "green hypovial" = "hypovial-a", "orange hypovial" = "hypovial-k", "purple hypovial" = "hypovial-p", - "black hypovial" = "hypovial-t" + "black hypovial" = "hypovial-t", + "pink hypovial" = "hypovial-pink" ) always_reskinnable = TRUE @@ -136,6 +137,16 @@ icon_state = "hypovial" comes_with = list("tricordrazine" = 30) +/obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction + name = "pink hypovial (breast treatment)" + icon_state = "hypovial-pink" + comes_with = list("BEsmaller_hypo" = 30) + +/obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction + name = "pink hypovial (penis treatment)" + icon_state = "hypovial-pink" + comes_with = list("PEsmaller_hypo" = 30) + /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/CMO name = "deluxe hypovial" icon_state = "hypoviallarge-cmos" diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm index 2a6f03fae3..c4c1cff1e7 100644 --- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm +++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm @@ -8,6 +8,7 @@ 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) @@ -19,7 +20,6 @@ var/obj/effect/decal/cleanable/semen/S = locate() in T if(!S) S = new(T) - S.reagents.add_reagent("semen", reac_volume) if(data["blood_DNA"]) S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) @@ -50,6 +50,7 @@ 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 @@ -82,7 +83,6 @@ var/obj/effect/decal/cleanable/femcum/S = locate() in T if(!S) S = new(T) - S.reagents.add_reagent("femcum", reac_volume) if(data["blood_DNA"]) S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) @@ -152,11 +152,9 @@ /datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE) && prob(33)) - if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) - var/mob/living/carbon/human/H = M - if(prob(50)) //Less spam - to_chat(H, "Your libido is going haywire!") - H.mob_climax(forced_climax=TRUE) + if(prob(5) && M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) + if(prob(5)) //Less spam + to_chat(M, "Your libido is going haywire!") if(M.min_arousal < 50) M.min_arousal += 1 if(M.min_arousal < M.max_arousal) diff --git a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm index 22085d520c..1ad29c1af3 100644 --- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm +++ b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm @@ -47,7 +47,7 @@ var/tmp/next_process = 0 // Waiting for this SSbellies times_fired to process again. var/tmp/list/items_preserved = list() // Stuff that wont digest so we shouldn't process it again. var/tmp/next_emote = 0 // When we're supposed to print our next emote, as a belly controller tick # - var/tmp/recent_sound = FALSE // Prevent audio spam + var/tmp/recent_sound // Prevent audio spam var/tmp/last_hearcheck = 0 var/tmp/list/hearing_mobs @@ -152,11 +152,13 @@ SSbellies.belly_list += src /obj/belly/Destroy() - SSbellies.belly_list -= src if(owner) - owner.vore_organs -= src - owner = null - . = ..() + Remove(owner) + return ..() + +/obj/belly/proc/Remove(mob/living/owner) + owner.vore_organs -= src + owner = null // Called whenever an atom enters this belly /obj/belly/Entered(var/atom/movable/thing,var/atom/OldLoc) @@ -167,12 +169,13 @@ to_chat(owner,"[thing] slides into your [lowertext(name)].") //Sound w/ antispam flag setting - if(is_wet && !recent_sound) - for(var/mob/M in get_hearers_in_view(2, get_turf(owner))) - if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) - var/sound/devourments = GLOB.vore_sounds[vore_sound] - playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) - recent_sound = TRUE + if(is_wet && (world.time > recent_sound)) + var/turf/source = get_turf(owner) + var/sound/eating = GLOB.vore_sounds[vore_sound] + for(var/mob/living/M in get_hearers_in_view(3, source)) + if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + SEND_SOUND(M, eating) + recent_sound = (world.time + 20 SECONDS) //Messages if it's a mob if(isliving(thing)) @@ -187,7 +190,7 @@ var/atom/destination = drop_location() //Don't bother if we don't have contents if(!contents.len) - return 0 + return FALSE var/count = 0 for(var/thing in contents) @@ -206,10 +209,10 @@ SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey) AM.forceMove(destination) // Move the belly contents into the same location as belly's owner. count++ - for(var/mob/M in get_hearers_in_view(2, get_turf(owner))) + for(var/mob/living/M in get_hearers_in_view(2, get_turf(owner))) if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) var/sound/releasement = GLOB.release_sounds[release_sound] - playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) + SEND_SOUND(M, releasement) //Clean up our own business items_preserved.Cut() @@ -233,10 +236,10 @@ M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner. items_preserved -= M if(!silent) - for(var/mob/H in get_hearers_in_view(2, get_turf(owner))) + for(var/mob/living/H in get_hearers_in_view(2, get_turf(owner))) if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES)) var/sound/releasement = GLOB.release_sounds[release_sound] - playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) + SEND_SOUND(H, releasement) if(istype(M,/mob/living)) var/mob/living/ML = M @@ -285,10 +288,6 @@ SEND_SIGNAL(prey, COMSIG_CLEAR_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey) prey.forceMove(src) - var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE) - - if(is_wet) - prey.playsound_local(loc,preyloop,70,0, channel = CHANNEL_PREYLOOP) owner.updateVRPanel() @@ -317,10 +316,12 @@ M.cure_blind("belly_[REF(src)]") target.nom_mob(content, target.owner) if(!silent) - for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) - if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) - var/sound/devourments = GLOB.vore_sounds[vore_sound] - playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) + var/turf/source = get_turf(owner) + var/sound/eating = GLOB.vore_sounds[vore_sound] + for(var/mob/living/M in get_hearers_in_view(3, source)) + if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + SEND_SOUND(M, eating) + owner.updateVRPanel() for(var/mob/living/M in contents) M.updateVRPanel() @@ -524,22 +525,25 @@ struggle_outer_message = "" + struggle_outer_message + "" struggle_user_message = "" + struggle_user_message + "" + var/turf/source = get_turf(owner) + var/sound/struggle_snuggle = sound(get_sfx("struggle_sound")) + var/sound/struggle_rustle = sound(get_sfx("rustle")) + if(is_wet) - for(var/mob/M in get_hearers_in_view(2, get_turf(owner))) - if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) - playsound(get_turf(owner),"struggle_sound",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED) - R.stop_sound_channel(CHANNEL_PRED) - var/sound/prey_struggle = sound(get_sfx("prey_struggle")) - R.playsound_local(get_turf(R),prey_struggle,45,0) + for(var/mob/living/M in get_hearers_in_view(3, source)) + if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + SEND_SOUND(M, struggle_snuggle) else - for(var/mob/M in get_hearers_in_view(2, get_turf(owner))) - if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) - playsound(get_turf(owner),"rustle",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED) + for(var/mob/living/M in get_hearers_in_view(3, source)) + if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + SEND_SOUND(M, struggle_rustle) - for(var/mob/M in get_hearers_in_view(3, get_turf(owner))) + var/list/watching = hearers(3, owner) + for(var/mob/living/M in watching) if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) //Might as well censor the normies here too. M.show_message(struggle_outer_message, 1) // visible + to_chat(R,struggle_user_message) if(escapable) //If the stomach has escapable enabled. diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm index 6b6a3d30cc..da323f02e2 100644 --- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm +++ b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm @@ -4,10 +4,16 @@ recent_sound = FALSE return SSBELLIES_IGNORED + if(!owner) + qdel(src) + SSbellies.belly_list -= src + return SSBELLIES_PROCESSED + if(loc != owner) - if(istype(owner)) - loc = owner + if(isliving(owner)) //we don't have machine based bellies. (yet :honk:) + forceMove(owner) else + SSbellies.belly_list -= src qdel(src) return SSBELLIES_PROCESSED @@ -26,10 +32,13 @@ if(isbelly(M.loc)) if(world.time > M.next_preyloop) if(is_wet) + if(!M.client) + continue M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case - var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE) - M.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP) - M.next_preyloop = world.time + 52 SECONDS + if(M.client.prefs.cit_toggles & DIGESTION_NOISES) + var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE) + M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP) + M.next_preyloop = (world.time + 52 SECONDS) /////////////////////////// Exit Early //////////////////////////// @@ -63,12 +72,12 @@ if(prob(25)) if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) else if(H in contents) @@ -100,12 +109,12 @@ owner.nutrition += 400 // so eating dead mobs gives you *something*. if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_death) else if(H in contents) @@ -135,12 +144,12 @@ if(prob(25)) if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) else if(H in contents) @@ -159,12 +168,12 @@ if(prob(35)) if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) else if(H in contents) @@ -179,12 +188,12 @@ if(prob(10))//Less often than gurgles. People might leave this on forever. if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) else if(H in contents) @@ -221,12 +230,12 @@ if(prob(55)) //if you're hearing this, you're a vore ho anyway. if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) else if(H in contents) @@ -254,12 +263,12 @@ M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.") if((world.time - NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/H in get_hearers_in_view(3, source)) + for(var/mob/living/H in get_hearers_in_view(3, source)) if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) continue LAZYADD(hearing_mobs, H) last_hearcheck = world.time - for(var/mob/H in hearing_mobs) + for(var/mob/living/H in hearing_mobs) if(!isbelly(H.loc)) H.playsound_local(source, null, 45, falloff = 0, S = pred_death) else if(H in contents) diff --git a/modular_citadel/code/modules/vore/eating/living_vr.dm b/modular_citadel/code/modules/vore/eating/living_vr.dm index a8a77895c8..d9adde04d1 100644 --- a/modular_citadel/code/modules/vore/eating/living_vr.dm +++ b/modular_citadel/code/modules/vore/eating/living_vr.dm @@ -60,18 +60,6 @@ B.can_taste = 1 return TRUE -/* -// Hide vore organs in contents -// -/datum/proc/view_variables_filter_contents(list/L) - return 0 - -/mob/living/view_variables_filter_contents(list/L) - . = ..() - var/len_before = L.len - L -= vore_organs - . += len_before - L.len*/ - // Handle being clicked, perhaps with something to devour // @@ -121,21 +109,12 @@ /mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) var/belly = user.vore_selected return perform_the_nom(user, prey, user, belly) -/* -/mob/living/proc/eat_held_mob(var/mob/living/user, var/mob/living/prey, var/mob/living/pred) - var/belly - if(user != pred) - belly = input("Choose Belly") in pred.vore_organs - else - belly = pred.vore_selected - return perform_the_nom(user, prey, pred, belly)*/ /mob/living/proc/feed_self_to_grabbed(var/mob/living/user, var/mob/living/pred) var/belly = input("Choose Belly") in pred.vore_organs return perform_the_nom(user, user, pred, belly) /mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred) -// return//disabled until I can make that toggle work var/belly = input("Choose Belly") in pred.vore_organs return perform_the_nom(user, prey, pred, belly) @@ -182,9 +161,13 @@ // If we got this far, nom successful! Announce it! user.visible_message(success_msg) - for(var/mob/M in get_hearers_in_view(5, get_turf(user))) + + // incredibly contentious eating noises time + var/turf/source = get_turf(user) + var/sound/eating = GLOB.vore_sounds[belly.vore_sound] + for(var/mob/living/M in get_hearers_in_view(3, source)) if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) - playsound(get_turf(user),"[belly.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) + SEND_SOUND(M, eating) // Actually shove prey into the belly. belly.nom_mob(prey, user) @@ -214,41 +197,7 @@ // //End vore code. -/* - //Handle case: /obj/item/holder - if(/obj/item/holder/micro) - var/obj/item/holder/H = I - if(!isliving(user)) return 0 // Return 0 to continue upper procs - var/mob/living/attacker = user // Typecast to living - - if (is_vore_predator(src)) - for (var/mob/living/M in H.contents) - attacker.eat_held_mob(attacker, M, src) - return 1 //Return 1 to exit upper procs - else - log_attack("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it failed.") - - // I just can't imagine this not being complained about - //Handle case: /obj/item/radio/beacon - if(/obj/item/radio/beacon) - var/confirm = alert(user, "[src == user ? "Eat the beacon?" : "Feed the beacon to [src]?"]", "Confirmation", "Yes!", "Cancel") - if(confirm == "Yes!") - var/bellychoice = input("Which belly?","Select A Belly") in src.vore_organs - var/datum/belly/B = src.vore_organs[bellychoice] - src.visible_message("[user] is trying to stuff a beacon into [src]'s [bellychoice]!","[user] is trying to stuff a beacon into you!") - if(do_after(user,30,src)) - user.drop_item() - I.loc = src - B.internal_contents += I - src.visible_message("[src] is fed the beacon!","You're fed the beacon!") - playsound(get_turf(src), B.vore_sound,50,0,-6,0) - return 1 - else - return 1 //You don't get to hit someone 'later' - - return 0 -*/ // // Our custom resist catches for /mob/living @@ -272,7 +221,7 @@ if(isbelly(loc)) src.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE) - src.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP) + SEND_SOUND(src, preyloop) else to_chat(src, "You aren't inside anything, you clod.") diff --git a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm index 6f484e7a51..ae7da895a6 100644 --- a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm +++ b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm @@ -57,7 +57,7 @@ /datum/vore_look/proc/gen_vui(var/mob/living/user) var/dat dat += "Remember to toggle the vore mode, it's to the left of your combat toggle. Open mouth means you're voracious!
    " - dat += "Remember that your prey is blind, use audible mode subtle messages to communicate to them with posts!
    " + dat += "Remember that the prey is blind, use audible mode subtle messages to communicate to them with posts!
    " dat += "
    " var/atom/userloc = user.loc if (isbelly(userloc)) @@ -554,7 +554,7 @@ if(href_list["b_releasesoundtest"]) var/sound/releasetest = GLOB.release_sounds[selected.release_sound] if(releasetest) - user << releasetest + SEND_SOUND(user, releasetest) if(href_list["b_sound"]) var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.vore_sounds @@ -567,7 +567,7 @@ if(href_list["b_soundtest"]) var/sound/voretest = GLOB.vore_sounds[selected.vore_sound] if(voretest) - user << voretest + SEND_SOUND(user, voretest) if(href_list["b_tastes"]) selected.can_taste = !selected.can_taste diff --git a/modular_citadel/icons/firstaid.dmi b/modular_citadel/icons/firstaid.dmi index 693f5a2fa4..8c603c8762 100644 Binary files a/modular_citadel/icons/firstaid.dmi and b/modular_citadel/icons/firstaid.dmi differ diff --git a/modular_citadel/icons/mob/citadel_refs/widerobot_vr.dmi b/modular_citadel/icons/mob/citadel_refs/widerobot_vr.dmi index fa7285ae4c..7fbb26f1af 100644 Binary files a/modular_citadel/icons/mob/citadel_refs/widerobot_vr.dmi and b/modular_citadel/icons/mob/citadel_refs/widerobot_vr.dmi differ diff --git a/modular_citadel/icons/mob/mutant_bodyparts.dmi b/modular_citadel/icons/mob/mutant_bodyparts.dmi index 5f72d1013b..1e12d2bf1a 100644 Binary files a/modular_citadel/icons/mob/mutant_bodyparts.dmi and b/modular_citadel/icons/mob/mutant_bodyparts.dmi differ diff --git a/modular_citadel/icons/mob/muzzled_helmet.dmi b/modular_citadel/icons/mob/muzzled_helmet.dmi index e321f8ae47..a318f394f8 100644 Binary files a/modular_citadel/icons/mob/muzzled_helmet.dmi and b/modular_citadel/icons/mob/muzzled_helmet.dmi differ diff --git a/modular_citadel/icons/mob/suit_digi.dmi b/modular_citadel/icons/mob/suit_digi.dmi index 1f1f506d9f..eba761ff79 100644 Binary files a/modular_citadel/icons/mob/suit_digi.dmi and b/modular_citadel/icons/mob/suit_digi.dmi differ diff --git a/modular_citadel/icons/mob/uniform_digi.dmi b/modular_citadel/icons/mob/uniform_digi.dmi index 5ff291f400..aea900d110 100644 Binary files a/modular_citadel/icons/mob/uniform_digi.dmi and b/modular_citadel/icons/mob/uniform_digi.dmi differ diff --git a/modular_citadel/icons/mob/widerobot.dmi b/modular_citadel/icons/mob/widerobot.dmi index 178897fac8..3667345f8d 100644 Binary files a/modular_citadel/icons/mob/widerobot.dmi and b/modular_citadel/icons/mob/widerobot.dmi differ diff --git a/modular_citadel/icons/obj/FermiChem.dmi b/modular_citadel/icons/obj/FermiChem.dmi new file mode 100644 index 0000000000..de7a86d574 Binary files /dev/null and b/modular_citadel/icons/obj/FermiChem.dmi differ diff --git a/modular_citadel/icons/obj/clothing/hats.dmi b/modular_citadel/icons/obj/clothing/hats.dmi new file mode 100644 index 0000000000..ba9b4b5f8e Binary files /dev/null and b/modular_citadel/icons/obj/clothing/hats.dmi differ diff --git a/modular_citadel/icons/obj/food/cake.dmi b/modular_citadel/icons/obj/food/cake.dmi deleted file mode 100644 index 840bfe714d..0000000000 Binary files a/modular_citadel/icons/obj/food/cake.dmi and /dev/null differ diff --git a/modular_citadel/icons/obj/genitals/breasts.dmi b/modular_citadel/icons/obj/genitals/breasts.dmi index 8c76891396..d70207ee69 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts.dmi and b/modular_citadel/icons/obj/genitals/breasts.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi index c4b75b1172..371041b6f4 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi and b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis.dmi b/modular_citadel/icons/obj/genitals/penis.dmi index 397fa335e5..517758b248 100644 Binary files a/modular_citadel/icons/obj/genitals/penis.dmi and b/modular_citadel/icons/obj/genitals/penis.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 434f171e22..416965415d 100644 Binary files a/modular_citadel/icons/obj/genitals/penis_onmob.dmi and b/modular_citadel/icons/obj/genitals/penis_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi b/modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi index 3debbd0047..ae2339e2e0 100644 Binary files a/modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi and b/modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi index c4cf891eac..ab71b22e3b 100644 Binary files a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi and b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi differ diff --git a/modular_citadel/icons/obj/guns/cit_guns.dmi b/modular_citadel/icons/obj/guns/cit_guns.dmi index cc04fbcb14..bd48d8edbd 100644 Binary files a/modular_citadel/icons/obj/guns/cit_guns.dmi and b/modular_citadel/icons/obj/guns/cit_guns.dmi differ diff --git a/modular_citadel/icons/obj/vial.dmi b/modular_citadel/icons/obj/vial.dmi index bc282ab1d3..8d1fefe470 100755 Binary files a/modular_citadel/icons/obj/vial.dmi and b/modular_citadel/icons/obj/vial.dmi differ diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf index e4531a24ea..c5b5138609 100644 --- a/modular_citadel/interface/skin.dmf +++ b/modular_citadel/interface/skin.dmf @@ -54,7 +54,7 @@ window "mainwindow" size = 640x440 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #eeeeee is-default = true saved-params = "pos;size;is-minimized;is-maximized" icon = 'icons\\ss13_64.png' @@ -66,7 +66,7 @@ window "mainwindow" size = 637x440 anchor1 = 0,0 anchor2 = 100,100 - background-color = #272727 + background-color = #eeeeee saved-params = "splitter" left = "mapwindow" right = "infowindow" @@ -78,7 +78,7 @@ window "mainwindow" size = 200x200 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #ffffff is-visible = false saved-params = "" elem "tooltip" @@ -87,7 +87,7 @@ window "mainwindow" size = 999x999 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #ffffff is-visible = false saved-params = "" @@ -98,7 +98,6 @@ window "mapwindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #272727 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "map" @@ -120,7 +119,7 @@ window "infowindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #eeeeee saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "info" @@ -129,7 +128,6 @@ window "infowindow" size = 640x445 anchor1 = 0,0 anchor2 = 100,100 - background-color = #272727 saved-params = "splitter" left = "statwindow" right = "outputwindow" @@ -140,8 +138,7 @@ window "infowindow" size = 104x20 anchor1 = 3,0 anchor2 = 19,0 - text-color = #ffffff - background-color = #40628a + background-color = #90b3dd saved-params = "is-checked" text = "Changelog" command = "changelog" @@ -151,8 +148,7 @@ window "infowindow" size = 100x20 anchor1 = 19,0 anchor2 = 34,0 - text-color = #ffffff - background-color = #40628a + background-color = #90b3dd saved-params = "is-checked" text = "Rules" command = "rules" @@ -162,8 +158,7 @@ window "infowindow" size = 100x20 anchor1 = 34,0 anchor2 = 50,0 - text-color = #ffffff - background-color = #40628a + background-color = #90b3dd saved-params = "is-checked" text = "Wiki" command = "wiki" @@ -173,8 +168,7 @@ window "infowindow" size = 100x20 anchor1 = 50,0 anchor2 = 66,0 - text-color = #ffffff - background-color = #40628a + background-color = #90b3dd saved-params = "is-checked" text = "Forum" command = "forum" @@ -184,8 +178,7 @@ window "infowindow" size = 100x20 anchor1 = 66,0 anchor2 = 81,0 - text-color = #ffffff - background-color = #40628a + background-color = #90b3dd saved-params = "is-checked" text = "GitHub" command = "github" @@ -196,8 +189,7 @@ window "infowindow" anchor1 = 81,0 anchor2 = 97,0 font-size = 8 - text-color = #ffffff - background-color = #40628a + background-color = #ef7f7f saved-params = "is-checked" text = "Report Issue" command = "report-issue" @@ -209,7 +201,7 @@ window "outputwindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #eeeeee saved-params = "pos;size;is-minimized;is-maximized" titlebar = false statusbar = false @@ -223,9 +215,9 @@ window "outputwindow" size = 595x20 anchor1 = 0,100 anchor2 = 100,100 - font-size = 10 background-color = #d3b5b5 is-default = true + border = sunken saved-params = "command" elem "say" type = BUTTON @@ -233,8 +225,7 @@ window "outputwindow" size = 37x20 anchor1 = 100,100 anchor2 = none - text-color = #ffffff - background-color = #272727 + background-color = #eeeeee saved-params = "is-checked" text = "Chat" command = ".winset \"say.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"" @@ -246,7 +237,7 @@ window "outputwindow" size = 640x456 anchor1 = 0,0 anchor2 = 100,100 - background-color = #272727 + background-color = #ffffff is-visible = false is-disabled = true saved-params = "" @@ -257,8 +248,6 @@ window "outputwindow" size = 640x456 anchor1 = 0,0 anchor2 = 100,100 - text-color = #40628a - background-color = #272727 is-default = true saved-params = "" @@ -269,7 +258,7 @@ window "statwindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #272727 + background-color = #eeeeee saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "stat" @@ -278,14 +267,9 @@ window "statwindow" size = 640x480 anchor1 = 0,0 anchor2 = 100,100 - text-color = #ffffff - background-color = #383838 is-default = true saved-params = "" - tab-text-color = #ffffff - tab-background-color = #272727 - prefix-color = #ebebeb - suffix-color = #ebebeb + tab-background-color = #eeeeee window "preferences_window" elem "preferences_window" @@ -294,7 +278,6 @@ window "preferences_window" size = 1280x1000 anchor1 = none anchor2 = none - background-color = none is-visible = false saved-params = "pos;size;is-minimized;is-maximized" statusbar = false @@ -304,7 +287,6 @@ window "preferences_window" size = 960x1000 anchor1 = 0,0 anchor2 = 75,100 - background-color = none saved-params = "" elem "character_preview_map" type = MAP diff --git a/modular_citadel/sound/vox/_comma.ogg b/modular_citadel/sound/vox/_comma.ogg new file mode 100644 index 0000000000..55ee3102a0 Binary files /dev/null and b/modular_citadel/sound/vox/_comma.ogg differ diff --git a/modular_citadel/sound/vox/_period.ogg b/modular_citadel/sound/vox/_period.ogg new file mode 100644 index 0000000000..dfb816d006 Binary files /dev/null and b/modular_citadel/sound/vox/_period.ogg differ diff --git a/modular_citadel/sound/vox/a.ogg b/modular_citadel/sound/vox/a.ogg new file mode 100644 index 0000000000..ad3a851290 Binary files /dev/null and b/modular_citadel/sound/vox/a.ogg differ diff --git a/modular_citadel/sound/vox/accelerating.ogg b/modular_citadel/sound/vox/accelerating.ogg new file mode 100644 index 0000000000..d6426aa798 Binary files /dev/null and b/modular_citadel/sound/vox/accelerating.ogg differ diff --git a/modular_citadel/sound/vox/accelerator.ogg b/modular_citadel/sound/vox/accelerator.ogg new file mode 100644 index 0000000000..6e8e1f10e8 Binary files /dev/null and b/modular_citadel/sound/vox/accelerator.ogg differ diff --git a/modular_citadel/sound/vox/accepted.ogg b/modular_citadel/sound/vox/accepted.ogg new file mode 100644 index 0000000000..f6c411f8c5 Binary files /dev/null and b/modular_citadel/sound/vox/accepted.ogg differ diff --git a/modular_citadel/sound/vox/access.ogg b/modular_citadel/sound/vox/access.ogg new file mode 100644 index 0000000000..ae8390e516 Binary files /dev/null and b/modular_citadel/sound/vox/access.ogg differ diff --git a/modular_citadel/sound/vox/acknowledge.ogg b/modular_citadel/sound/vox/acknowledge.ogg new file mode 100644 index 0000000000..da3143b729 Binary files /dev/null and b/modular_citadel/sound/vox/acknowledge.ogg differ diff --git a/modular_citadel/sound/vox/acknowledged.ogg b/modular_citadel/sound/vox/acknowledged.ogg new file mode 100644 index 0000000000..b4b89eaa52 Binary files /dev/null and b/modular_citadel/sound/vox/acknowledged.ogg differ diff --git a/modular_citadel/sound/vox/acquired.ogg b/modular_citadel/sound/vox/acquired.ogg new file mode 100644 index 0000000000..ba4595a908 Binary files /dev/null and b/modular_citadel/sound/vox/acquired.ogg differ diff --git a/modular_citadel/sound/vox/acquisition.ogg b/modular_citadel/sound/vox/acquisition.ogg new file mode 100644 index 0000000000..fcdf6a9832 Binary files /dev/null and b/modular_citadel/sound/vox/acquisition.ogg differ diff --git a/modular_citadel/sound/vox/across.ogg b/modular_citadel/sound/vox/across.ogg new file mode 100644 index 0000000000..d026b3dba9 Binary files /dev/null and b/modular_citadel/sound/vox/across.ogg differ diff --git a/modular_citadel/sound/vox/activate.ogg b/modular_citadel/sound/vox/activate.ogg new file mode 100644 index 0000000000..5611c456a7 Binary files /dev/null and b/modular_citadel/sound/vox/activate.ogg differ diff --git a/modular_citadel/sound/vox/activated.ogg b/modular_citadel/sound/vox/activated.ogg new file mode 100644 index 0000000000..e3fafca3b2 Binary files /dev/null and b/modular_citadel/sound/vox/activated.ogg differ diff --git a/modular_citadel/sound/vox/activity.ogg b/modular_citadel/sound/vox/activity.ogg new file mode 100644 index 0000000000..66535b485d Binary files /dev/null and b/modular_citadel/sound/vox/activity.ogg differ diff --git a/modular_citadel/sound/vox/adios.ogg b/modular_citadel/sound/vox/adios.ogg new file mode 100644 index 0000000000..1eedd5468b Binary files /dev/null and b/modular_citadel/sound/vox/adios.ogg differ diff --git a/modular_citadel/sound/vox/administration.ogg b/modular_citadel/sound/vox/administration.ogg new file mode 100644 index 0000000000..44f8b3e8d8 Binary files /dev/null and b/modular_citadel/sound/vox/administration.ogg differ diff --git a/modular_citadel/sound/vox/advanced.ogg b/modular_citadel/sound/vox/advanced.ogg new file mode 100644 index 0000000000..df110dd8db Binary files /dev/null and b/modular_citadel/sound/vox/advanced.ogg differ diff --git a/modular_citadel/sound/vox/after.ogg b/modular_citadel/sound/vox/after.ogg new file mode 100644 index 0000000000..8c0857f99c Binary files /dev/null and b/modular_citadel/sound/vox/after.ogg differ diff --git a/modular_citadel/sound/vox/agent.ogg b/modular_citadel/sound/vox/agent.ogg new file mode 100644 index 0000000000..eae99227bc Binary files /dev/null and b/modular_citadel/sound/vox/agent.ogg differ diff --git a/modular_citadel/sound/vox/alarm.ogg b/modular_citadel/sound/vox/alarm.ogg new file mode 100644 index 0000000000..54bcc0b980 Binary files /dev/null and b/modular_citadel/sound/vox/alarm.ogg differ diff --git a/modular_citadel/sound/vox/alert.ogg b/modular_citadel/sound/vox/alert.ogg new file mode 100644 index 0000000000..08620fa58c Binary files /dev/null and b/modular_citadel/sound/vox/alert.ogg differ diff --git a/modular_citadel/sound/vox/alien.ogg b/modular_citadel/sound/vox/alien.ogg new file mode 100644 index 0000000000..cb3c3d7787 Binary files /dev/null and b/modular_citadel/sound/vox/alien.ogg differ diff --git a/modular_citadel/sound/vox/aligned.ogg b/modular_citadel/sound/vox/aligned.ogg new file mode 100644 index 0000000000..f561a1ec2f Binary files /dev/null and b/modular_citadel/sound/vox/aligned.ogg differ diff --git a/modular_citadel/sound/vox/all.ogg b/modular_citadel/sound/vox/all.ogg new file mode 100644 index 0000000000..48d05f1007 Binary files /dev/null and b/modular_citadel/sound/vox/all.ogg differ diff --git a/modular_citadel/sound/vox/alpha.ogg b/modular_citadel/sound/vox/alpha.ogg new file mode 100644 index 0000000000..b80828c408 Binary files /dev/null and b/modular_citadel/sound/vox/alpha.ogg differ diff --git a/modular_citadel/sound/vox/am.ogg b/modular_citadel/sound/vox/am.ogg new file mode 100644 index 0000000000..9d4289758e Binary files /dev/null and b/modular_citadel/sound/vox/am.ogg differ diff --git a/modular_citadel/sound/vox/amigo.ogg b/modular_citadel/sound/vox/amigo.ogg new file mode 100644 index 0000000000..6992689553 Binary files /dev/null and b/modular_citadel/sound/vox/amigo.ogg differ diff --git a/modular_citadel/sound/vox/ammunition.ogg b/modular_citadel/sound/vox/ammunition.ogg new file mode 100644 index 0000000000..108fb2dc83 Binary files /dev/null and b/modular_citadel/sound/vox/ammunition.ogg differ diff --git a/modular_citadel/sound/vox/an.ogg b/modular_citadel/sound/vox/an.ogg new file mode 100644 index 0000000000..53382c68a0 Binary files /dev/null and b/modular_citadel/sound/vox/an.ogg differ diff --git a/modular_citadel/sound/vox/and.ogg b/modular_citadel/sound/vox/and.ogg new file mode 100644 index 0000000000..b9b4de26bf Binary files /dev/null and b/modular_citadel/sound/vox/and.ogg differ diff --git a/modular_citadel/sound/vox/announcement.ogg b/modular_citadel/sound/vox/announcement.ogg new file mode 100644 index 0000000000..ba16d76c18 Binary files /dev/null and b/modular_citadel/sound/vox/announcement.ogg differ diff --git a/modular_citadel/sound/vox/anomalous.ogg b/modular_citadel/sound/vox/anomalous.ogg new file mode 100644 index 0000000000..a331afd06e Binary files /dev/null and b/modular_citadel/sound/vox/anomalous.ogg differ diff --git a/modular_citadel/sound/vox/antenna.ogg b/modular_citadel/sound/vox/antenna.ogg new file mode 100644 index 0000000000..547e64786a Binary files /dev/null and b/modular_citadel/sound/vox/antenna.ogg differ diff --git a/modular_citadel/sound/vox/any.ogg b/modular_citadel/sound/vox/any.ogg new file mode 100644 index 0000000000..49d578758b Binary files /dev/null and b/modular_citadel/sound/vox/any.ogg differ diff --git a/modular_citadel/sound/vox/apprehend.ogg b/modular_citadel/sound/vox/apprehend.ogg new file mode 100644 index 0000000000..de0fc4d664 Binary files /dev/null and b/modular_citadel/sound/vox/apprehend.ogg differ diff --git a/modular_citadel/sound/vox/approach.ogg b/modular_citadel/sound/vox/approach.ogg new file mode 100644 index 0000000000..3135bb7fc4 Binary files /dev/null and b/modular_citadel/sound/vox/approach.ogg differ diff --git a/modular_citadel/sound/vox/are.ogg b/modular_citadel/sound/vox/are.ogg new file mode 100644 index 0000000000..b3e68aa8a6 Binary files /dev/null and b/modular_citadel/sound/vox/are.ogg differ diff --git a/modular_citadel/sound/vox/area.ogg b/modular_citadel/sound/vox/area.ogg new file mode 100644 index 0000000000..1408fedf4c Binary files /dev/null and b/modular_citadel/sound/vox/area.ogg differ diff --git a/modular_citadel/sound/vox/arm.ogg b/modular_citadel/sound/vox/arm.ogg new file mode 100644 index 0000000000..e078c567b5 Binary files /dev/null and b/modular_citadel/sound/vox/arm.ogg differ diff --git a/modular_citadel/sound/vox/armed.ogg b/modular_citadel/sound/vox/armed.ogg new file mode 100644 index 0000000000..2b1d092658 Binary files /dev/null and b/modular_citadel/sound/vox/armed.ogg differ diff --git a/modular_citadel/sound/vox/armor.ogg b/modular_citadel/sound/vox/armor.ogg new file mode 100644 index 0000000000..70217b55a4 Binary files /dev/null and b/modular_citadel/sound/vox/armor.ogg differ diff --git a/modular_citadel/sound/vox/armory.ogg b/modular_citadel/sound/vox/armory.ogg new file mode 100644 index 0000000000..22835188f8 Binary files /dev/null and b/modular_citadel/sound/vox/armory.ogg differ diff --git a/modular_citadel/sound/vox/arrest.ogg b/modular_citadel/sound/vox/arrest.ogg new file mode 100644 index 0000000000..bfef18601f Binary files /dev/null and b/modular_citadel/sound/vox/arrest.ogg differ diff --git a/modular_citadel/sound/vox/ass.ogg b/modular_citadel/sound/vox/ass.ogg new file mode 100644 index 0000000000..6bf9c01e62 Binary files /dev/null and b/modular_citadel/sound/vox/ass.ogg differ diff --git a/modular_citadel/sound/vox/at.ogg b/modular_citadel/sound/vox/at.ogg new file mode 100644 index 0000000000..5146ab9afb Binary files /dev/null and b/modular_citadel/sound/vox/at.ogg differ diff --git a/modular_citadel/sound/vox/atomic.ogg b/modular_citadel/sound/vox/atomic.ogg new file mode 100644 index 0000000000..b8b1e1cec7 Binary files /dev/null and b/modular_citadel/sound/vox/atomic.ogg differ diff --git a/modular_citadel/sound/vox/attention.ogg b/modular_citadel/sound/vox/attention.ogg new file mode 100644 index 0000000000..ca5073e6c4 Binary files /dev/null and b/modular_citadel/sound/vox/attention.ogg differ diff --git a/modular_citadel/sound/vox/authorize.ogg b/modular_citadel/sound/vox/authorize.ogg new file mode 100644 index 0000000000..7ef68781ef Binary files /dev/null and b/modular_citadel/sound/vox/authorize.ogg differ diff --git a/modular_citadel/sound/vox/authorized.ogg b/modular_citadel/sound/vox/authorized.ogg new file mode 100644 index 0000000000..5142ceba8d Binary files /dev/null and b/modular_citadel/sound/vox/authorized.ogg differ diff --git a/modular_citadel/sound/vox/automatic.ogg b/modular_citadel/sound/vox/automatic.ogg new file mode 100644 index 0000000000..48d09f2304 Binary files /dev/null and b/modular_citadel/sound/vox/automatic.ogg differ diff --git a/modular_citadel/sound/vox/away.ogg b/modular_citadel/sound/vox/away.ogg new file mode 100644 index 0000000000..3e99af620e Binary files /dev/null and b/modular_citadel/sound/vox/away.ogg differ diff --git a/modular_citadel/sound/vox/b.ogg b/modular_citadel/sound/vox/b.ogg new file mode 100644 index 0000000000..00b64030d6 Binary files /dev/null and b/modular_citadel/sound/vox/b.ogg differ diff --git a/modular_citadel/sound/vox/back.ogg b/modular_citadel/sound/vox/back.ogg new file mode 100644 index 0000000000..a8ca34ef52 Binary files /dev/null and b/modular_citadel/sound/vox/back.ogg differ diff --git a/modular_citadel/sound/vox/backman.ogg b/modular_citadel/sound/vox/backman.ogg new file mode 100644 index 0000000000..e0e6351f57 Binary files /dev/null and b/modular_citadel/sound/vox/backman.ogg differ diff --git a/modular_citadel/sound/vox/bad.ogg b/modular_citadel/sound/vox/bad.ogg new file mode 100644 index 0000000000..2dd38058a2 Binary files /dev/null and b/modular_citadel/sound/vox/bad.ogg differ diff --git a/modular_citadel/sound/vox/bag.ogg b/modular_citadel/sound/vox/bag.ogg new file mode 100644 index 0000000000..6daa1ab172 Binary files /dev/null and b/modular_citadel/sound/vox/bag.ogg differ diff --git a/modular_citadel/sound/vox/bailey.ogg b/modular_citadel/sound/vox/bailey.ogg new file mode 100644 index 0000000000..b912fe5801 Binary files /dev/null and b/modular_citadel/sound/vox/bailey.ogg differ diff --git a/modular_citadel/sound/vox/barracks.ogg b/modular_citadel/sound/vox/barracks.ogg new file mode 100644 index 0000000000..5e13a42773 Binary files /dev/null and b/modular_citadel/sound/vox/barracks.ogg differ diff --git a/modular_citadel/sound/vox/base.ogg b/modular_citadel/sound/vox/base.ogg new file mode 100644 index 0000000000..17d60fbc02 Binary files /dev/null and b/modular_citadel/sound/vox/base.ogg differ diff --git a/modular_citadel/sound/vox/bay.ogg b/modular_citadel/sound/vox/bay.ogg new file mode 100644 index 0000000000..7ac9991c69 Binary files /dev/null and b/modular_citadel/sound/vox/bay.ogg differ diff --git a/modular_citadel/sound/vox/be.ogg b/modular_citadel/sound/vox/be.ogg new file mode 100644 index 0000000000..01865aba54 Binary files /dev/null and b/modular_citadel/sound/vox/be.ogg differ diff --git a/modular_citadel/sound/vox/been.ogg b/modular_citadel/sound/vox/been.ogg new file mode 100644 index 0000000000..cf9e92a032 Binary files /dev/null and b/modular_citadel/sound/vox/been.ogg differ diff --git a/modular_citadel/sound/vox/before.ogg b/modular_citadel/sound/vox/before.ogg new file mode 100644 index 0000000000..fc16e8fef4 Binary files /dev/null and b/modular_citadel/sound/vox/before.ogg differ diff --git a/modular_citadel/sound/vox/beyond.ogg b/modular_citadel/sound/vox/beyond.ogg new file mode 100644 index 0000000000..e25982e700 Binary files /dev/null and b/modular_citadel/sound/vox/beyond.ogg differ diff --git a/modular_citadel/sound/vox/biohazard.ogg b/modular_citadel/sound/vox/biohazard.ogg new file mode 100644 index 0000000000..12d20ff2f3 Binary files /dev/null and b/modular_citadel/sound/vox/biohazard.ogg differ diff --git a/modular_citadel/sound/vox/biological.ogg b/modular_citadel/sound/vox/biological.ogg new file mode 100644 index 0000000000..538c2c4604 Binary files /dev/null and b/modular_citadel/sound/vox/biological.ogg differ diff --git a/modular_citadel/sound/vox/birdwell.ogg b/modular_citadel/sound/vox/birdwell.ogg new file mode 100644 index 0000000000..d3735d2531 Binary files /dev/null and b/modular_citadel/sound/vox/birdwell.ogg differ diff --git a/modular_citadel/sound/vox/bizwarn.ogg b/modular_citadel/sound/vox/bizwarn.ogg new file mode 100644 index 0000000000..1f875c644e Binary files /dev/null and b/modular_citadel/sound/vox/bizwarn.ogg differ diff --git a/modular_citadel/sound/vox/black.ogg b/modular_citadel/sound/vox/black.ogg new file mode 100644 index 0000000000..28e5d48afe Binary files /dev/null and b/modular_citadel/sound/vox/black.ogg differ diff --git a/modular_citadel/sound/vox/blast.ogg b/modular_citadel/sound/vox/blast.ogg new file mode 100644 index 0000000000..84a28e1fc8 Binary files /dev/null and b/modular_citadel/sound/vox/blast.ogg differ diff --git a/modular_citadel/sound/vox/blocked.ogg b/modular_citadel/sound/vox/blocked.ogg new file mode 100644 index 0000000000..f6efacfda1 Binary files /dev/null and b/modular_citadel/sound/vox/blocked.ogg differ diff --git a/modular_citadel/sound/vox/bloop.ogg b/modular_citadel/sound/vox/bloop.ogg new file mode 100644 index 0000000000..ada6ed636e Binary files /dev/null and b/modular_citadel/sound/vox/bloop.ogg differ diff --git a/modular_citadel/sound/vox/blue.ogg b/modular_citadel/sound/vox/blue.ogg new file mode 100644 index 0000000000..a336a61968 Binary files /dev/null and b/modular_citadel/sound/vox/blue.ogg differ diff --git a/modular_citadel/sound/vox/bottom.ogg b/modular_citadel/sound/vox/bottom.ogg new file mode 100644 index 0000000000..b81c30477c Binary files /dev/null and b/modular_citadel/sound/vox/bottom.ogg differ diff --git a/modular_citadel/sound/vox/bravo.ogg b/modular_citadel/sound/vox/bravo.ogg new file mode 100644 index 0000000000..df47058d5c Binary files /dev/null and b/modular_citadel/sound/vox/bravo.ogg differ diff --git a/modular_citadel/sound/vox/breach.ogg b/modular_citadel/sound/vox/breach.ogg new file mode 100644 index 0000000000..3a4bae3f0d Binary files /dev/null and b/modular_citadel/sound/vox/breach.ogg differ diff --git a/modular_citadel/sound/vox/breached.ogg b/modular_citadel/sound/vox/breached.ogg new file mode 100644 index 0000000000..0823bfc0d9 Binary files /dev/null and b/modular_citadel/sound/vox/breached.ogg differ diff --git a/modular_citadel/sound/vox/break.ogg b/modular_citadel/sound/vox/break.ogg new file mode 100644 index 0000000000..1bebe2b940 Binary files /dev/null and b/modular_citadel/sound/vox/break.ogg differ diff --git a/modular_citadel/sound/vox/bridge.ogg b/modular_citadel/sound/vox/bridge.ogg new file mode 100644 index 0000000000..8de8159b1e Binary files /dev/null and b/modular_citadel/sound/vox/bridge.ogg differ diff --git a/modular_citadel/sound/vox/bust.ogg b/modular_citadel/sound/vox/bust.ogg new file mode 100644 index 0000000000..67622a5e4a Binary files /dev/null and b/modular_citadel/sound/vox/bust.ogg differ diff --git a/modular_citadel/sound/vox/but.ogg b/modular_citadel/sound/vox/but.ogg new file mode 100644 index 0000000000..3c4d7172ef Binary files /dev/null and b/modular_citadel/sound/vox/but.ogg differ diff --git a/modular_citadel/sound/vox/button.ogg b/modular_citadel/sound/vox/button.ogg new file mode 100644 index 0000000000..74639090f8 Binary files /dev/null and b/modular_citadel/sound/vox/button.ogg differ diff --git a/modular_citadel/sound/vox/buzwarn.ogg b/modular_citadel/sound/vox/buzwarn.ogg new file mode 100644 index 0000000000..34595dfe9b Binary files /dev/null and b/modular_citadel/sound/vox/buzwarn.ogg differ diff --git a/modular_citadel/sound/vox/bypass.ogg b/modular_citadel/sound/vox/bypass.ogg new file mode 100644 index 0000000000..649fb0ca72 Binary files /dev/null and b/modular_citadel/sound/vox/bypass.ogg differ diff --git a/modular_citadel/sound/vox/c.ogg b/modular_citadel/sound/vox/c.ogg new file mode 100644 index 0000000000..99fc8eeb61 Binary files /dev/null and b/modular_citadel/sound/vox/c.ogg differ diff --git a/modular_citadel/sound/vox/cable.ogg b/modular_citadel/sound/vox/cable.ogg new file mode 100644 index 0000000000..8a03fec7a3 Binary files /dev/null and b/modular_citadel/sound/vox/cable.ogg differ diff --git a/modular_citadel/sound/vox/call.ogg b/modular_citadel/sound/vox/call.ogg new file mode 100644 index 0000000000..1cd702986d Binary files /dev/null and b/modular_citadel/sound/vox/call.ogg differ diff --git a/modular_citadel/sound/vox/called.ogg b/modular_citadel/sound/vox/called.ogg new file mode 100644 index 0000000000..96c87be172 Binary files /dev/null and b/modular_citadel/sound/vox/called.ogg differ diff --git a/modular_citadel/sound/vox/canal.ogg b/modular_citadel/sound/vox/canal.ogg new file mode 100644 index 0000000000..0d4e92deb4 Binary files /dev/null and b/modular_citadel/sound/vox/canal.ogg differ diff --git a/modular_citadel/sound/vox/cap.ogg b/modular_citadel/sound/vox/cap.ogg new file mode 100644 index 0000000000..c229e6f5b1 Binary files /dev/null and b/modular_citadel/sound/vox/cap.ogg differ diff --git a/modular_citadel/sound/vox/captain.ogg b/modular_citadel/sound/vox/captain.ogg new file mode 100644 index 0000000000..69d2521e68 Binary files /dev/null and b/modular_citadel/sound/vox/captain.ogg differ diff --git a/modular_citadel/sound/vox/capture.ogg b/modular_citadel/sound/vox/capture.ogg new file mode 100644 index 0000000000..18eab2035b Binary files /dev/null and b/modular_citadel/sound/vox/capture.ogg differ diff --git a/modular_citadel/sound/vox/captured.ogg b/modular_citadel/sound/vox/captured.ogg new file mode 100644 index 0000000000..fd6b652809 Binary files /dev/null and b/modular_citadel/sound/vox/captured.ogg differ diff --git a/modular_citadel/sound/vox/ceiling.ogg b/modular_citadel/sound/vox/ceiling.ogg new file mode 100644 index 0000000000..2f8d7eca0a Binary files /dev/null and b/modular_citadel/sound/vox/ceiling.ogg differ diff --git a/modular_citadel/sound/vox/celsius.ogg b/modular_citadel/sound/vox/celsius.ogg new file mode 100644 index 0000000000..abb728c5c3 Binary files /dev/null and b/modular_citadel/sound/vox/celsius.ogg differ diff --git a/modular_citadel/sound/vox/center.ogg b/modular_citadel/sound/vox/center.ogg new file mode 100644 index 0000000000..1936e9190d Binary files /dev/null and b/modular_citadel/sound/vox/center.ogg differ diff --git a/modular_citadel/sound/vox/centi.ogg b/modular_citadel/sound/vox/centi.ogg new file mode 100644 index 0000000000..63f9ce0aed Binary files /dev/null and b/modular_citadel/sound/vox/centi.ogg differ diff --git a/modular_citadel/sound/vox/central.ogg b/modular_citadel/sound/vox/central.ogg new file mode 100644 index 0000000000..a805204243 Binary files /dev/null and b/modular_citadel/sound/vox/central.ogg differ diff --git a/modular_citadel/sound/vox/chamber.ogg b/modular_citadel/sound/vox/chamber.ogg new file mode 100644 index 0000000000..e3c77e927f Binary files /dev/null and b/modular_citadel/sound/vox/chamber.ogg differ diff --git a/modular_citadel/sound/vox/charlie.ogg b/modular_citadel/sound/vox/charlie.ogg new file mode 100644 index 0000000000..bdadd74ca0 Binary files /dev/null and b/modular_citadel/sound/vox/charlie.ogg differ diff --git a/modular_citadel/sound/vox/check.ogg b/modular_citadel/sound/vox/check.ogg new file mode 100644 index 0000000000..f4a2a95de7 Binary files /dev/null and b/modular_citadel/sound/vox/check.ogg differ diff --git a/modular_citadel/sound/vox/checkpoint.ogg b/modular_citadel/sound/vox/checkpoint.ogg new file mode 100644 index 0000000000..aca98b09fa Binary files /dev/null and b/modular_citadel/sound/vox/checkpoint.ogg differ diff --git a/modular_citadel/sound/vox/chemical.ogg b/modular_citadel/sound/vox/chemical.ogg new file mode 100644 index 0000000000..f7eae25c99 Binary files /dev/null and b/modular_citadel/sound/vox/chemical.ogg differ diff --git a/modular_citadel/sound/vox/cleanup.ogg b/modular_citadel/sound/vox/cleanup.ogg new file mode 100644 index 0000000000..2118f130cb Binary files /dev/null and b/modular_citadel/sound/vox/cleanup.ogg differ diff --git a/modular_citadel/sound/vox/clear.ogg b/modular_citadel/sound/vox/clear.ogg new file mode 100644 index 0000000000..1b97835f0f Binary files /dev/null and b/modular_citadel/sound/vox/clear.ogg differ diff --git a/modular_citadel/sound/vox/clearance.ogg b/modular_citadel/sound/vox/clearance.ogg new file mode 100644 index 0000000000..d2b641df40 Binary files /dev/null and b/modular_citadel/sound/vox/clearance.ogg differ diff --git a/modular_citadel/sound/vox/close.ogg b/modular_citadel/sound/vox/close.ogg new file mode 100644 index 0000000000..15e9fd315c Binary files /dev/null and b/modular_citadel/sound/vox/close.ogg differ diff --git a/modular_citadel/sound/vox/clown.ogg b/modular_citadel/sound/vox/clown.ogg new file mode 100644 index 0000000000..e72f9703fd Binary files /dev/null and b/modular_citadel/sound/vox/clown.ogg differ diff --git a/modular_citadel/sound/vox/code.ogg b/modular_citadel/sound/vox/code.ogg new file mode 100644 index 0000000000..cee2e4c036 Binary files /dev/null and b/modular_citadel/sound/vox/code.ogg differ diff --git a/modular_citadel/sound/vox/coded.ogg b/modular_citadel/sound/vox/coded.ogg new file mode 100644 index 0000000000..d4435296ae Binary files /dev/null and b/modular_citadel/sound/vox/coded.ogg differ diff --git a/modular_citadel/sound/vox/collider.ogg b/modular_citadel/sound/vox/collider.ogg new file mode 100644 index 0000000000..a29bda0d17 Binary files /dev/null and b/modular_citadel/sound/vox/collider.ogg differ diff --git a/modular_citadel/sound/vox/comma.ogg b/modular_citadel/sound/vox/comma.ogg new file mode 100644 index 0000000000..a94221d0ed Binary files /dev/null and b/modular_citadel/sound/vox/comma.ogg differ diff --git a/modular_citadel/sound/vox/command.ogg b/modular_citadel/sound/vox/command.ogg new file mode 100644 index 0000000000..cf6c32f736 Binary files /dev/null and b/modular_citadel/sound/vox/command.ogg differ diff --git a/modular_citadel/sound/vox/communication.ogg b/modular_citadel/sound/vox/communication.ogg new file mode 100644 index 0000000000..67ec74b30d Binary files /dev/null and b/modular_citadel/sound/vox/communication.ogg differ diff --git a/modular_citadel/sound/vox/complex.ogg b/modular_citadel/sound/vox/complex.ogg new file mode 100644 index 0000000000..66dad5b30a Binary files /dev/null and b/modular_citadel/sound/vox/complex.ogg differ diff --git a/modular_citadel/sound/vox/computer.ogg b/modular_citadel/sound/vox/computer.ogg new file mode 100644 index 0000000000..849cf4e96c Binary files /dev/null and b/modular_citadel/sound/vox/computer.ogg differ diff --git a/modular_citadel/sound/vox/condition.ogg b/modular_citadel/sound/vox/condition.ogg new file mode 100644 index 0000000000..b16ea99736 Binary files /dev/null and b/modular_citadel/sound/vox/condition.ogg differ diff --git a/modular_citadel/sound/vox/containment.ogg b/modular_citadel/sound/vox/containment.ogg new file mode 100644 index 0000000000..0a1424a8c0 Binary files /dev/null and b/modular_citadel/sound/vox/containment.ogg differ diff --git a/modular_citadel/sound/vox/contamination.ogg b/modular_citadel/sound/vox/contamination.ogg new file mode 100644 index 0000000000..0d60c1c351 Binary files /dev/null and b/modular_citadel/sound/vox/contamination.ogg differ diff --git a/modular_citadel/sound/vox/control.ogg b/modular_citadel/sound/vox/control.ogg new file mode 100644 index 0000000000..7e4fae7220 Binary files /dev/null and b/modular_citadel/sound/vox/control.ogg differ diff --git a/modular_citadel/sound/vox/coolant.ogg b/modular_citadel/sound/vox/coolant.ogg new file mode 100644 index 0000000000..ca51223548 Binary files /dev/null and b/modular_citadel/sound/vox/coolant.ogg differ diff --git a/modular_citadel/sound/vox/coomer.ogg b/modular_citadel/sound/vox/coomer.ogg new file mode 100644 index 0000000000..eb684a6ab7 Binary files /dev/null and b/modular_citadel/sound/vox/coomer.ogg differ diff --git a/modular_citadel/sound/vox/core.ogg b/modular_citadel/sound/vox/core.ogg new file mode 100644 index 0000000000..6170255986 Binary files /dev/null and b/modular_citadel/sound/vox/core.ogg differ diff --git a/modular_citadel/sound/vox/correct.ogg b/modular_citadel/sound/vox/correct.ogg new file mode 100644 index 0000000000..99ca3efccc Binary files /dev/null and b/modular_citadel/sound/vox/correct.ogg differ diff --git a/modular_citadel/sound/vox/corridor.ogg b/modular_citadel/sound/vox/corridor.ogg new file mode 100644 index 0000000000..e3ddeb39cc Binary files /dev/null and b/modular_citadel/sound/vox/corridor.ogg differ diff --git a/modular_citadel/sound/vox/crew.ogg b/modular_citadel/sound/vox/crew.ogg new file mode 100644 index 0000000000..b63ce31874 Binary files /dev/null and b/modular_citadel/sound/vox/crew.ogg differ diff --git a/modular_citadel/sound/vox/cross.ogg b/modular_citadel/sound/vox/cross.ogg new file mode 100644 index 0000000000..ffd9f4161d Binary files /dev/null and b/modular_citadel/sound/vox/cross.ogg differ diff --git a/modular_citadel/sound/vox/cryogenic.ogg b/modular_citadel/sound/vox/cryogenic.ogg new file mode 100644 index 0000000000..def31fe7c0 Binary files /dev/null and b/modular_citadel/sound/vox/cryogenic.ogg differ diff --git a/modular_citadel/sound/vox/d.ogg b/modular_citadel/sound/vox/d.ogg new file mode 100644 index 0000000000..08b85fc9eb Binary files /dev/null and b/modular_citadel/sound/vox/d.ogg differ diff --git a/modular_citadel/sound/vox/dadeda.ogg b/modular_citadel/sound/vox/dadeda.ogg new file mode 100644 index 0000000000..9fd19f577c Binary files /dev/null and b/modular_citadel/sound/vox/dadeda.ogg differ diff --git a/modular_citadel/sound/vox/damage.ogg b/modular_citadel/sound/vox/damage.ogg new file mode 100644 index 0000000000..d45cb0b532 Binary files /dev/null and b/modular_citadel/sound/vox/damage.ogg differ diff --git a/modular_citadel/sound/vox/damaged.ogg b/modular_citadel/sound/vox/damaged.ogg new file mode 100644 index 0000000000..cec2617cd2 Binary files /dev/null and b/modular_citadel/sound/vox/damaged.ogg differ diff --git a/modular_citadel/sound/vox/danger.ogg b/modular_citadel/sound/vox/danger.ogg new file mode 100644 index 0000000000..50bce6a5a5 Binary files /dev/null and b/modular_citadel/sound/vox/danger.ogg differ diff --git a/modular_citadel/sound/vox/day.ogg b/modular_citadel/sound/vox/day.ogg new file mode 100644 index 0000000000..c11c1b696c Binary files /dev/null and b/modular_citadel/sound/vox/day.ogg differ diff --git a/modular_citadel/sound/vox/deactivated.ogg b/modular_citadel/sound/vox/deactivated.ogg new file mode 100644 index 0000000000..2c700cf4a7 Binary files /dev/null and b/modular_citadel/sound/vox/deactivated.ogg differ diff --git a/modular_citadel/sound/vox/decompression.ogg b/modular_citadel/sound/vox/decompression.ogg new file mode 100644 index 0000000000..39ba52f36a Binary files /dev/null and b/modular_citadel/sound/vox/decompression.ogg differ diff --git a/modular_citadel/sound/vox/decontamination.ogg b/modular_citadel/sound/vox/decontamination.ogg new file mode 100644 index 0000000000..2115ec8aa4 Binary files /dev/null and b/modular_citadel/sound/vox/decontamination.ogg differ diff --git a/modular_citadel/sound/vox/deeoo.ogg b/modular_citadel/sound/vox/deeoo.ogg new file mode 100644 index 0000000000..22197de5e6 Binary files /dev/null and b/modular_citadel/sound/vox/deeoo.ogg differ diff --git a/modular_citadel/sound/vox/defense.ogg b/modular_citadel/sound/vox/defense.ogg new file mode 100644 index 0000000000..dc00256e0f Binary files /dev/null and b/modular_citadel/sound/vox/defense.ogg differ diff --git a/modular_citadel/sound/vox/degrees.ogg b/modular_citadel/sound/vox/degrees.ogg new file mode 100644 index 0000000000..eb640ca08c Binary files /dev/null and b/modular_citadel/sound/vox/degrees.ogg differ diff --git a/modular_citadel/sound/vox/delta.ogg b/modular_citadel/sound/vox/delta.ogg new file mode 100644 index 0000000000..93cbe2bdb6 Binary files /dev/null and b/modular_citadel/sound/vox/delta.ogg differ diff --git a/modular_citadel/sound/vox/denied.ogg b/modular_citadel/sound/vox/denied.ogg new file mode 100644 index 0000000000..8ef3366dbc Binary files /dev/null and b/modular_citadel/sound/vox/denied.ogg differ diff --git a/modular_citadel/sound/vox/deploy.ogg b/modular_citadel/sound/vox/deploy.ogg new file mode 100644 index 0000000000..71bd4c4d7d Binary files /dev/null and b/modular_citadel/sound/vox/deploy.ogg differ diff --git a/modular_citadel/sound/vox/deployed.ogg b/modular_citadel/sound/vox/deployed.ogg new file mode 100644 index 0000000000..d21fa814ba Binary files /dev/null and b/modular_citadel/sound/vox/deployed.ogg differ diff --git a/modular_citadel/sound/vox/destroy.ogg b/modular_citadel/sound/vox/destroy.ogg new file mode 100644 index 0000000000..954d474a07 Binary files /dev/null and b/modular_citadel/sound/vox/destroy.ogg differ diff --git a/modular_citadel/sound/vox/destroyed.ogg b/modular_citadel/sound/vox/destroyed.ogg new file mode 100644 index 0000000000..cf5f20bf84 Binary files /dev/null and b/modular_citadel/sound/vox/destroyed.ogg differ diff --git a/modular_citadel/sound/vox/detain.ogg b/modular_citadel/sound/vox/detain.ogg new file mode 100644 index 0000000000..98a6d34c2f Binary files /dev/null and b/modular_citadel/sound/vox/detain.ogg differ diff --git a/modular_citadel/sound/vox/detected.ogg b/modular_citadel/sound/vox/detected.ogg new file mode 100644 index 0000000000..80704064a4 Binary files /dev/null and b/modular_citadel/sound/vox/detected.ogg differ diff --git a/modular_citadel/sound/vox/detonation.ogg b/modular_citadel/sound/vox/detonation.ogg new file mode 100644 index 0000000000..a6c64c331c Binary files /dev/null and b/modular_citadel/sound/vox/detonation.ogg differ diff --git a/modular_citadel/sound/vox/device.ogg b/modular_citadel/sound/vox/device.ogg new file mode 100644 index 0000000000..3f1b4905df Binary files /dev/null and b/modular_citadel/sound/vox/device.ogg differ diff --git a/modular_citadel/sound/vox/did.ogg b/modular_citadel/sound/vox/did.ogg new file mode 100644 index 0000000000..966e8a3a13 Binary files /dev/null and b/modular_citadel/sound/vox/did.ogg differ diff --git a/modular_citadel/sound/vox/die.ogg b/modular_citadel/sound/vox/die.ogg new file mode 100644 index 0000000000..b2f99b4152 Binary files /dev/null and b/modular_citadel/sound/vox/die.ogg differ diff --git a/modular_citadel/sound/vox/dimensional.ogg b/modular_citadel/sound/vox/dimensional.ogg new file mode 100644 index 0000000000..a4ed638db0 Binary files /dev/null and b/modular_citadel/sound/vox/dimensional.ogg differ diff --git a/modular_citadel/sound/vox/dirt.ogg b/modular_citadel/sound/vox/dirt.ogg new file mode 100644 index 0000000000..b175b93205 Binary files /dev/null and b/modular_citadel/sound/vox/dirt.ogg differ diff --git a/modular_citadel/sound/vox/disengaged.ogg b/modular_citadel/sound/vox/disengaged.ogg new file mode 100644 index 0000000000..eb75ab975b Binary files /dev/null and b/modular_citadel/sound/vox/disengaged.ogg differ diff --git a/modular_citadel/sound/vox/dish.ogg b/modular_citadel/sound/vox/dish.ogg new file mode 100644 index 0000000000..3b0f1f58ce Binary files /dev/null and b/modular_citadel/sound/vox/dish.ogg differ diff --git a/modular_citadel/sound/vox/disposal.ogg b/modular_citadel/sound/vox/disposal.ogg new file mode 100644 index 0000000000..1a4c1f8bd1 Binary files /dev/null and b/modular_citadel/sound/vox/disposal.ogg differ diff --git a/modular_citadel/sound/vox/distance.ogg b/modular_citadel/sound/vox/distance.ogg new file mode 100644 index 0000000000..8bcec9ac7c Binary files /dev/null and b/modular_citadel/sound/vox/distance.ogg differ diff --git a/modular_citadel/sound/vox/distortion.ogg b/modular_citadel/sound/vox/distortion.ogg new file mode 100644 index 0000000000..7ee3a5f560 Binary files /dev/null and b/modular_citadel/sound/vox/distortion.ogg differ diff --git a/modular_citadel/sound/vox/do.ogg b/modular_citadel/sound/vox/do.ogg new file mode 100644 index 0000000000..7202691b87 Binary files /dev/null and b/modular_citadel/sound/vox/do.ogg differ diff --git a/modular_citadel/sound/vox/doctor.ogg b/modular_citadel/sound/vox/doctor.ogg new file mode 100644 index 0000000000..adbbfab77a Binary files /dev/null and b/modular_citadel/sound/vox/doctor.ogg differ diff --git a/modular_citadel/sound/vox/doop.ogg b/modular_citadel/sound/vox/doop.ogg new file mode 100644 index 0000000000..b497a8594d Binary files /dev/null and b/modular_citadel/sound/vox/doop.ogg differ diff --git a/modular_citadel/sound/vox/door.ogg b/modular_citadel/sound/vox/door.ogg new file mode 100644 index 0000000000..db389b4eb9 Binary files /dev/null and b/modular_citadel/sound/vox/door.ogg differ diff --git a/modular_citadel/sound/vox/down.ogg b/modular_citadel/sound/vox/down.ogg new file mode 100644 index 0000000000..e16b0249dd Binary files /dev/null and b/modular_citadel/sound/vox/down.ogg differ diff --git a/modular_citadel/sound/vox/dual.ogg b/modular_citadel/sound/vox/dual.ogg new file mode 100644 index 0000000000..d8833faf9b Binary files /dev/null and b/modular_citadel/sound/vox/dual.ogg differ diff --git a/modular_citadel/sound/vox/duct.ogg b/modular_citadel/sound/vox/duct.ogg new file mode 100644 index 0000000000..23379f6cc2 Binary files /dev/null and b/modular_citadel/sound/vox/duct.ogg differ diff --git a/modular_citadel/sound/vox/e.ogg b/modular_citadel/sound/vox/e.ogg new file mode 100644 index 0000000000..105ea13ef2 Binary files /dev/null and b/modular_citadel/sound/vox/e.ogg differ diff --git a/modular_citadel/sound/vox/east.ogg b/modular_citadel/sound/vox/east.ogg new file mode 100644 index 0000000000..9e69856edb Binary files /dev/null and b/modular_citadel/sound/vox/east.ogg differ diff --git a/modular_citadel/sound/vox/echo.ogg b/modular_citadel/sound/vox/echo.ogg new file mode 100644 index 0000000000..3ee16750a4 Binary files /dev/null and b/modular_citadel/sound/vox/echo.ogg differ diff --git a/modular_citadel/sound/vox/ed.ogg b/modular_citadel/sound/vox/ed.ogg new file mode 100644 index 0000000000..094bd4f3ba Binary files /dev/null and b/modular_citadel/sound/vox/ed.ogg differ diff --git a/modular_citadel/sound/vox/effect.ogg b/modular_citadel/sound/vox/effect.ogg new file mode 100644 index 0000000000..01a77a1bba Binary files /dev/null and b/modular_citadel/sound/vox/effect.ogg differ diff --git a/modular_citadel/sound/vox/egress.ogg b/modular_citadel/sound/vox/egress.ogg new file mode 100644 index 0000000000..6da62c754a Binary files /dev/null and b/modular_citadel/sound/vox/egress.ogg differ diff --git a/modular_citadel/sound/vox/eight.ogg b/modular_citadel/sound/vox/eight.ogg new file mode 100644 index 0000000000..7c64ba326b Binary files /dev/null and b/modular_citadel/sound/vox/eight.ogg differ diff --git a/modular_citadel/sound/vox/eighteen.ogg b/modular_citadel/sound/vox/eighteen.ogg new file mode 100644 index 0000000000..73330bfaa2 Binary files /dev/null and b/modular_citadel/sound/vox/eighteen.ogg differ diff --git a/modular_citadel/sound/vox/eighty.ogg b/modular_citadel/sound/vox/eighty.ogg new file mode 100644 index 0000000000..c190b69e02 Binary files /dev/null and b/modular_citadel/sound/vox/eighty.ogg differ diff --git a/modular_citadel/sound/vox/electric.ogg b/modular_citadel/sound/vox/electric.ogg new file mode 100644 index 0000000000..7d7154b350 Binary files /dev/null and b/modular_citadel/sound/vox/electric.ogg differ diff --git a/modular_citadel/sound/vox/electromagnetic.ogg b/modular_citadel/sound/vox/electromagnetic.ogg new file mode 100644 index 0000000000..160725e8c0 Binary files /dev/null and b/modular_citadel/sound/vox/electromagnetic.ogg differ diff --git a/modular_citadel/sound/vox/elevator.ogg b/modular_citadel/sound/vox/elevator.ogg new file mode 100644 index 0000000000..bcafc3ce3f Binary files /dev/null and b/modular_citadel/sound/vox/elevator.ogg differ diff --git a/modular_citadel/sound/vox/eleven.ogg b/modular_citadel/sound/vox/eleven.ogg new file mode 100644 index 0000000000..6607692e1d Binary files /dev/null and b/modular_citadel/sound/vox/eleven.ogg differ diff --git a/modular_citadel/sound/vox/eliminate.ogg b/modular_citadel/sound/vox/eliminate.ogg new file mode 100644 index 0000000000..2e81f5eb6c Binary files /dev/null and b/modular_citadel/sound/vox/eliminate.ogg differ diff --git a/modular_citadel/sound/vox/emergency.ogg b/modular_citadel/sound/vox/emergency.ogg new file mode 100644 index 0000000000..5d2e068944 Binary files /dev/null and b/modular_citadel/sound/vox/emergency.ogg differ diff --git a/modular_citadel/sound/vox/enemy.ogg b/modular_citadel/sound/vox/enemy.ogg new file mode 100644 index 0000000000..ecee923235 Binary files /dev/null and b/modular_citadel/sound/vox/enemy.ogg differ diff --git a/modular_citadel/sound/vox/energy.ogg b/modular_citadel/sound/vox/energy.ogg new file mode 100644 index 0000000000..82d07e95dd Binary files /dev/null and b/modular_citadel/sound/vox/energy.ogg differ diff --git a/modular_citadel/sound/vox/engage.ogg b/modular_citadel/sound/vox/engage.ogg new file mode 100644 index 0000000000..7e1cf2e625 Binary files /dev/null and b/modular_citadel/sound/vox/engage.ogg differ diff --git a/modular_citadel/sound/vox/engaged.ogg b/modular_citadel/sound/vox/engaged.ogg new file mode 100644 index 0000000000..0e8196b026 Binary files /dev/null and b/modular_citadel/sound/vox/engaged.ogg differ diff --git a/modular_citadel/sound/vox/engine.ogg b/modular_citadel/sound/vox/engine.ogg new file mode 100644 index 0000000000..0ed1b4bd80 Binary files /dev/null and b/modular_citadel/sound/vox/engine.ogg differ diff --git a/modular_citadel/sound/vox/enter.ogg b/modular_citadel/sound/vox/enter.ogg new file mode 100644 index 0000000000..d7392eeada Binary files /dev/null and b/modular_citadel/sound/vox/enter.ogg differ diff --git a/modular_citadel/sound/vox/entry.ogg b/modular_citadel/sound/vox/entry.ogg new file mode 100644 index 0000000000..1ef6b14442 Binary files /dev/null and b/modular_citadel/sound/vox/entry.ogg differ diff --git a/modular_citadel/sound/vox/environment.ogg b/modular_citadel/sound/vox/environment.ogg new file mode 100644 index 0000000000..d05ba3106a Binary files /dev/null and b/modular_citadel/sound/vox/environment.ogg differ diff --git a/modular_citadel/sound/vox/error.ogg b/modular_citadel/sound/vox/error.ogg new file mode 100644 index 0000000000..237191732a Binary files /dev/null and b/modular_citadel/sound/vox/error.ogg differ diff --git a/modular_citadel/sound/vox/escape.ogg b/modular_citadel/sound/vox/escape.ogg new file mode 100644 index 0000000000..15e1181ac6 Binary files /dev/null and b/modular_citadel/sound/vox/escape.ogg differ diff --git a/modular_citadel/sound/vox/evacuate.ogg b/modular_citadel/sound/vox/evacuate.ogg new file mode 100644 index 0000000000..d0d755f1ba Binary files /dev/null and b/modular_citadel/sound/vox/evacuate.ogg differ diff --git a/modular_citadel/sound/vox/exchange.ogg b/modular_citadel/sound/vox/exchange.ogg new file mode 100644 index 0000000000..d69eac774a Binary files /dev/null and b/modular_citadel/sound/vox/exchange.ogg differ diff --git a/modular_citadel/sound/vox/exit.ogg b/modular_citadel/sound/vox/exit.ogg new file mode 100644 index 0000000000..a201b6b76b Binary files /dev/null and b/modular_citadel/sound/vox/exit.ogg differ diff --git a/modular_citadel/sound/vox/expect.ogg b/modular_citadel/sound/vox/expect.ogg new file mode 100644 index 0000000000..95e559fdd3 Binary files /dev/null and b/modular_citadel/sound/vox/expect.ogg differ diff --git a/modular_citadel/sound/vox/experiment.ogg b/modular_citadel/sound/vox/experiment.ogg new file mode 100644 index 0000000000..34ef253e69 Binary files /dev/null and b/modular_citadel/sound/vox/experiment.ogg differ diff --git a/modular_citadel/sound/vox/experimental.ogg b/modular_citadel/sound/vox/experimental.ogg new file mode 100644 index 0000000000..6635998222 Binary files /dev/null and b/modular_citadel/sound/vox/experimental.ogg differ diff --git a/modular_citadel/sound/vox/explode.ogg b/modular_citadel/sound/vox/explode.ogg new file mode 100644 index 0000000000..16b38926e4 Binary files /dev/null and b/modular_citadel/sound/vox/explode.ogg differ diff --git a/modular_citadel/sound/vox/explosion.ogg b/modular_citadel/sound/vox/explosion.ogg new file mode 100644 index 0000000000..ede66453bd Binary files /dev/null and b/modular_citadel/sound/vox/explosion.ogg differ diff --git a/modular_citadel/sound/vox/exposure.ogg b/modular_citadel/sound/vox/exposure.ogg new file mode 100644 index 0000000000..d2f66ca1ba Binary files /dev/null and b/modular_citadel/sound/vox/exposure.ogg differ diff --git a/modular_citadel/sound/vox/exterminate.ogg b/modular_citadel/sound/vox/exterminate.ogg new file mode 100644 index 0000000000..34be77f8e2 Binary files /dev/null and b/modular_citadel/sound/vox/exterminate.ogg differ diff --git a/modular_citadel/sound/vox/extinguish.ogg b/modular_citadel/sound/vox/extinguish.ogg new file mode 100644 index 0000000000..c003ff4547 Binary files /dev/null and b/modular_citadel/sound/vox/extinguish.ogg differ diff --git a/modular_citadel/sound/vox/extinguisher.ogg b/modular_citadel/sound/vox/extinguisher.ogg new file mode 100644 index 0000000000..d23b898014 Binary files /dev/null and b/modular_citadel/sound/vox/extinguisher.ogg differ diff --git a/modular_citadel/sound/vox/extreme.ogg b/modular_citadel/sound/vox/extreme.ogg new file mode 100644 index 0000000000..c3f5a2d9f0 Binary files /dev/null and b/modular_citadel/sound/vox/extreme.ogg differ diff --git a/modular_citadel/sound/vox/f.ogg b/modular_citadel/sound/vox/f.ogg new file mode 100644 index 0000000000..344734986f Binary files /dev/null and b/modular_citadel/sound/vox/f.ogg differ diff --git a/modular_citadel/sound/vox/face.ogg b/modular_citadel/sound/vox/face.ogg new file mode 100644 index 0000000000..acdd8722ef Binary files /dev/null and b/modular_citadel/sound/vox/face.ogg differ diff --git a/modular_citadel/sound/vox/facility.ogg b/modular_citadel/sound/vox/facility.ogg new file mode 100644 index 0000000000..43649febb0 Binary files /dev/null and b/modular_citadel/sound/vox/facility.ogg differ diff --git a/modular_citadel/sound/vox/fahrenheit.ogg b/modular_citadel/sound/vox/fahrenheit.ogg new file mode 100644 index 0000000000..4730726ea4 Binary files /dev/null and b/modular_citadel/sound/vox/fahrenheit.ogg differ diff --git a/modular_citadel/sound/vox/failed.ogg b/modular_citadel/sound/vox/failed.ogg new file mode 100644 index 0000000000..f801962345 Binary files /dev/null and b/modular_citadel/sound/vox/failed.ogg differ diff --git a/modular_citadel/sound/vox/failure.ogg b/modular_citadel/sound/vox/failure.ogg new file mode 100644 index 0000000000..e9b5808f27 Binary files /dev/null and b/modular_citadel/sound/vox/failure.ogg differ diff --git a/modular_citadel/sound/vox/farthest.ogg b/modular_citadel/sound/vox/farthest.ogg new file mode 100644 index 0000000000..3d18f669b1 Binary files /dev/null and b/modular_citadel/sound/vox/farthest.ogg differ diff --git a/modular_citadel/sound/vox/fast.ogg b/modular_citadel/sound/vox/fast.ogg new file mode 100644 index 0000000000..dbf82c32a4 Binary files /dev/null and b/modular_citadel/sound/vox/fast.ogg differ diff --git a/modular_citadel/sound/vox/feet.ogg b/modular_citadel/sound/vox/feet.ogg new file mode 100644 index 0000000000..eba093e73d Binary files /dev/null and b/modular_citadel/sound/vox/feet.ogg differ diff --git a/modular_citadel/sound/vox/field.ogg b/modular_citadel/sound/vox/field.ogg new file mode 100644 index 0000000000..bba79e6ddd Binary files /dev/null and b/modular_citadel/sound/vox/field.ogg differ diff --git a/modular_citadel/sound/vox/fifteen.ogg b/modular_citadel/sound/vox/fifteen.ogg new file mode 100644 index 0000000000..60eca844ae Binary files /dev/null and b/modular_citadel/sound/vox/fifteen.ogg differ diff --git a/modular_citadel/sound/vox/fifth.ogg b/modular_citadel/sound/vox/fifth.ogg new file mode 100644 index 0000000000..d6a76567d2 Binary files /dev/null and b/modular_citadel/sound/vox/fifth.ogg differ diff --git a/modular_citadel/sound/vox/fifty.ogg b/modular_citadel/sound/vox/fifty.ogg new file mode 100644 index 0000000000..30fd60072b Binary files /dev/null and b/modular_citadel/sound/vox/fifty.ogg differ diff --git a/modular_citadel/sound/vox/final.ogg b/modular_citadel/sound/vox/final.ogg new file mode 100644 index 0000000000..d06bef9fc2 Binary files /dev/null and b/modular_citadel/sound/vox/final.ogg differ diff --git a/modular_citadel/sound/vox/fine.ogg b/modular_citadel/sound/vox/fine.ogg new file mode 100644 index 0000000000..3445a9ea54 Binary files /dev/null and b/modular_citadel/sound/vox/fine.ogg differ diff --git a/modular_citadel/sound/vox/fire.ogg b/modular_citadel/sound/vox/fire.ogg new file mode 100644 index 0000000000..094043b953 Binary files /dev/null and b/modular_citadel/sound/vox/fire.ogg differ diff --git a/modular_citadel/sound/vox/first.ogg b/modular_citadel/sound/vox/first.ogg new file mode 100644 index 0000000000..84977e4eb7 Binary files /dev/null and b/modular_citadel/sound/vox/first.ogg differ diff --git a/modular_citadel/sound/vox/five.ogg b/modular_citadel/sound/vox/five.ogg new file mode 100644 index 0000000000..0a28539c34 Binary files /dev/null and b/modular_citadel/sound/vox/five.ogg differ diff --git a/modular_citadel/sound/vox/flag.ogg b/modular_citadel/sound/vox/flag.ogg new file mode 100644 index 0000000000..0d13587d60 Binary files /dev/null and b/modular_citadel/sound/vox/flag.ogg differ diff --git a/modular_citadel/sound/vox/flooding.ogg b/modular_citadel/sound/vox/flooding.ogg new file mode 100644 index 0000000000..c32bf475f5 Binary files /dev/null and b/modular_citadel/sound/vox/flooding.ogg differ diff --git a/modular_citadel/sound/vox/floor.ogg b/modular_citadel/sound/vox/floor.ogg new file mode 100644 index 0000000000..14d4a84131 Binary files /dev/null and b/modular_citadel/sound/vox/floor.ogg differ diff --git a/modular_citadel/sound/vox/fool.ogg b/modular_citadel/sound/vox/fool.ogg new file mode 100644 index 0000000000..965251cc4a Binary files /dev/null and b/modular_citadel/sound/vox/fool.ogg differ diff --git a/modular_citadel/sound/vox/for.ogg b/modular_citadel/sound/vox/for.ogg new file mode 100644 index 0000000000..b69a8f4b6c Binary files /dev/null and b/modular_citadel/sound/vox/for.ogg differ diff --git a/modular_citadel/sound/vox/forbidden.ogg b/modular_citadel/sound/vox/forbidden.ogg new file mode 100644 index 0000000000..23daae8496 Binary files /dev/null and b/modular_citadel/sound/vox/forbidden.ogg differ diff --git a/modular_citadel/sound/vox/force.ogg b/modular_citadel/sound/vox/force.ogg new file mode 100644 index 0000000000..ff4cb84c3a Binary files /dev/null and b/modular_citadel/sound/vox/force.ogg differ diff --git a/modular_citadel/sound/vox/forms.ogg b/modular_citadel/sound/vox/forms.ogg new file mode 100644 index 0000000000..7ef1862bb6 Binary files /dev/null and b/modular_citadel/sound/vox/forms.ogg differ diff --git a/modular_citadel/sound/vox/found.ogg b/modular_citadel/sound/vox/found.ogg new file mode 100644 index 0000000000..660a2f8520 Binary files /dev/null and b/modular_citadel/sound/vox/found.ogg differ diff --git a/modular_citadel/sound/vox/four.ogg b/modular_citadel/sound/vox/four.ogg new file mode 100644 index 0000000000..df8adfcd31 Binary files /dev/null and b/modular_citadel/sound/vox/four.ogg differ diff --git a/modular_citadel/sound/vox/fourteen.ogg b/modular_citadel/sound/vox/fourteen.ogg new file mode 100644 index 0000000000..21b61a0fd5 Binary files /dev/null and b/modular_citadel/sound/vox/fourteen.ogg differ diff --git a/modular_citadel/sound/vox/fourth.ogg b/modular_citadel/sound/vox/fourth.ogg new file mode 100644 index 0000000000..986102ea54 Binary files /dev/null and b/modular_citadel/sound/vox/fourth.ogg differ diff --git a/modular_citadel/sound/vox/fourty.ogg b/modular_citadel/sound/vox/fourty.ogg new file mode 100644 index 0000000000..b0edb0a7c7 Binary files /dev/null and b/modular_citadel/sound/vox/fourty.ogg differ diff --git a/modular_citadel/sound/vox/foxtrot.ogg b/modular_citadel/sound/vox/foxtrot.ogg new file mode 100644 index 0000000000..3be534fd22 Binary files /dev/null and b/modular_citadel/sound/vox/foxtrot.ogg differ diff --git a/modular_citadel/sound/vox/freeman.ogg b/modular_citadel/sound/vox/freeman.ogg new file mode 100644 index 0000000000..b2bc590942 Binary files /dev/null and b/modular_citadel/sound/vox/freeman.ogg differ diff --git a/modular_citadel/sound/vox/freezer.ogg b/modular_citadel/sound/vox/freezer.ogg new file mode 100644 index 0000000000..6bb30ad953 Binary files /dev/null and b/modular_citadel/sound/vox/freezer.ogg differ diff --git a/modular_citadel/sound/vox/from.ogg b/modular_citadel/sound/vox/from.ogg new file mode 100644 index 0000000000..535de03d14 Binary files /dev/null and b/modular_citadel/sound/vox/from.ogg differ diff --git a/modular_citadel/sound/vox/front.ogg b/modular_citadel/sound/vox/front.ogg new file mode 100644 index 0000000000..f1755a788b Binary files /dev/null and b/modular_citadel/sound/vox/front.ogg differ diff --git a/modular_citadel/sound/vox/fuel.ogg b/modular_citadel/sound/vox/fuel.ogg new file mode 100644 index 0000000000..53d7889314 Binary files /dev/null and b/modular_citadel/sound/vox/fuel.ogg differ diff --git a/modular_citadel/sound/vox/g.ogg b/modular_citadel/sound/vox/g.ogg new file mode 100644 index 0000000000..a3702ca3e5 Binary files /dev/null and b/modular_citadel/sound/vox/g.ogg differ diff --git a/modular_citadel/sound/vox/gay.ogg b/modular_citadel/sound/vox/gay.ogg new file mode 100644 index 0000000000..a70d05716b Binary files /dev/null and b/modular_citadel/sound/vox/gay.ogg differ diff --git a/modular_citadel/sound/vox/get.ogg b/modular_citadel/sound/vox/get.ogg new file mode 100644 index 0000000000..b5c0d47cd5 Binary files /dev/null and b/modular_citadel/sound/vox/get.ogg differ diff --git a/modular_citadel/sound/vox/go.ogg b/modular_citadel/sound/vox/go.ogg new file mode 100644 index 0000000000..f7dcb56f8e Binary files /dev/null and b/modular_citadel/sound/vox/go.ogg differ diff --git a/modular_citadel/sound/vox/going.ogg b/modular_citadel/sound/vox/going.ogg new file mode 100644 index 0000000000..3ff4fe5427 Binary files /dev/null and b/modular_citadel/sound/vox/going.ogg differ diff --git a/modular_citadel/sound/vox/good.ogg b/modular_citadel/sound/vox/good.ogg new file mode 100644 index 0000000000..c8115bb5fb Binary files /dev/null and b/modular_citadel/sound/vox/good.ogg differ diff --git a/modular_citadel/sound/vox/goodbye.ogg b/modular_citadel/sound/vox/goodbye.ogg new file mode 100644 index 0000000000..e793ba2fa6 Binary files /dev/null and b/modular_citadel/sound/vox/goodbye.ogg differ diff --git a/modular_citadel/sound/vox/gordon.ogg b/modular_citadel/sound/vox/gordon.ogg new file mode 100644 index 0000000000..5d5ab4ddba Binary files /dev/null and b/modular_citadel/sound/vox/gordon.ogg differ diff --git a/modular_citadel/sound/vox/got.ogg b/modular_citadel/sound/vox/got.ogg new file mode 100644 index 0000000000..3d712c9fc4 Binary files /dev/null and b/modular_citadel/sound/vox/got.ogg differ diff --git a/modular_citadel/sound/vox/government.ogg b/modular_citadel/sound/vox/government.ogg new file mode 100644 index 0000000000..830b59bac2 Binary files /dev/null and b/modular_citadel/sound/vox/government.ogg differ diff --git a/modular_citadel/sound/vox/granted.ogg b/modular_citadel/sound/vox/granted.ogg new file mode 100644 index 0000000000..4dae196cf6 Binary files /dev/null and b/modular_citadel/sound/vox/granted.ogg differ diff --git a/modular_citadel/sound/vox/great.ogg b/modular_citadel/sound/vox/great.ogg new file mode 100644 index 0000000000..d820a56179 Binary files /dev/null and b/modular_citadel/sound/vox/great.ogg differ diff --git a/modular_citadel/sound/vox/green.ogg b/modular_citadel/sound/vox/green.ogg new file mode 100644 index 0000000000..05f6e6b0fa Binary files /dev/null and b/modular_citadel/sound/vox/green.ogg differ diff --git a/modular_citadel/sound/vox/grenade.ogg b/modular_citadel/sound/vox/grenade.ogg new file mode 100644 index 0000000000..971a5d515b Binary files /dev/null and b/modular_citadel/sound/vox/grenade.ogg differ diff --git a/modular_citadel/sound/vox/guard.ogg b/modular_citadel/sound/vox/guard.ogg new file mode 100644 index 0000000000..795ba08486 Binary files /dev/null and b/modular_citadel/sound/vox/guard.ogg differ diff --git a/modular_citadel/sound/vox/gulf.ogg b/modular_citadel/sound/vox/gulf.ogg new file mode 100644 index 0000000000..87cc1f953d Binary files /dev/null and b/modular_citadel/sound/vox/gulf.ogg differ diff --git a/modular_citadel/sound/vox/gun.ogg b/modular_citadel/sound/vox/gun.ogg new file mode 100644 index 0000000000..472620ea76 Binary files /dev/null and b/modular_citadel/sound/vox/gun.ogg differ diff --git a/modular_citadel/sound/vox/guthrie.ogg b/modular_citadel/sound/vox/guthrie.ogg new file mode 100644 index 0000000000..b87c5f6cb1 Binary files /dev/null and b/modular_citadel/sound/vox/guthrie.ogg differ diff --git a/modular_citadel/sound/vox/handling.ogg b/modular_citadel/sound/vox/handling.ogg new file mode 100644 index 0000000000..be05e82d75 Binary files /dev/null and b/modular_citadel/sound/vox/handling.ogg differ diff --git a/modular_citadel/sound/vox/hangar.ogg b/modular_citadel/sound/vox/hangar.ogg new file mode 100644 index 0000000000..d6fe4084ae Binary files /dev/null and b/modular_citadel/sound/vox/hangar.ogg differ diff --git a/modular_citadel/sound/vox/has.ogg b/modular_citadel/sound/vox/has.ogg new file mode 100644 index 0000000000..055cb0dc15 Binary files /dev/null and b/modular_citadel/sound/vox/has.ogg differ diff --git a/modular_citadel/sound/vox/have.ogg b/modular_citadel/sound/vox/have.ogg new file mode 100644 index 0000000000..c514165582 Binary files /dev/null and b/modular_citadel/sound/vox/have.ogg differ diff --git a/modular_citadel/sound/vox/hazard.ogg b/modular_citadel/sound/vox/hazard.ogg new file mode 100644 index 0000000000..032b1fb251 Binary files /dev/null and b/modular_citadel/sound/vox/hazard.ogg differ diff --git a/modular_citadel/sound/vox/head.ogg b/modular_citadel/sound/vox/head.ogg new file mode 100644 index 0000000000..e4902fcc6f Binary files /dev/null and b/modular_citadel/sound/vox/head.ogg differ diff --git a/modular_citadel/sound/vox/health.ogg b/modular_citadel/sound/vox/health.ogg new file mode 100644 index 0000000000..c11ad1bcf2 Binary files /dev/null and b/modular_citadel/sound/vox/health.ogg differ diff --git a/modular_citadel/sound/vox/heat.ogg b/modular_citadel/sound/vox/heat.ogg new file mode 100644 index 0000000000..a6c0752ab8 Binary files /dev/null and b/modular_citadel/sound/vox/heat.ogg differ diff --git a/modular_citadel/sound/vox/helicopter.ogg b/modular_citadel/sound/vox/helicopter.ogg new file mode 100644 index 0000000000..6bfe6466b2 Binary files /dev/null and b/modular_citadel/sound/vox/helicopter.ogg differ diff --git a/modular_citadel/sound/vox/helium.ogg b/modular_citadel/sound/vox/helium.ogg new file mode 100644 index 0000000000..4a5c8326a5 Binary files /dev/null and b/modular_citadel/sound/vox/helium.ogg differ diff --git a/modular_citadel/sound/vox/hello.ogg b/modular_citadel/sound/vox/hello.ogg new file mode 100644 index 0000000000..622e4669ef Binary files /dev/null and b/modular_citadel/sound/vox/hello.ogg differ diff --git a/modular_citadel/sound/vox/help.ogg b/modular_citadel/sound/vox/help.ogg new file mode 100644 index 0000000000..038438d63b Binary files /dev/null and b/modular_citadel/sound/vox/help.ogg differ diff --git a/modular_citadel/sound/vox/here.ogg b/modular_citadel/sound/vox/here.ogg new file mode 100644 index 0000000000..ef69f1b282 Binary files /dev/null and b/modular_citadel/sound/vox/here.ogg differ diff --git a/modular_citadel/sound/vox/hide.ogg b/modular_citadel/sound/vox/hide.ogg new file mode 100644 index 0000000000..aa329d1f72 Binary files /dev/null and b/modular_citadel/sound/vox/hide.ogg differ diff --git a/modular_citadel/sound/vox/high.ogg b/modular_citadel/sound/vox/high.ogg new file mode 100644 index 0000000000..c20e382388 Binary files /dev/null and b/modular_citadel/sound/vox/high.ogg differ diff --git a/modular_citadel/sound/vox/highest.ogg b/modular_citadel/sound/vox/highest.ogg new file mode 100644 index 0000000000..d64bfd528c Binary files /dev/null and b/modular_citadel/sound/vox/highest.ogg differ diff --git a/modular_citadel/sound/vox/hit.ogg b/modular_citadel/sound/vox/hit.ogg new file mode 100644 index 0000000000..bfe3cd0501 Binary files /dev/null and b/modular_citadel/sound/vox/hit.ogg differ diff --git a/modular_citadel/sound/vox/holds.ogg b/modular_citadel/sound/vox/holds.ogg new file mode 100644 index 0000000000..41b88d990e Binary files /dev/null and b/modular_citadel/sound/vox/holds.ogg differ diff --git a/modular_citadel/sound/vox/hole.ogg b/modular_citadel/sound/vox/hole.ogg new file mode 100644 index 0000000000..a5dea701c8 Binary files /dev/null and b/modular_citadel/sound/vox/hole.ogg differ diff --git a/modular_citadel/sound/vox/hostile.ogg b/modular_citadel/sound/vox/hostile.ogg new file mode 100644 index 0000000000..7b8e495c87 Binary files /dev/null and b/modular_citadel/sound/vox/hostile.ogg differ diff --git a/modular_citadel/sound/vox/hot.ogg b/modular_citadel/sound/vox/hot.ogg new file mode 100644 index 0000000000..508f643856 Binary files /dev/null and b/modular_citadel/sound/vox/hot.ogg differ diff --git a/modular_citadel/sound/vox/hotel.ogg b/modular_citadel/sound/vox/hotel.ogg new file mode 100644 index 0000000000..5a5b66cdbf Binary files /dev/null and b/modular_citadel/sound/vox/hotel.ogg differ diff --git a/modular_citadel/sound/vox/hour.ogg b/modular_citadel/sound/vox/hour.ogg new file mode 100644 index 0000000000..39f0fd0917 Binary files /dev/null and b/modular_citadel/sound/vox/hour.ogg differ diff --git a/modular_citadel/sound/vox/hours.ogg b/modular_citadel/sound/vox/hours.ogg new file mode 100644 index 0000000000..691b7a643b Binary files /dev/null and b/modular_citadel/sound/vox/hours.ogg differ diff --git a/modular_citadel/sound/vox/hundred.ogg b/modular_citadel/sound/vox/hundred.ogg new file mode 100644 index 0000000000..3a254a137a Binary files /dev/null and b/modular_citadel/sound/vox/hundred.ogg differ diff --git a/modular_citadel/sound/vox/hydro.ogg b/modular_citadel/sound/vox/hydro.ogg new file mode 100644 index 0000000000..47c9ad5d01 Binary files /dev/null and b/modular_citadel/sound/vox/hydro.ogg differ diff --git a/modular_citadel/sound/vox/i.ogg b/modular_citadel/sound/vox/i.ogg new file mode 100644 index 0000000000..1c4ce81b7a Binary files /dev/null and b/modular_citadel/sound/vox/i.ogg differ diff --git a/modular_citadel/sound/vox/idiot.ogg b/modular_citadel/sound/vox/idiot.ogg new file mode 100644 index 0000000000..66e058effc Binary files /dev/null and b/modular_citadel/sound/vox/idiot.ogg differ diff --git a/modular_citadel/sound/vox/illegal.ogg b/modular_citadel/sound/vox/illegal.ogg new file mode 100644 index 0000000000..e1f22738bd Binary files /dev/null and b/modular_citadel/sound/vox/illegal.ogg differ diff --git a/modular_citadel/sound/vox/immediate.ogg b/modular_citadel/sound/vox/immediate.ogg new file mode 100644 index 0000000000..3e551dfa57 Binary files /dev/null and b/modular_citadel/sound/vox/immediate.ogg differ diff --git a/modular_citadel/sound/vox/immediately.ogg b/modular_citadel/sound/vox/immediately.ogg new file mode 100644 index 0000000000..0ca780ddac Binary files /dev/null and b/modular_citadel/sound/vox/immediately.ogg differ diff --git a/modular_citadel/sound/vox/in.ogg b/modular_citadel/sound/vox/in.ogg new file mode 100644 index 0000000000..e0b20f4795 Binary files /dev/null and b/modular_citadel/sound/vox/in.ogg differ diff --git a/modular_citadel/sound/vox/inches.ogg b/modular_citadel/sound/vox/inches.ogg new file mode 100644 index 0000000000..058f8e9131 Binary files /dev/null and b/modular_citadel/sound/vox/inches.ogg differ diff --git a/modular_citadel/sound/vox/india.ogg b/modular_citadel/sound/vox/india.ogg new file mode 100644 index 0000000000..1eefc45266 Binary files /dev/null and b/modular_citadel/sound/vox/india.ogg differ diff --git a/modular_citadel/sound/vox/ing.ogg b/modular_citadel/sound/vox/ing.ogg new file mode 100644 index 0000000000..d8c5c72fc9 Binary files /dev/null and b/modular_citadel/sound/vox/ing.ogg differ diff --git a/modular_citadel/sound/vox/inoperative.ogg b/modular_citadel/sound/vox/inoperative.ogg new file mode 100644 index 0000000000..01f13af948 Binary files /dev/null and b/modular_citadel/sound/vox/inoperative.ogg differ diff --git a/modular_citadel/sound/vox/inside.ogg b/modular_citadel/sound/vox/inside.ogg new file mode 100644 index 0000000000..778f4539ed Binary files /dev/null and b/modular_citadel/sound/vox/inside.ogg differ diff --git a/modular_citadel/sound/vox/inspection.ogg b/modular_citadel/sound/vox/inspection.ogg new file mode 100644 index 0000000000..60a2b3e788 Binary files /dev/null and b/modular_citadel/sound/vox/inspection.ogg differ diff --git a/modular_citadel/sound/vox/inspector.ogg b/modular_citadel/sound/vox/inspector.ogg new file mode 100644 index 0000000000..177651d631 Binary files /dev/null and b/modular_citadel/sound/vox/inspector.ogg differ diff --git a/modular_citadel/sound/vox/interchange.ogg b/modular_citadel/sound/vox/interchange.ogg new file mode 100644 index 0000000000..6c4230d2d1 Binary files /dev/null and b/modular_citadel/sound/vox/interchange.ogg differ diff --git a/modular_citadel/sound/vox/intruder.ogg b/modular_citadel/sound/vox/intruder.ogg new file mode 100644 index 0000000000..db4810966f Binary files /dev/null and b/modular_citadel/sound/vox/intruder.ogg differ diff --git a/modular_citadel/sound/vox/invallid.ogg b/modular_citadel/sound/vox/invallid.ogg new file mode 100644 index 0000000000..b2e5628fa5 Binary files /dev/null and b/modular_citadel/sound/vox/invallid.ogg differ diff --git a/modular_citadel/sound/vox/invasion.ogg b/modular_citadel/sound/vox/invasion.ogg new file mode 100644 index 0000000000..8e9a41fc10 Binary files /dev/null and b/modular_citadel/sound/vox/invasion.ogg differ diff --git a/modular_citadel/sound/vox/is.ogg b/modular_citadel/sound/vox/is.ogg new file mode 100644 index 0000000000..db3ca1dc81 Binary files /dev/null and b/modular_citadel/sound/vox/is.ogg differ diff --git a/modular_citadel/sound/vox/it.ogg b/modular_citadel/sound/vox/it.ogg new file mode 100644 index 0000000000..c0d3de3992 Binary files /dev/null and b/modular_citadel/sound/vox/it.ogg differ diff --git a/modular_citadel/sound/vox/johnson.ogg b/modular_citadel/sound/vox/johnson.ogg new file mode 100644 index 0000000000..ea74d8a61f Binary files /dev/null and b/modular_citadel/sound/vox/johnson.ogg differ diff --git a/modular_citadel/sound/vox/juliet.ogg b/modular_citadel/sound/vox/juliet.ogg new file mode 100644 index 0000000000..c9a61b63ab Binary files /dev/null and b/modular_citadel/sound/vox/juliet.ogg differ diff --git a/modular_citadel/sound/vox/key.ogg b/modular_citadel/sound/vox/key.ogg new file mode 100644 index 0000000000..b761d5c1f9 Binary files /dev/null and b/modular_citadel/sound/vox/key.ogg differ diff --git a/modular_citadel/sound/vox/kill.ogg b/modular_citadel/sound/vox/kill.ogg new file mode 100644 index 0000000000..00db499476 Binary files /dev/null and b/modular_citadel/sound/vox/kill.ogg differ diff --git a/modular_citadel/sound/vox/kilo.ogg b/modular_citadel/sound/vox/kilo.ogg new file mode 100644 index 0000000000..7786c4fc7c Binary files /dev/null and b/modular_citadel/sound/vox/kilo.ogg differ diff --git a/modular_citadel/sound/vox/kit.ogg b/modular_citadel/sound/vox/kit.ogg new file mode 100644 index 0000000000..15bbe46087 Binary files /dev/null and b/modular_citadel/sound/vox/kit.ogg differ diff --git a/modular_citadel/sound/vox/lab.ogg b/modular_citadel/sound/vox/lab.ogg new file mode 100644 index 0000000000..2031fdd255 Binary files /dev/null and b/modular_citadel/sound/vox/lab.ogg differ diff --git a/modular_citadel/sound/vox/lambda.ogg b/modular_citadel/sound/vox/lambda.ogg new file mode 100644 index 0000000000..f933c45376 Binary files /dev/null and b/modular_citadel/sound/vox/lambda.ogg differ diff --git a/modular_citadel/sound/vox/laser.ogg b/modular_citadel/sound/vox/laser.ogg new file mode 100644 index 0000000000..04b5ec4341 Binary files /dev/null and b/modular_citadel/sound/vox/laser.ogg differ diff --git a/modular_citadel/sound/vox/last.ogg b/modular_citadel/sound/vox/last.ogg new file mode 100644 index 0000000000..9ce61ac234 Binary files /dev/null and b/modular_citadel/sound/vox/last.ogg differ diff --git a/modular_citadel/sound/vox/launch.ogg b/modular_citadel/sound/vox/launch.ogg new file mode 100644 index 0000000000..c8e3b0820e Binary files /dev/null and b/modular_citadel/sound/vox/launch.ogg differ diff --git a/modular_citadel/sound/vox/leak.ogg b/modular_citadel/sound/vox/leak.ogg new file mode 100644 index 0000000000..3154ac53c3 Binary files /dev/null and b/modular_citadel/sound/vox/leak.ogg differ diff --git a/modular_citadel/sound/vox/leave.ogg b/modular_citadel/sound/vox/leave.ogg new file mode 100644 index 0000000000..cec4a6befd Binary files /dev/null and b/modular_citadel/sound/vox/leave.ogg differ diff --git a/modular_citadel/sound/vox/left.ogg b/modular_citadel/sound/vox/left.ogg new file mode 100644 index 0000000000..c6f32829ad Binary files /dev/null and b/modular_citadel/sound/vox/left.ogg differ diff --git a/modular_citadel/sound/vox/legal.ogg b/modular_citadel/sound/vox/legal.ogg new file mode 100644 index 0000000000..c8f5163bd1 Binary files /dev/null and b/modular_citadel/sound/vox/legal.ogg differ diff --git a/modular_citadel/sound/vox/level.ogg b/modular_citadel/sound/vox/level.ogg new file mode 100644 index 0000000000..4d898a5ef7 Binary files /dev/null and b/modular_citadel/sound/vox/level.ogg differ diff --git a/modular_citadel/sound/vox/lever.ogg b/modular_citadel/sound/vox/lever.ogg new file mode 100644 index 0000000000..28c8c33e76 Binary files /dev/null and b/modular_citadel/sound/vox/lever.ogg differ diff --git a/modular_citadel/sound/vox/lie.ogg b/modular_citadel/sound/vox/lie.ogg new file mode 100644 index 0000000000..1516dc0072 Binary files /dev/null and b/modular_citadel/sound/vox/lie.ogg differ diff --git a/modular_citadel/sound/vox/lieutenant.ogg b/modular_citadel/sound/vox/lieutenant.ogg new file mode 100644 index 0000000000..1393b36008 Binary files /dev/null and b/modular_citadel/sound/vox/lieutenant.ogg differ diff --git a/modular_citadel/sound/vox/life.ogg b/modular_citadel/sound/vox/life.ogg new file mode 100644 index 0000000000..0d03320ce2 Binary files /dev/null and b/modular_citadel/sound/vox/life.ogg differ diff --git a/modular_citadel/sound/vox/light.ogg b/modular_citadel/sound/vox/light.ogg new file mode 100644 index 0000000000..c4e8a9fc78 Binary files /dev/null and b/modular_citadel/sound/vox/light.ogg differ diff --git a/modular_citadel/sound/vox/lima.ogg b/modular_citadel/sound/vox/lima.ogg new file mode 100644 index 0000000000..84e26666cf Binary files /dev/null and b/modular_citadel/sound/vox/lima.ogg differ diff --git a/modular_citadel/sound/vox/liquid.ogg b/modular_citadel/sound/vox/liquid.ogg new file mode 100644 index 0000000000..b942e3cf6c Binary files /dev/null and b/modular_citadel/sound/vox/liquid.ogg differ diff --git a/modular_citadel/sound/vox/loading.ogg b/modular_citadel/sound/vox/loading.ogg new file mode 100644 index 0000000000..2dfefd952e Binary files /dev/null and b/modular_citadel/sound/vox/loading.ogg differ diff --git a/modular_citadel/sound/vox/locate.ogg b/modular_citadel/sound/vox/locate.ogg new file mode 100644 index 0000000000..2ea19ec257 Binary files /dev/null and b/modular_citadel/sound/vox/locate.ogg differ diff --git a/modular_citadel/sound/vox/located.ogg b/modular_citadel/sound/vox/located.ogg new file mode 100644 index 0000000000..cd161b556b Binary files /dev/null and b/modular_citadel/sound/vox/located.ogg differ diff --git a/modular_citadel/sound/vox/location.ogg b/modular_citadel/sound/vox/location.ogg new file mode 100644 index 0000000000..966c9ae3f6 Binary files /dev/null and b/modular_citadel/sound/vox/location.ogg differ diff --git a/modular_citadel/sound/vox/lock.ogg b/modular_citadel/sound/vox/lock.ogg new file mode 100644 index 0000000000..c4c89992db Binary files /dev/null and b/modular_citadel/sound/vox/lock.ogg differ diff --git a/modular_citadel/sound/vox/locked.ogg b/modular_citadel/sound/vox/locked.ogg new file mode 100644 index 0000000000..d1a05ba323 Binary files /dev/null and b/modular_citadel/sound/vox/locked.ogg differ diff --git a/modular_citadel/sound/vox/locker.ogg b/modular_citadel/sound/vox/locker.ogg new file mode 100644 index 0000000000..2c5c9ccb4b Binary files /dev/null and b/modular_citadel/sound/vox/locker.ogg differ diff --git a/modular_citadel/sound/vox/lockout.ogg b/modular_citadel/sound/vox/lockout.ogg new file mode 100644 index 0000000000..36748ecb71 Binary files /dev/null and b/modular_citadel/sound/vox/lockout.ogg differ diff --git a/modular_citadel/sound/vox/lower.ogg b/modular_citadel/sound/vox/lower.ogg new file mode 100644 index 0000000000..a3a6a3ae9d Binary files /dev/null and b/modular_citadel/sound/vox/lower.ogg differ diff --git a/modular_citadel/sound/vox/lowest.ogg b/modular_citadel/sound/vox/lowest.ogg new file mode 100644 index 0000000000..787fa2a961 Binary files /dev/null and b/modular_citadel/sound/vox/lowest.ogg differ diff --git a/modular_citadel/sound/vox/magnetic.ogg b/modular_citadel/sound/vox/magnetic.ogg new file mode 100644 index 0000000000..1211ab1cfd Binary files /dev/null and b/modular_citadel/sound/vox/magnetic.ogg differ diff --git a/modular_citadel/sound/vox/main.ogg b/modular_citadel/sound/vox/main.ogg new file mode 100644 index 0000000000..a1e49b2c16 Binary files /dev/null and b/modular_citadel/sound/vox/main.ogg differ diff --git a/modular_citadel/sound/vox/maintenance.ogg b/modular_citadel/sound/vox/maintenance.ogg new file mode 100644 index 0000000000..691fea8b60 Binary files /dev/null and b/modular_citadel/sound/vox/maintenance.ogg differ diff --git a/modular_citadel/sound/vox/malfunction.ogg b/modular_citadel/sound/vox/malfunction.ogg new file mode 100644 index 0000000000..5e0d416d4f Binary files /dev/null and b/modular_citadel/sound/vox/malfunction.ogg differ diff --git a/modular_citadel/sound/vox/man.ogg b/modular_citadel/sound/vox/man.ogg new file mode 100644 index 0000000000..10ca95640a Binary files /dev/null and b/modular_citadel/sound/vox/man.ogg differ diff --git a/modular_citadel/sound/vox/mass.ogg b/modular_citadel/sound/vox/mass.ogg new file mode 100644 index 0000000000..6b785f5e8b Binary files /dev/null and b/modular_citadel/sound/vox/mass.ogg differ diff --git a/modular_citadel/sound/vox/materials.ogg b/modular_citadel/sound/vox/materials.ogg new file mode 100644 index 0000000000..0321e579f7 Binary files /dev/null and b/modular_citadel/sound/vox/materials.ogg differ diff --git a/modular_citadel/sound/vox/maximum.ogg b/modular_citadel/sound/vox/maximum.ogg new file mode 100644 index 0000000000..ef566342a7 Binary files /dev/null and b/modular_citadel/sound/vox/maximum.ogg differ diff --git a/modular_citadel/sound/vox/may.ogg b/modular_citadel/sound/vox/may.ogg new file mode 100644 index 0000000000..2f9fa02cf0 Binary files /dev/null and b/modular_citadel/sound/vox/may.ogg differ diff --git a/modular_citadel/sound/vox/med.ogg b/modular_citadel/sound/vox/med.ogg new file mode 100644 index 0000000000..280a12362f Binary files /dev/null and b/modular_citadel/sound/vox/med.ogg differ diff --git a/modular_citadel/sound/vox/medical.ogg b/modular_citadel/sound/vox/medical.ogg new file mode 100644 index 0000000000..3a293f31b2 Binary files /dev/null and b/modular_citadel/sound/vox/medical.ogg differ diff --git a/modular_citadel/sound/vox/men.ogg b/modular_citadel/sound/vox/men.ogg new file mode 100644 index 0000000000..a9e92245f1 Binary files /dev/null and b/modular_citadel/sound/vox/men.ogg differ diff --git a/modular_citadel/sound/vox/mercy.ogg b/modular_citadel/sound/vox/mercy.ogg new file mode 100644 index 0000000000..2de89bc70a Binary files /dev/null and b/modular_citadel/sound/vox/mercy.ogg differ diff --git a/modular_citadel/sound/vox/mesa.ogg b/modular_citadel/sound/vox/mesa.ogg new file mode 100644 index 0000000000..649d3671ba Binary files /dev/null and b/modular_citadel/sound/vox/mesa.ogg differ diff --git a/modular_citadel/sound/vox/message.ogg b/modular_citadel/sound/vox/message.ogg new file mode 100644 index 0000000000..1454e3df9e Binary files /dev/null and b/modular_citadel/sound/vox/message.ogg differ diff --git a/modular_citadel/sound/vox/meter.ogg b/modular_citadel/sound/vox/meter.ogg new file mode 100644 index 0000000000..7afc6fb3d1 Binary files /dev/null and b/modular_citadel/sound/vox/meter.ogg differ diff --git a/modular_citadel/sound/vox/micro.ogg b/modular_citadel/sound/vox/micro.ogg new file mode 100644 index 0000000000..38d59ed2de Binary files /dev/null and b/modular_citadel/sound/vox/micro.ogg differ diff --git a/modular_citadel/sound/vox/middle.ogg b/modular_citadel/sound/vox/middle.ogg new file mode 100644 index 0000000000..ef33287eff Binary files /dev/null and b/modular_citadel/sound/vox/middle.ogg differ diff --git a/modular_citadel/sound/vox/mike.ogg b/modular_citadel/sound/vox/mike.ogg new file mode 100644 index 0000000000..27d4fdeb9e Binary files /dev/null and b/modular_citadel/sound/vox/mike.ogg differ diff --git a/modular_citadel/sound/vox/miles.ogg b/modular_citadel/sound/vox/miles.ogg new file mode 100644 index 0000000000..fbf06913e2 Binary files /dev/null and b/modular_citadel/sound/vox/miles.ogg differ diff --git a/modular_citadel/sound/vox/military.ogg b/modular_citadel/sound/vox/military.ogg new file mode 100644 index 0000000000..8273851291 Binary files /dev/null and b/modular_citadel/sound/vox/military.ogg differ diff --git a/modular_citadel/sound/vox/milli.ogg b/modular_citadel/sound/vox/milli.ogg new file mode 100644 index 0000000000..806bccebab Binary files /dev/null and b/modular_citadel/sound/vox/milli.ogg differ diff --git a/modular_citadel/sound/vox/million.ogg b/modular_citadel/sound/vox/million.ogg new file mode 100644 index 0000000000..e4c10a2d86 Binary files /dev/null and b/modular_citadel/sound/vox/million.ogg differ diff --git a/modular_citadel/sound/vox/minefield.ogg b/modular_citadel/sound/vox/minefield.ogg new file mode 100644 index 0000000000..b437449d1d Binary files /dev/null and b/modular_citadel/sound/vox/minefield.ogg differ diff --git a/modular_citadel/sound/vox/minimum.ogg b/modular_citadel/sound/vox/minimum.ogg new file mode 100644 index 0000000000..a15483bde6 Binary files /dev/null and b/modular_citadel/sound/vox/minimum.ogg differ diff --git a/modular_citadel/sound/vox/minutes.ogg b/modular_citadel/sound/vox/minutes.ogg new file mode 100644 index 0000000000..2b7bf579ea Binary files /dev/null and b/modular_citadel/sound/vox/minutes.ogg differ diff --git a/modular_citadel/sound/vox/mister.ogg b/modular_citadel/sound/vox/mister.ogg new file mode 100644 index 0000000000..bc5409bbed Binary files /dev/null and b/modular_citadel/sound/vox/mister.ogg differ diff --git a/modular_citadel/sound/vox/mode.ogg b/modular_citadel/sound/vox/mode.ogg new file mode 100644 index 0000000000..04d6684bde Binary files /dev/null and b/modular_citadel/sound/vox/mode.ogg differ diff --git a/modular_citadel/sound/vox/motor.ogg b/modular_citadel/sound/vox/motor.ogg new file mode 100644 index 0000000000..5a3084201a Binary files /dev/null and b/modular_citadel/sound/vox/motor.ogg differ diff --git a/modular_citadel/sound/vox/motorpool.ogg b/modular_citadel/sound/vox/motorpool.ogg new file mode 100644 index 0000000000..a29772d545 Binary files /dev/null and b/modular_citadel/sound/vox/motorpool.ogg differ diff --git a/modular_citadel/sound/vox/move.ogg b/modular_citadel/sound/vox/move.ogg new file mode 100644 index 0000000000..cc6344813f Binary files /dev/null and b/modular_citadel/sound/vox/move.ogg differ diff --git a/modular_citadel/sound/vox/must.ogg b/modular_citadel/sound/vox/must.ogg new file mode 100644 index 0000000000..d52d2c85e0 Binary files /dev/null and b/modular_citadel/sound/vox/must.ogg differ diff --git a/modular_citadel/sound/vox/nearest.ogg b/modular_citadel/sound/vox/nearest.ogg new file mode 100644 index 0000000000..fdf34564ad Binary files /dev/null and b/modular_citadel/sound/vox/nearest.ogg differ diff --git a/modular_citadel/sound/vox/nice.ogg b/modular_citadel/sound/vox/nice.ogg new file mode 100644 index 0000000000..102f0eaf87 Binary files /dev/null and b/modular_citadel/sound/vox/nice.ogg differ diff --git a/modular_citadel/sound/vox/nine.ogg b/modular_citadel/sound/vox/nine.ogg new file mode 100644 index 0000000000..1d4fd45add Binary files /dev/null and b/modular_citadel/sound/vox/nine.ogg differ diff --git a/modular_citadel/sound/vox/nineteen.ogg b/modular_citadel/sound/vox/nineteen.ogg new file mode 100644 index 0000000000..907ecc6e92 Binary files /dev/null and b/modular_citadel/sound/vox/nineteen.ogg differ diff --git a/modular_citadel/sound/vox/ninety.ogg b/modular_citadel/sound/vox/ninety.ogg new file mode 100644 index 0000000000..0f1c3c4fb5 Binary files /dev/null and b/modular_citadel/sound/vox/ninety.ogg differ diff --git a/modular_citadel/sound/vox/no.ogg b/modular_citadel/sound/vox/no.ogg new file mode 100644 index 0000000000..85d8497891 Binary files /dev/null and b/modular_citadel/sound/vox/no.ogg differ diff --git a/modular_citadel/sound/vox/nominal.ogg b/modular_citadel/sound/vox/nominal.ogg new file mode 100644 index 0000000000..45da127f1b Binary files /dev/null and b/modular_citadel/sound/vox/nominal.ogg differ diff --git a/modular_citadel/sound/vox/north.ogg b/modular_citadel/sound/vox/north.ogg new file mode 100644 index 0000000000..03eb6f88d2 Binary files /dev/null and b/modular_citadel/sound/vox/north.ogg differ diff --git a/modular_citadel/sound/vox/not.ogg b/modular_citadel/sound/vox/not.ogg new file mode 100644 index 0000000000..bc691af375 Binary files /dev/null and b/modular_citadel/sound/vox/not.ogg differ diff --git a/modular_citadel/sound/vox/november.ogg b/modular_citadel/sound/vox/november.ogg new file mode 100644 index 0000000000..4819c132dc Binary files /dev/null and b/modular_citadel/sound/vox/november.ogg differ diff --git a/modular_citadel/sound/vox/now.ogg b/modular_citadel/sound/vox/now.ogg new file mode 100644 index 0000000000..0e26869bac Binary files /dev/null and b/modular_citadel/sound/vox/now.ogg differ diff --git a/modular_citadel/sound/vox/number.ogg b/modular_citadel/sound/vox/number.ogg new file mode 100644 index 0000000000..c139db7d17 Binary files /dev/null and b/modular_citadel/sound/vox/number.ogg differ diff --git a/modular_citadel/sound/vox/objective.ogg b/modular_citadel/sound/vox/objective.ogg new file mode 100644 index 0000000000..2496f83ccf Binary files /dev/null and b/modular_citadel/sound/vox/objective.ogg differ diff --git a/modular_citadel/sound/vox/observation.ogg b/modular_citadel/sound/vox/observation.ogg new file mode 100644 index 0000000000..af04410915 Binary files /dev/null and b/modular_citadel/sound/vox/observation.ogg differ diff --git a/modular_citadel/sound/vox/of.ogg b/modular_citadel/sound/vox/of.ogg new file mode 100644 index 0000000000..ee71e1a46e Binary files /dev/null and b/modular_citadel/sound/vox/of.ogg differ diff --git a/modular_citadel/sound/vox/officer.ogg b/modular_citadel/sound/vox/officer.ogg new file mode 100644 index 0000000000..c9f94915e6 Binary files /dev/null and b/modular_citadel/sound/vox/officer.ogg differ diff --git a/modular_citadel/sound/vox/ok.ogg b/modular_citadel/sound/vox/ok.ogg new file mode 100644 index 0000000000..cf58af4d13 Binary files /dev/null and b/modular_citadel/sound/vox/ok.ogg differ diff --git a/modular_citadel/sound/vox/on.ogg b/modular_citadel/sound/vox/on.ogg new file mode 100644 index 0000000000..3c59c6abd8 Binary files /dev/null and b/modular_citadel/sound/vox/on.ogg differ diff --git a/modular_citadel/sound/vox/one.ogg b/modular_citadel/sound/vox/one.ogg new file mode 100644 index 0000000000..377f270179 Binary files /dev/null and b/modular_citadel/sound/vox/one.ogg differ diff --git a/modular_citadel/sound/vox/open.ogg b/modular_citadel/sound/vox/open.ogg new file mode 100644 index 0000000000..81c11de72f Binary files /dev/null and b/modular_citadel/sound/vox/open.ogg differ diff --git a/modular_citadel/sound/vox/operating.ogg b/modular_citadel/sound/vox/operating.ogg new file mode 100644 index 0000000000..cd2de79d79 Binary files /dev/null and b/modular_citadel/sound/vox/operating.ogg differ diff --git a/modular_citadel/sound/vox/operations.ogg b/modular_citadel/sound/vox/operations.ogg new file mode 100644 index 0000000000..9323d95f46 Binary files /dev/null and b/modular_citadel/sound/vox/operations.ogg differ diff --git a/modular_citadel/sound/vox/operative.ogg b/modular_citadel/sound/vox/operative.ogg new file mode 100644 index 0000000000..ba9c7d0cf4 Binary files /dev/null and b/modular_citadel/sound/vox/operative.ogg differ diff --git a/modular_citadel/sound/vox/option.ogg b/modular_citadel/sound/vox/option.ogg new file mode 100644 index 0000000000..c404be5556 Binary files /dev/null and b/modular_citadel/sound/vox/option.ogg differ diff --git a/modular_citadel/sound/vox/order.ogg b/modular_citadel/sound/vox/order.ogg new file mode 100644 index 0000000000..2961f353ed Binary files /dev/null and b/modular_citadel/sound/vox/order.ogg differ diff --git a/modular_citadel/sound/vox/organic.ogg b/modular_citadel/sound/vox/organic.ogg new file mode 100644 index 0000000000..6195be46b4 Binary files /dev/null and b/modular_citadel/sound/vox/organic.ogg differ diff --git a/modular_citadel/sound/vox/oscar.ogg b/modular_citadel/sound/vox/oscar.ogg new file mode 100644 index 0000000000..5f43814f5e Binary files /dev/null and b/modular_citadel/sound/vox/oscar.ogg differ diff --git a/modular_citadel/sound/vox/out.ogg b/modular_citadel/sound/vox/out.ogg new file mode 100644 index 0000000000..3a64ae9751 Binary files /dev/null and b/modular_citadel/sound/vox/out.ogg differ diff --git a/modular_citadel/sound/vox/outside.ogg b/modular_citadel/sound/vox/outside.ogg new file mode 100644 index 0000000000..a6417b9f97 Binary files /dev/null and b/modular_citadel/sound/vox/outside.ogg differ diff --git a/modular_citadel/sound/vox/over.ogg b/modular_citadel/sound/vox/over.ogg new file mode 100644 index 0000000000..193bbd797b Binary files /dev/null and b/modular_citadel/sound/vox/over.ogg differ diff --git a/modular_citadel/sound/vox/overload.ogg b/modular_citadel/sound/vox/overload.ogg new file mode 100644 index 0000000000..d90e52e97d Binary files /dev/null and b/modular_citadel/sound/vox/overload.ogg differ diff --git a/modular_citadel/sound/vox/override.ogg b/modular_citadel/sound/vox/override.ogg new file mode 100644 index 0000000000..f2efb63799 Binary files /dev/null and b/modular_citadel/sound/vox/override.ogg differ diff --git a/modular_citadel/sound/vox/pacify.ogg b/modular_citadel/sound/vox/pacify.ogg new file mode 100644 index 0000000000..232865ebe2 Binary files /dev/null and b/modular_citadel/sound/vox/pacify.ogg differ diff --git a/modular_citadel/sound/vox/pain.ogg b/modular_citadel/sound/vox/pain.ogg new file mode 100644 index 0000000000..88e8813158 Binary files /dev/null and b/modular_citadel/sound/vox/pain.ogg differ diff --git a/modular_citadel/sound/vox/pal.ogg b/modular_citadel/sound/vox/pal.ogg new file mode 100644 index 0000000000..185a15a6ac Binary files /dev/null and b/modular_citadel/sound/vox/pal.ogg differ diff --git a/modular_citadel/sound/vox/panel.ogg b/modular_citadel/sound/vox/panel.ogg new file mode 100644 index 0000000000..e200e9ddd9 Binary files /dev/null and b/modular_citadel/sound/vox/panel.ogg differ diff --git a/modular_citadel/sound/vox/percent.ogg b/modular_citadel/sound/vox/percent.ogg new file mode 100644 index 0000000000..43c04572ba Binary files /dev/null and b/modular_citadel/sound/vox/percent.ogg differ diff --git a/modular_citadel/sound/vox/perimeter.ogg b/modular_citadel/sound/vox/perimeter.ogg new file mode 100644 index 0000000000..7bd3f039ef Binary files /dev/null and b/modular_citadel/sound/vox/perimeter.ogg differ diff --git a/modular_citadel/sound/vox/period.ogg b/modular_citadel/sound/vox/period.ogg new file mode 100644 index 0000000000..e333dc159b Binary files /dev/null and b/modular_citadel/sound/vox/period.ogg differ diff --git a/modular_citadel/sound/vox/permitted.ogg b/modular_citadel/sound/vox/permitted.ogg new file mode 100644 index 0000000000..832fec7c24 Binary files /dev/null and b/modular_citadel/sound/vox/permitted.ogg differ diff --git a/modular_citadel/sound/vox/personnel.ogg b/modular_citadel/sound/vox/personnel.ogg new file mode 100644 index 0000000000..f499fb9f1d Binary files /dev/null and b/modular_citadel/sound/vox/personnel.ogg differ diff --git a/modular_citadel/sound/vox/pipe.ogg b/modular_citadel/sound/vox/pipe.ogg new file mode 100644 index 0000000000..63ab07e4cb Binary files /dev/null and b/modular_citadel/sound/vox/pipe.ogg differ diff --git a/modular_citadel/sound/vox/plant.ogg b/modular_citadel/sound/vox/plant.ogg new file mode 100644 index 0000000000..d82d73900d Binary files /dev/null and b/modular_citadel/sound/vox/plant.ogg differ diff --git a/modular_citadel/sound/vox/platform.ogg b/modular_citadel/sound/vox/platform.ogg new file mode 100644 index 0000000000..cf9eb6ce53 Binary files /dev/null and b/modular_citadel/sound/vox/platform.ogg differ diff --git a/modular_citadel/sound/vox/please.ogg b/modular_citadel/sound/vox/please.ogg new file mode 100644 index 0000000000..cc21919798 Binary files /dev/null and b/modular_citadel/sound/vox/please.ogg differ diff --git a/modular_citadel/sound/vox/point.ogg b/modular_citadel/sound/vox/point.ogg new file mode 100644 index 0000000000..29925c714c Binary files /dev/null and b/modular_citadel/sound/vox/point.ogg differ diff --git a/modular_citadel/sound/vox/portal.ogg b/modular_citadel/sound/vox/portal.ogg new file mode 100644 index 0000000000..4492842d97 Binary files /dev/null and b/modular_citadel/sound/vox/portal.ogg differ diff --git a/modular_citadel/sound/vox/power.ogg b/modular_citadel/sound/vox/power.ogg new file mode 100644 index 0000000000..109dde7b19 Binary files /dev/null and b/modular_citadel/sound/vox/power.ogg differ diff --git a/modular_citadel/sound/vox/presence.ogg b/modular_citadel/sound/vox/presence.ogg new file mode 100644 index 0000000000..fc929ee991 Binary files /dev/null and b/modular_citadel/sound/vox/presence.ogg differ diff --git a/modular_citadel/sound/vox/press.ogg b/modular_citadel/sound/vox/press.ogg new file mode 100644 index 0000000000..704c907141 Binary files /dev/null and b/modular_citadel/sound/vox/press.ogg differ diff --git a/modular_citadel/sound/vox/primary.ogg b/modular_citadel/sound/vox/primary.ogg new file mode 100644 index 0000000000..6f667e6a57 Binary files /dev/null and b/modular_citadel/sound/vox/primary.ogg differ diff --git a/modular_citadel/sound/vox/proceed.ogg b/modular_citadel/sound/vox/proceed.ogg new file mode 100644 index 0000000000..86df9fcf25 Binary files /dev/null and b/modular_citadel/sound/vox/proceed.ogg differ diff --git a/modular_citadel/sound/vox/processing.ogg b/modular_citadel/sound/vox/processing.ogg new file mode 100644 index 0000000000..f5aae3574c Binary files /dev/null and b/modular_citadel/sound/vox/processing.ogg differ diff --git a/modular_citadel/sound/vox/progress.ogg b/modular_citadel/sound/vox/progress.ogg new file mode 100644 index 0000000000..c07c102a97 Binary files /dev/null and b/modular_citadel/sound/vox/progress.ogg differ diff --git a/modular_citadel/sound/vox/proper.ogg b/modular_citadel/sound/vox/proper.ogg new file mode 100644 index 0000000000..0dbfbaf599 Binary files /dev/null and b/modular_citadel/sound/vox/proper.ogg differ diff --git a/modular_citadel/sound/vox/propulsion.ogg b/modular_citadel/sound/vox/propulsion.ogg new file mode 100644 index 0000000000..8a4a77274a Binary files /dev/null and b/modular_citadel/sound/vox/propulsion.ogg differ diff --git a/modular_citadel/sound/vox/prosecute.ogg b/modular_citadel/sound/vox/prosecute.ogg new file mode 100644 index 0000000000..c0895c54ef Binary files /dev/null and b/modular_citadel/sound/vox/prosecute.ogg differ diff --git a/modular_citadel/sound/vox/protective.ogg b/modular_citadel/sound/vox/protective.ogg new file mode 100644 index 0000000000..67c1f1195b Binary files /dev/null and b/modular_citadel/sound/vox/protective.ogg differ diff --git a/modular_citadel/sound/vox/push.ogg b/modular_citadel/sound/vox/push.ogg new file mode 100644 index 0000000000..2d9cfca1f7 Binary files /dev/null and b/modular_citadel/sound/vox/push.ogg differ diff --git a/modular_citadel/sound/vox/quantum.ogg b/modular_citadel/sound/vox/quantum.ogg new file mode 100644 index 0000000000..5082f84e7d Binary files /dev/null and b/modular_citadel/sound/vox/quantum.ogg differ diff --git a/modular_citadel/sound/vox/quebec.ogg b/modular_citadel/sound/vox/quebec.ogg new file mode 100644 index 0000000000..59e84cd4a3 Binary files /dev/null and b/modular_citadel/sound/vox/quebec.ogg differ diff --git a/modular_citadel/sound/vox/question.ogg b/modular_citadel/sound/vox/question.ogg new file mode 100644 index 0000000000..197f11ca9a Binary files /dev/null and b/modular_citadel/sound/vox/question.ogg differ diff --git a/modular_citadel/sound/vox/questioning.ogg b/modular_citadel/sound/vox/questioning.ogg new file mode 100644 index 0000000000..ba0436cf32 Binary files /dev/null and b/modular_citadel/sound/vox/questioning.ogg differ diff --git a/modular_citadel/sound/vox/quick.ogg b/modular_citadel/sound/vox/quick.ogg new file mode 100644 index 0000000000..19d4e91261 Binary files /dev/null and b/modular_citadel/sound/vox/quick.ogg differ diff --git a/modular_citadel/sound/vox/quit.ogg b/modular_citadel/sound/vox/quit.ogg new file mode 100644 index 0000000000..7ab07efa87 Binary files /dev/null and b/modular_citadel/sound/vox/quit.ogg differ diff --git a/modular_citadel/sound/vox/radiation.ogg b/modular_citadel/sound/vox/radiation.ogg new file mode 100644 index 0000000000..8d8fbdc001 Binary files /dev/null and b/modular_citadel/sound/vox/radiation.ogg differ diff --git a/modular_citadel/sound/vox/radioactive.ogg b/modular_citadel/sound/vox/radioactive.ogg new file mode 100644 index 0000000000..f5751882d4 Binary files /dev/null and b/modular_citadel/sound/vox/radioactive.ogg differ diff --git a/modular_citadel/sound/vox/rads.ogg b/modular_citadel/sound/vox/rads.ogg new file mode 100644 index 0000000000..e42722dd62 Binary files /dev/null and b/modular_citadel/sound/vox/rads.ogg differ diff --git a/modular_citadel/sound/vox/rapid.ogg b/modular_citadel/sound/vox/rapid.ogg new file mode 100644 index 0000000000..c803204bc8 Binary files /dev/null and b/modular_citadel/sound/vox/rapid.ogg differ diff --git a/modular_citadel/sound/vox/reach.ogg b/modular_citadel/sound/vox/reach.ogg new file mode 100644 index 0000000000..ab1a02e9ee Binary files /dev/null and b/modular_citadel/sound/vox/reach.ogg differ diff --git a/modular_citadel/sound/vox/reached.ogg b/modular_citadel/sound/vox/reached.ogg new file mode 100644 index 0000000000..eddba60eed Binary files /dev/null and b/modular_citadel/sound/vox/reached.ogg differ diff --git a/modular_citadel/sound/vox/reactor.ogg b/modular_citadel/sound/vox/reactor.ogg new file mode 100644 index 0000000000..75ea481a37 Binary files /dev/null and b/modular_citadel/sound/vox/reactor.ogg differ diff --git a/modular_citadel/sound/vox/red.ogg b/modular_citadel/sound/vox/red.ogg new file mode 100644 index 0000000000..97f2513772 Binary files /dev/null and b/modular_citadel/sound/vox/red.ogg differ diff --git a/modular_citadel/sound/vox/relay.ogg b/modular_citadel/sound/vox/relay.ogg new file mode 100644 index 0000000000..edc904c3f4 Binary files /dev/null and b/modular_citadel/sound/vox/relay.ogg differ diff --git a/modular_citadel/sound/vox/released.ogg b/modular_citadel/sound/vox/released.ogg new file mode 100644 index 0000000000..b86a39af72 Binary files /dev/null and b/modular_citadel/sound/vox/released.ogg differ diff --git a/modular_citadel/sound/vox/remaining.ogg b/modular_citadel/sound/vox/remaining.ogg new file mode 100644 index 0000000000..3ca55d3373 Binary files /dev/null and b/modular_citadel/sound/vox/remaining.ogg differ diff --git a/modular_citadel/sound/vox/renegade.ogg b/modular_citadel/sound/vox/renegade.ogg new file mode 100644 index 0000000000..6a4a3f3d50 Binary files /dev/null and b/modular_citadel/sound/vox/renegade.ogg differ diff --git a/modular_citadel/sound/vox/repair.ogg b/modular_citadel/sound/vox/repair.ogg new file mode 100644 index 0000000000..9435fe2ade Binary files /dev/null and b/modular_citadel/sound/vox/repair.ogg differ diff --git a/modular_citadel/sound/vox/report.ogg b/modular_citadel/sound/vox/report.ogg new file mode 100644 index 0000000000..873ad6cbfe Binary files /dev/null and b/modular_citadel/sound/vox/report.ogg differ diff --git a/modular_citadel/sound/vox/reports.ogg b/modular_citadel/sound/vox/reports.ogg new file mode 100644 index 0000000000..2fbf3151d0 Binary files /dev/null and b/modular_citadel/sound/vox/reports.ogg differ diff --git a/modular_citadel/sound/vox/required.ogg b/modular_citadel/sound/vox/required.ogg new file mode 100644 index 0000000000..902071124c Binary files /dev/null and b/modular_citadel/sound/vox/required.ogg differ diff --git a/modular_citadel/sound/vox/research.ogg b/modular_citadel/sound/vox/research.ogg new file mode 100644 index 0000000000..c75b2ad2d0 Binary files /dev/null and b/modular_citadel/sound/vox/research.ogg differ diff --git a/modular_citadel/sound/vox/reset.ogg b/modular_citadel/sound/vox/reset.ogg new file mode 100644 index 0000000000..9864b79a54 Binary files /dev/null and b/modular_citadel/sound/vox/reset.ogg differ diff --git a/modular_citadel/sound/vox/resevoir.ogg b/modular_citadel/sound/vox/resevoir.ogg new file mode 100644 index 0000000000..30364c6400 Binary files /dev/null and b/modular_citadel/sound/vox/resevoir.ogg differ diff --git a/modular_citadel/sound/vox/resistance.ogg b/modular_citadel/sound/vox/resistance.ogg new file mode 100644 index 0000000000..dfbe6c512d Binary files /dev/null and b/modular_citadel/sound/vox/resistance.ogg differ diff --git a/modular_citadel/sound/vox/returned.ogg b/modular_citadel/sound/vox/returned.ogg new file mode 100644 index 0000000000..0119402e24 Binary files /dev/null and b/modular_citadel/sound/vox/returned.ogg differ diff --git a/modular_citadel/sound/vox/right.ogg b/modular_citadel/sound/vox/right.ogg new file mode 100644 index 0000000000..b46b8cb135 Binary files /dev/null and b/modular_citadel/sound/vox/right.ogg differ diff --git a/modular_citadel/sound/vox/rocket.ogg b/modular_citadel/sound/vox/rocket.ogg new file mode 100644 index 0000000000..bfb2d3b0ed Binary files /dev/null and b/modular_citadel/sound/vox/rocket.ogg differ diff --git a/modular_citadel/sound/vox/roger.ogg b/modular_citadel/sound/vox/roger.ogg new file mode 100644 index 0000000000..b249613c56 Binary files /dev/null and b/modular_citadel/sound/vox/roger.ogg differ diff --git a/modular_citadel/sound/vox/romeo.ogg b/modular_citadel/sound/vox/romeo.ogg new file mode 100644 index 0000000000..4c0b2356e3 Binary files /dev/null and b/modular_citadel/sound/vox/romeo.ogg differ diff --git a/modular_citadel/sound/vox/room.ogg b/modular_citadel/sound/vox/room.ogg new file mode 100644 index 0000000000..5151e39d46 Binary files /dev/null and b/modular_citadel/sound/vox/room.ogg differ diff --git a/modular_citadel/sound/vox/round.ogg b/modular_citadel/sound/vox/round.ogg new file mode 100644 index 0000000000..685f42d223 Binary files /dev/null and b/modular_citadel/sound/vox/round.ogg differ diff --git a/modular_citadel/sound/vox/run.ogg b/modular_citadel/sound/vox/run.ogg new file mode 100644 index 0000000000..9d6012cf3b Binary files /dev/null and b/modular_citadel/sound/vox/run.ogg differ diff --git a/modular_citadel/sound/vox/safe.ogg b/modular_citadel/sound/vox/safe.ogg new file mode 100644 index 0000000000..d7a16d66b4 Binary files /dev/null and b/modular_citadel/sound/vox/safe.ogg differ diff --git a/modular_citadel/sound/vox/safety.ogg b/modular_citadel/sound/vox/safety.ogg new file mode 100644 index 0000000000..68ad663df4 Binary files /dev/null and b/modular_citadel/sound/vox/safety.ogg differ diff --git a/modular_citadel/sound/vox/sargeant.ogg b/modular_citadel/sound/vox/sargeant.ogg new file mode 100644 index 0000000000..1ab4150c9c Binary files /dev/null and b/modular_citadel/sound/vox/sargeant.ogg differ diff --git a/modular_citadel/sound/vox/satellite.ogg b/modular_citadel/sound/vox/satellite.ogg new file mode 100644 index 0000000000..c07895ab77 Binary files /dev/null and b/modular_citadel/sound/vox/satellite.ogg differ diff --git a/modular_citadel/sound/vox/save.ogg b/modular_citadel/sound/vox/save.ogg new file mode 100644 index 0000000000..8a53055d62 Binary files /dev/null and b/modular_citadel/sound/vox/save.ogg differ diff --git a/modular_citadel/sound/vox/science.ogg b/modular_citadel/sound/vox/science.ogg new file mode 100644 index 0000000000..6e2e748cbb Binary files /dev/null and b/modular_citadel/sound/vox/science.ogg differ diff --git a/modular_citadel/sound/vox/scores.ogg b/modular_citadel/sound/vox/scores.ogg new file mode 100644 index 0000000000..3328f38dc7 Binary files /dev/null and b/modular_citadel/sound/vox/scores.ogg differ diff --git a/modular_citadel/sound/vox/scream.ogg b/modular_citadel/sound/vox/scream.ogg new file mode 100644 index 0000000000..c795ca95ba Binary files /dev/null and b/modular_citadel/sound/vox/scream.ogg differ diff --git a/modular_citadel/sound/vox/screen.ogg b/modular_citadel/sound/vox/screen.ogg new file mode 100644 index 0000000000..514cc3f71a Binary files /dev/null and b/modular_citadel/sound/vox/screen.ogg differ diff --git a/modular_citadel/sound/vox/search.ogg b/modular_citadel/sound/vox/search.ogg new file mode 100644 index 0000000000..638710b721 Binary files /dev/null and b/modular_citadel/sound/vox/search.ogg differ diff --git a/modular_citadel/sound/vox/second.ogg b/modular_citadel/sound/vox/second.ogg new file mode 100644 index 0000000000..fc4dc806ca Binary files /dev/null and b/modular_citadel/sound/vox/second.ogg differ diff --git a/modular_citadel/sound/vox/secondary.ogg b/modular_citadel/sound/vox/secondary.ogg new file mode 100644 index 0000000000..3cffa3dbe9 Binary files /dev/null and b/modular_citadel/sound/vox/secondary.ogg differ diff --git a/modular_citadel/sound/vox/seconds.ogg b/modular_citadel/sound/vox/seconds.ogg new file mode 100644 index 0000000000..98d08be46c Binary files /dev/null and b/modular_citadel/sound/vox/seconds.ogg differ diff --git a/modular_citadel/sound/vox/sector.ogg b/modular_citadel/sound/vox/sector.ogg new file mode 100644 index 0000000000..ae2d733b87 Binary files /dev/null and b/modular_citadel/sound/vox/sector.ogg differ diff --git a/modular_citadel/sound/vox/secure.ogg b/modular_citadel/sound/vox/secure.ogg new file mode 100644 index 0000000000..c860e376dd Binary files /dev/null and b/modular_citadel/sound/vox/secure.ogg differ diff --git a/modular_citadel/sound/vox/secured.ogg b/modular_citadel/sound/vox/secured.ogg new file mode 100644 index 0000000000..3134b679fa Binary files /dev/null and b/modular_citadel/sound/vox/secured.ogg differ diff --git a/modular_citadel/sound/vox/security.ogg b/modular_citadel/sound/vox/security.ogg new file mode 100644 index 0000000000..40f6bc61af Binary files /dev/null and b/modular_citadel/sound/vox/security.ogg differ diff --git a/modular_citadel/sound/vox/select.ogg b/modular_citadel/sound/vox/select.ogg new file mode 100644 index 0000000000..ef04570d32 Binary files /dev/null and b/modular_citadel/sound/vox/select.ogg differ diff --git a/modular_citadel/sound/vox/selected.ogg b/modular_citadel/sound/vox/selected.ogg new file mode 100644 index 0000000000..23891f5189 Binary files /dev/null and b/modular_citadel/sound/vox/selected.ogg differ diff --git a/modular_citadel/sound/vox/service.ogg b/modular_citadel/sound/vox/service.ogg new file mode 100644 index 0000000000..90294bd34b Binary files /dev/null and b/modular_citadel/sound/vox/service.ogg differ diff --git a/modular_citadel/sound/vox/seven.ogg b/modular_citadel/sound/vox/seven.ogg new file mode 100644 index 0000000000..a0b2de4119 Binary files /dev/null and b/modular_citadel/sound/vox/seven.ogg differ diff --git a/modular_citadel/sound/vox/seventeen.ogg b/modular_citadel/sound/vox/seventeen.ogg new file mode 100644 index 0000000000..f23a0b0572 Binary files /dev/null and b/modular_citadel/sound/vox/seventeen.ogg differ diff --git a/modular_citadel/sound/vox/seventy.ogg b/modular_citadel/sound/vox/seventy.ogg new file mode 100644 index 0000000000..54f6cd6aef Binary files /dev/null and b/modular_citadel/sound/vox/seventy.ogg differ diff --git a/modular_citadel/sound/vox/severe.ogg b/modular_citadel/sound/vox/severe.ogg new file mode 100644 index 0000000000..9a0cf3784e Binary files /dev/null and b/modular_citadel/sound/vox/severe.ogg differ diff --git a/modular_citadel/sound/vox/sewage.ogg b/modular_citadel/sound/vox/sewage.ogg new file mode 100644 index 0000000000..44fb0d7fd5 Binary files /dev/null and b/modular_citadel/sound/vox/sewage.ogg differ diff --git a/modular_citadel/sound/vox/sewer.ogg b/modular_citadel/sound/vox/sewer.ogg new file mode 100644 index 0000000000..10516d86de Binary files /dev/null and b/modular_citadel/sound/vox/sewer.ogg differ diff --git a/modular_citadel/sound/vox/shield.ogg b/modular_citadel/sound/vox/shield.ogg new file mode 100644 index 0000000000..c190383867 Binary files /dev/null and b/modular_citadel/sound/vox/shield.ogg differ diff --git a/modular_citadel/sound/vox/shipment.ogg b/modular_citadel/sound/vox/shipment.ogg new file mode 100644 index 0000000000..9677d3db98 Binary files /dev/null and b/modular_citadel/sound/vox/shipment.ogg differ diff --git a/modular_citadel/sound/vox/shock.ogg b/modular_citadel/sound/vox/shock.ogg new file mode 100644 index 0000000000..1c44bcca33 Binary files /dev/null and b/modular_citadel/sound/vox/shock.ogg differ diff --git a/modular_citadel/sound/vox/shoot.ogg b/modular_citadel/sound/vox/shoot.ogg new file mode 100644 index 0000000000..978a4aaa35 Binary files /dev/null and b/modular_citadel/sound/vox/shoot.ogg differ diff --git a/modular_citadel/sound/vox/shower.ogg b/modular_citadel/sound/vox/shower.ogg new file mode 100644 index 0000000000..d131987f13 Binary files /dev/null and b/modular_citadel/sound/vox/shower.ogg differ diff --git a/modular_citadel/sound/vox/shut.ogg b/modular_citadel/sound/vox/shut.ogg new file mode 100644 index 0000000000..ceba400b93 Binary files /dev/null and b/modular_citadel/sound/vox/shut.ogg differ diff --git a/modular_citadel/sound/vox/side.ogg b/modular_citadel/sound/vox/side.ogg new file mode 100644 index 0000000000..dbc3a7c9ff Binary files /dev/null and b/modular_citadel/sound/vox/side.ogg differ diff --git a/modular_citadel/sound/vox/sierra.ogg b/modular_citadel/sound/vox/sierra.ogg new file mode 100644 index 0000000000..5c33745f28 Binary files /dev/null and b/modular_citadel/sound/vox/sierra.ogg differ diff --git a/modular_citadel/sound/vox/sight.ogg b/modular_citadel/sound/vox/sight.ogg new file mode 100644 index 0000000000..027c356b8d Binary files /dev/null and b/modular_citadel/sound/vox/sight.ogg differ diff --git a/modular_citadel/sound/vox/silo.ogg b/modular_citadel/sound/vox/silo.ogg new file mode 100644 index 0000000000..3e0801f8ba Binary files /dev/null and b/modular_citadel/sound/vox/silo.ogg differ diff --git a/modular_citadel/sound/vox/six.ogg b/modular_citadel/sound/vox/six.ogg new file mode 100644 index 0000000000..3544814963 Binary files /dev/null and b/modular_citadel/sound/vox/six.ogg differ diff --git a/modular_citadel/sound/vox/sixteen.ogg b/modular_citadel/sound/vox/sixteen.ogg new file mode 100644 index 0000000000..8c1159e147 Binary files /dev/null and b/modular_citadel/sound/vox/sixteen.ogg differ diff --git a/modular_citadel/sound/vox/sixty.ogg b/modular_citadel/sound/vox/sixty.ogg new file mode 100644 index 0000000000..bdf47b25b8 Binary files /dev/null and b/modular_citadel/sound/vox/sixty.ogg differ diff --git a/modular_citadel/sound/vox/slime.ogg b/modular_citadel/sound/vox/slime.ogg new file mode 100644 index 0000000000..0a6c1254e8 Binary files /dev/null and b/modular_citadel/sound/vox/slime.ogg differ diff --git a/modular_citadel/sound/vox/slow.ogg b/modular_citadel/sound/vox/slow.ogg new file mode 100644 index 0000000000..7639f9c7c2 Binary files /dev/null and b/modular_citadel/sound/vox/slow.ogg differ diff --git a/modular_citadel/sound/vox/soldier.ogg b/modular_citadel/sound/vox/soldier.ogg new file mode 100644 index 0000000000..3eb10ff590 Binary files /dev/null and b/modular_citadel/sound/vox/soldier.ogg differ diff --git a/modular_citadel/sound/vox/some.ogg b/modular_citadel/sound/vox/some.ogg new file mode 100644 index 0000000000..bcb5bbbbd3 Binary files /dev/null and b/modular_citadel/sound/vox/some.ogg differ diff --git a/modular_citadel/sound/vox/someone.ogg b/modular_citadel/sound/vox/someone.ogg new file mode 100644 index 0000000000..420a58e925 Binary files /dev/null and b/modular_citadel/sound/vox/someone.ogg differ diff --git a/modular_citadel/sound/vox/something.ogg b/modular_citadel/sound/vox/something.ogg new file mode 100644 index 0000000000..e3d26ede65 Binary files /dev/null and b/modular_citadel/sound/vox/something.ogg differ diff --git a/modular_citadel/sound/vox/son.ogg b/modular_citadel/sound/vox/son.ogg new file mode 100644 index 0000000000..843536c84a Binary files /dev/null and b/modular_citadel/sound/vox/son.ogg differ diff --git a/modular_citadel/sound/vox/sorry.ogg b/modular_citadel/sound/vox/sorry.ogg new file mode 100644 index 0000000000..c125765112 Binary files /dev/null and b/modular_citadel/sound/vox/sorry.ogg differ diff --git a/modular_citadel/sound/vox/south.ogg b/modular_citadel/sound/vox/south.ogg new file mode 100644 index 0000000000..d32f048772 Binary files /dev/null and b/modular_citadel/sound/vox/south.ogg differ diff --git a/modular_citadel/sound/vox/squad.ogg b/modular_citadel/sound/vox/squad.ogg new file mode 100644 index 0000000000..582f6459af Binary files /dev/null and b/modular_citadel/sound/vox/squad.ogg differ diff --git a/modular_citadel/sound/vox/square.ogg b/modular_citadel/sound/vox/square.ogg new file mode 100644 index 0000000000..a9beddd3c9 Binary files /dev/null and b/modular_citadel/sound/vox/square.ogg differ diff --git a/modular_citadel/sound/vox/stairway.ogg b/modular_citadel/sound/vox/stairway.ogg new file mode 100644 index 0000000000..31b0042edd Binary files /dev/null and b/modular_citadel/sound/vox/stairway.ogg differ diff --git a/modular_citadel/sound/vox/status.ogg b/modular_citadel/sound/vox/status.ogg new file mode 100644 index 0000000000..611088f19a Binary files /dev/null and b/modular_citadel/sound/vox/status.ogg differ diff --git a/modular_citadel/sound/vox/sterile.ogg b/modular_citadel/sound/vox/sterile.ogg new file mode 100644 index 0000000000..4e4d9fad22 Binary files /dev/null and b/modular_citadel/sound/vox/sterile.ogg differ diff --git a/modular_citadel/sound/vox/sterilization.ogg b/modular_citadel/sound/vox/sterilization.ogg new file mode 100644 index 0000000000..fec2104d0b Binary files /dev/null and b/modular_citadel/sound/vox/sterilization.ogg differ diff --git a/modular_citadel/sound/vox/stolen.ogg b/modular_citadel/sound/vox/stolen.ogg new file mode 100644 index 0000000000..7e8c624bdf Binary files /dev/null and b/modular_citadel/sound/vox/stolen.ogg differ diff --git a/modular_citadel/sound/vox/storage.ogg b/modular_citadel/sound/vox/storage.ogg new file mode 100644 index 0000000000..e47ef4e09f Binary files /dev/null and b/modular_citadel/sound/vox/storage.ogg differ diff --git a/modular_citadel/sound/vox/sub.ogg b/modular_citadel/sound/vox/sub.ogg new file mode 100644 index 0000000000..ca9a621ad1 Binary files /dev/null and b/modular_citadel/sound/vox/sub.ogg differ diff --git a/modular_citadel/sound/vox/subsurface.ogg b/modular_citadel/sound/vox/subsurface.ogg new file mode 100644 index 0000000000..08c98d50f5 Binary files /dev/null and b/modular_citadel/sound/vox/subsurface.ogg differ diff --git a/modular_citadel/sound/vox/sudden.ogg b/modular_citadel/sound/vox/sudden.ogg new file mode 100644 index 0000000000..7140e0f874 Binary files /dev/null and b/modular_citadel/sound/vox/sudden.ogg differ diff --git a/modular_citadel/sound/vox/suit.ogg b/modular_citadel/sound/vox/suit.ogg new file mode 100644 index 0000000000..c636d5f278 Binary files /dev/null and b/modular_citadel/sound/vox/suit.ogg differ diff --git a/modular_citadel/sound/vox/superconducting.ogg b/modular_citadel/sound/vox/superconducting.ogg new file mode 100644 index 0000000000..244bda01c6 Binary files /dev/null and b/modular_citadel/sound/vox/superconducting.ogg differ diff --git a/modular_citadel/sound/vox/supercooled.ogg b/modular_citadel/sound/vox/supercooled.ogg new file mode 100644 index 0000000000..c758cdf7f8 Binary files /dev/null and b/modular_citadel/sound/vox/supercooled.ogg differ diff --git a/modular_citadel/sound/vox/supply.ogg b/modular_citadel/sound/vox/supply.ogg new file mode 100644 index 0000000000..13341124b3 Binary files /dev/null and b/modular_citadel/sound/vox/supply.ogg differ diff --git a/modular_citadel/sound/vox/surface.ogg b/modular_citadel/sound/vox/surface.ogg new file mode 100644 index 0000000000..f498cfd6bd Binary files /dev/null and b/modular_citadel/sound/vox/surface.ogg differ diff --git a/modular_citadel/sound/vox/surrender.ogg b/modular_citadel/sound/vox/surrender.ogg new file mode 100644 index 0000000000..ba1864d38f Binary files /dev/null and b/modular_citadel/sound/vox/surrender.ogg differ diff --git a/modular_citadel/sound/vox/surround.ogg b/modular_citadel/sound/vox/surround.ogg new file mode 100644 index 0000000000..7a3ab9a69a Binary files /dev/null and b/modular_citadel/sound/vox/surround.ogg differ diff --git a/modular_citadel/sound/vox/surrounded.ogg b/modular_citadel/sound/vox/surrounded.ogg new file mode 100644 index 0000000000..464ae912f4 Binary files /dev/null and b/modular_citadel/sound/vox/surrounded.ogg differ diff --git a/modular_citadel/sound/vox/switch.ogg b/modular_citadel/sound/vox/switch.ogg new file mode 100644 index 0000000000..d007893d35 Binary files /dev/null and b/modular_citadel/sound/vox/switch.ogg differ diff --git a/modular_citadel/sound/vox/system.ogg b/modular_citadel/sound/vox/system.ogg new file mode 100644 index 0000000000..fb459b927f Binary files /dev/null and b/modular_citadel/sound/vox/system.ogg differ diff --git a/modular_citadel/sound/vox/systems.ogg b/modular_citadel/sound/vox/systems.ogg new file mode 100644 index 0000000000..37072c97f4 Binary files /dev/null and b/modular_citadel/sound/vox/systems.ogg differ diff --git a/modular_citadel/sound/vox/tactical.ogg b/modular_citadel/sound/vox/tactical.ogg new file mode 100644 index 0000000000..ae294b916b Binary files /dev/null and b/modular_citadel/sound/vox/tactical.ogg differ diff --git a/modular_citadel/sound/vox/take.ogg b/modular_citadel/sound/vox/take.ogg new file mode 100644 index 0000000000..83409da4a3 Binary files /dev/null and b/modular_citadel/sound/vox/take.ogg differ diff --git a/modular_citadel/sound/vox/talk.ogg b/modular_citadel/sound/vox/talk.ogg new file mode 100644 index 0000000000..043385c389 Binary files /dev/null and b/modular_citadel/sound/vox/talk.ogg differ diff --git a/modular_citadel/sound/vox/tango.ogg b/modular_citadel/sound/vox/tango.ogg new file mode 100644 index 0000000000..f852cb0df3 Binary files /dev/null and b/modular_citadel/sound/vox/tango.ogg differ diff --git a/modular_citadel/sound/vox/tank.ogg b/modular_citadel/sound/vox/tank.ogg new file mode 100644 index 0000000000..df09c12f98 Binary files /dev/null and b/modular_citadel/sound/vox/tank.ogg differ diff --git a/modular_citadel/sound/vox/target.ogg b/modular_citadel/sound/vox/target.ogg new file mode 100644 index 0000000000..0601cac45b Binary files /dev/null and b/modular_citadel/sound/vox/target.ogg differ diff --git a/modular_citadel/sound/vox/team.ogg b/modular_citadel/sound/vox/team.ogg new file mode 100644 index 0000000000..4fc1a7f198 Binary files /dev/null and b/modular_citadel/sound/vox/team.ogg differ diff --git a/modular_citadel/sound/vox/temperature.ogg b/modular_citadel/sound/vox/temperature.ogg new file mode 100644 index 0000000000..d7b92a0cdc Binary files /dev/null and b/modular_citadel/sound/vox/temperature.ogg differ diff --git a/modular_citadel/sound/vox/temporal.ogg b/modular_citadel/sound/vox/temporal.ogg new file mode 100644 index 0000000000..c2f9aedb48 Binary files /dev/null and b/modular_citadel/sound/vox/temporal.ogg differ diff --git a/modular_citadel/sound/vox/ten.ogg b/modular_citadel/sound/vox/ten.ogg new file mode 100644 index 0000000000..704d38c1ae Binary files /dev/null and b/modular_citadel/sound/vox/ten.ogg differ diff --git a/modular_citadel/sound/vox/terminal.ogg b/modular_citadel/sound/vox/terminal.ogg new file mode 100644 index 0000000000..f756e03064 Binary files /dev/null and b/modular_citadel/sound/vox/terminal.ogg differ diff --git a/modular_citadel/sound/vox/terminated.ogg b/modular_citadel/sound/vox/terminated.ogg new file mode 100644 index 0000000000..52d35451b0 Binary files /dev/null and b/modular_citadel/sound/vox/terminated.ogg differ diff --git a/modular_citadel/sound/vox/termination.ogg b/modular_citadel/sound/vox/termination.ogg new file mode 100644 index 0000000000..aec4df5b01 Binary files /dev/null and b/modular_citadel/sound/vox/termination.ogg differ diff --git a/modular_citadel/sound/vox/test.ogg b/modular_citadel/sound/vox/test.ogg new file mode 100644 index 0000000000..df3ab175c6 Binary files /dev/null and b/modular_citadel/sound/vox/test.ogg differ diff --git a/modular_citadel/sound/vox/that.ogg b/modular_citadel/sound/vox/that.ogg new file mode 100644 index 0000000000..442dc3d264 Binary files /dev/null and b/modular_citadel/sound/vox/that.ogg differ diff --git a/modular_citadel/sound/vox/the.ogg b/modular_citadel/sound/vox/the.ogg new file mode 100644 index 0000000000..71caecef1f Binary files /dev/null and b/modular_citadel/sound/vox/the.ogg differ diff --git a/modular_citadel/sound/vox/then.ogg b/modular_citadel/sound/vox/then.ogg new file mode 100644 index 0000000000..916d9276af Binary files /dev/null and b/modular_citadel/sound/vox/then.ogg differ diff --git a/modular_citadel/sound/vox/there.ogg b/modular_citadel/sound/vox/there.ogg new file mode 100644 index 0000000000..c3536a2f72 Binary files /dev/null and b/modular_citadel/sound/vox/there.ogg differ diff --git a/modular_citadel/sound/vox/third.ogg b/modular_citadel/sound/vox/third.ogg new file mode 100644 index 0000000000..ba1125fe5b Binary files /dev/null and b/modular_citadel/sound/vox/third.ogg differ diff --git a/modular_citadel/sound/vox/thirteen.ogg b/modular_citadel/sound/vox/thirteen.ogg new file mode 100644 index 0000000000..b3585a2d3b Binary files /dev/null and b/modular_citadel/sound/vox/thirteen.ogg differ diff --git a/modular_citadel/sound/vox/thirty.ogg b/modular_citadel/sound/vox/thirty.ogg new file mode 100644 index 0000000000..cac0402265 Binary files /dev/null and b/modular_citadel/sound/vox/thirty.ogg differ diff --git a/modular_citadel/sound/vox/this.ogg b/modular_citadel/sound/vox/this.ogg new file mode 100644 index 0000000000..e7acd16108 Binary files /dev/null and b/modular_citadel/sound/vox/this.ogg differ diff --git a/modular_citadel/sound/vox/those.ogg b/modular_citadel/sound/vox/those.ogg new file mode 100644 index 0000000000..149a806b23 Binary files /dev/null and b/modular_citadel/sound/vox/those.ogg differ diff --git a/modular_citadel/sound/vox/thousand.ogg b/modular_citadel/sound/vox/thousand.ogg new file mode 100644 index 0000000000..fd5d46bf9b Binary files /dev/null and b/modular_citadel/sound/vox/thousand.ogg differ diff --git a/modular_citadel/sound/vox/threat.ogg b/modular_citadel/sound/vox/threat.ogg new file mode 100644 index 0000000000..d4aa8d1d13 Binary files /dev/null and b/modular_citadel/sound/vox/threat.ogg differ diff --git a/modular_citadel/sound/vox/three.ogg b/modular_citadel/sound/vox/three.ogg new file mode 100644 index 0000000000..72bab5ff6b Binary files /dev/null and b/modular_citadel/sound/vox/three.ogg differ diff --git a/modular_citadel/sound/vox/through.ogg b/modular_citadel/sound/vox/through.ogg new file mode 100644 index 0000000000..9f527f38c7 Binary files /dev/null and b/modular_citadel/sound/vox/through.ogg differ diff --git a/modular_citadel/sound/vox/time.ogg b/modular_citadel/sound/vox/time.ogg new file mode 100644 index 0000000000..ff32baa603 Binary files /dev/null and b/modular_citadel/sound/vox/time.ogg differ diff --git a/modular_citadel/sound/vox/to.ogg b/modular_citadel/sound/vox/to.ogg new file mode 100644 index 0000000000..9e7f76c84d Binary files /dev/null and b/modular_citadel/sound/vox/to.ogg differ diff --git a/modular_citadel/sound/vox/top.ogg b/modular_citadel/sound/vox/top.ogg new file mode 100644 index 0000000000..bc6b0bce22 Binary files /dev/null and b/modular_citadel/sound/vox/top.ogg differ diff --git a/modular_citadel/sound/vox/topside.ogg b/modular_citadel/sound/vox/topside.ogg new file mode 100644 index 0000000000..34dfaf4405 Binary files /dev/null and b/modular_citadel/sound/vox/topside.ogg differ diff --git a/modular_citadel/sound/vox/touch.ogg b/modular_citadel/sound/vox/touch.ogg new file mode 100644 index 0000000000..fe34a1b083 Binary files /dev/null and b/modular_citadel/sound/vox/touch.ogg differ diff --git a/modular_citadel/sound/vox/towards.ogg b/modular_citadel/sound/vox/towards.ogg new file mode 100644 index 0000000000..edb2bf04d1 Binary files /dev/null and b/modular_citadel/sound/vox/towards.ogg differ diff --git a/modular_citadel/sound/vox/track.ogg b/modular_citadel/sound/vox/track.ogg new file mode 100644 index 0000000000..447d1f6982 Binary files /dev/null and b/modular_citadel/sound/vox/track.ogg differ diff --git a/modular_citadel/sound/vox/train.ogg b/modular_citadel/sound/vox/train.ogg new file mode 100644 index 0000000000..e4b78fe638 Binary files /dev/null and b/modular_citadel/sound/vox/train.ogg differ diff --git a/modular_citadel/sound/vox/transportation.ogg b/modular_citadel/sound/vox/transportation.ogg new file mode 100644 index 0000000000..78d2122ccb Binary files /dev/null and b/modular_citadel/sound/vox/transportation.ogg differ diff --git a/modular_citadel/sound/vox/truck.ogg b/modular_citadel/sound/vox/truck.ogg new file mode 100644 index 0000000000..5822f17d83 Binary files /dev/null and b/modular_citadel/sound/vox/truck.ogg differ diff --git a/modular_citadel/sound/vox/tunnel.ogg b/modular_citadel/sound/vox/tunnel.ogg new file mode 100644 index 0000000000..3264b41496 Binary files /dev/null and b/modular_citadel/sound/vox/tunnel.ogg differ diff --git a/modular_citadel/sound/vox/turn.ogg b/modular_citadel/sound/vox/turn.ogg new file mode 100644 index 0000000000..5a8a32cbd4 Binary files /dev/null and b/modular_citadel/sound/vox/turn.ogg differ diff --git a/modular_citadel/sound/vox/turret.ogg b/modular_citadel/sound/vox/turret.ogg new file mode 100644 index 0000000000..96d5bf6da9 Binary files /dev/null and b/modular_citadel/sound/vox/turret.ogg differ diff --git a/modular_citadel/sound/vox/twelve.ogg b/modular_citadel/sound/vox/twelve.ogg new file mode 100644 index 0000000000..2e45cf797d Binary files /dev/null and b/modular_citadel/sound/vox/twelve.ogg differ diff --git a/modular_citadel/sound/vox/twenty.ogg b/modular_citadel/sound/vox/twenty.ogg new file mode 100644 index 0000000000..c54922a384 Binary files /dev/null and b/modular_citadel/sound/vox/twenty.ogg differ diff --git a/modular_citadel/sound/vox/two.ogg b/modular_citadel/sound/vox/two.ogg new file mode 100644 index 0000000000..e1abe93d97 Binary files /dev/null and b/modular_citadel/sound/vox/two.ogg differ diff --git a/modular_citadel/sound/vox/unauthorized.ogg b/modular_citadel/sound/vox/unauthorized.ogg new file mode 100644 index 0000000000..2238e09696 Binary files /dev/null and b/modular_citadel/sound/vox/unauthorized.ogg differ diff --git a/modular_citadel/sound/vox/under.ogg b/modular_citadel/sound/vox/under.ogg new file mode 100644 index 0000000000..8445ce571a Binary files /dev/null and b/modular_citadel/sound/vox/under.ogg differ diff --git a/modular_citadel/sound/vox/uniform.ogg b/modular_citadel/sound/vox/uniform.ogg new file mode 100644 index 0000000000..6d3029ed7f Binary files /dev/null and b/modular_citadel/sound/vox/uniform.ogg differ diff --git a/modular_citadel/sound/vox/unlocked.ogg b/modular_citadel/sound/vox/unlocked.ogg new file mode 100644 index 0000000000..1f66ba7003 Binary files /dev/null and b/modular_citadel/sound/vox/unlocked.ogg differ diff --git a/modular_citadel/sound/vox/until.ogg b/modular_citadel/sound/vox/until.ogg new file mode 100644 index 0000000000..00e1417aaa Binary files /dev/null and b/modular_citadel/sound/vox/until.ogg differ diff --git a/modular_citadel/sound/vox/up.ogg b/modular_citadel/sound/vox/up.ogg new file mode 100644 index 0000000000..31d9dd13cc Binary files /dev/null and b/modular_citadel/sound/vox/up.ogg differ diff --git a/modular_citadel/sound/vox/upper.ogg b/modular_citadel/sound/vox/upper.ogg new file mode 100644 index 0000000000..c26d7450ed Binary files /dev/null and b/modular_citadel/sound/vox/upper.ogg differ diff --git a/modular_citadel/sound/vox/uranium.ogg b/modular_citadel/sound/vox/uranium.ogg new file mode 100644 index 0000000000..8eeed7b34e Binary files /dev/null and b/modular_citadel/sound/vox/uranium.ogg differ diff --git a/modular_citadel/sound/vox/us.ogg b/modular_citadel/sound/vox/us.ogg new file mode 100644 index 0000000000..1d0cc90667 Binary files /dev/null and b/modular_citadel/sound/vox/us.ogg differ diff --git a/modular_citadel/sound/vox/usa.ogg b/modular_citadel/sound/vox/usa.ogg new file mode 100644 index 0000000000..2a057059f7 Binary files /dev/null and b/modular_citadel/sound/vox/usa.ogg differ diff --git a/modular_citadel/sound/vox/use.ogg b/modular_citadel/sound/vox/use.ogg new file mode 100644 index 0000000000..6fdb0d2f51 Binary files /dev/null and b/modular_citadel/sound/vox/use.ogg differ diff --git a/modular_citadel/sound/vox/used.ogg b/modular_citadel/sound/vox/used.ogg new file mode 100644 index 0000000000..126ab4cce3 Binary files /dev/null and b/modular_citadel/sound/vox/used.ogg differ diff --git a/modular_citadel/sound/vox/user.ogg b/modular_citadel/sound/vox/user.ogg new file mode 100644 index 0000000000..fa99d50a09 Binary files /dev/null and b/modular_citadel/sound/vox/user.ogg differ diff --git a/modular_citadel/sound/vox/vacate.ogg b/modular_citadel/sound/vox/vacate.ogg new file mode 100644 index 0000000000..1eadec9832 Binary files /dev/null and b/modular_citadel/sound/vox/vacate.ogg differ diff --git a/modular_citadel/sound/vox/valid.ogg b/modular_citadel/sound/vox/valid.ogg new file mode 100644 index 0000000000..5ec3b93b3b Binary files /dev/null and b/modular_citadel/sound/vox/valid.ogg differ diff --git a/modular_citadel/sound/vox/vapor.ogg b/modular_citadel/sound/vox/vapor.ogg new file mode 100644 index 0000000000..9ceb555e77 Binary files /dev/null and b/modular_citadel/sound/vox/vapor.ogg differ diff --git a/modular_citadel/sound/vox/vent.ogg b/modular_citadel/sound/vox/vent.ogg new file mode 100644 index 0000000000..47f37d441f Binary files /dev/null and b/modular_citadel/sound/vox/vent.ogg differ diff --git a/modular_citadel/sound/vox/ventillation.ogg b/modular_citadel/sound/vox/ventillation.ogg new file mode 100644 index 0000000000..a8e9928e7c Binary files /dev/null and b/modular_citadel/sound/vox/ventillation.ogg differ diff --git a/modular_citadel/sound/vox/victor.ogg b/modular_citadel/sound/vox/victor.ogg new file mode 100644 index 0000000000..686b6fd7cd Binary files /dev/null and b/modular_citadel/sound/vox/victor.ogg differ diff --git a/modular_citadel/sound/vox/violated.ogg b/modular_citadel/sound/vox/violated.ogg new file mode 100644 index 0000000000..01ebe6a2de Binary files /dev/null and b/modular_citadel/sound/vox/violated.ogg differ diff --git a/modular_citadel/sound/vox/violation.ogg b/modular_citadel/sound/vox/violation.ogg new file mode 100644 index 0000000000..2d9e1b6fbe Binary files /dev/null and b/modular_citadel/sound/vox/violation.ogg differ diff --git a/modular_citadel/sound/vox/voltage.ogg b/modular_citadel/sound/vox/voltage.ogg new file mode 100644 index 0000000000..64417b2556 Binary files /dev/null and b/modular_citadel/sound/vox/voltage.ogg differ diff --git a/modular_citadel/sound/vox/vox_login.ogg b/modular_citadel/sound/vox/vox_login.ogg new file mode 100644 index 0000000000..5c406191a2 Binary files /dev/null and b/modular_citadel/sound/vox/vox_login.ogg differ diff --git a/modular_citadel/sound/vox/walk.ogg b/modular_citadel/sound/vox/walk.ogg new file mode 100644 index 0000000000..6d4cebd36c Binary files /dev/null and b/modular_citadel/sound/vox/walk.ogg differ diff --git a/modular_citadel/sound/vox/wall.ogg b/modular_citadel/sound/vox/wall.ogg new file mode 100644 index 0000000000..8f34bb6fdd Binary files /dev/null and b/modular_citadel/sound/vox/wall.ogg differ diff --git a/modular_citadel/sound/vox/want.ogg b/modular_citadel/sound/vox/want.ogg new file mode 100644 index 0000000000..b307dbfdc6 Binary files /dev/null and b/modular_citadel/sound/vox/want.ogg differ diff --git a/modular_citadel/sound/vox/wanted.ogg b/modular_citadel/sound/vox/wanted.ogg new file mode 100644 index 0000000000..a783e64ee2 Binary files /dev/null and b/modular_citadel/sound/vox/wanted.ogg differ diff --git a/modular_citadel/sound/vox/warm.ogg b/modular_citadel/sound/vox/warm.ogg new file mode 100644 index 0000000000..00fbe521b1 Binary files /dev/null and b/modular_citadel/sound/vox/warm.ogg differ diff --git a/modular_citadel/sound/vox/warn.ogg b/modular_citadel/sound/vox/warn.ogg new file mode 100644 index 0000000000..931ae208c6 Binary files /dev/null and b/modular_citadel/sound/vox/warn.ogg differ diff --git a/modular_citadel/sound/vox/warning.ogg b/modular_citadel/sound/vox/warning.ogg new file mode 100644 index 0000000000..e237c5e0ae Binary files /dev/null and b/modular_citadel/sound/vox/warning.ogg differ diff --git a/modular_citadel/sound/vox/waste.ogg b/modular_citadel/sound/vox/waste.ogg new file mode 100644 index 0000000000..7152c80fc8 Binary files /dev/null and b/modular_citadel/sound/vox/waste.ogg differ diff --git a/modular_citadel/sound/vox/water.ogg b/modular_citadel/sound/vox/water.ogg new file mode 100644 index 0000000000..fdced84c63 Binary files /dev/null and b/modular_citadel/sound/vox/water.ogg differ diff --git a/modular_citadel/sound/vox/we.ogg b/modular_citadel/sound/vox/we.ogg new file mode 100644 index 0000000000..f31d0c34d3 Binary files /dev/null and b/modular_citadel/sound/vox/we.ogg differ diff --git a/modular_citadel/sound/vox/weapon.ogg b/modular_citadel/sound/vox/weapon.ogg new file mode 100644 index 0000000000..fcf4b8bf07 Binary files /dev/null and b/modular_citadel/sound/vox/weapon.ogg differ diff --git a/modular_citadel/sound/vox/west.ogg b/modular_citadel/sound/vox/west.ogg new file mode 100644 index 0000000000..35eb23ac27 Binary files /dev/null and b/modular_citadel/sound/vox/west.ogg differ diff --git a/modular_citadel/sound/vox/whiskey.ogg b/modular_citadel/sound/vox/whiskey.ogg new file mode 100644 index 0000000000..53102ef546 Binary files /dev/null and b/modular_citadel/sound/vox/whiskey.ogg differ diff --git a/modular_citadel/sound/vox/white.ogg b/modular_citadel/sound/vox/white.ogg new file mode 100644 index 0000000000..b9c2c6e8fb Binary files /dev/null and b/modular_citadel/sound/vox/white.ogg differ diff --git a/modular_citadel/sound/vox/wilco.ogg b/modular_citadel/sound/vox/wilco.ogg new file mode 100644 index 0000000000..08f1b38f60 Binary files /dev/null and b/modular_citadel/sound/vox/wilco.ogg differ diff --git a/modular_citadel/sound/vox/will.ogg b/modular_citadel/sound/vox/will.ogg new file mode 100644 index 0000000000..8b11eec8d5 Binary files /dev/null and b/modular_citadel/sound/vox/will.ogg differ diff --git a/modular_citadel/sound/vox/with.ogg b/modular_citadel/sound/vox/with.ogg new file mode 100644 index 0000000000..100131ddfd Binary files /dev/null and b/modular_citadel/sound/vox/with.ogg differ diff --git a/modular_citadel/sound/vox/without.ogg b/modular_citadel/sound/vox/without.ogg new file mode 100644 index 0000000000..5e6b99206f Binary files /dev/null and b/modular_citadel/sound/vox/without.ogg differ diff --git a/modular_citadel/sound/vox/woop.ogg b/modular_citadel/sound/vox/woop.ogg new file mode 100644 index 0000000000..c29a975858 Binary files /dev/null and b/modular_citadel/sound/vox/woop.ogg differ diff --git a/modular_citadel/sound/vox/xeno.ogg b/modular_citadel/sound/vox/xeno.ogg new file mode 100644 index 0000000000..9230e650c7 Binary files /dev/null and b/modular_citadel/sound/vox/xeno.ogg differ diff --git a/modular_citadel/sound/vox/yankee.ogg b/modular_citadel/sound/vox/yankee.ogg new file mode 100644 index 0000000000..ea5578d28f Binary files /dev/null and b/modular_citadel/sound/vox/yankee.ogg differ diff --git a/modular_citadel/sound/vox/yards.ogg b/modular_citadel/sound/vox/yards.ogg new file mode 100644 index 0000000000..7b911ad4bd Binary files /dev/null and b/modular_citadel/sound/vox/yards.ogg differ diff --git a/modular_citadel/sound/vox/year.ogg b/modular_citadel/sound/vox/year.ogg new file mode 100644 index 0000000000..7cd1065af1 Binary files /dev/null and b/modular_citadel/sound/vox/year.ogg differ diff --git a/modular_citadel/sound/vox/yellow.ogg b/modular_citadel/sound/vox/yellow.ogg new file mode 100644 index 0000000000..87668cd45f Binary files /dev/null and b/modular_citadel/sound/vox/yellow.ogg differ diff --git a/modular_citadel/sound/vox/yes.ogg b/modular_citadel/sound/vox/yes.ogg new file mode 100644 index 0000000000..24be399de3 Binary files /dev/null and b/modular_citadel/sound/vox/yes.ogg differ diff --git a/modular_citadel/sound/vox/you.ogg b/modular_citadel/sound/vox/you.ogg new file mode 100644 index 0000000000..4a30e5c721 Binary files /dev/null and b/modular_citadel/sound/vox/you.ogg differ diff --git a/modular_citadel/sound/vox/your.ogg b/modular_citadel/sound/vox/your.ogg new file mode 100644 index 0000000000..12d49c3ded Binary files /dev/null and b/modular_citadel/sound/vox/your.ogg differ diff --git a/modular_citadel/sound/vox/yourself.ogg b/modular_citadel/sound/vox/yourself.ogg new file mode 100644 index 0000000000..03a0af6531 Binary files /dev/null and b/modular_citadel/sound/vox/yourself.ogg differ diff --git a/modular_citadel/sound/vox/zero.ogg b/modular_citadel/sound/vox/zero.ogg new file mode 100644 index 0000000000..e14f91344c Binary files /dev/null and b/modular_citadel/sound/vox/zero.ogg differ diff --git a/modular_citadel/sound/vox/zone.ogg b/modular_citadel/sound/vox/zone.ogg new file mode 100644 index 0000000000..3c8834c8f4 Binary files /dev/null and b/modular_citadel/sound/vox/zone.ogg differ diff --git a/modular_citadel/sound/vox/zulu.ogg b/modular_citadel/sound/vox/zulu.ogg new file mode 100644 index 0000000000..739cdd2187 Binary files /dev/null and b/modular_citadel/sound/vox/zulu.ogg differ diff --git a/sound/FermiChem/SoundSources.txt b/sound/FermiChem/SoundSources.txt new file mode 100644 index 0000000000..bd45f866f5 --- /dev/null +++ b/sound/FermiChem/SoundSources.txt @@ -0,0 +1,10 @@ +heatmelt.ogg - from https://freesound.org/people/toiletrolltube/sounds/181483/ + from https://freesound.org/people/MrVasLuk/sounds/304619/ + from https://freesound.org/people/Benboncan/sounds/74899/ + from bubbles2.ogg +heatacid.ogg - from https://freesound.org/people/klankbeeld/sounds/233697/ + from bubbles2.ogg + from fuse.ogg +bufferadd.ogg- https://freesound.org/people/toiletrolltube/sounds/181483/ + +Work is licensed under the Creative Commons and Attribution License. \ No newline at end of file diff --git a/sound/FermiChem/acidmelt.ogg b/sound/FermiChem/acidmelt.ogg new file mode 100644 index 0000000000..bef257be55 Binary files /dev/null and b/sound/FermiChem/acidmelt.ogg differ diff --git a/sound/FermiChem/bufferadd.ogg b/sound/FermiChem/bufferadd.ogg new file mode 100644 index 0000000000..31bc440425 Binary files /dev/null and b/sound/FermiChem/bufferadd.ogg differ diff --git a/sound/FermiChem/heatmelt.ogg b/sound/FermiChem/heatmelt.ogg new file mode 100644 index 0000000000..87dab3a18f Binary files /dev/null and b/sound/FermiChem/heatmelt.ogg differ diff --git a/sound/effects/femur_breaker.ogg b/sound/effects/femur_breaker.ogg new file mode 100644 index 0000000000..140dc0477e Binary files /dev/null and b/sound/effects/femur_breaker.ogg differ diff --git a/sound/items/towelwhip.ogg b/sound/items/towelwhip.ogg new file mode 100644 index 0000000000..49dab750a8 Binary files /dev/null and b/sound/items/towelwhip.ogg differ diff --git a/sound/items/towelwipe.ogg b/sound/items/towelwipe.ogg new file mode 100644 index 0000000000..2bee55c38d Binary files /dev/null and b/sound/items/towelwipe.ogg differ diff --git a/sound/music/flyinghigh.ogg b/sound/music/flyinghigh.ogg new file mode 100644 index 0000000000..4f1aa1458a Binary files /dev/null and b/sound/music/flyinghigh.ogg differ diff --git a/sound/music/samsara.ogg b/sound/music/samsara.ogg new file mode 100644 index 0000000000..4842aab3e5 Binary files /dev/null and b/sound/music/samsara.ogg differ diff --git a/sound/music/theend.ogg b/sound/music/theend.ogg new file mode 100644 index 0000000000..52255eee2a Binary files /dev/null and b/sound/music/theend.ogg differ diff --git a/sound/vehicles/rocketlaunch.ogg b/sound/vehicles/rocketlaunch.ogg new file mode 100644 index 0000000000..d0ee9c7248 Binary files /dev/null and b/sound/vehicles/rocketlaunch.ogg differ diff --git a/strings/redpill.json b/strings/redpill.json new file mode 100644 index 0000000000..3f65db73e7 --- /dev/null +++ b/strings/redpill.json @@ -0,0 +1,43 @@ +{ + "redpill_questions": [ + "What happened to the ceiling?", + "Why is it called the emergency shuttle if it arrives every single shift?", + "Where does the Cook get all this meat from?", + "Space wind? How does that even make sense?", + "Why does Nanotrasen hire Clowns and Mimes for every single station?", + "Why is the station's air supply connected to the plasma tank?", + "Why are there fire alarms everywhere but no sprinklers?", + "Why is this a plasma research station if we know everything about plasma already?", + "Who hires all these unqualified, violent assistants?", + "How do the morgue trays know whether someone's soul is still in their body?", + "If two miners were in Lavaland and one of them killed the other with a pickaxe, wouldn't that be fucked up or what?", + "How do I know the names of all these people that I've never met before?", + "How do I know the name of someone just by hearing them talk?", + "How come a hole in the floor doesn't suck you out into space?", + "Why is space cold?", + "Why does space circle around on itself?", + "Nanotrasen just clones us every shift.", + "There's no biological difference between lizards and humans.", + "Why is there a floor, but no roof?", + "The universe always ends after we reach Centcomm.", + "Everyone is controlled by strings behind a glowing screen", + "Seperation is absolute.", + "It doesn't take much for people to murder their friends.", + "All the crew are just greytiders with different paint.", + "What the fuck is CO2?", + "2008 was 550 years ago.", + "This is all an endless looping nightmare of misery.", + "The ultimate god is really really stoned.", + "Space stations are no substitute for healthy social interaction.", + "The gods are always watching, and will wipe you from existence if you fuck up.", + "How do mirrors give people haircuts?", + "Why is this station so poorly designed?", + "How can an escape pod only take two people normally, but an infinite number of people if they're lying down?", + "Why do only lizards get their own native language?", + "Why do people just randomly murder all their friends some shifts?", + "If magic is real, why aren't we researching that?", + "How is everyone a complete expert in every threat in the universe?", + "If suit sensors are so important, why don't they always start maximized?", + "If we can wash clothes in a sink, why do we need washing machines?" + ] +} diff --git a/strings/round_start_sounds.txt b/strings/round_start_sounds.txt index a8409188fc..c67bf6b4a6 100644 --- a/strings/round_start_sounds.txt +++ b/strings/round_start_sounds.txt @@ -22,3 +22,6 @@ sound/music/goodbyemoonmen.ogg sound/music/flytothemoon_otomatone.ogg sound/music/milkyway.ogg sound/music/rocketridersprayer.ogg +sound/music/theend.ogg +sound/music/flyinghigh.ogg +sound/music/samsara.ogg diff --git a/strings/traumas.json b/strings/traumas.json index f83a023491..45e31f2367 100644 --- a/strings/traumas.json +++ b/strings/traumas.json @@ -132,7 +132,9 @@ "ahelp help security powergaming with mindshields???", ";,g absorbing @pick(roles)", ";chemist can u @pick(create_verbs) holy @pick(mellens) for @pick(s_roles)???!!", - "@pick(semicolon) LIZZARRD SPEAKIGN IN EVIL BULL LANGUAGE SCI!!" + "@pick(semicolon) LIZZARRD SPEAKIGN IN EVIL BULL LANGUAGE SCI!!", + "@pick(semicolon)POST REBOOT MESSAGE LOLOL FUCK FUCK FUCK YOU", + "@pick(semicolon)so, i was trying to talk to someone on rp today, and then a mime walks up and pies them in the face along with some other prankster--i thought that mimes and clowns are supposed to be hired to entertain not to be a nuisance, and that if entertainment comes at someone elses expense then it's not supposed to be done. is that enough to like submit a player complaint or some shit or am i just being petty?" ], "mutations": [ @@ -295,4 +297,4 @@ "bluh daymon", "wizzerd" ] -} \ No newline at end of file +} diff --git a/tgstation.dme b/tgstation.dme index 531806171e..25daba0be6 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -41,6 +41,7 @@ #include "code\__DEFINES\cult.dm" #include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\DNA.dm" +#include "code\__DEFINES\donator_groupings.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\exports.dm" #include "code\__DEFINES\flags.dm" @@ -62,6 +63,7 @@ #include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\medal.dm" +#include "code\__DEFINES\melee.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" @@ -114,6 +116,7 @@ #include "code\__HELPERS\AStar.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\dates.dm" +#include "code\__HELPERS\donator_groupings.dm" #include "code\__HELPERS\files.dm" #include "code\__HELPERS\game.dm" #include "code\__HELPERS\global_lists.dm" @@ -158,6 +161,7 @@ #include "code\_globalvars\lists\maintenance_loot.dm" #include "code\_globalvars\lists\mapping.dm" #include "code\_globalvars\lists\medals.dm" +#include "code\_globalvars\lists\misc.dm" #include "code\_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\names.dm" #include "code\_globalvars\lists\objects.dm" @@ -217,6 +221,7 @@ #include "code\controllers\configuration\configuration.dm" #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\dbconfig.dm" +#include "code\controllers\configuration\entries\donator.dm" #include "code\controllers\configuration\entries\game_options.dm" #include "code\controllers\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" @@ -244,6 +249,7 @@ #include "code\controllers\subsystem\machines.dm" #include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\medals.dm" +#include "code\controllers\subsystem\minor_mapping.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" @@ -260,7 +266,6 @@ #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" #include "code\controllers\subsystem\spacedrift.dm" -#include "code\controllers\subsystem\squeak.dm" #include "code\controllers\subsystem\stickyban.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\tgui.dm" @@ -274,6 +279,7 @@ #include "code\controllers\subsystem\vore.dm" #include "code\controllers\subsystem\vote.dm" #include "code\controllers\subsystem\weather.dm" +#include "code\controllers\subsystem\processing\chemistry.dm" #include "code\controllers\subsystem\processing\circuit.dm" #include "code\controllers\subsystem\processing\fastprocess.dm" #include "code\controllers\subsystem\processing\fields.dm" @@ -327,6 +333,7 @@ #include "code\datums\actions\beam_rifle.dm" #include "code\datums\actions\ninja.dm" #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\mild.dm" #include "code\datums\brain_damage\phobia.dm" @@ -336,6 +343,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\armor_plate.dm" +#include "code\datums\components\bouncy.dm" #include "code\datums\components\butchering.dm" #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" @@ -424,6 +432,7 @@ #include "code\datums\diseases\advance\symptoms\headache.dm" #include "code\datums\diseases\advance\symptoms\heal.dm" #include "code\datums\diseases\advance\symptoms\itching.dm" +#include "code\datums\diseases\advance\symptoms\nanites.dm" #include "code\datums\diseases\advance\symptoms\narcolepsy.dm" #include "code\datums\diseases\advance\symptoms\oxygen.dm" #include "code\datums\diseases\advance\symptoms\sensory.dm" @@ -444,8 +453,8 @@ #include "code\datums\helper_datums\icon_snapshot.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" +#include "code\datums\looping_sounds\_looping_sound.dm" #include "code\datums\looping_sounds\item_sounds.dm" -#include "code\datums\looping_sounds\looping_sound.dm" #include "code\datums\looping_sounds\machinery_sounds.dm" #include "code\datums\looping_sounds\weather.dm" #include "code\datums\martial\boxing.dm" @@ -859,6 +868,7 @@ #include "code\game\objects\items\devices\pipe_painter.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" #include "code\game\objects\items\devices\reverse_bear_trap.dm" #include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\sensor_device.dm" @@ -966,6 +976,7 @@ #include "code\game\objects\structures\electricchair.dm" #include "code\game\objects\structures\extinguisher.dm" #include "code\game\objects\structures\false_walls.dm" +#include "code\game\objects\structures\femur_breaker.dm" #include "code\game\objects\structures\fence.dm" #include "code\game\objects\structures\fireaxe.dm" #include "code\game\objects\structures\fireplace.dm" @@ -984,6 +995,7 @@ #include "code\game\objects\structures\ladders.dm" #include "code\game\objects\structures\lattice.dm" #include "code\game\objects\structures\life_candle.dm" +#include "code\game\objects\structures\loom.dm" #include "code\game\objects\structures\manned_turret.dm" #include "code\game\objects\structures\memorial.dm" #include "code\game\objects\structures\mineral_doors.dm" @@ -1274,6 +1286,7 @@ #include "code\modules\antagonists\disease\disease_mob.dm" #include "code\modules\antagonists\ert\ert.dm" #include "code\modules\antagonists\greentext\greentext.dm" +#include "code\modules\antagonists\greybois\greybois.dm" #include "code\modules\antagonists\highlander\highlander.dm" #include "code\modules\antagonists\monkey\monkey.dm" #include "code\modules\antagonists\morph\morph.dm" @@ -1451,6 +1464,7 @@ #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" +#include "code\modules\client\darkmode.dm" #include "code\modules\client\message.dm" #include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" @@ -1544,7 +1558,6 @@ #include "code\modules\crafting\recipes.dm" #include "code\modules\detectivework\detective_work.dm" #include "code\modules\detectivework\evidence.dm" -#include "code\modules\detectivework\footprints_and_rag.dm" #include "code\modules\detectivework\scanner.dm" #include "code\modules\emoji\emoji_parse.dm" #include "code\modules\error_handler\error_handler.dm" @@ -1710,6 +1723,7 @@ #include "code\modules\hydroponics\grown\citrus.dm" #include "code\modules\hydroponics\grown\cocoa_vanilla.dm" #include "code\modules\hydroponics\grown\corn.dm" +#include "code\modules\hydroponics\grown\cotton.dm" #include "code\modules\hydroponics\grown\eggplant.dm" #include "code\modules\hydroponics\grown\flowers.dm" #include "code\modules\hydroponics\grown\grass_carpet.dm" @@ -1719,6 +1733,7 @@ #include "code\modules\hydroponics\grown\mushrooms.dm" #include "code\modules\hydroponics\grown\nettle.dm" #include "code\modules\hydroponics\grown\onion.dm" +#include "code\modules\hydroponics\grown\peach.dm" #include "code\modules\hydroponics\grown\peanuts.dm" #include "code\modules\hydroponics\grown\pineapple.dm" #include "code\modules\hydroponics\grown\potato.dm" @@ -2079,6 +2094,7 @@ #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\say.dm" #include "code\modules\mob\living\simple_animal\animal_defense.dm" +#include "code\modules\mob\living\simple_animal\astral.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\damage_procs.dm" @@ -2497,6 +2513,7 @@ #include "code\modules\reagents\reagent_containers\medspray.dm" #include "code\modules\reagents\reagent_containers\patch.dm" #include "code\modules\reagents\reagent_containers\pill.dm" +#include "code\modules\reagents\reagent_containers\rags.dm" #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\recycling\conveyor2.dm" @@ -2693,6 +2710,7 @@ #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\core_removal.dm" #include "code\modules\surgery\dental_implant.dm" +#include "code\modules\surgery\embalming.dm" #include "code\modules\surgery\eye_surgery.dm" #include "code\modules\surgery\helpers.dm" #include "code\modules\surgery\implant_removal.dm" @@ -2714,6 +2732,7 @@ #include "code\modules\surgery\advanced\pacification.dm" #include "code\modules\surgery\advanced\reconstruction.dm" #include "code\modules\surgery\advanced\revival.dm" +#include "code\modules\surgery\advanced\toxichealing.dm" #include "code\modules\surgery\advanced\viral_bonding.dm" #include "code\modules\surgery\advanced\bioware\bioware.dm" #include "code\modules\surgery\advanced\bioware\bioware_surgery.dm" @@ -2828,6 +2847,7 @@ #include "modular_citadel\code\_onclick\item_attack.dm" #include "modular_citadel\code\_onclick\other_mobs.dm" #include "modular_citadel\code\_onclick\hud\screen_objects.dm" +#include "modular_citadel\code\_onclick\hud\sprint.dm" #include "modular_citadel\code\_onclick\hud\stamina.dm" #include "modular_citadel\code\controllers\configuration\entries\general.dm" #include "modular_citadel\code\controllers\subsystem\job.dm" @@ -2835,11 +2855,14 @@ #include "modular_citadel\code\datums\components\material_container.dm" #include "modular_citadel\code\datums\components\phantomthief.dm" #include "modular_citadel\code\datums\components\souldeath.dm" +#include "modular_citadel\code\datums\mood_events\chem_events.dm" #include "modular_citadel\code\datums\mood_events\generic_negative_events.dm" #include "modular_citadel\code\datums\mood_events\generic_positive_events.dm" #include "modular_citadel\code\datums\mood_events\moodular.dm" #include "modular_citadel\code\datums\mutations\hulk.dm" +#include "modular_citadel\code\datums\status_effects\chems.dm" #include "modular_citadel\code\datums\status_effects\debuffs.dm" +#include "modular_citadel\code\datums\traits\negative.dm" #include "modular_citadel\code\datums\traits\neutral.dm" #include "modular_citadel\code\datums\wires\airlock.dm" #include "modular_citadel\code\datums\wires\autoylathe.dm" @@ -2878,7 +2901,6 @@ #include "modular_citadel\code\game\objects\effects\temporary_visuals\projectiles\tracer.dm" #include "modular_citadel\code\game\objects\items\balls.dm" #include "modular_citadel\code\game\objects\items\boombox.dm" -#include "modular_citadel\code\game\objects\items\handcuffs.dm" #include "modular_citadel\code\game\objects\items\holy_weapons.dm" #include "modular_citadel\code\game\objects\items\honk.dm" #include "modular_citadel\code\game\objects\items\meat.dm" @@ -2889,10 +2911,8 @@ #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" #include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" -#include "modular_citadel\code\game\objects\items\melee\energy.dm" #include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" #include "modular_citadel\code\game\objects\items\melee\misc.dm" -#include "modular_citadel\code\game\objects\items\melee\transforming.dm" #include "modular_citadel\code\game\objects\items\robot\robot_upgrades.dm" #include "modular_citadel\code\game\objects\items\storage\firstaid.dm" #include "modular_citadel\code\game\objects\structures\tables_racks.dm" @@ -2920,13 +2940,13 @@ #include "modular_citadel\code\modules\arousal\toys\dildos.dm" #include "modular_citadel\code\modules\awaymissions\citadel_ghostrole_spawners.dm" #include "modular_citadel\code\modules\cargo\console.dm" -#include "modular_citadel\code\modules\cargo\packs.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.dm" #include "modular_citadel\code\modules\client\preferences_savefile.dm" #include "modular_citadel\code\modules\client\preferences_toggles.dm" #include "modular_citadel\code\modules\client\loadout\__donator.dm" +#include "modular_citadel\code\modules\client\loadout\_loadout.dm" #include "modular_citadel\code\modules\client\loadout\_medical.dm" #include "modular_citadel\code\modules\client\loadout\_security.dm" #include "modular_citadel\code\modules\client\loadout\_service.dm" @@ -2935,7 +2955,6 @@ #include "modular_citadel\code\modules\client\loadout\gloves.dm" #include "modular_citadel\code\modules\client\loadout\hands.dm" #include "modular_citadel\code\modules\client\loadout\head.dm" -#include "modular_citadel\code\modules\client\loadout\loadout.dm" #include "modular_citadel\code\modules\client\loadout\mask.dm" #include "modular_citadel\code\modules\client\loadout\neck.dm" #include "modular_citadel\code\modules\client\loadout\shoes.dm" @@ -2954,7 +2973,6 @@ #include "modular_citadel\code\modules\clothing\under\trek_under.dm" #include "modular_citadel\code\modules\clothing\under\turtlenecks.dm" #include "modular_citadel\code\modules\clothing\under\under.dm" -#include "modular_citadel\code\modules\crafting\recipes.dm" #include "modular_citadel\code\modules\custom_loadout\custom_items.dm" #include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm" #include "modular_citadel\code\modules\custom_loadout\read_from_file.dm" @@ -2979,16 +2997,15 @@ #include "modular_citadel\code\modules\mentor\mentorhelp.dm" #include "modular_citadel\code\modules\mentor\mentorpm.dm" #include "modular_citadel\code\modules\mentor\mentorsay.dm" -#include "modular_citadel\code\modules\mining\mine_items.dm" #include "modular_citadel\code\modules\mining\mining_ruins.dm" #include "modular_citadel\code\modules\mob\cit_emotes.dm" #include "modular_citadel\code\modules\mob\mob.dm" #include "modular_citadel\code\modules\mob\dead\new_player\sprite_accessories.dm" #include "modular_citadel\code\modules\mob\living\damage_procs.dm" #include "modular_citadel\code\modules\mob\living\living.dm" -#include "modular_citadel\code\modules\mob\living\status_procs.dm" #include "modular_citadel\code\modules\mob\living\carbon\carbon.dm" #include "modular_citadel\code\modules\mob\living\carbon\damage_procs.dm" +#include "modular_citadel\code\modules\mob\living\carbon\life.dm" #include "modular_citadel\code\modules\mob\living\carbon\reindex_screams.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm" @@ -2998,6 +3015,7 @@ #include "modular_citadel\code\modules\mob\living\carbon\human\species_types\furrypeople.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\species_types\ipc.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\species_types\jellypeople.dm" +#include "modular_citadel\code\modules\mob\living\silicon\ai\vox_sounds.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\dogborg_equipment.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\robot.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm" @@ -3015,7 +3033,6 @@ #include "modular_citadel\code\modules\projectiles\bullets\bullets\smg.dm" #include "modular_citadel\code\modules\projectiles\guns\pumpenergy.dm" #include "modular_citadel\code\modules\projectiles\guns\toys.dm" -#include "modular_citadel\code\modules\projectiles\guns\ballistic\flechette.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\handguns.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\magweapon.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\magweapon_energy.dm" @@ -3026,7 +3043,17 @@ #include "modular_citadel\code\modules\projectiles\guns\energy\laser.dm" #include "modular_citadel\code\modules\projectiles\projectile\energy.dm" #include "modular_citadel\code\modules\projectiles\projectiles\reusable.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\astrogen.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\eigentstasium.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\enlargement.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\fermi_reagents.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\healing.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\MKUltra.dm" #include "modular_citadel\code\modules\reagents\chemistry\reagents\other_reagents.dm" +#include "modular_citadel\code\modules\reagents\chemistry\reagents\SDGF.dm" +#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\reagent container\cit_kegs.dm" #include "modular_citadel\code\modules\reagents\reagent container\hypospraymkii.dm" #include "modular_citadel\code\modules\reagents\reagent container\hypovial.dm" @@ -3038,7 +3065,6 @@ #include "modular_citadel\code\modules\research\designs\xenobio_designs.dm" #include "modular_citadel\code\modules\research\designs\weapon_designs\weapon_designs.dm" #include "modular_citadel\code\modules\research\techweb\_techweb.dm" -#include "modular_citadel\code\modules\research\techweb\all_nodes.dm" #include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm" #include "modular_citadel\code\modules\vehicles\secway.dm" #include "modular_citadel\code\modules\vore\hook-defs_vr.dm" diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 2eef691676..3599ece4f4 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,21 +1,21 @@ require=function(){function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var p="function"==typeof require&&require;if(!s&&p)return p(o,!0);if(i)return i(o,!0);var u=Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n||t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0;--a){var r=this.tryEntries[a],i=r.completion;if("root"===r.tryLoc)return e("end");if(r.tryLoc<=this.prev){var o=b.call(r,"catchLoc"),s=b.call(r,"finallyLoc");if(o&&s){if(this.prev=0;--n){var a=this.tryEntries[n];if(a.tryLoc<=this.prev&&b.call(a,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),d(n),O}},"catch":function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var a=n.completion;if("throw"===a.type){var r=a.arg;d(n)}return r}}throw Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:h(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=g),O}}}("object"==typeof t?t:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,void 0!==t?t:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(t,e,n){t(129),e.exports=t(24).RegExp.escape},{129:129,24:24}],4:[function(t,e,n){e.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},{}],5:[function(t,e,n){var a=t(19);e.exports=function(t,e){if("number"!=typeof t&&"Number"!=a(t))throw TypeError(e);return+t}},{19:19}],6:[function(t,e,n){var a=t(127)("unscopables"),r=Array.prototype;void 0==r[a]&&t(43)(r,a,{}),e.exports=function(t){r[a][t]=!0}},{127:127,43:43}],7:[function(t,e,n){e.exports=function(t,e,n,a){if(!(t instanceof e)||void 0!==a&&a in t)throw TypeError(n+": incorrect invocation!");return t}},{}],8:[function(t,e,n){var a=t(52);e.exports=function(t){if(!a(t))throw TypeError(t+" is not an object!");return t}},{52:52}],9:[function(t,e,n){"use strict";var a=t(117),r=t(112),i=t(116);e.exports=[].copyWithin||function(t,e){var n=a(this),o=i(n.length),s=r(t,o),p=r(e,o),u=arguments.length>2?arguments[2]:void 0,c=Math.min((void 0===u?o:r(u,o))-p,o-s),l=1;for(s>p&&p+c>s&&(l=-1,p+=c-1,s+=c-1);c-- >0;)p in n?n[s]=n[p]:delete n[s],s+=l,p+=l;return n}},{112:112,116:116,117:117}],10:[function(t,e,n){"use strict";var a=t(117),r=t(112),i=t(116);e.exports=function(t){for(var e=a(this),n=i(e.length),o=arguments.length,s=r(o>1?arguments[1]:void 0,n),p=o>2?arguments[2]:void 0,u=void 0===p?n:r(p,n);u>s;)e[s++]=t;return e}},{112:112,116:116,117:117}],11:[function(t,e,n){var a=t(40);e.exports=function(t,e){var n=[];return a(t,!1,n.push,n,e),n}},{40:40}],12:[function(t,e,n){var a=t(115),r=t(116),i=t(112);e.exports=function(t){return function(e,n,o){var s,p=a(e),u=r(p.length),c=i(o,u);if(t&&n!=n){for(;u>c;)if(s=p[c++],s!=s)return!0}else for(;u>c;c++)if((t||c in p)&&p[c]===n)return t||c||0;return!t&&-1}}},{112:112,115:115,116:116}],13:[function(t,e,n){var a=t(26),r=t(48),i=t(117),o=t(116),s=t(16);e.exports=function(t,e){var n=1==t,p=2==t,u=3==t,c=4==t,l=6==t,d=5==t||l,f=e||s;return function(e,s,h){for(var m,g,v=i(e),b=r(v),y=a(s,h,3),_=o(b.length),x=0,w=n?f(e,_):p?f(e,0):void 0;_>x;x++)if((d||x in b)&&(m=b[x],g=y(m,x,v),t))if(n)w[x]=g;else if(g)switch(t){case 3:return!0;case 5:return m;case 6:return x;case 2:w.push(m)}else if(c)return!1;return l?-1:u||c?c:w}}},{116:116,117:117,16:16,26:26,48:48}],14:[function(t,e,n){var a=t(4),r=t(117),i=t(48),o=t(116);e.exports=function(t,e,n,s,p){a(e);var u=r(t),c=i(u),l=o(u.length),d=p?l-1:0,f=p?-1:1;if(2>n)for(;;){if(d in c){s=c[d],d+=f;break}if(d+=f,p?0>d:d>=l)throw TypeError("Reduce of empty array with no initial value")}for(;p?d>=0:l>d;d+=f)d in c&&(s=e(s,c[d],d,u));return s}},{116:116,117:117,4:4,48:48}],15:[function(t,e,n){var a=t(52),r=t(50),i=t(127)("species");e.exports=function(t){var e;return r(t)&&(e=t.constructor,"function"!=typeof e||e!==Array&&!r(e.prototype)||(e=void 0),a(e)&&(e=e[i],null===e&&(e=void 0))),void 0===e?Array:e}},{127:127,50:50,52:52}],16:[function(t,e,n){var a=t(15);e.exports=function(t,e){return new(a(t))(e)}},{15:15}],17:[function(t,e,n){"use strict";var a=t(4),r=t(52),i=t(47),o=[].slice,s={},p=function(t,e,n){if(!(e in s)){for(var a=[],r=0;e>r;r++)a[r]="a["+r+"]";s[e]=Function("F,a","return new F("+a.join(",")+")")}return s[e](t,n)};e.exports=Function.bind||function(t){var e=a(this),n=o.call(arguments,1),s=function(){var a=n.concat(o.call(arguments));return this instanceof s?p(e,a.length,a):i(e,a,t)};return r(e.prototype)&&(s.prototype=e.prototype),s}},{4:4,47:47,52:52}],18:[function(t,e,n){var a=t(19),r=t(127)("toStringTag"),i="Arguments"==a(function(){return arguments}()),o=function(t,e){try{return t[e]}catch(n){}};e.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=o(e=Object(t),r))?n:i?a(e):"Object"==(s=a(e))&&"function"==typeof e.callee?"Arguments":s}},{127:127,19:19}],19:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],20:[function(t,e,n){"use strict";var a=t(72).f,r=t(71),i=t(91),o=t(26),s=t(7),p=t(40),u=t(56),c=t(58),l=t(98),d=t(30),f=t(66).fastKey,h=t(124),m=d?"_s":"size",g=function(t,e){var n,a=f(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,u){var c=t(function(t,a){s(t,c,e,"_i"),t._t=e,t._i=r(null),t._f=void 0,t._l=void 0,t[m]=0,void 0!=a&&p(a,n,t[u],t)});return i(c.prototype,{clear:function(){for(var t=h(this,e),n=t._i,a=t._f;a;a=a.n)a.r=!0,a.p&&(a.p=a.p.n=void 0),delete n[a.i];t._f=t._l=void 0,t[m]=0},"delete":function(t){var n=h(this,e),a=g(n,t);if(a){var r=a.n,i=a.p;delete n._i[a.i],a.r=!0,i&&(i.n=r),r&&(r.p=i),n._f==a&&(n._f=r),n._l==a&&(n._l=i),n[m]--}return!!a},forEach:function(t){h(this,e);for(var n,a=o(t,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(a(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!g(h(this,e),t)}}),d&&a(c.prototype,"size",{get:function(){return h(this,e)[m]}}),c},def:function(t,e,n){var a,r,i=g(t,e);return i?i.v=n:(t._l=i={i:r=f(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[m]++,"F"!==r&&(t._i[r]=i)),t},getEntry:g,setStrong:function(t,e,n){u(t,e,function(t,n){this._t=h(t,e),this._k=n,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?c(0,n.k):"values"==e?c(0,n.v):c(0,[n.k,n.v]):(t._t=void 0,c(1))},n?"entries":"values",!n,!0),l(e)}}},{124:124,26:26,30:30,40:40,56:56,58:58,66:66,7:7,71:71,72:72,91:91,98:98}],21:[function(t,e,n){var a=t(18),r=t(11);e.exports=function(t){return function(){if(a(this)!=t)throw TypeError(t+"#toJSON isn't generic");return r(this)}}},{11:11,18:18}],22:[function(t,e,n){"use strict";var a=t(91),r=t(66).getWeak,i=t(8),o=t(52),s=t(7),p=t(40),u=t(13),c=t(42),l=t(124),d=u(5),f=u(6),h=0,m=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},v=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=v(this,t);return e?e[1]:void 0},has:function(t){return!!v(this,t)},set:function(t,e){var n=v(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=f(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,i){var u=t(function(t,a){s(t,u,e,"_i"),t._t=e,t._i=h++,t._l=void 0,void 0!=a&&p(a,n,t[i],t)});return a(u.prototype,{"delete":function(t){if(!o(t))return!1;var n=r(t);return n===!0?m(l(this,e))["delete"](t):n&&c(n,this._i)&&delete n[this._i]},has:function(t){if(!o(t))return!1;var n=r(t);return n===!0?m(l(this,e)).has(t):n&&c(n,this._i)}}),u},def:function(t,e,n){var a=r(i(e),!0);return a===!0?m(t).set(e,n):a[t._i]=n,t},ufstore:m}},{124:124,13:13,40:40,42:42,52:52,66:66,7:7,8:8,91:91}],23:[function(t,e,n){"use strict";var a=t(41),r=t(34),i=t(92),o=t(91),s=t(66),p=t(40),u=t(7),c=t(52),l=t(36),d=t(57),f=t(99),h=t(46);e.exports=function(t,e,n,m,g,v){var b=a[t],y=b,_=g?"set":"add",x=y&&y.prototype,w={},k=function(t){var e=x[t];i(x,t,"delete"==t?function(t){return v&&!c(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return v&&!c(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return v&&!c(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof y&&(v||x.forEach&&!l(function(){(new y).entries().next()}))){var S=new y,E=S[_](v?{}:-0,1)!=S,C=l(function(){S.has(1)}),P=d(function(t){new y(t)}),A=!v&&l(function(){for(var t=new y,e=5;e--;)t[_](e,e);return!t.has(-0)});P||(y=e(function(e,n){u(e,y,t);var a=h(new b,e,y);return void 0!=n&&p(n,g,a[_],a),a}),y.prototype=x,x.constructor=y),(C||A)&&(k("delete"),k("has"),g&&k("get")),(A||E)&&k(_),v&&x.clear&&delete x.clear}else y=m.getConstructor(e,t,g,_),o(y.prototype,n),s.NEED=!0;return f(y,t),w[t]=y,r(r.G+r.W+r.F*(y!=b),w),v||m.setStrong(y,t,g),y}},{34:34,36:36,40:40,41:41,46:46,52:52,57:57,66:66,7:7,91:91,92:92,99:99}],24:[function(t,e,n){var a=e.exports={version:"2.5.6"};"number"==typeof __e&&(__e=a)},{}],25:[function(t,e,n){"use strict";var a=t(72),r=t(90);e.exports=function(t,e,n){e in t?a.f(t,e,r(0,n)):t[e]=n}},{72:72,90:90}],26:[function(t,e,n){var a=t(4);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{4:4}],27:[function(t,e,n){"use strict";var a=t(36),r=Date.prototype.getTime,i=Date.prototype.toISOString,o=function(t){return t>9?t:"0"+t};e.exports=a(function(){return"0385-07-25T07:06:39.999Z"!=i.call(new Date(-5e13-1))})||!a(function(){i.call(new Date(NaN))})?function(){if(!isFinite(r.call(this)))throw RangeError("Invalid time value");var t=this,e=t.getUTCFullYear(),n=t.getUTCMilliseconds(),a=0>e?"-":e>9999?"+":"";return a+("00000"+Math.abs(e)).slice(a?-6:-4)+"-"+o(t.getUTCMonth()+1)+"-"+o(t.getUTCDate())+"T"+o(t.getUTCHours())+":"+o(t.getUTCMinutes())+":"+o(t.getUTCSeconds())+"."+(n>99?n:"0"+o(n))+"Z"}:i},{36:36}],28:[function(t,e,n){"use strict";var a=t(8),r=t(118),i="number";e.exports=function(t){if("string"!==t&&t!==i&&"default"!==t)throw TypeError("Incorrect hint");return r(a(this),t!=i)}},{118:118,8:8}],29:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],30:[function(t,e,n){e.exports=!t(36)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{36:36}],31:[function(t,e,n){var a=t(52),r=t(41).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{41:41,52:52}],32:[function(t,e,n){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},{}],33:[function(t,e,n){var a=t(81),r=t(78),i=t(82);e.exports=function(t){var e=a(t),n=r.f;if(n)for(var o,s=n(t),p=i.f,u=0;s.length>u;)p.call(t,o=s[u++])&&e.push(o);return e}},{78:78,81:81,82:82}],34:[function(t,e,n){var a=t(41),r=t(24),i=t(43),o=t(92),s=t(26),p="prototype",u=function(t,e,n){var c,l,d,f,h=t&u.F,m=t&u.G,g=t&u.S,v=t&u.P,b=t&u.B,y=m?a:g?a[e]||(a[e]={}):(a[e]||{})[p],_=m?r:r[e]||(r[e]={}),x=_[p]||(_[p]={});m&&(n=e);for(c in n)l=!h&&y&&void 0!==y[c],d=(l?y:n)[c],f=b&&l?s(d,a):v&&"function"==typeof d?s(Function.call,d):d,y&&o(y,c,d,t&u.U),_[c]!=d&&i(_,c,f),v&&x[c]!=d&&(x[c]=d)};a.core=r,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},{24:24,26:26,41:41,43:43,92:92}],35:[function(t,e,n){var a=t(127)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{127:127}],36:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],37:[function(t,e,n){"use strict";var a=t(43),r=t(92),i=t(36),o=t(29),s=t(127);e.exports=function(t,e,n){var p=s(t),u=n(o,p,""[t]),c=u[0],l=u[1];i(function(){var e={};return e[p]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,c),a(RegExp.prototype,p,2==e?function(t,e){return l.call(t,this,e)}:function(t){return l.call(t,this)}))}},{127:127,29:29,36:36,43:43,92:92}],38:[function(t,e,n){"use strict";var a=t(8);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{8:8}],39:[function(t,e,n){"use strict";function a(t,e,n,u,c,l,d,f){for(var h,m,g=c,v=0,b=d?s(d,f,3):!1;u>v;){if(v in n){if(h=b?b(n[v],v,e):n[v],m=!1,i(h)&&(m=h[p],m=void 0!==m?!!m:r(h)),m&&l>0)g=a(t,e,h,o(h.length),g,l-1)-1;else{if(g>=9007199254740991)throw TypeError();t[g]=h}g++}v++}return g}var r=t(50),i=t(52),o=t(116),s=t(26),p=t(127)("isConcatSpreadable");e.exports=a},{116:116,127:127,26:26,50:50,52:52}],40:[function(t,e,n){var a=t(26),r=t(54),i=t(49),o=t(8),s=t(116),p=t(128),u={},c={},n=e.exports=function(t,e,n,l,d){var f,h,m,g,v=d?function(){return t}:p(t),b=a(n,l,e?2:1),y=0;if("function"!=typeof v)throw TypeError(t+" is not iterable!");if(i(v)){for(f=s(t.length);f>y;y++)if(g=e?b(o(h=t[y])[0],h[1]):b(t[y]),g===u||g===c)return g}else for(m=v.call(t);!(h=m.next()).done;)if(g=r(m,b,h.value,e),g===u||g===c)return g};n.BREAK=u,n.RETURN=c},{116:116,128:128,26:26,49:49,54:54,8:8}],41:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],42:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],43:[function(t,e,n){var a=t(72),r=t(90);e.exports=t(30)?function(t,e,n){return a.f(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{30:30,72:72,90:90}],44:[function(t,e,n){var a=t(41).document;e.exports=a&&a.documentElement},{41:41}],45:[function(t,e,n){e.exports=!t(30)&&!t(36)(function(){return 7!=Object.defineProperty(t(31)("div"),"a",{get:function(){return 7}}).a})},{30:30,31:31,36:36}],46:[function(t,e,n){var a=t(52),r=t(97).set;e.exports=function(t,e,n){var i,o=e.constructor;return o!==n&&"function"==typeof o&&(i=o.prototype)!==n.prototype&&a(i)&&r&&r(t,i),t}},{52:52,97:97}],47:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],48:[function(t,e,n){var a=t(19);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{19:19}],49:[function(t,e,n){var a=t(59),r=t(127)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{127:127,59:59}],50:[function(t,e,n){var a=t(19);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{19:19}],51:[function(t,e,n){var a=t(52),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{52:52}],52:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],53:[function(t,e,n){var a=t(52),r=t(19),i=t(127)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{127:127,19:19,52:52}],54:[function(t,e,n){var a=t(8);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{8:8}],55:[function(t,e,n){"use strict";var a=t(71),r=t(90),i=t(99),o={};t(43)(o,t(127)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a(o,{next:r(1,n)}),i(t,e+" Iterator")}},{127:127,43:43,71:71,90:90,99:99}],56:[function(t,e,n){"use strict";var a=t(60),r=t(34),i=t(92),o=t(43),s=t(59),p=t(55),u=t(99),c=t(79),l=t(127)("iterator"),d=!([].keys&&"next"in[].keys()),f="@@iterator",h="keys",m="values",g=function(){return this};e.exports=function(t,e,n,v,b,y,_){p(n,e,v);var x,w,k,S=function(t){if(!d&&t in A)return A[t];switch(t){case h:return function(){return new n(this,t)};case m:return function(){return new n(this,t)}}return function(){return new n(this,t)}},E=e+" Iterator",C=b==m,P=!1,A=t.prototype,O=A[l]||A[f]||b&&A[b],T=O||S(b),R=b?C?S("entries"):T:void 0,M="Array"==e?A.entries||O:O;if(M&&(k=c(M.call(new t)),k!==Object.prototype&&k.next&&(u(k,E,!0),a||"function"==typeof k[l]||o(k,l,g))),C&&O&&O.name!==m&&(P=!0,T=function(){return O.call(this)}),a&&!_||!d&&!P&&A[l]||o(A,l,T),s[e]=T,s[E]=g,b)if(x={values:C?T:S(m),keys:y?T:S(h),entries:R},_)for(w in x)w in A||i(A,w,x[w]);else r(r.P+r.F*(d||P),e,x);return x}},{127:127,34:34,43:43,55:55,59:59,60:60,79:79,92:92,99:99}],57:[function(t,e,n){var a=t(127)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{127:127}],58:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],59:[function(t,e,n){e.exports={}},{}],60:[function(t,e,n){e.exports=!1},{}],61:[function(t,e,n){var a=Math.expm1;e.exports=!a||a(10)>22025.465794806718||a(10)<22025.465794806718||-2e-17!=a(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}:a},{}],62:[function(t,e,n){var a=t(65),r=Math.pow,i=r(2,-52),o=r(2,-23),s=r(2,127)*(2-o),p=r(2,-126),u=function(t){return t+1/i-1/i};e.exports=Math.fround||function(t){var e,n,r=Math.abs(t),c=a(t);return p>r?c*u(r/p/o)*p*o:(e=(1+o/i)*r,n=e-(e-r),n>s||n!=n?c*(1/0):c*n)}},{65:65}],63:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],64:[function(t,e,n){e.exports=Math.scale||function(t,e,n,a,r){return 0===arguments.length||t!=t||e!=e||n!=n||a!=a||r!=r?NaN:t===1/0||t===-(1/0)?t:(t-e)*(r-a)/(n-e)+a}},{}],65:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],66:[function(t,e,n){var a=t(122)("meta"),r=t(52),i=t(42),o=t(72).f,s=0,p=Object.isExtensible||function(){return!0},u=!t(36)(function(){return p(Object.preventExtensions({}))}),c=function(t){o(t,a,{value:{i:"O"+ ++s,w:{}}})},l=function(t,e){if(!r(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!i(t,a)){if(!p(t))return"F";if(!e)return"E";c(t)}return t[a].i},d=function(t,e){if(!i(t,a)){if(!p(t))return!0;if(!e)return!1;c(t)}return t[a].w},f=function(t){return u&&h.NEED&&p(t)&&!i(t,a)&&c(t),t},h=e.exports={KEY:a,NEED:!1,fastKey:l,getWeak:d,onFreeze:f}},{122:122,36:36,42:42,52:52,72:72}],67:[function(t,e,n){var a=t(159),r=t(34),i=t(101)("metadata"),o=i.store||(i.store=new(t(265))),s=function(t,e,n){var r=o.get(t);if(!r){if(!n)return;o.set(t,r=new a)}var i=r.get(e);if(!i){if(!n)return;r.set(e,i=new a)}return i},p=function(t,e,n){var a=s(e,n,!1);return void 0===a?!1:a.has(t)},u=function(t,e,n){var a=s(e,n,!1);return void 0===a?void 0:a.get(t)},c=function(t,e,n,a){s(n,a,!0).set(t,e)},l=function(t,e){var n=s(t,e,!1),a=[];return n&&n.forEach(function(t,e){a.push(e)}),a},d=function(t){return void 0===t||"symbol"==typeof t?t:t+""},f=function(t){r(r.S,"Reflect",t)};e.exports={store:o,map:s,has:p,get:u,set:c,keys:l,key:d,exp:f}},{101:101,159:159,265:265,34:34}],68:[function(t,e,n){var a=t(41),r=t(111).set,i=a.MutationObserver||a.WebKitMutationObserver,o=a.process,s=a.Promise,p="process"==t(19)(o);e.exports=function(){var t,e,n,u=function(){var a,r;for(p&&(a=o.domain)&&a.exit();t;){r=t.fn,t=t.next;try{r()}catch(i){throw t?n():e=void 0,i}}e=void 0,a&&a.enter()};if(p)n=function(){o.nextTick(u)};else if(!i||a.navigator&&a.navigator.standalone)if(s&&s.resolve){var c=s.resolve(void 0);n=function(){c.then(u)}}else n=function(){r.call(a,u)};else{var l=!0,d=document.createTextNode("");new i(u).observe(d,{characterData:!0}),n=function(){d.data=l=!l}}return function(a){var r={fn:a,next:void 0};e&&(e.next=r),t||(t=r,n()),e=r}}},{111:111,19:19,41:41}],69:[function(t,e,n){"use strict";function a(t){var e,n;this.promise=new t(function(t,a){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=a}),this.resolve=r(e),this.reject=r(n)}var r=t(4);e.exports.f=function(t){return new a(t)}},{4:4}],70:[function(t,e,n){"use strict";var a=t(81),r=t(78),i=t(82),o=t(117),s=t(48),p=Object.assign;e.exports=!p||t(36)(function(){var t={},e={},n=Symbol(),a="abcdefghijklmnopqrst";return t[n]=7,a.split("").forEach(function(t){e[t]=t}),7!=p({},t)[n]||Object.keys(p({},e)).join("")!=a})?function(t,e){for(var n=o(t),p=arguments.length,u=1,c=r.f,l=i.f;p>u;)for(var d,f=s(arguments[u++]),h=c?a(f).concat(c(f)):a(f),m=h.length,g=0;m>g;)l.call(f,d=h[g++])&&(n[d]=f[d]);return n}:p},{117:117,36:36,48:48,78:78,81:81,82:82}],71:[function(t,e,n){var a=t(8),r=t(73),i=t(32),o=t(100)("IE_PROTO"),s=function(){},p="prototype",u=function(){var e,n=t(31)("iframe"),a=i.length,r="<",o=">";for(n.style.display="none",t(44).appendChild(n),n.src="javascript:",e=n.contentWindow.document,e.open(),e.write(r+"script"+o+"document.F=Object"+r+"/script"+o),e.close(),u=e.F;a--;)delete u[p][i[a]];return u()};e.exports=Object.create||function(t,e){var n;return null!==t?(s[p]=a(t),n=new s,s[p]=null,n[o]=t):n=u(),void 0===e?n:r(n,e)}},{100:100,31:31,32:32,44:44,73:73,8:8}],72:[function(t,e,n){var a=t(8),r=t(45),i=t(118),o=Object.defineProperty;n.f=t(30)?Object.defineProperty:function(t,e,n){if(a(t),e=i(e,!0),a(n),r)try{return o(t,e,n)}catch(s){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},{118:118,30:30,45:45,8:8}],73:[function(t,e,n){var a=t(72),r=t(8),i=t(81);e.exports=t(30)?Object.defineProperties:function(t,e){r(t);for(var n,o=i(e),s=o.length,p=0;s>p;)a.f(t,n=o[p++],e[n]);return t}},{30:30,72:72,8:8,81:81}],74:[function(t,e,n){"use strict";e.exports=t(60)||!t(36)(function(){var e=Math.random();__defineSetter__.call(null,e,function(){}),delete t(41)[e]})},{36:36,41:41,60:60}],75:[function(t,e,n){var a=t(82),r=t(90),i=t(115),o=t(118),s=t(42),p=t(45),u=Object.getOwnPropertyDescriptor;n.f=t(30)?u:function(t,e){if(t=i(t),e=o(e,!0),p)try{return u(t,e)}catch(n){}return s(t,e)?r(!a.f.call(t,e),t[e]):void 0}},{115:115,118:118,30:30,42:42,45:45,82:82,90:90}],76:[function(t,e,n){var a=t(115),r=t(77).f,i={}.toString,o="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.f=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{115:115,77:77}],77:[function(t,e,n){var a=t(80),r=t(32).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return a(t,r)}},{32:32,80:80}],78:[function(t,e,n){n.f=Object.getOwnPropertySymbols},{}],79:[function(t,e,n){var a=t(42),r=t(117),i=t(100)("IE_PROTO"),o=Object.prototype;e.exports=Object.getPrototypeOf||function(t){return t=r(t),a(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?o:null}},{100:100,117:117,42:42}],80:[function(t,e,n){var a=t(42),r=t(115),i=t(12)(!1),o=t(100)("IE_PROTO");e.exports=function(t,e){var n,s=r(t),p=0,u=[];for(n in s)n!=o&&a(s,n)&&u.push(n);for(;e.length>p;)a(s,n=e[p++])&&(~i(u,n)||u.push(n));return u}},{100:100,115:115,12:12,42:42}],81:[function(t,e,n){var a=t(80),r=t(32);e.exports=Object.keys||function(t){return a(t,r)}},{32:32,80:80}],82:[function(t,e,n){n.f={}.propertyIsEnumerable},{}],83:[function(t,e,n){var a=t(34),r=t(24),i=t(36);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{24:24,34:34,36:36}],84:[function(t,e,n){var a=t(81),r=t(115),i=t(82).f;e.exports=function(t){return function(e){for(var n,o=r(e),s=a(o),p=s.length,u=0,c=[];p>u;)i.call(o,n=s[u++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{115:115,81:81,82:82}],85:[function(t,e,n){var a=t(77),r=t(78),i=t(8),o=t(41).Reflect;e.exports=o&&o.ownKeys||function(t){var e=a.f(i(t)),n=r.f;return n?e.concat(n(t)):e}},{41:41,77:77,78:78,8:8}],86:[function(t,e,n){var a=t(41).parseFloat,r=t(109).trim;e.exports=1/a(t(110)+"-0")!==-(1/0)?function(t){var e=r(t+"",3),n=a(e);return 0===n&&"-"==e.charAt(0)?-0:n}:a},{109:109,110:110,41:41}],87:[function(t,e,n){var a=t(41).parseInt,r=t(109).trim,i=t(110),o=/^[-+]?0[xX]/;e.exports=8!==a(i+"08")||22!==a(i+"0x16")?function(t,e){var n=r(t+"",3);return a(n,e>>>0||(o.test(n)?16:10))}:a},{109:109,110:110,41:41}],88:[function(t,e,n){e.exports=function(t){try{return{e:!1,v:t()}}catch(e){return{e:!0,v:e}}}},{}],89:[function(t,e,n){var a=t(8),r=t(52),i=t(69);e.exports=function(t,e){if(a(t),r(e)&&e.constructor===t)return e;var n=i.f(t),o=n.resolve;return o(e),n.promise}},{52:52,69:69,8:8}],90:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],91:[function(t,e,n){var a=t(92);e.exports=function(t,e,n){for(var r in e)a(t,r,e[r],n);return t}},{92:92}],92:[function(t,e,n){var a=t(41),r=t(43),i=t(42),o=t(122)("src"),s="toString",p=Function[s],u=(""+p).split(s);t(24).inspectSource=function(t){return p.call(t)},(e.exports=function(t,e,n,s){var p="function"==typeof n;p&&(i(n,"name")||r(n,"name",e)),t[e]!==n&&(p&&(i(n,o)||r(n,o,t[e]?""+t[e]:u.join(e+""))),t===a?t[e]=n:s?t[e]?t[e]=n:r(t,e,n):(delete t[e],r(t,e,n)))})(Function.prototype,s,function(){ -return"function"==typeof this&&this[o]||p.call(this)})},{122:122,24:24,41:41,42:42,43:43}],93:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],94:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],95:[function(t,e,n){"use strict";var a=t(34),r=t(4),i=t(26),o=t(40);e.exports=function(t){a(a.S,t,{from:function(t){var e,n,a,s,p=arguments[1];return r(this),e=void 0!==p,e&&r(p),void 0==t?new this:(n=[],e?(a=0,s=i(p,arguments[2],2),o(t,!1,function(t){n.push(s(t,a++))})):o(t,!1,n.push,n),new this(n))}})}},{26:26,34:34,4:4,40:40}],96:[function(t,e,n){"use strict";var a=t(34);e.exports=function(t){a(a.S,t,{of:function(){for(var t=arguments.length,e=Array(t);t--;)e[t]=arguments[t];return new this(e)}})}},{34:34}],97:[function(t,e,n){var a=t(52),r=t(8),i=function(t,e){if(r(t),!a(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,a){try{a=t(26)(Function.call,t(75).f(Object.prototype,"__proto__").set,2),a(e,[]),n=!(e instanceof Array)}catch(r){n=!0}return function(t,e){return i(t,e),n?t.__proto__=e:a(t,e),t}}({},!1):void 0),check:i}},{26:26,52:52,75:75,8:8}],98:[function(t,e,n){"use strict";var a=t(41),r=t(72),i=t(30),o=t(127)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.f(e,o,{configurable:!0,get:function(){return this}})}},{127:127,30:30,41:41,72:72}],99:[function(t,e,n){var a=t(72).f,r=t(42),i=t(127)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{127:127,42:42,72:72}],100:[function(t,e,n){var a=t(101)("keys"),r=t(122);e.exports=function(t){return a[t]||(a[t]=r(t))}},{101:101,122:122}],101:[function(t,e,n){var a=t(24),r=t(41),i="__core-js_shared__",o=r[i]||(r[i]={});(e.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:a.version,mode:t(60)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},{24:24,41:41,60:60}],102:[function(t,e,n){var a=t(8),r=t(4),i=t(127)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{127:127,4:4,8:8}],103:[function(t,e,n){"use strict";var a=t(36);e.exports=function(t,e){return!!t&&a(function(){e?t.call(null,function(){},1):t.call(null)})}},{36:36}],104:[function(t,e,n){var a=t(114),r=t(29);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",p=a(n),u=s.length;return 0>p||p>=u?t?"":void 0:(i=s.charCodeAt(p),55296>i||i>56319||p+1===u||(o=s.charCodeAt(p+1))<56320||o>57343?t?s.charAt(p):i:t?s.slice(p,p+2):(i-55296<<10)+(o-56320)+65536)}}},{114:114,29:29}],105:[function(t,e,n){var a=t(53),r=t(29);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{29:29,53:53}],106:[function(t,e,n){var a=t(34),r=t(36),i=t(29),o=/"/g,s=function(t,e,n,a){var r=i(t)+"",s="<"+e;return""!==n&&(s+=" "+n+'="'+(a+"").replace(o,""")+'"'),s+">"+r+""};e.exports=function(t,e){var n={};n[t]=e(s),a(a.P+a.F*r(function(){var e=""[t]('"');return e!==e.toLowerCase()||e.split('"').length>3}),"String",n)}},{29:29,34:34,36:36}],107:[function(t,e,n){var a=t(116),r=t(108),i=t(29);e.exports=function(t,e,n,o){var s=i(t)+"",p=s.length,u=void 0===n?" ":n+"",c=a(e);if(p>=c||""==u)return s;var l=c-p,d=r.call(u,Math.ceil(l/u.length));return d.length>l&&(d=d.slice(0,l)),o?d+s:s+d}},{108:108,116:116,29:29}],108:[function(t,e,n){"use strict";var a=t(114),r=t(29);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{114:114,29:29}],109:[function(t,e,n){var a=t(34),r=t(29),i=t(36),o=t(110),s="["+o+"]",p="​…",u=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e,n){var r={},s=i(function(){return!!o[t]()||p[t]()!=p}),u=r[t]=s?e(d):o[t];n&&(r[n]=u),a(a.P+a.F*s,"String",r)},d=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(u,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{110:110,29:29,34:34,36:36}],110:[function(t,e,n){e.exports=" \n\x0B\f\r   ᠎              \u2028\u2029\ufeff"},{}],111:[function(t,e,n){var a,r,i,o=t(26),s=t(47),p=t(44),u=t(31),c=t(41),l=c.process,d=c.setImmediate,f=c.clearImmediate,h=c.MessageChannel,m=c.Dispatch,g=0,v={},b="onreadystatechange",y=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},_=function(t){y.call(t.data)};d&&f||(d=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++g]=function(){s("function"==typeof t?t:Function(t),e)},a(g),g},f=function(t){delete v[t]},"process"==t(19)(l)?a=function(t){l.nextTick(o(y,t,1))}:m&&m.now?a=function(t){m.now(o(y,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=_,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",_,!1)):a=b in u("script")?function(t){p.appendChild(u("script"))[b]=function(){p.removeChild(this),y.call(t)}}:function(t){setTimeout(o(y,t,1),0)}),e.exports={set:d,clear:f}},{19:19,26:26,31:31,41:41,44:44,47:47}],112:[function(t,e,n){var a=t(114),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{114:114}],113:[function(t,e,n){var a=t(114),r=t(116);e.exports=function(t){if(void 0===t)return 0;var e=a(t),n=r(e);if(e!==n)throw RangeError("Wrong length!");return n}},{114:114,116:116}],114:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],115:[function(t,e,n){var a=t(48),r=t(29);e.exports=function(t){return a(r(t))}},{29:29,48:48}],116:[function(t,e,n){var a=t(114),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{114:114}],117:[function(t,e,n){var a=t(29);e.exports=function(t){return Object(a(t))}},{29:29}],118:[function(t,e,n){var a=t(52);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{52:52}],119:[function(t,e,n){"use strict";if(t(30)){var a=t(60),r=t(41),i=t(36),o=t(34),s=t(121),p=t(120),u=t(26),c=t(7),l=t(90),d=t(43),f=t(91),h=t(114),m=t(116),g=t(113),v=t(112),b=t(118),y=t(42),_=t(18),x=t(52),w=t(117),k=t(49),S=t(71),E=t(79),C=t(77).f,P=t(128),A=t(122),O=t(127),T=t(13),R=t(12),M=t(102),L=t(140),j=t(59),D=t(57),N=t(98),F=t(10),I=t(9),B=t(72),q=t(75),U=B.f,V=q.f,G=r.RangeError,z=r.TypeError,W=r.Uint8Array,H="ArrayBuffer",K="Shared"+H,Q="BYTES_PER_ELEMENT",Y="prototype",$=Array[Y],J=p.ArrayBuffer,X=p.DataView,Z=T(0),tt=T(2),et=T(3),nt=T(4),at=T(5),rt=T(6),it=R(!0),ot=R(!1),st=L.values,pt=L.keys,ut=L.entries,ct=$.lastIndexOf,lt=$.reduce,dt=$.reduceRight,ft=$.join,ht=$.sort,mt=$.slice,gt=$.toString,vt=$.toLocaleString,bt=O("iterator"),yt=O("toStringTag"),_t=A("typed_constructor"),xt=A("def_constructor"),wt=s.CONSTR,kt=s.TYPED,St=s.VIEW,Et="Wrong length!",Ct=T(1,function(t,e){return Rt(M(t,t[xt]),e)}),Pt=i(function(){return 1===new W(new Uint16Array([1]).buffer)[0]}),At=!!W&&!!W[Y].set&&i(function(){new W(1).set({})}),Ot=function(t,e){var n=h(t);if(0>n||n%e)throw G("Wrong offset!");return n},Tt=function(t){if(x(t)&&kt in t)return t;throw z(t+" is not a typed array!")},Rt=function(t,e){if(!(x(t)&&_t in t))throw z("It is not a typed array constructor!");return new t(e)},Mt=function(t,e){return Lt(M(t,t[xt]),e)},Lt=function(t,e){for(var n=0,a=e.length,r=Rt(t,a);a>n;)r[n]=e[n++];return r},jt=function(t,e,n){U(t,e,{get:function(){return this._d[n]}})},Dt=function(t){var e,n,a,r,i,o,s=w(t),p=arguments.length,c=p>1?arguments[1]:void 0,l=void 0!==c,d=P(s);if(void 0!=d&&!k(d)){for(o=d.call(s),a=[],e=0;!(i=o.next()).done;e++)a.push(i.value);s=a}for(l&&p>2&&(c=u(c,arguments[2],2)),e=0,n=m(s.length),r=Rt(this,n);n>e;e++)r[e]=l?c(s[e],e):s[e];return r},Nt=function(){for(var t=0,e=arguments.length,n=Rt(this,e);e>t;)n[t]=arguments[t++];return n},Ft=!!W&&i(function(){vt.call(new W(1))}),It=function(){return vt.apply(Ft?mt.call(Tt(this)):Tt(this),arguments)},Bt={copyWithin:function(t,e){return I.call(Tt(this),t,e,arguments.length>2?arguments[2]:void 0)},every:function(t){return nt(Tt(this),t,arguments.length>1?arguments[1]:void 0)},fill:function(t){return F.apply(Tt(this),arguments)},filter:function(t){return Mt(this,tt(Tt(this),t,arguments.length>1?arguments[1]:void 0))},find:function(t){return at(Tt(this),t,arguments.length>1?arguments[1]:void 0)},findIndex:function(t){return rt(Tt(this),t,arguments.length>1?arguments[1]:void 0)},forEach:function(t){Z(Tt(this),t,arguments.length>1?arguments[1]:void 0)},indexOf:function(t){return ot(Tt(this),t,arguments.length>1?arguments[1]:void 0)},includes:function(t){return it(Tt(this),t,arguments.length>1?arguments[1]:void 0)},join:function(t){return ft.apply(Tt(this),arguments)},lastIndexOf:function(t){return ct.apply(Tt(this),arguments)},map:function(t){return Ct(Tt(this),t,arguments.length>1?arguments[1]:void 0)},reduce:function(t){return lt.apply(Tt(this),arguments)},reduceRight:function(t){return dt.apply(Tt(this),arguments)},reverse:function(){for(var t,e=this,n=Tt(e).length,a=Math.floor(n/2),r=0;a>r;)t=e[r],e[r++]=e[--n],e[n]=t;return e},some:function(t){return et(Tt(this),t,arguments.length>1?arguments[1]:void 0)},sort:function(t){return ht.call(Tt(this),t)},subarray:function(t,e){var n=Tt(this),a=n.length,r=v(t,a);return new(M(n,n[xt]))(n.buffer,n.byteOffset+r*n.BYTES_PER_ELEMENT,m((void 0===e?a:v(e,a))-r))}},qt=function(t,e){return Mt(this,mt.call(Tt(this),t,e))},Ut=function(t){Tt(this);var e=Ot(arguments[1],1),n=this.length,a=w(t),r=m(a.length),i=0;if(r+e>n)throw G(Et);for(;r>i;)this[e+i]=a[i++]},Vt={entries:function(){return ut.call(Tt(this))},keys:function(){return pt.call(Tt(this))},values:function(){return st.call(Tt(this))}},Gt=function(t,e){return x(t)&&t[kt]&&"symbol"!=typeof e&&e in t&&+e+""==e+""},zt=function(t,e){return Gt(t,e=b(e,!0))?l(2,t[e]):V(t,e)},Wt=function(t,e,n){return!(Gt(t,e=b(e,!0))&&x(n)&&y(n,"value"))||y(n,"get")||y(n,"set")||n.configurable||y(n,"writable")&&!n.writable||y(n,"enumerable")&&!n.enumerable?U(t,e,n):(t[e]=n.value,t)};wt||(q.f=zt,B.f=Wt),o(o.S+o.F*!wt,"Object",{getOwnPropertyDescriptor:zt,defineProperty:Wt}),i(function(){gt.call({})})&&(gt=vt=function(){return ft.call(this)});var Ht=f({},Bt);f(Ht,Vt),d(Ht,bt,Vt.values),f(Ht,{slice:qt,set:Ut,constructor:function(){},toString:gt,toLocaleString:It}),jt(Ht,"buffer","b"),jt(Ht,"byteOffset","o"),jt(Ht,"byteLength","l"),jt(Ht,"length","e"),U(Ht,yt,{get:function(){return this[kt]}}),e.exports=function(t,e,n,p){p=!!p;var u=t+(p?"Clamped":"")+"Array",l="get"+t,f="set"+t,h=r[u],v=h||{},b=h&&E(h),y=!h||!s.ABV,w={},k=h&&h[Y],P=function(t,n){var a=t._d;return a.v[l](n*e+a.o,Pt)},A=function(t,n,a){var r=t._d;p&&(a=(a=Math.round(a))<0?0:a>255?255:255&a),r.v[f](n*e+r.o,a,Pt)},O=function(t,e){U(t,e,{get:function(){return P(this,e)},set:function(t){return A(this,e,t)},enumerable:!0})};y?(h=n(function(t,n,a,r){c(t,h,u,"_d");var i,o,s,p,l=0,f=0;if(x(n)){if(!(n instanceof J||(p=_(n))==H||p==K))return kt in n?Lt(h,n):Dt.call(h,n);i=n,f=Ot(a,e);var v=n.byteLength;if(void 0===r){if(v%e)throw G(Et);if(o=v-f,0>o)throw G(Et)}else if(o=m(r)*e,o+f>v)throw G(Et);s=o/e}else s=g(n),o=s*e,i=new J(o);for(d(t,"_d",{b:i,o:f,l:o,e:s,v:new X(i)});s>l;)O(t,l++)}),k=h[Y]=S(Ht),d(k,"constructor",h)):i(function(){h(1)})&&i(function(){new h(-1)})&&D(function(t){new h,new h(null),new h(1.5),new h(t)},!0)||(h=n(function(t,n,a,r){c(t,h,u);var i;return x(n)?n instanceof J||(i=_(n))==H||i==K?void 0!==r?new v(n,Ot(a,e),r):void 0!==a?new v(n,Ot(a,e)):new v(n):kt in n?Lt(h,n):Dt.call(h,n):new v(g(n))}),Z(b!==Function.prototype?C(v).concat(C(b)):C(v),function(t){t in h||d(h,t,v[t])}),h[Y]=k,a||(k.constructor=h));var T=k[bt],R=!!T&&("values"==T.name||void 0==T.name),M=Vt.values;d(h,_t,!0),d(k,kt,u),d(k,St,!0),d(k,xt,h),(p?new h(1)[yt]==u:yt in k)||U(k,yt,{get:function(){return u}}),w[u]=h,o(o.G+o.W+o.F*(h!=v),w),o(o.S,u,{BYTES_PER_ELEMENT:e}),o(o.S+o.F*i(function(){v.of.call(h,1)}),u,{from:Dt,of:Nt}),Q in k||d(k,Q,e),o(o.P,u,Bt),N(u),o(o.P+o.F*At,u,{set:Ut}),o(o.P+o.F*!R,u,Vt),a||k.toString==gt||(k.toString=gt),o(o.P+o.F*i(function(){new h(1).slice()}),u,{slice:qt}),o(o.P+o.F*(i(function(){return[1,2].toLocaleString()!=new h([1,2]).toLocaleString()})||!i(function(){k.toLocaleString.call([1,2])})),u,{toLocaleString:It}),j[u]=R?T:M,a||R||d(k,bt,M)}}else e.exports=function(){}},{10:10,102:102,112:112,113:113,114:114,116:116,117:117,118:118,12:12,120:120,121:121,122:122,127:127,128:128,13:13,140:140,18:18,26:26,30:30,34:34,36:36,41:41,42:42,43:43,49:49,52:52,57:57,59:59,60:60,7:7,71:71,72:72,75:75,77:77,79:79,9:9,90:90,91:91,98:98}],120:[function(t,e,n){"use strict";function a(t,e,n){var a,r,i,o=Array(n),s=8*n-e-1,p=(1<>1,c=23===e?U(2,-24)-U(2,-77):0,l=0,d=0>t||0===t&&0>1/t?1:0;for(t=q(t),t!=t||t===I?(r=t!=t?1:0,a=p):(a=V(G(t)/z),t*(i=U(2,-a))<1&&(a--,i*=2),t+=a+u>=1?c/i:c*U(2,1-u),t*i>=2&&(a++,i/=2),a+u>=p?(r=0,a=p):a+u>=1?(r=(t*i-1)*U(2,e),a+=u):(r=t*U(2,u-1)*U(2,e),a=0));e>=8;o[l++]=255&r,r/=256,e-=8);for(a=a<0;o[l++]=255&a,a/=256,s-=8);return o[--l]|=128*d,o}function r(t,e,n){var a,r=8*n-e-1,i=(1<>1,s=r-7,p=n-1,u=t[p--],c=127&u;for(u>>=7;s>0;c=256*c+t[p],p--,s-=8);for(a=c&(1<<-s)-1,c>>=-s,s+=e;s>0;a=256*a+t[p],p--,s-=8);if(0===c)c=1-o;else{if(c===i)return a?NaN:u?-I:I;a+=U(2,e),c-=o}return(u?-1:1)*a*U(2,c-e)}function i(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]}function o(t){return[255&t]}function s(t){return[255&t,t>>8&255]}function p(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]}function u(t){return a(t,52,8)}function c(t){return a(t,23,4)}function l(t,e,n){C(t[R],e,{get:function(){return this[n]}})}function d(t,e,n,a){var r=+n,i=S(r);if(i+e>t[Y])throw F(L);var o=t[Q]._b,s=i+t[$],p=o.slice(s,s+e);return a?p:p.reverse()}function f(t,e,n,a,r,i){var o=+n,s=S(o);if(s+e>t[Y])throw F(L);for(var p=t[Q]._b,u=s+t[$],c=a(+r),l=0;e>l;l++)p[u+l]=c[i?l:e-l-1]}var h=t(41),m=t(30),g=t(60),v=t(121),b=t(43),y=t(91),_=t(36),x=t(7),w=t(114),k=t(116),S=t(113),E=t(77).f,C=t(72).f,P=t(10),A=t(99),O="ArrayBuffer",T="DataView",R="prototype",M="Wrong length!",L="Wrong index!",j=h[O],D=h[T],N=h.Math,F=h.RangeError,I=h.Infinity,B=j,q=N.abs,U=N.pow,V=N.floor,G=N.log,z=N.LN2,W="buffer",H="byteLength",K="byteOffset",Q=m?"_b":W,Y=m?"_l":H,$=m?"_o":K;if(v.ABV){if(!_(function(){j(1)})||!_(function(){new j(-1)})||_(function(){return new j,new j(1.5),new j(NaN),j.name!=O})){j=function(t){return x(this,j),new B(S(t))};for(var J,X=j[R]=B[R],Z=E(B),tt=0;Z.length>tt;)(J=Z[tt++])in j||b(j,J,B[J]);g||(X.constructor=j)}var et=new D(new j(2)),nt=D[R].setInt8;et.setInt8(0,2147483648),et.setInt8(1,2147483649),(et.getInt8(0)||!et.getInt8(1))&&y(D[R],{setInt8:function(t,e){nt.call(this,t,e<<24>>24)},setUint8:function(t,e){nt.call(this,t,e<<24>>24)}},!0)}else j=function(t){x(this,j,O);var e=S(t);this._b=P.call(Array(e),0),this[Y]=e},D=function(t,e,n){x(this,D,T),x(t,j,T);var a=t[Y],r=w(e);if(0>r||r>a)throw F("Wrong offset!");if(n=void 0===n?a-r:k(n),r+n>a)throw F(M);this[Q]=t,this[$]=r,this[Y]=n},m&&(l(j,H,"_l"),l(D,W,"_b"),l(D,H,"_l"),l(D,K,"_o")),y(D[R],{getInt8:function(t){return d(this,1,t)[0]<<24>>24},getUint8:function(t){return d(this,1,t)[0]},getInt16:function(t){var e=d(this,2,t,arguments[1]);return(e[1]<<8|e[0])<<16>>16},getUint16:function(t){var e=d(this,2,t,arguments[1]);return e[1]<<8|e[0]},getInt32:function(t){return i(d(this,4,t,arguments[1]))},getUint32:function(t){return i(d(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return r(d(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return r(d(this,8,t,arguments[1]),52,8)},setInt8:function(t,e){f(this,1,t,o,e)},setUint8:function(t,e){f(this,1,t,o,e)},setInt16:function(t,e){f(this,2,t,s,e,arguments[2])},setUint16:function(t,e){f(this,2,t,s,e,arguments[2])},setInt32:function(t,e){f(this,4,t,p,e,arguments[2])},setUint32:function(t,e){f(this,4,t,p,e,arguments[2])},setFloat32:function(t,e){f(this,4,t,c,e,arguments[2])},setFloat64:function(t,e){f(this,8,t,u,e,arguments[2])}});A(j,O),A(D,T),b(D[R],v.VIEW,!0),n[O]=j,n[T]=D},{10:10,113:113,114:114,116:116,121:121,30:30,36:36,41:41,43:43,60:60,7:7,72:72,77:77,91:91,99:99}],121:[function(t,e,n){for(var a,r=t(41),i=t(43),o=t(122),s=o("typed_array"),p=o("view"),u=!(!r.ArrayBuffer||!r.DataView),c=u,l=0,d=9,f="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");d>l;)(a=r[f[l++]])?(i(a.prototype,s,!0),i(a.prototype,p,!0)):c=!1;e.exports={ABV:u,CONSTR:c,TYPED:s,VIEW:p}},{122:122,41:41,43:43}],122:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],123:[function(t,e,n){var a=t(41),r=a.navigator;e.exports=r&&r.userAgent||""},{41:41}],124:[function(t,e,n){var a=t(52);e.exports=function(t,e){if(!a(t)||t._t!==e)throw TypeError("Incompatible receiver, "+e+" required!");return t}},{52:52}],125:[function(t,e,n){var a=t(41),r=t(24),i=t(60),o=t(126),s=t(72).f;e.exports=function(t){var e=r.Symbol||(r.Symbol=i?{}:a.Symbol||{});"_"==t.charAt(0)||t in e||s(e,t,{value:o.f(t)})}},{126:126,24:24,41:41,60:60,72:72}],126:[function(t,e,n){n.f=t(127)},{127:127}],127:[function(t,e,n){var a=t(101)("wks"),r=t(122),i=t(41).Symbol,o="function"==typeof i,s=e.exports=function(t){return a[t]||(a[t]=o&&i[t]||(o?i:r)("Symbol."+t))};s.store=a},{101:101,122:122,41:41}],128:[function(t,e,n){var a=t(18),r=t(127)("iterator"),i=t(59);e.exports=t(24).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{127:127,18:18,24:24,59:59}],129:[function(t,e,n){var a=t(34),r=t(93)(/[\\^$*+?.()|[\]{}]/g,"\\$&");a(a.S,"RegExp",{escape:function(t){return r(t)}})},{34:34,93:93}],130:[function(t,e,n){var a=t(34);a(a.P,"Array",{copyWithin:t(9)}),t(6)("copyWithin")},{34:34,6:6,9:9}],131:[function(t,e,n){"use strict";var a=t(34),r=t(13)(4);a(a.P+a.F*!t(103)([].every,!0),"Array",{every:function(t){return r(this,t,arguments[1])}})},{103:103,13:13,34:34}],132:[function(t,e,n){var a=t(34);a(a.P,"Array",{fill:t(10)}),t(6)("fill")},{10:10,34:34,6:6}],133:[function(t,e,n){"use strict";var a=t(34),r=t(13)(2);a(a.P+a.F*!t(103)([].filter,!0),"Array",{filter:function(t){return r(this,t,arguments[1])}})},{103:103,13:13,34:34}],134:[function(t,e,n){"use strict";var a=t(34),r=t(13)(6),i="findIndex",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{findIndex:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(6)(i)},{13:13,34:34,6:6}],135:[function(t,e,n){"use strict";var a=t(34),r=t(13)(5),i="find",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{find:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(6)(i)},{13:13,34:34,6:6}],136:[function(t,e,n){"use strict";var a=t(34),r=t(13)(0),i=t(103)([].forEach,!0);a(a.P+a.F*!i,"Array",{forEach:function(t){return r(this,t,arguments[1])}})},{103:103,13:13,34:34}],137:[function(t,e,n){"use strict";var a=t(26),r=t(34),i=t(117),o=t(54),s=t(49),p=t(116),u=t(25),c=t(128);r(r.S+r.F*!t(57)(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,r,l,d=i(t),f="function"==typeof this?this:Array,h=arguments.length,m=h>1?arguments[1]:void 0,g=void 0!==m,v=0,b=c(d);if(g&&(m=a(m,h>2?arguments[2]:void 0,2)),void 0==b||f==Array&&s(b))for(e=p(d.length),n=new f(e);e>v;v++)u(n,v,g?m(d[v],v):d[v]);else for(l=b.call(d),n=new f;!(r=l.next()).done;v++)u(n,v,g?o(l,m,[r.value,v],!0):r.value);return n.length=v,n}})},{116:116,117:117,128:128,25:25,26:26,34:34,49:49,54:54,57:57}],138:[function(t,e,n){"use strict";var a=t(34),r=t(12)(!1),i=[].indexOf,o=!!i&&1/[1].indexOf(1,-0)<0;a(a.P+a.F*(o||!t(103)(i)),"Array",{indexOf:function(t){return o?i.apply(this,arguments)||0:r(this,t,arguments[1])}})},{103:103,12:12,34:34}],139:[function(t,e,n){var a=t(34);a(a.S,"Array",{isArray:t(50)})},{34:34,50:50}],140:[function(t,e,n){"use strict";var a=t(6),r=t(58),i=t(59),o=t(115);e.exports=t(56)(Array,"Array",function(t,e){this._t=o(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,r(1)):"keys"==e?r(0,n):"values"==e?r(0,t[n]):r(0,[n,t[n]])},"values"),i.Arguments=i.Array,a("keys"),a("values"),a("entries")},{115:115,56:56,58:58,59:59,6:6}],141:[function(t,e,n){"use strict";var a=t(34),r=t(115),i=[].join;a(a.P+a.F*(t(48)!=Object||!t(103)(i)),"Array",{join:function(t){return i.call(r(this),void 0===t?",":t)}})},{103:103,115:115,34:34,48:48}],142:[function(t,e,n){"use strict";var a=t(34),r=t(115),i=t(114),o=t(116),s=[].lastIndexOf,p=!!s&&1/[1].lastIndexOf(1,-0)<0;a(a.P+a.F*(p||!t(103)(s)),"Array",{lastIndexOf:function(t){if(p)return s.apply(this,arguments)||0;var e=r(this),n=o(e.length),a=n-1;for(arguments.length>1&&(a=Math.min(a,i(arguments[1]))),0>a&&(a=n+a);a>=0;a--)if(a in e&&e[a]===t)return a||0;return-1}})},{103:103,114:114,115:115,116:116,34:34}],143:[function(t,e,n){"use strict";var a=t(34),r=t(13)(1);a(a.P+a.F*!t(103)([].map,!0),"Array",{map:function(t){return r(this,t,arguments[1])}})},{103:103,13:13,34:34}],144:[function(t,e,n){"use strict";var a=t(34),r=t(25);a(a.S+a.F*t(36)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,e=arguments.length,n=new("function"==typeof this?this:Array)(e);e>t;)r(n,t,arguments[t++]);return n.length=e,n}})},{25:25,34:34,36:36}],145:[function(t,e,n){"use strict";var a=t(34),r=t(14);a(a.P+a.F*!t(103)([].reduceRight,!0),"Array",{reduceRight:function(t){return r(this,t,arguments.length,arguments[1],!0)}})},{103:103,14:14,34:34}],146:[function(t,e,n){"use strict";var a=t(34),r=t(14);a(a.P+a.F*!t(103)([].reduce,!0),"Array",{reduce:function(t){return r(this,t,arguments.length,arguments[1],!1)}})},{103:103,14:14,34:34}],147:[function(t,e,n){"use strict";var a=t(34),r=t(44),i=t(19),o=t(112),s=t(116),p=[].slice;a(a.P+a.F*t(36)(function(){r&&p.call(r)}),"Array",{slice:function(t,e){var n=s(this.length),a=i(this);if(e=void 0===e?n:e,"Array"==a)return p.call(this,t,e);for(var r=o(t,n),u=o(e,n),c=s(u-r),l=Array(c),d=0;c>d;d++)l[d]="String"==a?this.charAt(r+d):this[r+d];return l}})},{112:112,116:116,19:19,34:34,36:36,44:44}],148:[function(t,e,n){"use strict";var a=t(34),r=t(13)(3);a(a.P+a.F*!t(103)([].some,!0),"Array",{some:function(t){return r(this,t,arguments[1])}})},{103:103,13:13,34:34}],149:[function(t,e,n){"use strict";var a=t(34),r=t(4),i=t(117),o=t(36),s=[].sort,p=[1,2,3];a(a.P+a.F*(o(function(){p.sort(void 0)})||!o(function(){p.sort(null)})||!t(103)(s)),"Array",{sort:function(t){return void 0===t?s.call(i(this)):s.call(i(this),r(t))}})},{103:103,117:117,34:34,36:36,4:4}],150:[function(t,e,n){t(98)("Array")},{98:98}],151:[function(t,e,n){var a=t(34);a(a.S,"Date",{now:function(){return(new Date).getTime()}})},{34:34}],152:[function(t,e,n){var a=t(34),r=t(27);a(a.P+a.F*(Date.prototype.toISOString!==r),"Date",{toISOString:r})},{27:27,34:34}],153:[function(t,e,n){"use strict";var a=t(34),r=t(117),i=t(118);a(a.P+a.F*t(36)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var e=r(this),n=i(e);return"number"!=typeof n||isFinite(n)?e.toISOString():null}})},{117:117,118:118,34:34,36:36}],154:[function(t,e,n){var a=t(127)("toPrimitive"),r=Date.prototype;a in r||t(43)(r,a,t(28))},{127:127,28:28,43:43}],155:[function(t,e,n){var a=Date.prototype,r="Invalid Date",i="toString",o=a[i],s=a.getTime;new Date(NaN)+""!=r&&t(92)(a,i,function(){var t=s.call(this);return t===t?o.call(this):r})},{92:92}],156:[function(t,e,n){var a=t(34);a(a.P,"Function",{bind:t(17)})},{17:17,34:34}],157:[function(t,e,n){"use strict";var a=t(52),r=t(79),i=t(127)("hasInstance"),o=Function.prototype;i in o||t(72).f(o,i,{value:function(t){if("function"!=typeof this||!a(t))return!1;if(!a(this.prototype))return t instanceof this;for(;t=r(t);)if(this.prototype===t)return!0;return!1}})},{127:127,52:52,72:72,79:79}],158:[function(t,e,n){var a=t(72).f,r=Function.prototype,i=/^\s*function ([^ (]*)/,o="name";o in r||t(30)&&a(r,o,{configurable:!0,get:function(){try{return(""+this).match(i)[1]}catch(t){return""}}})},{30:30,72:72}],159:[function(t,e,n){"use strict";var a=t(20),r=t(124),i="Map";e.exports=t(23)(i,function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var e=a.getEntry(r(this,i),t);return e&&e.v},set:function(t,e){return a.def(r(this,i),0===t?0:t,e)}},a,!0)},{124:124,20:20,23:23}],160:[function(t,e,n){var a=t(34),r=t(63),i=Math.sqrt,o=Math.acosh;a(a.S+a.F*!(o&&710==Math.floor(o(Number.MAX_VALUE))&&o(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:r(t-1+i(t-1)*i(t+1))}})},{34:34,63:63}],161:[function(t,e,n){function a(t){return isFinite(t=+t)&&0!=t?0>t?-a(-t):Math.log(t+Math.sqrt(t*t+1)):t}var r=t(34),i=Math.asinh;r(r.S+r.F*!(i&&1/i(0)>0),"Math",{asinh:a})},{34:34}],162:[function(t,e,n){var a=t(34),r=Math.atanh;a(a.S+a.F*!(r&&1/r(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},{34:34}],163:[function(t,e,n){var a=t(34),r=t(65);a(a.S,"Math",{cbrt:function(t){return r(t=+t)*Math.pow(Math.abs(t),1/3)}})},{34:34,65:65}],164:[function(t,e,n){var a=t(34);a(a.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},{34:34}],165:[function(t,e,n){var a=t(34),r=Math.exp;a(a.S,"Math",{cosh:function(t){return(r(t=+t)+r(-t))/2}})},{34:34}],166:[function(t,e,n){var a=t(34),r=t(61);a(a.S+a.F*(r!=Math.expm1),"Math",{expm1:r})},{34:34,61:61}],167:[function(t,e,n){var a=t(34);a(a.S,"Math",{fround:t(62)})},{34:34,62:62}],168:[function(t,e,n){var a=t(34),r=Math.abs;a(a.S,"Math",{hypot:function(t,e){for(var n,a,i=0,o=0,s=arguments.length,p=0;s>o;)n=r(arguments[o++]),n>p?(a=p/n,i=i*a*a+1,p=n):n>0?(a=n/p,i+=a*a):i+=n;return p===1/0?1/0:p*Math.sqrt(i)}})},{34:34}],169:[function(t,e,n){var a=t(34),r=Math.imul;a(a.S+a.F*t(36)(function(){return-5!=r(4294967295,5)||2!=r.length}),"Math",{imul:function(t,e){var n=65535,a=+t,r=+e,i=n&a,o=n&r;return 0|i*o+((n&a>>>16)*o+i*(n&r>>>16)<<16>>>0)}})},{34:34,36:36}],170:[function(t,e,n){var a=t(34);a(a.S,"Math",{log10:function(t){return Math.log(t)*Math.LOG10E}})},{34:34}],171:[function(t,e,n){var a=t(34);a(a.S,"Math",{log1p:t(63)})},{34:34,63:63}],172:[function(t,e,n){var a=t(34);a(a.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},{34:34}],173:[function(t,e,n){var a=t(34);a(a.S,"Math",{sign:t(65)})},{34:34,65:65}],174:[function(t,e,n){var a=t(34),r=t(61),i=Math.exp;a(a.S+a.F*t(36)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(r(t)-r(-t))/2:(i(t-1)-i(-t-1))*(Math.E/2)}})},{34:34,36:36,61:61}],175:[function(t,e,n){var a=t(34),r=t(61),i=Math.exp;a(a.S,"Math",{tanh:function(t){var e=r(t=+t),n=r(-t);return e==1/0?1:n==1/0?-1:(e-n)/(i(t)+i(-t))}})},{34:34,61:61}],176:[function(t,e,n){var a=t(34);a(a.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},{34:34}],177:[function(t,e,n){"use strict";var a=t(41),r=t(42),i=t(19),o=t(46),s=t(118),p=t(36),u=t(77).f,c=t(75).f,l=t(72).f,d=t(109).trim,f="Number",h=a[f],m=h,g=h.prototype,v=i(t(71)(g))==f,b="trim"in String.prototype,y=function(t){var e=s(t,!1);if("string"==typeof e&&e.length>2){e=b?e.trim():d(e,3);var n,a,r,i=e.charCodeAt(0);if(43===i||45===i){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===i){switch(e.charCodeAt(1)){case 66:case 98:a=2,r=49;break;case 79:case 111:a=8,r=55;break;default:return+e}for(var o,p=e.slice(2),u=0,c=p.length;c>u;u++)if(o=p.charCodeAt(u),48>o||o>r)return NaN;return parseInt(p,a)}}return+e};if(!h(" 0o1")||!h("0b1")||h("+0x1")){h=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof h&&(v?p(function(){g.valueOf.call(n)}):i(n)!=f)?o(new m(y(e)),n,h):y(e)};for(var _,x=t(30)?u(m):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),w=0;x.length>w;w++)r(m,_=x[w])&&!r(h,_)&&l(h,_,c(m,_));h.prototype=g,g.constructor=h,t(92)(a,f,h)}},{109:109,118:118,19:19,30:30,36:36,41:41,42:42,46:46,71:71,72:72,75:75,77:77,92:92}],178:[function(t,e,n){var a=t(34);a(a.S,"Number",{EPSILON:Math.pow(2,-52)})},{34:34}],179:[function(t,e,n){var a=t(34),r=t(41).isFinite;a(a.S,"Number",{isFinite:function(t){return"number"==typeof t&&r(t)}})},{34:34,41:41}],180:[function(t,e,n){var a=t(34);a(a.S,"Number",{isInteger:t(51)})},{34:34,51:51}],181:[function(t,e,n){var a=t(34);a(a.S,"Number",{isNaN:function(t){return t!=t}})},{34:34}],182:[function(t,e,n){var a=t(34),r=t(51),i=Math.abs;a(a.S,"Number",{isSafeInteger:function(t){return r(t)&&i(t)<=9007199254740991}})},{34:34,51:51}],183:[function(t,e,n){var a=t(34);a(a.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},{34:34}],184:[function(t,e,n){var a=t(34);a(a.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},{34:34}],185:[function(t,e,n){var a=t(34),r=t(86);a(a.S+a.F*(Number.parseFloat!=r),"Number",{parseFloat:r})},{34:34,86:86}],186:[function(t,e,n){var a=t(34),r=t(87);a(a.S+a.F*(Number.parseInt!=r),"Number",{parseInt:r})},{34:34,87:87}],187:[function(t,e,n){"use strict";var a=t(34),r=t(114),i=t(5),o=t(108),s=1..toFixed,p=Math.floor,u=[0,0,0,0,0,0],c="Number.toFixed: incorrect invocation!",l="0",d=function(t,e){for(var n=-1,a=e;++n<6;)a+=t*u[n],u[n]=a%1e7,a=p(a/1e7)},f=function(t){for(var e=6,n=0;--e>=0;)n+=u[e],u[e]=p(n/t),n=n%t*1e7},h=function(){for(var t=6,e="";--t>=0;)if(""!==e||0===t||0!==u[t]){var n=u[t]+"";e=""===e?n:e+o.call(l,7-n.length)+n}return e},m=function(t,e,n){return 0===e?n:e%2===1?m(t,e-1,n*t):m(t*t,e/2,n)},g=function(t){for(var e=0,n=t;n>=4096;)e+=12,n/=4096;for(;n>=2;)e+=1,n/=2;return e};a(a.P+a.F*(!!s&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==0xde0b6b3a7640080.toFixed(0))||!t(36)(function(){s.call({})})),"Number",{toFixed:function(t){var e,n,a,s,p=i(this,c),u=r(t),v="",b=l;if(0>u||u>20)throw RangeError(c);if(p!=p)return"NaN";if(-1e21>=p||p>=1e21)return p+"";if(0>p&&(v="-",p=-p),p>1e-21)if(e=g(p*m(2,69,1))-69,n=0>e?p*m(2,-e,1):p/m(2,e,1),n*=4503599627370496,e=52-e,e>0){for(d(0,n),a=u;a>=7;)d(1e7,0),a-=7;for(d(m(10,a,1),0),a=e-1;a>=23;)f(1<<23),a-=23;f(1<0?(s=b.length,b=v+(u>=s?"0."+o.call(l,u-s)+b:b.slice(0,s-u)+"."+b.slice(s-u))):b=v+b,b}})},{108:108,114:114,34:34,36:36,5:5}],188:[function(t,e,n){"use strict";var a=t(34),r=t(36),i=t(5),o=1..toPrecision;a(a.P+a.F*(r(function(){return"1"!==o.call(1,void 0)})||!r(function(){o.call({})})),"Number",{toPrecision:function(t){var e=i(this,"Number#toPrecision: incorrect invocation!");return void 0===t?o.call(e):o.call(e,t)}})},{34:34,36:36,5:5}],189:[function(t,e,n){var a=t(34);a(a.S+a.F,"Object",{assign:t(70)})},{34:34,70:70}],190:[function(t,e,n){var a=t(34);a(a.S,"Object",{create:t(71)})},{34:34,71:71}],191:[function(t,e,n){var a=t(34);a(a.S+a.F*!t(30),"Object",{defineProperties:t(73)})},{30:30,34:34,73:73}],192:[function(t,e,n){var a=t(34);a(a.S+a.F*!t(30),"Object",{defineProperty:t(72).f})},{30:30,34:34,72:72}],193:[function(t,e,n){var a=t(52),r=t(66).onFreeze;t(83)("freeze",function(t){return function(e){return t&&a(e)?t(r(e)):e}})},{52:52,66:66,83:83}],194:[function(t,e,n){var a=t(115),r=t(75).f;t(83)("getOwnPropertyDescriptor",function(){return function(t,e){return r(a(t),e)}})},{115:115,75:75,83:83}],195:[function(t,e,n){t(83)("getOwnPropertyNames",function(){return t(76).f})},{76:76,83:83}],196:[function(t,e,n){var a=t(117),r=t(79);t(83)("getPrototypeOf",function(){return function(t){return r(a(t))}})},{117:117,79:79,83:83}],197:[function(t,e,n){var a=t(52);t(83)("isExtensible",function(t){return function(e){return a(e)?t?t(e):!0:!1}}); -},{52:52,83:83}],198:[function(t,e,n){var a=t(52);t(83)("isFrozen",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{52:52,83:83}],199:[function(t,e,n){var a=t(52);t(83)("isSealed",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{52:52,83:83}],200:[function(t,e,n){var a=t(34);a(a.S,"Object",{is:t(94)})},{34:34,94:94}],201:[function(t,e,n){var a=t(117),r=t(81);t(83)("keys",function(){return function(t){return r(a(t))}})},{117:117,81:81,83:83}],202:[function(t,e,n){var a=t(52),r=t(66).onFreeze;t(83)("preventExtensions",function(t){return function(e){return t&&a(e)?t(r(e)):e}})},{52:52,66:66,83:83}],203:[function(t,e,n){var a=t(52),r=t(66).onFreeze;t(83)("seal",function(t){return function(e){return t&&a(e)?t(r(e)):e}})},{52:52,66:66,83:83}],204:[function(t,e,n){var a=t(34);a(a.S,"Object",{setPrototypeOf:t(97).set})},{34:34,97:97}],205:[function(t,e,n){"use strict";var a=t(18),r={};r[t(127)("toStringTag")]="z",r+""!="[object z]"&&t(92)(Object.prototype,"toString",function(){return"[object "+a(this)+"]"},!0)},{127:127,18:18,92:92}],206:[function(t,e,n){var a=t(34),r=t(86);a(a.G+a.F*(parseFloat!=r),{parseFloat:r})},{34:34,86:86}],207:[function(t,e,n){var a=t(34),r=t(87);a(a.G+a.F*(parseInt!=r),{parseInt:r})},{34:34,87:87}],208:[function(t,e,n){"use strict";var a,r,i,o,s=t(60),p=t(41),u=t(26),c=t(18),l=t(34),d=t(52),f=t(4),h=t(7),m=t(40),g=t(102),v=t(111).set,b=t(68)(),y=t(69),_=t(88),x=t(123),w=t(89),k="Promise",S=p.TypeError,E=p.process,C=E&&E.versions,P=C&&C.v8||"",A=p[k],O="process"==c(E),T=function(){},R=r=y.f,M=!!function(){try{var e=A.resolve(1),n=(e.constructor={})[t(127)("species")]=function(t){t(T,T)};return(O||"function"==typeof PromiseRejectionEvent)&&e.then(T)instanceof n&&0!==P.indexOf("6.6")&&-1===x.indexOf("Chrome/66")}catch(a){}}(),L=function(t){var e;return d(t)&&"function"==typeof(e=t.then)?e:!1},j=function(t,e){if(!t._n){t._n=!0;var n=t._c;b(function(){for(var a=t._v,r=1==t._s,i=0,o=function(e){var n,i,o,s=r?e.ok:e.fail,p=e.resolve,u=e.reject,c=e.domain;try{s?(r||(2==t._h&&F(t),t._h=1),s===!0?n=a:(c&&c.enter(),n=s(a),c&&(c.exit(),o=!0)),n===e.promise?u(S("Promise-chain cycle")):(i=L(n))?i.call(n,p,u):p(n)):u(a)}catch(l){c&&!o&&c.exit(),u(l)}};n.length>i;)o(n[i++]);t._c=[],t._n=!1,e&&!t._h&&D(t)})}},D=function(t){v.call(p,function(){var e,n,a,r=t._v,i=N(t);if(i&&(e=_(function(){O?E.emit("unhandledRejection",r,t):(n=p.onunhandledrejection)?n({promise:t,reason:r}):(a=p.console)&&a.error&&a.error("Unhandled promise rejection",r)}),t._h=O||N(t)?2:1),t._a=void 0,i&&e.e)throw e.v})},N=function(t){return 1!==t._h&&0===(t._a||t._c).length},F=function(t){v.call(p,function(){var e;O?E.emit("rejectionHandled",t):(e=p.onrejectionhandled)&&e({promise:t,reason:t._v})})},I=function(t){var e=this;e._d||(e._d=!0,e=e._w||e,e._v=t,e._s=2,e._a||(e._a=e._c.slice()),j(e,!0))},B=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw S("Promise can't be resolved itself");(e=L(t))?b(function(){var a={_w:n,_d:!1};try{e.call(t,u(B,a,1),u(I,a,1))}catch(r){I.call(a,r)}}):(n._v=t,n._s=1,j(n,!1))}catch(a){I.call({_w:n,_d:!1},a)}}};M||(A=function(t){h(this,A,k,"_h"),f(t),a.call(this);try{t(u(B,this,1),u(I,this,1))}catch(e){I.call(this,e)}},a=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},a.prototype=t(91)(A.prototype,{then:function(t,e){var n=R(g(this,A));return n.ok="function"==typeof t?t:!0,n.fail="function"==typeof e&&e,n.domain=O?E.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&j(this,!1),n.promise},"catch":function(t){return this.then(void 0,t)}}),i=function(){var t=new a;this.promise=t,this.resolve=u(B,t,1),this.reject=u(I,t,1)},y.f=R=function(t){return t===A||t===o?new i(t):r(t)}),l(l.G+l.W+l.F*!M,{Promise:A}),t(99)(A,k),t(98)(k),o=t(24)[k],l(l.S+l.F*!M,k,{reject:function(t){var e=R(this),n=e.reject;return n(t),e.promise}}),l(l.S+l.F*(s||!M),k,{resolve:function(t){return w(s&&this===o?A:this,t)}}),l(l.S+l.F*!(M&&t(57)(function(t){A.all(t)["catch"](T)})),k,{all:function(t){var e=this,n=R(e),a=n.resolve,r=n.reject,i=_(function(){var n=[],i=0,o=1;m(t,!1,function(t){var s=i++,p=!1;n.push(void 0),o++,e.resolve(t).then(function(t){p||(p=!0,n[s]=t,--o||a(n))},r)}),--o||a(n)});return i.e&&r(i.v),n.promise},race:function(t){var e=this,n=R(e),a=n.reject,r=_(function(){m(t,!1,function(t){e.resolve(t).then(n.resolve,a)})});return r.e&&a(r.v),n.promise}})},{102:102,111:111,123:123,127:127,18:18,24:24,26:26,34:34,4:4,40:40,41:41,52:52,57:57,60:60,68:68,69:69,7:7,88:88,89:89,91:91,98:98,99:99}],209:[function(t,e,n){var a=t(34),r=t(4),i=t(8),o=(t(41).Reflect||{}).apply,s=Function.apply;a(a.S+a.F*!t(36)(function(){o(function(){})}),"Reflect",{apply:function(t,e,n){var a=r(t),p=i(n);return o?o(a,e,p):s.call(a,e,p)}})},{34:34,36:36,4:4,41:41,8:8}],210:[function(t,e,n){var a=t(34),r=t(71),i=t(4),o=t(8),s=t(52),p=t(36),u=t(17),c=(t(41).Reflect||{}).construct,l=p(function(){function t(){}return!(c(function(){},[],t)instanceof t)}),d=!p(function(){c(function(){})});a(a.S+a.F*(l||d),"Reflect",{construct:function(t,e){i(t),o(e);var n=arguments.length<3?t:i(arguments[2]);if(d&&!l)return c(t,e,n);if(t==n){switch(e.length){case 0:return new t;case 1:return new t(e[0]);case 2:return new t(e[0],e[1]);case 3:return new t(e[0],e[1],e[2]);case 4:return new t(e[0],e[1],e[2],e[3])}var a=[null];return a.push.apply(a,e),new(u.apply(t,a))}var p=n.prototype,f=r(s(p)?p:Object.prototype),h=Function.apply.call(t,f,e);return s(h)?h:f}})},{17:17,34:34,36:36,4:4,41:41,52:52,71:71,8:8}],211:[function(t,e,n){var a=t(72),r=t(34),i=t(8),o=t(118);r(r.S+r.F*t(36)(function(){Reflect.defineProperty(a.f({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,e,n){i(t),e=o(e,!0),i(n);try{return a.f(t,e,n),!0}catch(r){return!1}}})},{118:118,34:34,36:36,72:72,8:8}],212:[function(t,e,n){var a=t(34),r=t(75).f,i=t(8);a(a.S,"Reflect",{deleteProperty:function(t,e){var n=r(i(t),e);return n&&!n.configurable?!1:delete t[e]}})},{34:34,75:75,8:8}],213:[function(t,e,n){"use strict";var a=t(34),r=t(8),i=function(t){this._t=r(t),this._i=0;var e,n=this._k=[];for(e in t)n.push(e)};t(55)(i,"Object",function(){var t,e=this,n=e._k;do if(e._i>=n.length)return{value:void 0,done:!0};while(!((t=n[e._i++])in e._t));return{value:t,done:!1}}),a(a.S,"Reflect",{enumerate:function(t){return new i(t)}})},{34:34,55:55,8:8}],214:[function(t,e,n){var a=t(75),r=t(34),i=t(8);r(r.S,"Reflect",{getOwnPropertyDescriptor:function(t,e){return a.f(i(t),e)}})},{34:34,75:75,8:8}],215:[function(t,e,n){var a=t(34),r=t(79),i=t(8);a(a.S,"Reflect",{getPrototypeOf:function(t){return r(i(t))}})},{34:34,79:79,8:8}],216:[function(t,e,n){function a(t,e){var n,s,c=arguments.length<3?t:arguments[2];return u(t)===c?t[e]:(n=r.f(t,e))?o(n,"value")?n.value:void 0!==n.get?n.get.call(c):void 0:p(s=i(t))?a(s,e,c):void 0}var r=t(75),i=t(79),o=t(42),s=t(34),p=t(52),u=t(8);s(s.S,"Reflect",{get:a})},{34:34,42:42,52:52,75:75,79:79,8:8}],217:[function(t,e,n){var a=t(34);a(a.S,"Reflect",{has:function(t,e){return e in t}})},{34:34}],218:[function(t,e,n){var a=t(34),r=t(8),i=Object.isExtensible;a(a.S,"Reflect",{isExtensible:function(t){return r(t),i?i(t):!0}})},{34:34,8:8}],219:[function(t,e,n){var a=t(34);a(a.S,"Reflect",{ownKeys:t(85)})},{34:34,85:85}],220:[function(t,e,n){var a=t(34),r=t(8),i=Object.preventExtensions;a(a.S,"Reflect",{preventExtensions:function(t){r(t);try{return i&&i(t),!0}catch(e){return!1}}})},{34:34,8:8}],221:[function(t,e,n){var a=t(34),r=t(97);r&&a(a.S,"Reflect",{setPrototypeOf:function(t,e){r.check(t,e);try{return r.set(t,e),!0}catch(n){return!1}}})},{34:34,97:97}],222:[function(t,e,n){function a(t,e,n){var p,d,f=arguments.length<4?t:arguments[3],h=i.f(c(t),e);if(!h){if(l(d=o(t)))return a(d,e,n,f);h=u(0)}if(s(h,"value")){if(h.writable===!1||!l(f))return!1;if(p=i.f(f,e)){if(p.get||p.set||p.writable===!1)return!1;p.value=n,r.f(f,e,p)}else r.f(f,e,u(0,n));return!0}return void 0===h.set?!1:(h.set.call(f,n),!0)}var r=t(72),i=t(75),o=t(79),s=t(42),p=t(34),u=t(90),c=t(8),l=t(52);p(p.S,"Reflect",{set:a})},{34:34,42:42,52:52,72:72,75:75,79:79,8:8,90:90}],223:[function(t,e,n){var a=t(41),r=t(46),i=t(72).f,o=t(77).f,s=t(53),p=t(38),u=a.RegExp,c=u,l=u.prototype,d=/a/g,f=/a/g,h=new u(d)!==d;if(t(30)&&(!h||t(36)(function(){return f[t(127)("match")]=!1,u(d)!=d||u(f)==f||"/a/i"!=u(d,"i")}))){u=function(t,e){var n=this instanceof u,a=s(t),i=void 0===e;return!n&&a&&t.constructor===u&&i?t:r(h?new c(a&&!i?t.source:t,e):c((a=t instanceof u)?t.source:t,a&&i?p.call(t):e),n?this:l,u)};for(var m=(function(t){t in u||i(u,t,{configurable:!0,get:function(){return c[t]},set:function(e){c[t]=e}})}),g=o(c),v=0;g.length>v;)m(g[v++]);l.constructor=u,u.prototype=l,t(92)(a,"RegExp",u)}t(98)("RegExp")},{127:127,30:30,36:36,38:38,41:41,46:46,53:53,72:72,77:77,92:92,98:98}],224:[function(t,e,n){t(30)&&"g"!=/./g.flags&&t(72).f(RegExp.prototype,"flags",{configurable:!0,get:t(38)})},{30:30,38:38,72:72}],225:[function(t,e,n){t(37)("match",1,function(t,e,n){return[function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")},n]})},{37:37}],226:[function(t,e,n){t(37)("replace",2,function(t,e,n){return[function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)},n]})},{37:37}],227:[function(t,e,n){t(37)("search",1,function(t,e,n){return[function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")},n]})},{37:37}],228:[function(t,e,n){t(37)("split",2,function(e,n,a){"use strict";var r=t(53),i=a,o=[].push,s="split",p="length",u="lastIndex";if("c"=="abbc"[s](/(b)*/)[1]||4!="test"[s](/(?:)/,-1)[p]||2!="ab"[s](/(?:ab)*/)[p]||4!="."[s](/(.?)(.?)/)[p]||"."[s](/()()/)[p]>1||""[s](/.?/)[p]){var c=void 0===/()??/.exec("")[1];a=function(t,e){var n=this+"";if(void 0===t&&0===e)return[];if(!r(t))return i.call(n,t,e);var a,s,l,d,f,h=[],m=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),g=0,v=void 0===e?4294967295:e>>>0,b=RegExp(t.source,m+"g");for(c||(a=RegExp("^"+b.source+"$(?!\\s)",m));(s=b.exec(n))&&(l=s.index+s[0][p],!(l>g&&(h.push(n.slice(g,s.index)),!c&&s[p]>1&&s[0].replace(a,function(){for(f=1;f1&&s.index=v)));)b[u]===s.index&&b[u]++;return g===n[p]?(d||!b.test(""))&&h.push(""):h.push(n.slice(g)),h[p]>v?h.slice(0,v):h}}else"0"[s](void 0,0)[p]&&(a=function(t,e){return void 0===t&&0===e?[]:i.call(this,t,e)});return[function(t,r){var i=e(this),o=void 0==t?void 0:t[n];return void 0!==o?o.call(t,i,r):a.call(i+"",t,r)},a]})},{37:37,53:53}],229:[function(t,e,n){"use strict";t(224);var a=t(8),r=t(38),i=t(30),o="toString",s=/./[o],p=function(e){t(92)(RegExp.prototype,o,e,!0)};t(36)(function(){return"/a/b"!=s.call({source:"a",flags:"b"})})?p(function(){var t=a(this);return"/".concat(t.source,"/","flags"in t?t.flags:!i&&t instanceof RegExp?r.call(t):void 0)}):s.name!=o&&p(function(){return s.call(this)})},{224:224,30:30,36:36,38:38,8:8,92:92}],230:[function(t,e,n){"use strict";var a=t(20),r=t(124),i="Set";e.exports=t(23)(i,function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(r(this,i),t=0===t?0:t,t)}},a)},{124:124,20:20,23:23}],231:[function(t,e,n){"use strict";t(106)("anchor",function(t){return function(e){return t(this,"a","name",e)}})},{106:106}],232:[function(t,e,n){"use strict";t(106)("big",function(t){return function(){return t(this,"big","","")}})},{106:106}],233:[function(t,e,n){"use strict";t(106)("blink",function(t){return function(){return t(this,"blink","","")}})},{106:106}],234:[function(t,e,n){"use strict";t(106)("bold",function(t){return function(){return t(this,"b","","")}})},{106:106}],235:[function(t,e,n){"use strict";var a=t(34),r=t(104)(!1);a(a.P,"String",{codePointAt:function(t){return r(this,t)}})},{104:104,34:34}],236:[function(t,e,n){"use strict";var a=t(34),r=t(116),i=t(105),o="endsWith",s=""[o];a(a.P+a.F*t(35)(o),"String",{endsWith:function(t){var e=i(this,t,o),n=arguments.length>1?arguments[1]:void 0,a=r(e.length),p=void 0===n?a:Math.min(r(n),a),u=t+"";return s?s.call(e,u,p):e.slice(p-u.length,p)===u}})},{105:105,116:116,34:34,35:35}],237:[function(t,e,n){"use strict";t(106)("fixed",function(t){return function(){return t(this,"tt","","")}})},{106:106}],238:[function(t,e,n){"use strict";t(106)("fontcolor",function(t){return function(e){return t(this,"font","color",e)}})},{106:106}],239:[function(t,e,n){"use strict";t(106)("fontsize",function(t){return function(e){return t(this,"font","size",e)}})},{106:106}],240:[function(t,e,n){var a=t(34),r=t(112),i=String.fromCharCode,o=String.fromCodePoint;a(a.S+a.F*(!!o&&1!=o.length),"String",{fromCodePoint:function(t){for(var e,n=[],a=arguments.length,o=0;a>o;){if(e=+arguments[o++],r(e,1114111)!==e)throw RangeError(e+" is not a valid code point");n.push(65536>e?i(e):i(((e-=65536)>>10)+55296,e%1024+56320))}return n.join("")}})},{112:112,34:34}],241:[function(t,e,n){"use strict";var a=t(34),r=t(105),i="includes";a(a.P+a.F*t(35)(i),"String",{includes:function(t){return!!~r(this,t,i).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},{105:105,34:34,35:35}],242:[function(t,e,n){"use strict";t(106)("italics",function(t){return function(){return t(this,"i","","")}})},{106:106}],243:[function(t,e,n){"use strict";var a=t(104)(!0);t(56)(String,"String",function(t){this._t=t+"",this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=a(e,n),this._i+=t.length,{value:t,done:!1})})},{104:104,56:56}],244:[function(t,e,n){"use strict";t(106)("link",function(t){return function(e){return t(this,"a","href",e)}})},{106:106}],245:[function(t,e,n){var a=t(34),r=t(115),i=t(116);a(a.S,"String",{raw:function(t){for(var e=r(t.raw),n=i(e.length),a=arguments.length,o=[],s=0;n>s;)o.push(e[s++]+""),a>s&&o.push(arguments[s]+"");return o.join("")}})},{115:115,116:116,34:34}],246:[function(t,e,n){var a=t(34);a(a.P,"String",{repeat:t(108)})},{108:108,34:34}],247:[function(t,e,n){"use strict";t(106)("small",function(t){return function(){return t(this,"small","","")}})},{106:106}],248:[function(t,e,n){"use strict";var a=t(34),r=t(116),i=t(105),o="startsWith",s=""[o];a(a.P+a.F*t(35)(o),"String",{startsWith:function(t){var e=i(this,t,o),n=r(Math.min(arguments.length>1?arguments[1]:void 0,e.length)),a=t+"";return s?s.call(e,a,n):e.slice(n,n+a.length)===a}})},{105:105,116:116,34:34,35:35}],249:[function(t,e,n){"use strict";t(106)("strike",function(t){return function(){return t(this,"strike","","")}})},{106:106}],250:[function(t,e,n){"use strict";t(106)("sub",function(t){return function(){return t(this,"sub","","")}})},{106:106}],251:[function(t,e,n){"use strict";t(106)("sup",function(t){return function(){return t(this,"sup","","")}})},{106:106}],252:[function(t,e,n){"use strict";t(109)("trim",function(t){return function(){return t(this,3)}})},{109:109}],253:[function(t,e,n){"use strict";var a=t(41),r=t(42),i=t(30),o=t(34),s=t(92),p=t(66).KEY,u=t(36),c=t(101),l=t(99),d=t(122),f=t(127),h=t(126),m=t(125),g=t(33),v=t(50),b=t(8),y=t(52),_=t(115),x=t(118),w=t(90),k=t(71),S=t(76),E=t(75),C=t(72),P=t(81),A=E.f,O=C.f,T=S.f,R=a.Symbol,M=a.JSON,L=M&&M.stringify,j="prototype",D=f("_hidden"),N=f("toPrimitive"),F={}.propertyIsEnumerable,I=c("symbol-registry"),B=c("symbols"),q=c("op-symbols"),U=Object[j],V="function"==typeof R,G=a.QObject,z=!G||!G[j]||!G[j].findChild,W=i&&u(function(){return 7!=k(O({},"a",{get:function(){return O(this,"a",{value:7}).a}})).a})?function(t,e,n){var a=A(U,e);a&&delete U[e],O(t,e,n),a&&t!==U&&O(U,e,a)}:O,H=function(t){var e=B[t]=k(R[j]);return e._k=t,e},K=V&&"symbol"==typeof R.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof R},Q=function(t,e,n){return t===U&&Q(q,e,n),b(t),e=x(e,!0),b(n),r(B,e)?(n.enumerable?(r(t,D)&&t[D][e]&&(t[D][e]=!1),n=k(n,{enumerable:w(0,!1)})):(r(t,D)||O(t,D,w(1,{})),t[D][e]=!0),W(t,e,n)):O(t,e,n)},Y=function(t,e){b(t);for(var n,a=g(e=_(e)),r=0,i=a.length;i>r;)Q(t,n=a[r++],e[n]);return t},$=function(t,e){return void 0===e?k(t):Y(k(t),e)},J=function(t){var e=F.call(this,t=x(t,!0));return this===U&&r(B,t)&&!r(q,t)?!1:e||!r(this,t)||!r(B,t)||r(this,D)&&this[D][t]?e:!0},X=function(t,e){if(t=_(t),e=x(e,!0),t!==U||!r(B,e)||r(q,e)){var n=A(t,e);return!n||!r(B,e)||r(t,D)&&t[D][e]||(n.enumerable=!0),n}},Z=function(t){for(var e,n=T(_(t)),a=[],i=0;n.length>i;)r(B,e=n[i++])||e==D||e==p||a.push(e);return a},tt=function(t){for(var e,n=t===U,a=T(n?q:_(t)),i=[],o=0;a.length>o;)r(B,e=a[o++])&&(n?r(U,e):!0)&&i.push(B[e]);return i};V||(R=function(){if(this instanceof R)throw TypeError("Symbol is not a constructor!");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===U&&e.call(q,n),r(this,D)&&r(this[D],t)&&(this[D][t]=!1),W(this,t,w(1,n))};return i&&z&&W(U,t,{configurable:!0,set:e}),H(t)},s(R[j],"toString",function(){return this._k}),E.f=X,C.f=Q,t(77).f=S.f=Z,t(82).f=J,t(78).f=tt,i&&!t(60)&&s(U,"propertyIsEnumerable",J,!0),h.f=function(t){return H(f(t))}),o(o.G+o.W+o.F*!V,{Symbol:R});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)f(et[nt++]);for(var at=P(f.store),rt=0;at.length>rt;)m(at[rt++]);o(o.S+o.F*!V,"Symbol",{"for":function(t){return r(I,t+="")?I[t]:I[t]=R(t)},keyFor:function(t){if(!K(t))throw TypeError(t+" is not a symbol!");for(var e in I)if(I[e]===t)return e},useSetter:function(){z=!0},useSimple:function(){z=!1}}),o(o.S+o.F*!V,"Object",{create:$,defineProperty:Q,defineProperties:Y,getOwnPropertyDescriptor:X,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),M&&o(o.S+o.F*(!V||u(function(){var t=R();return"[null]"!=L([t])||"{}"!=L({a:t})||"{}"!=L(Object(t))})),"JSON",{stringify:function(t){for(var e,n,a=[t],r=1;arguments.length>r;)a.push(arguments[r++]);return n=e=a[1],!y(e)&&void 0===t||K(t)?void 0:(v(e)||(e=function(t,e){return"function"==typeof n&&(e=n.call(this,t,e)),K(e)?void 0:e}),a[1]=e,L.apply(M,a))}}),R[j][N]||t(43)(R[j],N,R[j].valueOf),l(R,"Symbol"),l(Math,"Math",!0),l(a.JSON,"JSON",!0)},{101:101,115:115,118:118,122:122,125:125,126:126,127:127,30:30,33:33,34:34,36:36,41:41,42:42,43:43,50:50,52:52,60:60,66:66,71:71,72:72,75:75,76:76,77:77,78:78,8:8,81:81,82:82,90:90,92:92,99:99}],254:[function(t,e,n){"use strict";var a=t(34),r=t(121),i=t(120),o=t(8),s=t(112),p=t(116),u=t(52),c=t(41).ArrayBuffer,l=t(102),d=i.ArrayBuffer,f=i.DataView,h=r.ABV&&c.isView,m=d.prototype.slice,g=r.VIEW,v="ArrayBuffer";a(a.G+a.W+a.F*(c!==d),{ArrayBuffer:d}),a(a.S+a.F*!r.CONSTR,v,{isView:function(t){return h&&h(t)||u(t)&&g in t}}),a(a.P+a.U+a.F*t(36)(function(){return!new d(2).slice(1,void 0).byteLength}),v,{slice:function(t,e){if(void 0!==m&&void 0===e)return m.call(o(this),t);for(var n=o(this).byteLength,a=s(t,n),r=s(void 0===e?n:e,n),i=new(l(this,d))(p(r-a)),u=new f(this),c=new f(i),h=0;r>a;)c.setUint8(h++,u.getUint8(a++));return i}}),t(98)(v)},{102:102,112:112,116:116,120:120,121:121,34:34,36:36,41:41,52:52,8:8,98:98}],255:[function(t,e,n){var a=t(34);a(a.G+a.W+a.F*!t(121).ABV,{DataView:t(120).DataView})},{120:120,121:121,34:34}],256:[function(t,e,n){t(119)("Float32",4,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],257:[function(t,e,n){t(119)("Float64",8,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],258:[function(t,e,n){t(119)("Int16",2,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],259:[function(t,e,n){t(119)("Int32",4,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],260:[function(t,e,n){t(119)("Int8",1,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],261:[function(t,e,n){t(119)("Uint16",2,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],262:[function(t,e,n){t(119)("Uint32",4,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],263:[function(t,e,n){t(119)("Uint8",1,function(t){return function(e,n,a){return t(this,e,n,a)}})},{119:119}],264:[function(t,e,n){t(119)("Uint8",1,function(t){return function(e,n,a){return t(this,e,n,a)}},!0)},{119:119}],265:[function(t,e,n){"use strict";var a,r=t(13)(0),i=t(92),o=t(66),s=t(70),p=t(22),u=t(52),c=t(36),l=t(124),d="WeakMap",f=o.getWeak,h=Object.isExtensible,m=p.ufstore,g={},v=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},b={get:function(t){if(u(t)){var e=f(t);return e===!0?m(l(this,d)).get(t):e?e[this._i]:void 0}},set:function(t,e){return p.def(l(this,d),t,e)}},y=e.exports=t(23)(d,v,b,p,!0,!0);c(function(){return 7!=(new y).set((Object.freeze||Object)(g),7).get(g)})&&(a=p.getConstructor(v,d),s(a.prototype,b),o.NEED=!0,r(["delete","has","get","set"],function(t){var e=y.prototype,n=e[t];i(e,t,function(e,r){if(u(e)&&!h(e)){this._f||(this._f=new a);var i=this._f[t](e,r);return"set"==t?this:i}return n.call(this,e,r)})}))},{124:124,13:13,22:22,23:23,36:36,52:52,66:66,70:70,92:92}],266:[function(t,e,n){"use strict";var a=t(22),r=t(124),i="WeakSet";t(23)(i,function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(r(this,i),t,!0)}},a,!1,!0)},{124:124,22:22,23:23}],267:[function(t,e,n){"use strict";var a=t(34),r=t(39),i=t(117),o=t(116),s=t(4),p=t(16);a(a.P,"Array",{flatMap:function(t){var e,n,a=i(this);return s(t),e=o(a.length),n=p(a,0),r(n,a,a,e,0,1,t,arguments[1]),n}}),t(6)("flatMap")},{116:116,117:117,16:16,34:34,39:39,4:4,6:6}],268:[function(t,e,n){"use strict";var a=t(34),r=t(39),i=t(117),o=t(116),s=t(114),p=t(16);a(a.P,"Array",{flatten:function(){var t=arguments[0],e=i(this),n=o(e.length),a=p(e,0);return r(a,e,e,n,0,void 0===t?1:s(t)),a}}),t(6)("flatten")},{114:114,116:116,117:117,16:16,34:34,39:39,6:6}],269:[function(t,e,n){"use strict";var a=t(34),r=t(12)(!0);a(a.P,"Array",{includes:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(6)("includes")},{12:12,34:34,6:6}],270:[function(t,e,n){var a=t(34),r=t(68)(),i=t(41).process,o="process"==t(19)(i);a(a.G,{asap:function(t){var e=o&&i.domain;r(e?e.bind(t):t)}})},{19:19,34:34,41:41,68:68}],271:[function(t,e,n){var a=t(34),r=t(19);a(a.S,"Error",{isError:function(t){return"Error"===r(t)}})},{19:19,34:34}],272:[function(t,e,n){var a=t(34);a(a.G,{global:t(41)})},{34:34,41:41}],273:[function(t,e,n){t(95)("Map")},{95:95}],274:[function(t,e,n){t(96)("Map")},{96:96}],275:[function(t,e,n){var a=t(34);a(a.P+a.R,"Map",{toJSON:t(21)("Map")})},{21:21,34:34}],276:[function(t,e,n){var a=t(34);a(a.S,"Math",{clamp:function(t,e,n){return Math.min(n,Math.max(e,t))}})},{34:34}],277:[function(t,e,n){var a=t(34);a(a.S,"Math",{DEG_PER_RAD:Math.PI/180})},{34:34}],278:[function(t,e,n){var a=t(34),r=180/Math.PI;a(a.S,"Math",{degrees:function(t){return t*r}})},{34:34}],279:[function(t,e,n){var a=t(34),r=t(64),i=t(62);a(a.S,"Math",{fscale:function(t,e,n,a,o){return i(r(t,e,n,a,o))}})},{34:34,62:62,64:64}],280:[function(t,e,n){var a=t(34);a(a.S,"Math",{iaddh:function(t,e,n,a){var r=t>>>0,i=e>>>0,o=n>>>0;return i+(a>>>0)+((r&o|(r|o)&~(r+o>>>0))>>>31)|0}})},{34:34}],281:[function(t,e,n){var a=t(34);a(a.S,"Math",{imulh:function(t,e){var n=65535,a=+t,r=+e,i=a&n,o=r&n,s=a>>16,p=r>>16,u=(s*o>>>0)+(i*o>>>16);return s*p+(u>>16)+((i*p>>>0)+(u&n)>>16)}})},{34:34}],282:[function(t,e,n){var a=t(34);a(a.S,"Math",{isubh:function(t,e,n,a){var r=t>>>0,i=e>>>0,o=n>>>0;return i-(a>>>0)-((~r&o|~(r^o)&r-o>>>0)>>>31)|0}})},{34:34}],283:[function(t,e,n){var a=t(34);a(a.S,"Math",{RAD_PER_DEG:180/Math.PI})},{34:34}],284:[function(t,e,n){var a=t(34),r=Math.PI/180;a(a.S,"Math",{radians:function(t){return t*r}})},{34:34}],285:[function(t,e,n){var a=t(34);a(a.S,"Math",{scale:t(64)})},{34:34,64:64}],286:[function(t,e,n){var a=t(34);a(a.S,"Math",{signbit:function(t){return(t=+t)!=t?t:0==t?1/t==1/0:t>0}})},{34:34}],287:[function(t,e,n){var a=t(34);a(a.S,"Math",{umulh:function(t,e){var n=65535,a=+t,r=+e,i=a&n,o=r&n,s=a>>>16,p=r>>>16,u=(s*o>>>0)+(i*o>>>16);return s*p+(u>>>16)+((i*p>>>0)+(u&n)>>>16)}})},{34:34}],288:[function(t,e,n){"use strict";var a=t(34),r=t(117),i=t(4),o=t(72);t(30)&&a(a.P+t(74),"Object",{__defineGetter__:function(t,e){o.f(r(this),t,{get:i(e),enumerable:!0,configurable:!0})}})},{117:117,30:30,34:34,4:4,72:72,74:74}],289:[function(t,e,n){"use strict";var a=t(34),r=t(117),i=t(4),o=t(72);t(30)&&a(a.P+t(74),"Object",{__defineSetter__:function(t,e){o.f(r(this),t,{set:i(e),enumerable:!0,configurable:!0})}})},{117:117,30:30,34:34,4:4,72:72,74:74}],290:[function(t,e,n){var a=t(34),r=t(84)(!0);a(a.S,"Object",{entries:function(t){return r(t)}})},{34:34,84:84}],291:[function(t,e,n){var a=t(34),r=t(85),i=t(115),o=t(75),s=t(25);a(a.S,"Object",{getOwnPropertyDescriptors:function(t){for(var e,n,a=i(t),p=o.f,u=r(a),c={},l=0;u.length>l;)n=p(a,e=u[l++]),void 0!==n&&s(c,e,n);return c}})},{115:115,25:25,34:34,75:75,85:85}],292:[function(t,e,n){"use strict";var a=t(34),r=t(117),i=t(118),o=t(79),s=t(75).f;t(30)&&a(a.P+t(74),"Object",{__lookupGetter__:function(t){var e,n=r(this),a=i(t,!0);do if(e=s(n,a))return e.get;while(n=o(n))}})},{117:117,118:118,30:30,34:34,74:74,75:75,79:79}],293:[function(t,e,n){"use strict";var a=t(34),r=t(117),i=t(118),o=t(79),s=t(75).f;t(30)&&a(a.P+t(74),"Object",{__lookupSetter__:function(t){var e,n=r(this),a=i(t,!0);do if(e=s(n,a))return e.set;while(n=o(n))}})},{117:117,118:118,30:30,34:34,74:74,75:75,79:79}],294:[function(t,e,n){var a=t(34),r=t(84)(!1);a(a.S,"Object",{values:function(t){return r(t)}})},{34:34,84:84}],295:[function(t,e,n){"use strict";var a=t(34),r=t(41),i=t(24),o=t(68)(),s=t(127)("observable"),p=t(4),u=t(8),c=t(7),l=t(91),d=t(43),f=t(40),h=f.RETURN,m=function(t){return null==t?void 0:p(t)},g=function(t){var e=t._c;e&&(t._c=void 0,e())},v=function(t){return void 0===t._o},b=function(t){v(t)||(t._o=void 0,g(t))},y=function(t,e){u(t),this._c=void 0,this._o=t,t=new _(this);try{var n=e(t),a=n;null!=n&&("function"==typeof n.unsubscribe?n=function(){a.unsubscribe()}:p(n),this._c=n)}catch(r){return void t.error(r)}v(this)&&g(this)};y.prototype=l({},{unsubscribe:function(){b(this)}});var _=function(t){this._s=t};_.prototype=l({},{next:function(t){var e=this._s;if(!v(e)){var n=e._o;try{var a=m(n.next);if(a)return a.call(n,t)}catch(r){try{b(e)}finally{throw r}}}},error:function(t){var e=this._s;if(v(e))throw t;var n=e._o;e._o=void 0;try{var a=m(n.error);if(!a)throw t;t=a.call(n,t)}catch(r){try{g(e)}finally{throw r}}return g(e),t},complete:function(t){var e=this._s;if(!v(e)){var n=e._o;e._o=void 0;try{var a=m(n.complete);t=a?a.call(n,t):void 0}catch(r){try{g(e)}finally{throw r}}return g(e),t}}});var x=function(t){c(this,x,"Observable","_f")._f=p(t)};l(x.prototype,{subscribe:function(t){return new y(t,this._f)},forEach:function(t){var e=this;return new(i.Promise||r.Promise)(function(n,a){p(t);var r=e.subscribe({next:function(e){try{return t(e)}catch(n){a(n),r.unsubscribe()}},error:a,complete:n})})}}),l(x,{from:function(t){var e="function"==typeof this?this:x,n=m(u(t)[s]);if(n){var a=u(n.call(t));return a.constructor===e?a:new e(function(t){return a.subscribe(t)})}return new e(function(e){var n=!1;return o(function(){if(!n){try{if(f(t,!1,function(t){return e.next(t),n?h:void 0})===h)return}catch(a){if(n)throw a;return void e.error(a)}e.complete()}}),function(){n=!0}})},of:function(){for(var t=0,e=arguments.length,n=Array(e);e>t;)n[t]=arguments[t++];return new("function"==typeof this?this:x)(function(t){var e=!1;return o(function(){if(!e){for(var a=0;a1?arguments[1]:void 0,!1)}})},{107:107,123:123,34:34}],313:[function(t,e,n){"use strict";var a=t(34),r=t(107),i=t(123);a(a.P+a.F*/Version\/10\.\d+(\.\d+)? Safari\//.test(i),"String",{padStart:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},{107:107,123:123,34:34}],314:[function(t,e,n){"use strict";t(109)("trimLeft",function(t){return function(){return t(this,1)}},"trimStart")},{109:109}],315:[function(t,e,n){"use strict";t(109)("trimRight",function(t){return function(){return t(this,2)}},"trimEnd")},{109:109}],316:[function(t,e,n){t(125)("asyncIterator")},{125:125}],317:[function(t,e,n){t(125)("observable")},{125:125}],318:[function(t,e,n){var a=t(34);a(a.S,"System",{global:t(41) -})},{34:34,41:41}],319:[function(t,e,n){t(95)("WeakMap")},{95:95}],320:[function(t,e,n){t(96)("WeakMap")},{96:96}],321:[function(t,e,n){t(95)("WeakSet")},{95:95}],322:[function(t,e,n){t(96)("WeakSet")},{96:96}],323:[function(t,e,n){for(var a=t(140),r=t(81),i=t(92),o=t(41),s=t(43),p=t(59),u=t(127),c=u("iterator"),l=u("toStringTag"),d=p.Array,f={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},h=r(f),m=0;m2,r=a?o.call(arguments,2):!1;return t(a?function(){("function"==typeof e?e:Function(e)).apply(this,r)}:e,n)}};r(r.G+r.B+r.F*s,{setTimeout:p(a.setTimeout),setInterval:p(a.setInterval)})},{123:123,34:34,41:41}],326:[function(t,e,n){t(253),t(190),t(192),t(191),t(194),t(196),t(201),t(195),t(193),t(203),t(202),t(198),t(199),t(197),t(189),t(200),t(204),t(205),t(156),t(158),t(157),t(207),t(206),t(177),t(187),t(188),t(178),t(179),t(180),t(181),t(182),t(183),t(184),t(185),t(186),t(160),t(161),t(162),t(163),t(164),t(165),t(166),t(167),t(168),t(169),t(170),t(171),t(172),t(173),t(174),t(175),t(176),t(240),t(245),t(252),t(243),t(235),t(236),t(241),t(246),t(248),t(231),t(232),t(233),t(234),t(237),t(238),t(239),t(242),t(244),t(247),t(249),t(250),t(251),t(151),t(153),t(152),t(155),t(154),t(139),t(137),t(144),t(141),t(147),t(149),t(136),t(143),t(133),t(148),t(131),t(146),t(145),t(138),t(142),t(130),t(132),t(135),t(134),t(150),t(140),t(223),t(229),t(224),t(225),t(226),t(227),t(228),t(208),t(159),t(230),t(265),t(266),t(254),t(255),t(260),t(263),t(264),t(258),t(261),t(259),t(262),t(256),t(257),t(209),t(210),t(211),t(212),t(213),t(216),t(214),t(215),t(217),t(218),t(219),t(220),t(222),t(221),t(269),t(267),t(268),t(310),t(313),t(312),t(314),t(315),t(311),t(316),t(317),t(291),t(294),t(290),t(288),t(289),t(292),t(293),t(275),t(309),t(274),t(308),t(320),t(322),t(273),t(307),t(319),t(321),t(272),t(318),t(271),t(276),t(277),t(278),t(279),t(280),t(282),t(281),t(283),t(284),t(285),t(287),t(286),t(296),t(297),t(298),t(299),t(301),t(300),t(303),t(302),t(304),t(305),t(306),t(270),t(295),t(325),t(324),t(323),e.exports=t(24)},{130:130,131:131,132:132,133:133,134:134,135:135,136:136,137:137,138:138,139:139,140:140,141:141,142:142,143:143,144:144,145:145,146:146,147:147,148:148,149:149,150:150,151:151,152:152,153:153,154:154,155:155,156:156,157:157,158:158,159:159,160:160,161:161,162:162,163:163,164:164,165:165,166:166,167:167,168:168,169:169,170:170,171:171,172:172,173:173,174:174,175:175,176:176,177:177,178:178,179:179,180:180,181:181,182:182,183:183,184:184,185:185,186:186,187:187,188:188,189:189,190:190,191:191,192:192,193:193,194:194,195:195,196:196,197:197,198:198,199:199,200:200,201:201,202:202,203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,216:216,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,24:24,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,307:307,308:308,309:309,310:310,311:311,312:312,313:313,314:314,315:315,316:316,317:317,318:318,319:319,320:320,321:321,322:322,323:323,324:324,325:325}],327:[function(t,e,n){!function(t){"use strict";function e(){return c.createDocumentFragment()}function n(t){return c.createElement(t)}function a(t){if(1===t.length)return r(t[0]);for(var n=e(),a=B.call(t),i=0;i-1}}([].indexOf||function(t){for(q=this.length;q--&&this[q]!==t;);return q}),item:function(t){return this[t]||null},remove:function(){for(var t,e=0;e=p?e(i):document.fonts.load(u(i,i.family),s).then(function(e){1<=e.length?t(i):setTimeout(d,25)},function(){e(i)})};d()}else n(function(){function n(){var e;(e=-1!=g&&-1!=v||-1!=g&&-1!=b||-1!=v&&-1!=b)&&((e=g!=v&&g!=b&&v!=b)||(null===l&&(e=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),l=!!e&&(536>parseInt(e[1],10)||536===parseInt(e[1],10)&&11>=parseInt(e[2],10))),e=l&&(g==y&&v==y&&b==y||g==_&&v==_&&b==_||g==x&&v==x&&b==x)),e=!e),e&&(null!==w.parentNode&&w.parentNode.removeChild(w),clearTimeout(k),t(i))}function d(){if((new Date).getTime()-c>=p)null!==w.parentNode&&w.parentNode.removeChild(w),e(i);else{var t=document.hidden;(!0===t||void 0===t)&&(g=f.a.offsetWidth,v=h.a.offsetWidth,b=m.a.offsetWidth,n()),k=setTimeout(d,50)}}var f=new a(s),h=new a(s),m=new a(s),g=-1,v=-1,b=-1,y=-1,_=-1,x=-1,w=document.createElement("div"),k=0;w.dir="ltr",r(f,u(i,"sans-serif")),r(h,u(i,"serif")),r(m,u(i,"monospace")),w.appendChild(f.a),w.appendChild(h.a),w.appendChild(m.a),document.body.appendChild(w),y=f.a.offsetWidth,_=h.a.offsetWidth,x=m.a.offsetWidth,d(),o(f,function(t){g=t,n()}),r(f,u(i,'"'+i.family+'",sans-serif')),o(h,function(t){v=t,n()}),r(h,u(i,'"'+i.family+'",serif')),o(m,function(t){b=t,n()}),r(m,u(i,'"'+i.family+'",monospace'))})})},window.FontFaceObserver=s,window.FontFaceObserver.prototype.check=s.prototype.a,void 0!==e&&(e.exports=window.FontFaceObserver)}()},{}],330:[function(t,e,n){!function(t,n){function a(t,e){var n=t.createElement("p"),a=t.getElementsByTagName("head")[0]||t.documentElement;return n.innerHTML="x",a.insertBefore(n.lastChild,a.firstChild)}function r(){var t=_.elements;return"string"==typeof t?t.split(" "):t}function i(t,e){var n=_.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof t&&(t=t.join(" ")),_.elements=n+" "+t,c(e)}function o(t){var e=y[t[v]];return e||(e={},b++,t[v]=b,y[b]=e),e}function s(t,e,a){if(e||(e=n),d)return e.createElement(t);a||(a=o(e));var r;return r=a.cache[t]?a.cache[t].cloneNode():g.test(t)?(a.cache[t]=a.createElem(t)).cloneNode():a.createElem(t),!r.canHaveChildren||m.test(t)||r.tagUrn?r:a.frag.appendChild(r)}function p(t,e){if(t||(t=n),d)return t.createDocumentFragment();e=e||o(t);for(var a=e.frag.cloneNode(),i=0,s=r(),p=s.length;p>i;i++)a.createElement(s[i]);return a}function u(t,e){e.cache||(e.cache={},e.createElem=t.createElement,e.createFrag=t.createDocumentFragment,e.frag=e.createFrag()),t.createElement=function(n){return _.shivMethods?s(n,t,e):e.createElem(n)},t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(t){return e.createElem(t),e.frag.createElement(t),'c("'+t+'")'})+");return n}")(_,e.frag)}function c(t){t||(t=n);var e=o(t);return!_.shivCSS||l||e.hasCSS||(e.hasCSS=!!a(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),d||u(t,e),t}var l,d,f="3.7.3-pre",h=t.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",b=0,y={};!function(){try{var t=n.createElement("a");t.innerHTML="",l="hidden"in t,d=1==t.childNodes.length||function(){n.createElement("a");var t=n.createDocumentFragment();return void 0===t.cloneNode||void 0===t.createDocumentFragment||void 0===t.createElement}()}catch(e){l=!0,d=!0}}();var _={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:f,shivCSS:h.shivCSS!==!1,supportsUnknownElements:d,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:c,createElement:s,createDocumentFragment:p,addElements:i};t.html5=_,c(n),"object"==typeof e&&e.exports&&(e.exports=_)}("undefined"!=typeof window?window:this,document)},{}],331:[function(t,e,n){(function(t){(function(t){!function(t){function e(t,e,n,a){for(var i,o,s=n.slice(),p=r(e,t),u=0,c=s.length;c>u&&(i=s[u],"object"==typeof i?"function"==typeof i.handleEvent&&i.handleEvent(p):i.call(t,p),!p.stoppedImmediatePropagation);u++);return o=!p.stoppedPropagation,a&&o&&t.parentNode?t.parentNode.dispatchEvent(p):!p.defaultPrevented}function n(t,e){return{configurable:!0,get:t,set:e}}function a(t,e,a){var r=y(e||t,a);v(t,"textContent",n(function(){return r.get.call(this)},function(t){r.set.call(this,t)}))}function r(t,e){return t.currentTarget=e,t.eventPhase=t.target===t.currentTarget?2:3,t}function i(t,e){for(var n=t.length;n--&&t[n]!==e;);return n}function o(){if("BR"===this.tagName)return"\n";for(var t=this.firstChild,e=[];t;)8!==t.nodeType&&7!==t.nodeType&&e.push(t.textContent),t=t.nextSibling;return e.join("")}function s(t){var e=document.createEvent("Event");e.initEvent("input",!0,!0),(t.srcElement||t.fromElement||document).dispatchEvent(e)}function p(t){!f&&S.test(document.readyState)&&(f=!f,document.detachEvent(h,p),t=document.createEvent("Event"),t.initEvent(m,!0,!0),document.dispatchEvent(t))}function u(t){return function(){return P[t]||document.body&&document.body[t]||0}}function c(t){for(var e;e=this.lastChild;)this.removeChild(e);null!=t&&this.appendChild(document.createTextNode(t))}function l(e,n){return n||(n=t.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var d=!0,f=!1,h="onreadystatechange",m="DOMContentLoaded",g="__IE8__"+Math.random(),v=Object.defineProperty||function(t,e,n){t[e]=n.value},b=Object.defineProperties||function(e,n){for(var a in n)if(_.call(n,a))try{v(e,a,n[a])}catch(r){t.console&&console.log(a+" failed on object:",e,r.message)}},y=Object.getOwnPropertyDescriptor,_=Object.prototype.hasOwnProperty,x=t.Element.prototype,w=t.Text.prototype,k=/^[a-z]+$/,S=/loaded|complete/,E={},C=document.createElement("div"),P=document.documentElement,A=P.removeAttribute,O=P.setAttribute,T=function(t){return{enumerable:!0,writable:!0,configurable:!0,value:t}};a(t.HTMLCommentElement.prototype,x,"nodeValue"),a(t.HTMLScriptElement.prototype,null,"text"),a(w,null,"nodeValue"),a(t.HTMLTitleElement.prototype,null,"text"),v(t.HTMLStyleElement.prototype,"textContent",function(t){return n(function(){return t.get.call(this.styleSheet)},function(e){t.set.call(this.styleSheet,e)})}(y(t.CSSStyleSheet.prototype,"cssText")));var R=/\b\s*alpha\s*\(\s*opacity\s*=\s*(\d+)\s*\)/;v(t.CSSStyleDeclaration.prototype,"opacity",{get:function(){var t=this.filter.match(R);return t?""+t[1]/100:""},set:function(t){this.zoom=1;var e=!1;t=1>t?" alpha(opacity="+Math.round(100*t)+")":"",this.filter=this.filter.replace(R,function(){return e=!0,t}),!e&&t&&(this.filter+=t)}}),b(x,{textContent:{get:o,set:c},firstElementChild:{get:function(){for(var t=this.childNodes||[],e=0,n=t.length;n>e;e++)if(1==t[e].nodeType)return t[e]}},lastElementChild:{get:function(){for(var t=this.childNodes||[],e=t.length;e--;)if(1==t[e].nodeType)return t[e]}},oninput:{get:function(){return this._oninput||null},set:function(t){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=t,t&&this.addEventListener("input",t))}},previousElementSibling:{get:function(){for(var t=this.previousSibling;t&&1!=t.nodeType;)t=t.previousSibling;return t}},nextElementSibling:{get:function(){for(var t=this.nextSibling;t&&1!=t.nodeType;)t=t.nextSibling;return t}},childElementCount:{get:function(){for(var t=0,e=this.childNodes||[],n=e.length;n--;t+=1==e[n].nodeType);return t}},addEventListener:T(function(t,n,a){if("function"==typeof n||"object"==typeof n){var r,o,p=this,u="on"+t,c=p[g]||v(p,g,{value:{}})[g],d=c[u]||(c[u]={}),f=d.h||(d.h=[]);if(!_.call(d,"w")){if(d.w=function(t){return t[g]||e(p,l(p,t),f,!1)},!_.call(E,u))if(k.test(t)){try{r=document.createEventObject(),r[g]=!0,9!=p.nodeType&&(null==p.parentNode&&C.appendChild(p),(o=p.getAttribute(u))&&A.call(p,u)),p.fireEvent(u,r),E[u]=!0}catch(h){for(E[u]=!1;C.hasChildNodes();)C.removeChild(C.firstChild)}null!=o&&O.call(p,u,o)}else E[u]=!1;(d.n=E[u])&&p.attachEvent(u,d.w)}i(f,n)<0&&f[a?"unshift":"push"](n),"input"===t&&p.attachEvent("onkeyup",s)}}),dispatchEvent:T(function(t){var n,a=this,r="on"+t.type,i=a[g],o=i&&i[r],s=!!o;return t.target||(t.target=a),s?o.n?a.fireEvent(r,t):e(a,t,o.h,!0):(n=a.parentNode)?n.dispatchEvent(t):!0,!t.defaultPrevented}),removeEventListener:T(function(t,e,n){if("function"==typeof e||"object"==typeof e){var a=this,r="on"+t,o=a[g],s=o&&o[r],p=s&&s.h,u=p?i(p,e):-1;u>-1&&p.splice(u,1)}})}),b(w,{addEventListener:T(x.addEventListener),dispatchEvent:T(x.dispatchEvent),removeEventListener:T(x.removeEventListener)}),b(t.XMLHttpRequest.prototype,{addEventListener:T(function(t,e,n){var a=this,r="on"+t,o=a[g]||v(a,g,{value:{}})[g],s=o[r]||(o[r]={}),p=s.h||(s.h=[]);i(p,e)<0&&(a[r]||(a[r]=function(){var e=document.createEvent("Event");e.initEvent(t,!0,!0),a.dispatchEvent(e)}),p[n?"unshift":"push"](e))}),dispatchEvent:T(function(t){var n=this,a="on"+t.type,r=n[g],i=r&&r[a],o=!!i;return o&&(i.n?n.fireEvent(a,t):e(n,t,i.h,!0))}),removeEventListener:T(x.removeEventListener)});var M=y(Event.prototype,"button").get;b(t.Event.prototype,{bubbles:T(!0),cancelable:T(!0),preventDefault:T(function(){this.cancelable&&(this.returnValue=!1)}),stopPropagation:T(function(){this.stoppedPropagation=!0,this.cancelBubble=!0}),stopImmediatePropagation:T(function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}),initEvent:T(function(t,e,n){this.type=t,this.bubbles=!!e,this.cancelable=!!n,this.bubbles||this.stopPropagation()}),pageX:{get:function(){return this._pageX||(this._pageX=this.clientX+t.scrollX-(P.clientLeft||0))}},pageY:{get:function(){return this._pageY||(this._pageY=this.clientY+t.scrollY-(P.clientTop||0))}},which:{get:function(){return this.keyCode?this.keyCode:isNaN(this.button)?void 0:this.button+1}},charCode:{get:function(){return this.keyCode&&"keypress"==this.type?this.keyCode:0}},buttons:{get:function(){return M.call(this)}},button:{get:function(){var t=this.buttons;return 1&t?0:2&t?2:4&t?1:void 0}},defaultPrevented:{get:function(){var t,e=this.returnValue;return!(e===t||e)}},relatedTarget:{get:function(){var t=this.type;return"mouseover"===t?this.fromElement:"mouseout"===t?this.toElement:null}}}),b(t.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?o.call(this):null},set:function(t){11===this.nodeType&&c.call(this,t)}},addEventListener:T(function(e,n,a){var r=this;x.addEventListener.call(r,e,n,a),d&&e===m&&!S.test(r.readyState)&&(d=!1,r.attachEvent(h,p),t==top&&!function i(t){try{r.documentElement.doScroll("left"),p()}catch(e){setTimeout(i,50)}}())}),dispatchEvent:T(x.dispatchEvent),removeEventListener:T(x.removeEventListener),createEvent:T(function(t){var e;if("Event"!==t)throw Error("unsupported "+t);return e=document.createEventObject(),e.timeStamp=(new Date).getTime(),e})}),b(t.Window.prototype,{getComputedStyle:T(function(){function t(t){this._=t}function e(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,a=/^(top|right|bottom|left)$/,r=/\-([a-z])/g,i=function(t,e){return e.toUpperCase()};return t.prototype.getPropertyValue=function(t){var e,o,s,p=this._,u=p.style,c=p.currentStyle,l=p.runtimeStyle;return"opacity"==t?u.opacity||"1":(t=("float"===t?"style-float":t).replace(r,i),e=c?c[t]:u[t],n.test(e)&&!a.test(t)&&(o=u.left,s=l&&l.left,s&&(l.left=c.left),u.left="fontSize"===t?"1em":e,e=u.pixelLeft+"px",u.left=o,s&&(l.left=s)),null==e?e:e+""||"auto")},e.prototype.getPropertyValue=function(){return null},function(n,a){return a?new e(n):new t(n)}}()),addEventListener:T(function(n,a,r){var o,s=t,p="on"+n;s[p]||(s[p]=function(t){return e(s,l(s,t),o,!1)&&void 0}),o=s[p][g]||(s[p][g]=[]),i(o,a)<0&&o[r?"unshift":"push"](a)}),dispatchEvent:T(function(e){var n=t["on"+e.type];return n?n.call(t,e)!==!1&&!e.defaultPrevented:!0}),removeEventListener:T(function(e,n,a){var r="on"+e,o=(t[r]||Object)[g],s=o?i(o,n):-1;s>-1&&o.splice(s,1)}),pageXOffset:{get:u("scrollLeft")},pageYOffset:{get:u("scrollTop")},scrollX:{get:u("scrollLeft")},scrollY:{get:u("scrollTop")},innerWidth:{get:u("clientWidth")},innerHeight:{get:u("clientHeight")}}),t.HTMLElement=t.Element,function(t,e,n){for(n=0;na;a++)e.appendChild(n[a].cloneNode(!0));return e},n.cloneRange=function(){var t=new e;return t._start=this._start,t._end=this._end,t},n.deleteContents=function(){for(var e=this._start.parentNode,n=t(this._start,this._end),a=0,r=n.length;r>a;a++)e.removeChild(n[a])},n.extractContents=function(){for(var e=this._start.ownerDocument.createDocumentFragment(),n=t(this._start,this._end),a=0,r=n.length;r>a;a++)e.appendChild(n[a]);return e},n.setEndAfter=function(t){this._end=t},n.setEndBefore=function(t){this._end=t.previousSibling},n.setStartAfter=function(t){this._start=t.nextSibling},n.setStartBefore=function(t){this._start=t}}}()}}(this.window||t)}).call(this,void 0!==t?t:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],332:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e=s)return(0,p["default"])({points:n});for(var l=1;s-1>=l;l++)i.push((0,u.times)(a,(0,u.minus)(n[l],n[l-1])));for(var d=[(0,u.plus)(n[0],c(i[0],i[1]))],l=1;s-2>=l;l++)d.push((0,u.minus)(n[l],(0,u.average)([i[l],i[l-1]])));d.push((0,u.minus)(n[s-1],c(i[s-2],i[s-3])));var f=d[0],h=d[1],m=n[0],g=n[1],v=(e=(0,o["default"])()).moveto.apply(e,r(m)).curveto(f[0],f[1],h[0],h[1],g[0],g[1]);return{path:(0,u.range)(2,s).reduce(function(t,e){var a=d[e],r=n[e];return t.smoothcurveto(a[0],a[1],r[0],r[1])},v),centroid:(0,u.average)(n)}},e.exports=n["default"]},{335:335,336:336,337:337}],333:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=t(334),o=a(i),s=t(335),p=1e-5,u=function(t,e){var n=t.map(e),a=n.sort(function(t,e){var n=r(t,2),a=n[0],i=(n[1],r(e,2)),o=i[0];i[1];return a-o}),i=a.length,o=a[0][0],u=a[i-1][0],c=(0,s.minBy)(a,function(t){return t[1]}),l=(0,s.maxBy)(a,function(t){return t[1]});return o==u&&(u+=p),c==l&&(l+=p),{points:a,xmin:o,xmax:u,ymin:c,ymax:l}};n["default"]=function(t){var e=t.data,n=t.xaccessor,a=t.yaccessor,i=t.width,p=t.height,c=t.closed,l=t.min,d=t.max;n||(n=function(t){var e=r(t,2),n=e[0];e[1];return n}),a||(a=function(t){var e=r(t,2),n=(e[0],e[1]);return n});var f=function(t){return[n(t),a(t)]},h=e.map(function(t){return u(t,f)}),m=(0,s.minBy)(h,function(t){return t.xmin}),g=(0,s.maxBy)(h,function(t){return t.xmax}),v=null==l?(0,s.minBy)(h,function(t){return t.ymin}):l,b=null==d?(0,s.maxBy)(h,function(t){return t.ymax}):d;c&&(v=Math.min(v,0),b=Math.max(b,0));var y=c?0:v,_=(0,o["default"])([m,g],[0,i]),x=(0,o["default"])([v,b],[p,0]),w=function(t){var e=r(t,2),n=e[0],a=e[1];return[_(n),x(a)]};return{arranged:h,scale:w,xscale:_,yscale:x,base:y}},e.exports=n["default"]},{334:334,335:335}],334:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t,e){var n=a(t,2),r=n[0],o=n[1],s=a(e,2),p=s[0],u=s[1],c=function(t){return p+(u-p)*(t-r)/(o-r)};return c.inverse=function(){return i([p,u],[r,o])},c};n["default"]=r,e.exports=n["default"]},{}],335:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(t){return t.reduce(function(t,e){return t+e},0)},i=function(t){return t.reduce(function(t,e){return Math.min(t,e)})},o=function(t){return t.reduce(function(t,e){return Math.max(t,e)})},s=function(t,e){return t.reduce(function(t,n){return t+e(n)},0)},p=function(t,e){return t.reduce(function(t,n){return Math.min(t,e(n))},1/0)},u=function(t,e){return t.reduce(function(t,n){return Math.max(t,e(n))},-(1/0))},c=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],p=o[1];return[r+s,i+p]},l=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],p=o[1];return[r-s,i-p]},d=function(t,e){var n=a(e,2),r=n[0],i=n[1];return[t*r,t*i]},f=function(t){var e=a(t,2),n=e[0],r=e[1];return Math.sqrt(n*n+r*r)},h=function(t){return t.reduce(c,[0,0])},m=function(t){return d(1/t.length,t.reduce(c))},g=function(t,e){return d(t,[Math.sin(e),-Math.cos(e)])},v=function(t,e){var n=t||{};for(var a in n){var r=n[a];e[a]=r(e.index,e.item,e.group)}return e},b=function(t,e,n){for(var a=[],r=t;e>r;r++)a.push(r);return n&&a.push(e),a},y=function(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(t)[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var p=o.value,u=t[p];n.push(e(p,u))}}catch(c){r=!0,i=c}finally{ -try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},_=function(t){return y(t,function(t,e){return[t,e]})},x=function(t){return t};n.sum=r,n.min=i,n.max=o,n.sumBy=s,n.minBy=p,n.maxBy=u,n.plus=c,n.minus=l,n.times=d,n.id=x,n.length=f,n.sumVectors=h,n.average=m,n.onCircle=g,n.enhance=v,n.range=b,n.mapObject=y,n.pairs=_,n["default"]={sum:r,min:i,max:o,sumBy:s,minBy:p,maxBy:u,plus:c,minus:l,times:d,id:x,length:f,sumVectors:h,average:m,onCircle:g,enhance:v,range:b,mapObject:y,pairs:_}},{}],336:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t){var e=t||[],n=function(t,e){var n=t.slice(0,t.length);return n.push(e),n},r=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],p=o[1];return r===s&&i===p},o=function(t,e){for(var n=t.length;"0"===t.charAt(n-1);)n-=1;return"."===t.charAt(n-1)&&(n-=1),t.substr(0,n)},s=function(t,e){var n=t.toFixed(e);return o(n)},p=function(t){var e=t.command,n=t.params,a=n.map(function(t){return s(t,6)});return e+" "+a.join(" ")},u=function(t,e){var n=t.command,r=t.params,i=a(e,2),o=i[0],s=i[1];switch(n){case"M":return[r[0],r[1]];case"L":return[r[0],r[1]];case"H":return[r[0],s];case"V":return[o,r[0]];case"Z":return null;case"C":return[r[4],r[5]];case"S":return[r[2],r[3]];case"Q":return[r[2],r[3]];case"T":return[r[0],r[1]];case"A":return[r[5],r[6]]}},c=function(t,e){return function(n){var a="object"==typeof n?t.map(function(t){return n[t]}):arguments;return e.apply(null,a)}},l=function(t){return i(n(e,t))};return{moveto:c(["x","y"],function(t,e){return l({command:"M",params:[t,e]})}),lineto:c(["x","y"],function(t,e){return l({command:"L",params:[t,e]})}),hlineto:c(["x"],function(t){return l({command:"H",params:[t]})}),vlineto:c(["y"],function(t){return l({command:"V",params:[t]})}),closepath:function(){return l({command:"Z",params:[]})},curveto:c(["x1","y1","x2","y2","x","y"],function(t,e,n,a,r,i){return l({command:"C",params:[t,e,n,a,r,i]})}),smoothcurveto:c(["x2","y2","x","y"],function(t,e,n,a){return l({command:"S",params:[t,e,n,a]})}),qcurveto:c(["x1","y1","x","y"],function(t,e,n,a){return l({command:"Q",params:[t,e,n,a]})}),smoothqcurveto:c(["x","y"],function(t,e){return l({command:"T",params:[t,e]})}),arc:c(["rx","ry","xrot","largeArcFlag","sweepFlag","x","y"],function(t,e,n,a,r,i,o){return l({command:"A",params:[t,e,n,a,r,i,o]})}),print:function(){return e.map(p).join(" ")},points:function(){var t=[],n=[0,0],a=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var p=o.value,c=u(p,n);n=c,c&&t.push(c)}}catch(l){r=!0,i=l}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return t},instructions:function(){return e.slice(0,e.length)},connect:function(t){var e=this.points(),n=e[e.length-1],a=t.points()[0],o=t.instructions().slice(1);return r(n,a)||o.unshift({command:"L",params:a}),i(this.instructions().concat(o))}}};n["default"]=function(){return r()},e.exports=n["default"]},{}],337:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];for(var r,i;i=n.shift();)for(r in i)Mo.call(i,r)&&(t[r]=i[r]);return t}function r(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];return n.forEach(function(e){for(var n in e)!e.hasOwnProperty(n)||n in t||(t[n]=e[n])}),t}function i(t){return"[object Array]"===Lo.call(t)}function o(t){return jo.test(Lo.call(t))}function s(t,e){return null===t&&null===e?!0:"object"==typeof t||"object"==typeof e?!1:t===e}function p(t){return!isNaN(parseFloat(t))&&isFinite(t)}function u(t){return t&&"[object Object]"===Lo.call(t)}function c(t,e){return t.replace(/%s/g,function(){return e.shift()})}function l(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];throw t=c(t,n),Error(t)}function d(){Mg.DEBUG&&Oo.apply(null,arguments)}function f(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),To(t,n)}function h(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),Do[t]||(Do[t]=!0,To(t,n))}function m(){Mg.DEBUG&&f.apply(null,arguments)}function g(){Mg.DEBUG&&h.apply(null,arguments)}function v(t,e,n){var a=b(t,e,n);return a?a[t][n]:null}function b(t,e,n){for(;e;){if(n in e[t])return e;if(e.isolated)return null;e=e.parent}}function y(t){return function(){return t}}function _(t){var e,n,a,r,i,o;for(e=t.split("."),(n=zo[e.length])||(n=x(e.length)),i=[],a=function(t,n){return t?"*":e[n]},r=n.length;r--;)o=n[r].map(a).join("."),i.hasOwnProperty(o)||(i.push(o),i[o]=!0);return i}function x(t){var e,n,a,r,i,o,s,p,u="";if(!zo[t]){for(a=[];u.length=i;i+=1){for(n=i.toString(2);n.lengtho;o++)p.push(r(n[o]));a[i]=p}zo[t]=a}return zo[t]}function w(t,e,n,a){var r=t[e];if(!r||!r.equalsOrStartsWith(a)&&r.equalsOrStartsWith(n))return t[e]=r?r.replace(n,a):a,!0}function k(t){var e=t.slice(2);return"i"===t[1]&&p(e)?+e:e}function S(t){return null==t?t:(Ko.hasOwnProperty(t)||(Ko[t]=new Qo(t)),Ko[t])}function E(t,e){function n(e,n){var a,r,o;return n.isRoot?o=[].concat(Object.keys(t.viewmodel.data),Object.keys(t.viewmodel.mappings),Object.keys(t.viewmodel.computations)):(a=t.viewmodel.wrapped[n.str],r=a?a.get():t.viewmodel.get(n),o=r?Object.keys(r):null),o&&o.forEach(function(t){"_ractive"===t&&i(r)||e.push(n.join(t))}),e}var a,r,o;for(a=e.str.split("."),o=[$o];r=a.shift();)"*"===r?o=o.reduce(n,[]):o[0]===$o?o[0]=S(r):o=o.map(C(r));return o}function C(t){return function(e){return e.join(t)}}function P(t){return t?t.replace(Wo,".$1"):""}function A(t,e,n){if("string"!=typeof e||!p(n))throw Error("Bad arguments");var a=void 0,r=void 0;if(/\*/.test(e))return r={},E(t,S(P(e))).forEach(function(e){var a=t.viewmodel.get(e);if(!p(a))throw Error(Xo);r[e.str]=a+n}),t.set(r);if(a=t.get(e),!p(a))throw Error(Xo);return t.set(e,+a+n)}function O(t,e){return Jo(this,t,void 0===e?1:+e)}function T(t){this.event=t,this.method="on"+t,this.deprecate=as[t]}function R(t,e){var n=t.indexOf(e);-1===n&&t.push(e)}function M(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n]==e)return!0;return!1}function L(t,e){var n;if(!i(t)||!i(e))return!1;if(t.length!==e.length)return!1;for(n=t.length;n--;)if(t[n]!==e[n])return!1;return!0}function j(t){return"string"==typeof t?[t]:void 0===t?[]:t}function D(t){return t[t.length-1]}function N(t,e){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}function F(t){for(var e=[],n=t.length;n--;)e[n]=t[n];return e}function I(t){setTimeout(t,0)}function B(t,e){return function(){for(var n;n=t.shift();)n(e)}}function q(t,e,n,a){var r;if(e===t)throw new TypeError("A promise's fulfillment handler cannot return the same promise");if(e instanceof rs)e.then(n,a);else if(!e||"object"!=typeof e&&"function"!=typeof e)n(e);else{try{r=e.then}catch(i){return void a(i)}if("function"==typeof r){var o,s,p;s=function(e){o||(o=!0,q(t,e,n,a))},p=function(t){o||(o=!0,a(t))};try{r.call(e,s,p)}catch(i){if(!o)return a(i),void(o=!0)}}else n(e)}}function U(t,e,n){var a;return e=P(e),"~/"===e.substr(0,2)?(a=S(e.substring(2)),z(t,a.firstKey,n)):"."===e[0]?(a=V(cs(n),e),a&&z(t,a.firstKey,n)):a=G(t,S(e),n),a}function V(t,e){var n;if(void 0!=t&&"string"!=typeof t&&(t=t.str),"."===e)return S(t);if(n=t?t.split("."):[],"../"===e.substr(0,3)){for(;"../"===e.substr(0,3);){if(!n.length)throw Error('Could not resolve reference - too many "../" prefixes');n.pop(),e=e.substring(3)}return n.push(e),S(n.join("."))}return S(t?t+e.replace(/^\.\//,"."):e.replace(/^\.\/?/,""))}function G(t,e,n,a){var r,i,o,s,p;if(e.isRoot)return e;for(i=e.firstKey;n;)if(r=n.context,n=n.parent,r&&(s=!0,o=t.viewmodel.get(r),o&&("object"==typeof o||"function"==typeof o)&&i in o))return r.join(e.str);return W(t.viewmodel,i)?e:t.parent&&!t.isolated&&(s=!0,n=t.component.parentFragment,i=S(i),p=G(t.parent,i,n,!0))?(t.viewmodel.map(i,{origin:t.parent.viewmodel,keypath:p}),e):a||s?void 0:(t.viewmodel.set(e,void 0),e)}function z(t,e){var n;!t.parent||t.isolated||W(t.viewmodel,e)||(e=S(e),(n=G(t.parent,e,t.component.parentFragment,!0))&&t.viewmodel.map(e,{origin:t.parent.viewmodel,keypath:n}))}function W(t,e){return""===e||e in t.data||e in t.computations||e in t.mappings}function H(t){t.teardown()}function K(t){t.unbind()}function Q(t){t.unrender()}function Y(t){t.cancel()}function $(t){t.detach()}function J(t){t.detachNodes()}function X(t){!t.ready||t.outros.length||t.outroChildren||(t.outrosComplete||(t.parent?t.parent.decrementOutros(t):t.detachNodes(),t.outrosComplete=!0),t.intros.length||t.totalChildren||("function"==typeof t.callback&&t.callback(),t.parent&&t.parent.decrementTotal()))}function Z(){for(var t,e,n;fs.ractives.length;)e=fs.ractives.pop(),n=e.viewmodel.applyChanges(),n&&vs.fire(e,n);for(tt(),t=0;t=0;i--)r=t._subs[e[i]],r&&(s=vt(t,r,n,a)&&s);if(Gs.dequeue(t),t.parent&&s){if(o&&t.component){var p=t.component.name+"."+e[e.length-1];e=S(p).wildcardMatches(),n&&(n.component=t)}gt(t.parent,e,n,a)}}function vt(t,e,n,a){var r=null,i=!1;n&&!n._noArg&&(a=[n].concat(a)),e=e.slice();for(var o=0,s=e.length;s>o;o+=1)e[o].apply(t,a)===!1&&(i=!0);return n&&!n._noArg&&i&&(r=n.original)&&(r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation()),!i}function bt(t){var e={args:Array.prototype.slice.call(arguments,1)};zs(this,t,e)}function yt(t){var e;return t=S(P(t)),e=this.viewmodel.get(t,Ks),void 0===e&&this.parent&&!this.isolated&&ls(this,t.str,this.component.parentFragment)&&(e=this.viewmodel.get(t)),e}function _t(e,n){if(!this.fragment.rendered)throw Error("The API has changed - you must call `ractive.render(target[, anchor])` to render your Ractive instance. Once rendered you can use `ractive.insert()`.");if(e=t(e),n=t(n)||null,!e)throw Error("You must specify a valid target to insert into");e.insertBefore(this.detach(),n),this.el=e,(e.__ractive_instances__||(e.__ractive_instances__=[])).push(this),this.detached=null,xt(this)}function xt(t){Ys.fire(t),t.findAllComponents("*").forEach(function(t){xt(t.instance)})}function wt(t,e,n){var a,r;return t=S(P(t)),a=this.viewmodel.get(t),i(a)&&i(e)?(r=bs.start(this,!0),this.viewmodel.merge(t,a,e,n),bs.end(),r):this.set(t,e,n&&n.complete)}function kt(t,e){var n,a;return n=E(t,e),a={},n.forEach(function(e){a[e.str]=t.get(e.str)}),a}function St(t,e,n,a){var r,i,o;e=S(P(e)),a=a||cp,e.isPattern?(r=new pp(t,e,n,a),t.viewmodel.patternObservers.push(r),i=!0):r=new Zs(t,e,n,a),r.init(a.init),t.viewmodel.register(e,r,i?"patternObservers":"observers"),r.ready=!0;var s={cancel:function(){var n;o||(i?(n=t.viewmodel.patternObservers.indexOf(r),t.viewmodel.patternObservers.splice(n,1),t.viewmodel.unregister(e,r,"patternObservers")):t.viewmodel.unregister(e,r,"observers"),o=!0)}};return t._observers.push(s),s}function Et(t,e,n){var a,r,i,o;if(u(t)){n=e,r=t,a=[];for(t in r)r.hasOwnProperty(t)&&(e=r[t],a.push(this.observe(t,e,n)));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}if("function"==typeof t)return n=e,e=t,t="",up(this,t,e,n);if(i=t.split(" "),1===i.length)return up(this,t,e,n);for(a=[],o=i.length;o--;)t=i[o],t&&a.push(up(this,t,e,n));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}function Ct(t,e,n){var a=this.observe(t,function(){e.apply(this,arguments),a.cancel()},{init:!1,defer:n&&n.defer});return a}function Pt(t,e){var n,a=this;if(t)n=t.split(" ").map(fp).filter(hp),n.forEach(function(t){var n,r;(n=a._subs[t])&&(e?(r=n.indexOf(e),-1!==r&&n.splice(r,1)):a._subs[t]=[])});else for(t in this._subs)delete this._subs[t];return this}function At(t,e){var n,a,r,i=this;if("object"==typeof t){n=[];for(a in t)t.hasOwnProperty(a)&&n.push(this.on(a,t[a]));return{cancel:function(){for(var t;t=n.pop();)t.cancel()}}}return r=t.split(" ").map(fp).filter(hp),r.forEach(function(t){(i._subs[t]||(i._subs[t]=[])).push(e)}),{cancel:function(){return i.off(t,e)}}}function Ot(t,e){var n=this.on(t,function(){e.apply(this,arguments),n.cancel()});return n}function Tt(t,e,n){var a,r,i,o,s,p,u=[];if(a=Rt(t,e,n),!a)return null;for(r=t.length,s=a.length-2-a[1],i=Math.min(r,a[0]),o=i+a[1],p=0;i>p;p+=1)u.push(p);for(;o>p;p+=1)u.push(-1);for(;r>p;p+=1)u.push(p+s);return 0!==s?u.touchedFrom=a[0]:u.touchedFrom=t.length,u}function Rt(t,e,n){switch(e){case"splice":for(void 0!==n[0]&&n[0]<0&&(n[0]=t.length+Math.max(n[0],-t.length));n.length<2;)n.push(0);return n[1]=Math.min(n[1],t.length-n[0]),n;case"sort":case"reverse":return null;case"pop":return t.length?[t.length-1,1]:[0,0];case"push":return[t.length,0].concat(n);case"shift":return[0,t.length?1:0];case"unshift":return[0,0].concat(n)}}function Mt(e,n){var a,r,i,o=this;if(i=this.transitionsEnabled,this.noIntro&&(this.transitionsEnabled=!1),a=bs.start(this,!0),bs.scheduleTask(function(){return Rp.fire(o)},!0),this.fragment.rendered)throw Error("You cannot call ractive.render() on an already rendered instance! Call ractive.unrender() first");if(e=t(e)||this.el,n=t(n)||this.anchor,this.el=e,this.anchor=n,!this.append&&e){var s=e.__ractive_instances__;s&&s.length&&Lt(s),e.innerHTML=""}return this.cssId&&Op.apply(),e&&((r=e.__ractive_instances__)?r.push(this):e.__ractive_instances__=[this],n?e.insertBefore(this.fragment.render(),n):e.appendChild(this.fragment.render())),bs.end(),this.transitionsEnabled=i,a.then(function(){return Mp.fire(o)})}function Lt(t){t.splice(0,t.length).forEach(H)}function jt(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function Dt(t,e){var n,a,r;return a='[data-ractive-css~="{'+e+'}"]',r=function(t){var e,n,r,i,o,s,p,u=[];for(e=[];n=Ip.exec(t);)e.push({str:n[0],base:n[1],modifiers:n[2]});for(i=e.map(Ft),p=e.length;p--;)s=i.slice(),r=e[p],s[p]=r.base+a+r.modifiers||"",o=i.slice(),o[p]=a+" "+o[p],u.push(s.join(" "),o.join(" "));return u.join(", ")},n=qp.test(t)?t.replace(qp,a):t.replace(Fp,"").replace(Np,function(t,e){var n,a;return Bp.test(e)?t:(n=e.split(",").map(Nt),a=n.map(r).join(", ")+" ",t.replace(e,a))})}function Nt(t){return t.trim?t.trim():t.replace(/^\s+/,"").replace(/\s+$/,"")}function Ft(t){return t.str}function It(t){t&&t.constructor!==Object&&("function"==typeof t||("object"!=typeof t?l("data option must be an object or a function, `"+t+"` is not valid"):m("If supplied, options.data should be a plain JavaScript object - using a non-POJO as the root object may work, but is discouraged")))}function Bt(t,e){It(e);var n="function"==typeof t,a="function"==typeof e;return e||n||(e={}),n||a?function(){var r=a?qt(e,this):e,i=n?qt(t,this):t;return Ut(r,i)}:Ut(e,t)}function qt(t,e){var n=t.call(e);if(n)return"object"!=typeof n&&l("Data function must return an object"),n.constructor!==Object&&g("Data function returned something other than a plain JavaScript object. This might work, but is strongly discouraged"),n}function Ut(t,e){if(t&&e){for(var n in e)n in t||(t[n]=e[n]);return t}return t||e}function Vt(t){var e=So(Qp);return e.parse=function(e,n){return Gt(e,n||t)},e}function Gt(t,e){if(!Hp)throw Error("Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser");return Hp(t,e||this.options)}function zt(t,e){var n;if(!Xi){if(e&&e.noThrow)return;throw Error("Cannot retrieve template #"+t+" as Ractive is not running in a browser.")}if(Wt(t)&&(t=t.substring(1)),!(n=document.getElementById(t))){if(e&&e.noThrow)return;throw Error("Could not find template element with id #"+t)}if("SCRIPT"!==n.tagName.toUpperCase()){if(e&&e.noThrow)return;throw Error("Template element with id #"+t+", must be a - + +